From 1bee5827bbea66695fe32443a47affcfd4864827 Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Sat, 20 Dec 2014 22:31:14 +0100 Subject: [PATCH] Fixed bug in deepCopy thay didnt deep copy array contents --- lib/model.js | 4 +-- test/db.test.js | 72 ++++++++++++++++++++++++++++++++-------------- test/model.test.js | 11 +++++++ 3 files changed, 63 insertions(+), 24 deletions(-) diff --git a/lib/model.js b/lib/model.js index a832121..c112a8e 100644 --- a/lib/model.js +++ b/lib/model.js @@ -113,7 +113,7 @@ function deepCopy (obj) { if (util.isArray(obj)) { res = []; - obj.forEach(function (o) { res.push(o); }); + obj.forEach(function (o) { res.push(deepCopy(o)); }); return res; } @@ -374,7 +374,6 @@ Object.keys(lastStepModifierFunctions).forEach(function (modifier) { /** * Modify a DB object according to an update query - * For now the updateQuery only replaces the object */ function modify (obj, updateQuery) { var keys = Object.keys(updateQuery) @@ -416,6 +415,7 @@ function modify (obj, updateQuery) { // Check result is valid and return it checkObject(newDoc); + if (obj._id !== newDoc._id) { throw "You can't change a document's _id"; } return newDoc; }; diff --git a/test/db.test.js b/test/db.test.js index bbeefa8..57aa2fd 100644 --- a/test/db.test.js +++ b/test/db.test.js @@ -971,38 +971,66 @@ describe('Database', function () { ], done); }); - it('Can perform upserts if needed', function (done) { - d.update({ impossible: 'db is empty anyway' }, { newDoc: true }, {}, function (err, nr, upsert) { - assert.isNull(err); - nr.should.equal(0); - assert.isUndefined(upsert); + describe.skip('Upserts', function () { + + it('Can perform upserts if needed', function (done) { + d.update({ impossible: 'db is empty anyway' }, { newDoc: true }, {}, function (err, nr, upsert) { + assert.isNull(err); + nr.should.equal(0); + assert.isUndefined(upsert); - d.find({}, function (err, docs) { - docs.length.should.equal(0); // Default option for upsert is false + d.find({}, function (err, docs) { + docs.length.should.equal(0); // Default option for upsert is false - d.update({ impossible: 'db is empty anyway' }, { something: "created ok" }, { upsert: true }, function (err, nr, newDoc) { - assert.isNull(err); - nr.should.equal(1); - newDoc.something.should.equal("created ok"); - assert.isDefined(newDoc._id); + d.update({ impossible: 'db is empty anyway' }, { something: "created ok" }, { upsert: true }, function (err, nr, newDoc) { + assert.isNull(err); + nr.should.equal(1); + newDoc.something.should.equal("created ok"); + assert.isDefined(newDoc._id); - d.find({}, function (err, docs) { - docs.length.should.equal(1); // Default option for upsert is false - docs[0].something.should.equal("created ok"); - - // Modifying the returned upserted document doesn't modify the database - newDoc.newField = true; d.find({}, function (err, docs) { + docs.length.should.equal(1); // Default option for upsert is false docs[0].something.should.equal("created ok"); - assert.isUndefined(docs[0].newField); - - done(); + + // Modifying the returned upserted document doesn't modify the database + newDoc.newField = true; + d.find({}, function (err, docs) { + docs[0].something.should.equal("created ok"); + assert.isUndefined(docs[0].newField); + + done(); + }); }); }); }); }); }); - }); + + it('If the update query is a normal object with no modifiers, it is the doc that will be upserted', function (done) { + d.update({ $or: [{ a: 4 }, { a: 5 }] }, { hello: 'world', bloup: 'blap' }, { upsert: true }, function (err) { + d.findOne({}, function (err, doc) { + assert.isNull(err); + Object.keys(doc).length.should.equal(3); + doc.hello.should.equal('world'); + doc.bloup.should.equal('blap'); + done(); + }); + }); + }); + + it('If the update query contains modifiers, it is applied to the object resulting from removing all operator fro; the find query', function (done) { + d.update({ $or: [{ a: 4 }, { a: 5 }] }, { hello: 'world', $inc: { bloup: 3 } }, { upsert: true }, function (err) { + d.findOne({ hello: 'world' }, function (err, doc) { + assert.isNull(err); + Object.keys(doc).length.should.equal(3); + doc.hello.should.equal('world'); + doc.bloup.should.equal(3); + done(); + }); + }); + }); + + }); // ==== End of 'Upserts' ==== // it('Cannot perform update if the update query is not either registered-modifiers-only or copy-only, or contain badly formatted fields', function (done) { d.insert({ something: 'yup' }, function () { diff --git a/test/model.test.js b/test/model.test.js index 79796e8..ac642ed 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -249,6 +249,17 @@ describe('Model', function () { res.subobj.a.should.equal('b'); res.subobj.b.should.equal('c'); }); + + it('Should deep copy the contents of an array', function () { + var a = [{ hello: 'world' }] + , b = model.deepCopy(a) + ; + + b[0].hello.should.equal('world'); + b[0].hello = 'another'; + b[0].hello.should.equal('another'); + a[0].hello.should.equal('world'); + }); }); // ==== End of 'Deep copying' ==== //