From 195b46ccbbe56ac014ad92daafdf0e3dc9bda012 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Fri, 12 Jan 2024 10:07:42 -0500 Subject: [PATCH 1/2] fix(document): allow calling `push()` with different `$position` arguments Fix #14244 Re: #4322 --- lib/types/array/methods/index.js | 18 ++++++++---------- test/document.test.js | 13 +++++++------ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/lib/types/array/methods/index.js b/lib/types/array/methods/index.js index 13b3f493c98..45c88a9b2ad 100644 --- a/lib/types/array/methods/index.js +++ b/lib/types/array/methods/index.js @@ -2,7 +2,6 @@ const Document = require('../../../document'); const ArraySubdocument = require('../../ArraySubdocument'); -const MongooseError = require('../../../error/mongooseError'); const cleanModifiedSubpaths = require('../../../helpers/document/cleanModifiedSubpaths'); const internalToObjectOptions = require('../../../options').internalToObjectOptions; const mpath = require('mpath'); @@ -684,22 +683,21 @@ const methods = { if ((atomics.$push && atomics.$push.$each && atomics.$push.$each.length || 0) !== 0 && atomics.$push.$position != atomic.$position) { - throw new MongooseError('Cannot call `Array#push()` multiple times ' + - 'with different `$position`'); - } + if (atomic.$position != null) { + [].splice.apply(arr, [atomic.$position, 0].concat(values)); + ret = arr.length; + } else { + ret = [].push.apply(arr, values); + } - if (atomic.$position != null) { + this._registerAtomic('$set', this); + } else if (atomic.$position != null) { [].splice.apply(arr, [atomic.$position, 0].concat(values)); ret = this.length; } else { ret = [].push.apply(arr, values); } } else { - if ((atomics.$push && atomics.$push.$each && atomics.$push.$each.length || 0) !== 0 && - atomics.$push.$position != null) { - throw new MongooseError('Cannot call `Array#push()` multiple times ' + - 'with different `$position`'); - } atomic = values; ret = [].push.apply(arr, values); } diff --git a/test/document.test.js b/test/document.test.js index 627a43cf1d7..cd2246a1e9b 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -8232,12 +8232,13 @@ describe('document', function() { $each: [0], $position: 0 }); - assert.throws(() => { - doc.nums.push({ $each: [5] }); - }, /Cannot call.*multiple times/); - assert.throws(() => { - doc.nums.push(5); - }, /Cannot call.*multiple times/); + assert.deepStrictEqual(doc.nums.$__getAtomics(), [['$push', { $each: [0], $position: 0 }]]); + + doc.nums.push({ $each: [5] }); + assert.deepStrictEqual(doc.nums.$__getAtomics(), [['$set', [0, 1, 2, 3, 4, 5]]]); + + doc.nums.push({ $each: [0.5], $position: 1 }); + assert.deepStrictEqual(doc.nums.$__getAtomics(), [['$set', [0, 0.5, 1, 2, 3, 4, 5]]]); }); it('setting a path to a single nested document should update the single nested doc parent (gh-8400)', function() { From 6bc42cee9803cc056ecf8a83e697a7f617d60e17 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Fri, 12 Jan 2024 10:30:32 -0500 Subject: [PATCH 2/2] test: add missing issue to test title --- test/document.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/document.test.js b/test/document.test.js index cd2246a1e9b..beefe366d1f 100644 --- a/test/document.test.js +++ b/test/document.test.js @@ -8208,7 +8208,7 @@ describe('document', function() { assert.deepEqual(Object.keys(err.errors), ['age']); }); - it('array push with $position (gh-4322)', async function() { + it('array push with $position (gh-14244) (gh-4322)', async function() { const schema = Schema({ nums: [Number] });