From 6586c7f81ac8882e7161d52775b99c1c26ebb544 Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Wed, 15 May 2013 18:12:34 +0200 Subject: [PATCH] Cannot mix behaviour and cannot use non registered modifiers --- lib/model.js | 35 ++++++++++++++++++++++++++++++----- test/model.test.js | 20 +++++++++++++++++++- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/lib/model.js b/lib/model.js index bf0710e..7d5f2c8 100644 --- a/lib/model.js +++ b/lib/model.js @@ -7,6 +7,8 @@ var dateToJSON = function () { return { $$date: this.getTime() }; } , originalDateToJSON = Date.prototype.toJSON , util = require('util') + , _ = require('underscore') + , modifierFunctions = {} ; @@ -123,19 +125,42 @@ function deepCopy (obj) { } +modifierFunctions.$inc = function () {}; +modifierFunctions.$set = function () {}; + + /** * Modify a DB object according to an update query * For now the updateQuery only replaces the object */ function modify (obj, updateQuery) { - if (updateQuery._id) { throw "You cannot change a document's _id"; } + var keys = Object.keys(updateQuery) + , firstChars = _.map(keys, function (item) { return item[0]; }) + , dollarFirstChars = _.filter(firstChars, function (c) { return c === '$'; }) + , newDoc, modifiers + ; + + if (keys.indexOf('_id') !== -1) { throw "You cannot change a document's _id"; } - updateQuery = deepCopy(updateQuery); - updateQuery._id = obj._id; + if (dollarFirstChars.length !== 0 && dollarFirstChars.length !== firstChars.length) { + throw "You cannot mix modifiers and normal fields"; + } - checkObject(updateQuery); + if (dollarFirstChars.length === 0) { + // Simply replace the object with the update query contents + newDoc = deepCopy(updateQuery); + newDoc._id = obj._id; + } else { + // Apply modifiers + modifiers = _.uniq(keys); + modifiers.forEach(function (m) { + if (!modifierFunctions[m]) { throw "Unknown modifier " + m; } + }); + } - return updateQuery; + // Check result is valid and return it + checkObject(newDoc); + return newDoc; }; diff --git a/test/model.test.js b/test/model.test.js index f0b17dd..1984bec 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -212,7 +212,7 @@ describe('Model', function () { t._id.should.equal('keepit'); }); - it('Raise an error if trying to replace the _id field in a copy-type modification', function () { + it('Throw an error if trying to replace the _id field in a copy-type modification', function () { var obj = { some: 'thing', _id: 'keepit' } , updateQuery = { replace: 'done', bloup: [ 1, 8], _id: 'donttryit' } ; @@ -222,6 +222,24 @@ describe('Model', function () { }).should.throw(); }); + it('Throw an error if trying to use modify in a mixed copy+modify way', function () { + var obj = { some: 'thing' } + , updateQuery = { replace: 'me', $modify: 'metoo' }; + + (function () { + model.modify(obj, updateQuery); + }).should.throw(); + }); + + it('Throw an error if trying to use an inexistent modifier', function () { + var obj = { some: 'thing' } + , updateQuery = { $set: 'this exists', $modify: 'not this one' }; + + (function () { + model.modify(obj, updateQuery); + }).should.throw(); + }); + }); // ==== End of 'Modifying documents' ==== // });