From 6ea62ddd37eb981a83cda77399af11c4d3663077 Mon Sep 17 00:00:00 2001 From: Hafez Date: Sun, 17 Nov 2019 22:25:47 +0200 Subject: [PATCH 1/7] Reproduce #8317 --- test/types.documentarray.test.js | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/types.documentarray.test.js b/test/types.documentarray.test.js index 1a148714750..4b31ee82cce 100644 --- a/test/types.documentarray.test.js +++ b/test/types.documentarray.test.js @@ -575,6 +575,20 @@ describe('types.documentarray', function() { assert.equal(arr.length, 1); assert.equal(doc.docs.length, 2); }); + + it('map() copies parent and path ()', function() { + const personSchema = new Schema({ friends: [{ name: { type: String } }]}); + const Person = mongoose.model('Person', personSchema); + + const person = new Person({ friends: [{ name: 'Hafez' }] }); + + const friendsNames = person.friends.map(friend => friend.name); + + friendsNames.push('Sam'); + + assert.equal(friendsNames.length, 2); + assert.equal(friendsNames[1], 'Sam'); + }); }); it('cleans modified subpaths on splice() (gh-7249)', function() { From 7bd3663f61460e0c2e2b6854ddcf9d8be72f6028 Mon Sep 17 00:00:00 2001 From: Hafez Date: Sun, 17 Nov 2019 22:26:09 +0200 Subject: [PATCH 2/7] Fixes #8317 map(...) --- lib/types/documentarray.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/lib/types/documentarray.js b/lib/types/documentarray.js index 87757e4f171..9ac61bf69fd 100644 --- a/lib/types/documentarray.js +++ b/lib/types/documentarray.js @@ -180,6 +180,15 @@ class CoreDocumentArray extends CoreMongooseArray { return arr; } + map() { + const arr = super.map.apply(this,arguments); + + arr[arrayParentSymbol] = this[arrayParentSymbol]; + arr[arrayPathSymbol] = this[arrayPathSymbol]; + + return arr; + } + /** * Wraps [`Array#push`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/push) with proper change tracking. * @@ -328,18 +337,18 @@ if (util.inspect.custom) { function _updateParentPopulated(arr) { const parent = arr[arrayParentSymbol]; - if (parent.$__.populated != null) { - const populatedPaths = Object.keys(parent.$__.populated). - filter(p => p.startsWith(arr[arrayPathSymbol] + '.')); + if (parent.$__.populated == null) return; - for (const path of populatedPaths) { - const remnant = path.slice((arr[arrayPathSymbol] + '.').length); - if (!Array.isArray(parent.$__.populated[path].value)) { - continue; - } + const populatedPaths = Object.keys(parent.$__.populated). + filter(p => p.startsWith(arr[arrayPathSymbol] + '.')); - parent.$__.populated[path].value = arr.map(val => val.populated(remnant)); + for (const path of populatedPaths) { + const remnant = path.slice((arr[arrayPathSymbol] + '.').length); + if (!Array.isArray(parent.$__.populated[path].value)) { + continue; } + + parent.$__.populated[path].value = arr.map(val => val.populated(remnant)); } } From e01c247537ecb179e804c5692aa476fa0f13ed9a Mon Sep 17 00:00:00 2001 From: Hafez Date: Sun, 17 Nov 2019 22:33:06 +0200 Subject: [PATCH 3/7] Fix overwriting model name --- test/types.documentarray.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/types.documentarray.test.js b/test/types.documentarray.test.js index 4b31ee82cce..3150bdf8aba 100644 --- a/test/types.documentarray.test.js +++ b/test/types.documentarray.test.js @@ -578,7 +578,7 @@ describe('types.documentarray', function() { it('map() copies parent and path ()', function() { const personSchema = new Schema({ friends: [{ name: { type: String } }]}); - const Person = mongoose.model('Person', personSchema); + const Person = mongoose.model('gh8317-map', personSchema); const person = new Person({ friends: [{ name: 'Hafez' }] }); From ba2c35377d5f48eca2d338eb10ab66de68ec237c Mon Sep 17 00:00:00 2001 From: Hafez Date: Tue, 19 Nov 2019 00:18:27 +0200 Subject: [PATCH 4/7] Make DocumentArray#map return a regular JS array --- lib/types/documentarray.js | 8 ++------ test/types.documentarray.test.js | 3 ++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/lib/types/documentarray.js b/lib/types/documentarray.js index 9ac61bf69fd..89709f2fbda 100644 --- a/lib/types/documentarray.js +++ b/lib/types/documentarray.js @@ -181,11 +181,7 @@ class CoreDocumentArray extends CoreMongooseArray { } map() { - const arr = super.map.apply(this,arguments); - - arr[arrayParentSymbol] = this[arrayParentSymbol]; - arr[arrayPathSymbol] = this[arrayPathSymbol]; - + const arr = [].concat(Array.prototype.map.apply(this,arguments)); return arr; } @@ -337,7 +333,7 @@ if (util.inspect.custom) { function _updateParentPopulated(arr) { const parent = arr[arrayParentSymbol]; - if (parent.$__.populated == null) return; + if (!parent || parent.$__.populated == null) return; const populatedPaths = Object.keys(parent.$__.populated). filter(p => p.startsWith(arr[arrayPathSymbol] + '.')); diff --git a/test/types.documentarray.test.js b/test/types.documentarray.test.js index 3150bdf8aba..28a8d5f3ac6 100644 --- a/test/types.documentarray.test.js +++ b/test/types.documentarray.test.js @@ -576,13 +576,14 @@ describe('types.documentarray', function() { assert.equal(doc.docs.length, 2); }); - it('map() copies parent and path ()', function() { + it('map() works and does not return a mongoose array', function() { const personSchema = new Schema({ friends: [{ name: { type: String } }]}); const Person = mongoose.model('gh8317-map', personSchema); const person = new Person({ friends: [{ name: 'Hafez' }] }); const friendsNames = person.friends.map(friend => friend.name); + assert.deepEqual(friendsNames.constructor, Array); friendsNames.push('Sam'); From ba38d1de8ec94d72d2730d6186fc01301f2258ea Mon Sep 17 00:00:00 2001 From: Hafez Date: Tue, 19 Nov 2019 00:33:19 +0200 Subject: [PATCH 5/7] Add test to fiter --- test/types.documentarray.test.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/test/types.documentarray.test.js b/test/types.documentarray.test.js index 28a8d5f3ac6..33a60fd948a 100644 --- a/test/types.documentarray.test.js +++ b/test/types.documentarray.test.js @@ -590,6 +590,25 @@ describe('types.documentarray', function() { assert.equal(friendsNames.length, 2); assert.equal(friendsNames[1], 'Sam'); }); + + it('filter() copies parent and path (gh-8317)', function() { + const personSchema = new Schema({ friends: [{ name: { type: String }, age: { type: Number } }] }); + const Person = mongoose.model('gh8317-filter', personSchema); + + const person = new Person({ friends: [ + { name: 'Hafez', age: 25 }, + { name: 'Sam', age: 27 } + ] }); + + const filteredFriends = person.friends.filter(friend => friend.age > 26); + assert.ok(filteredFriends.isMongooseArray); + assert.equal(filteredFriends.constructor.name, 'CoreDocumentArray'); + + filteredFriends.push({ name: 'John', age: 30 }); + + assert.equal(filteredFriends.length, 2); + assert.equal(filteredFriends[1].name, 'John'); + }); }); it('cleans modified subpaths on splice() (gh-7249)', function() { From 4599877d99b7c8f824acba6e520f4efdf8a1f616 Mon Sep 17 00:00:00 2001 From: Hafez Date: Tue, 19 Nov 2019 20:51:51 +0200 Subject: [PATCH 6/7] Revert making map return vanilla JS Array --- lib/types/documentarray.js | 5 ----- test/types.documentarray.test.js | 4 +--- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/types/documentarray.js b/lib/types/documentarray.js index 89709f2fbda..b9cc33cd24d 100644 --- a/lib/types/documentarray.js +++ b/lib/types/documentarray.js @@ -180,11 +180,6 @@ class CoreDocumentArray extends CoreMongooseArray { return arr; } - map() { - const arr = [].concat(Array.prototype.map.apply(this,arguments)); - return arr; - } - /** * Wraps [`Array#push`](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/push) with proper change tracking. * diff --git a/test/types.documentarray.test.js b/test/types.documentarray.test.js index 33a60fd948a..ae92c672169 100644 --- a/test/types.documentarray.test.js +++ b/test/types.documentarray.test.js @@ -576,15 +576,13 @@ describe('types.documentarray', function() { assert.equal(doc.docs.length, 2); }); - it('map() works and does not return a mongoose array', function() { + it('map() works', function() { const personSchema = new Schema({ friends: [{ name: { type: String } }]}); const Person = mongoose.model('gh8317-map', personSchema); const person = new Person({ friends: [{ name: 'Hafez' }] }); const friendsNames = person.friends.map(friend => friend.name); - assert.deepEqual(friendsNames.constructor, Array); - friendsNames.push('Sam'); assert.equal(friendsNames.length, 2); From 63c2f1efe21f4a0f0615008440df212d7ceaf9fa Mon Sep 17 00:00:00 2001 From: Hafez Date: Tue, 19 Nov 2019 21:19:19 +0200 Subject: [PATCH 7/7] Remove filter test --- test/types.documentarray.test.js | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/test/types.documentarray.test.js b/test/types.documentarray.test.js index ae92c672169..8140ee484b0 100644 --- a/test/types.documentarray.test.js +++ b/test/types.documentarray.test.js @@ -588,25 +588,6 @@ describe('types.documentarray', function() { assert.equal(friendsNames.length, 2); assert.equal(friendsNames[1], 'Sam'); }); - - it('filter() copies parent and path (gh-8317)', function() { - const personSchema = new Schema({ friends: [{ name: { type: String }, age: { type: Number } }] }); - const Person = mongoose.model('gh8317-filter', personSchema); - - const person = new Person({ friends: [ - { name: 'Hafez', age: 25 }, - { name: 'Sam', age: 27 } - ] }); - - const filteredFriends = person.friends.filter(friend => friend.age > 26); - assert.ok(filteredFriends.isMongooseArray); - assert.equal(filteredFriends.constructor.name, 'CoreDocumentArray'); - - filteredFriends.push({ name: 'John', age: 30 }); - - assert.equal(filteredFriends.length, 2); - assert.equal(filteredFriends[1].name, 'John'); - }); }); it('cleans modified subpaths on splice() (gh-7249)', function() {