From ae8b43aad4309cfed5a1dcf76cd8c0aa6f4648a3 Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Sat, 4 May 2013 13:38:09 +0200 Subject: [PATCH] Deep copy finished and tested --- lib/customUtils.js | 26 +------------------------- lib/datastore.js | 2 +- lib/model.js | 33 +++++++++++++++++++++++++++++++++ test/model.test.js | 35 +++++++++++++++++++++++++++++++++++ 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/lib/customUtils.js b/lib/customUtils.js index 52b564d..28c46bb 100644 --- a/lib/customUtils.js +++ b/lib/customUtils.js @@ -14,7 +14,7 @@ function ensureDirectoryExists (dir, cb) { , parts, currentPart ; - if (typeof dir === 'string') { return ensureDirectoryExists({ toTreat: dir, treated: '' }); } + if (typeof dir === 'string') { return ensureDirectoryExists({ toTreat: dir, treated: '' }, callback); } if (dir.toTreat.length === 0) { return callback(); } parts = dir.toTreat.split(path.sep); @@ -49,30 +49,6 @@ function uid (len) { } -/** - * Deep copy an DB object - * TODO: Put in serialization/deserialization and tackle all cases - */ -function deepCopy (obj) { - var res; - - if (typeof obj === 'boolean' || typeof obj === 'number' || typeof obj === 'string') { - return obj; - } - - if (typeof obj === 'object') { - res = {}; - Object.keys(obj).forEach(function (k) { - res[k] = deepCopy(obj[k]); - }); - return res; - } - - return undefined; // For now everything else is undefined. We should probably throw an error instead -} - - module.exports.ensureDirectoryExists = ensureDirectoryExists; module.exports.uid = uid; -module.exports.deepCopy = deepCopy; diff --git a/lib/datastore.js b/lib/datastore.js index e776400..e93830d 100644 --- a/lib/datastore.js +++ b/lib/datastore.js @@ -193,7 +193,7 @@ Datastore.prototype.persistWholeDatabase = function (data, cb) { * For now the updateQuery only replaces the object */ Datastore.modify = function (obj, updateQuery) { - updateQuery = customUtils.deepCopy(updateQuery); + updateQuery = model.deepCopy(updateQuery); updateQuery._id = obj._id; return updateQuery; }; diff --git a/lib/model.js b/lib/model.js index 1dffdba..9620119 100644 --- a/lib/model.js +++ b/lib/model.js @@ -48,7 +48,40 @@ function deserialize (rawData) { } +/** + * Deep copy a DB object + */ +function deepCopy (obj) { + var res; + + if ( typeof obj === 'boolean' || + typeof obj === 'number' || + typeof obj === 'string' || + obj === null || + (obj && obj.constructor && obj.constructor.name === 'Date') ) { + return obj; + } + + if (obj instanceof Array) { + res = []; + obj.forEach(function (o) { res.push(o); }); + return res; + } + + if (typeof obj === 'object') { + res = {}; + Object.keys(obj).forEach(function (k) { + res[k] = deepCopy(obj[k]); + }); + return res; + } + + return undefined; // For now everything else is undefined. We should probably throw an error instead +} + + // Interface module.exports.serialize = serialize; module.exports.deserialize = deserialize; +module.exports.deepCopy = deepCopy; diff --git a/test/model.test.js b/test/model.test.js index 646d2cd..a52c1d7 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -114,4 +114,39 @@ describe('Model', function () { }); // ==== End of 'Serialization, deserialization' ==== // + + describe('Deep copying', function () { + + it('Should be able to deep copy any serializable model', function () { + var d = new Date() + , obj = { a: ['ee', 'ff', 42], date: d, subobj: { a: 'b', b: 'c' } } + , res = model.deepCopy(obj); + ; + + res.a.length.should.equal(3); + res.a[0].should.equal('ee'); + res.a[1].should.equal('ff'); + res.a[2].should.equal(42); + res.date.getTime().should.equal(d.getTime()); + res.subobj.a.should.equal('b'); + res.subobj.b.should.equal('c'); + + obj.a.push('ggg'); + obj.date = 'notadate'; + obj.subobj = []; + + // Even if the original object is modified, the copied one isn't + res.a.length.should.equal(3); + res.a[0].should.equal('ee'); + res.a[1].should.equal('ff'); + res.a[2].should.equal(42); + res.date.getTime().should.equal(d.getTime()); + res.subobj.a.should.equal('b'); + res.subobj.b.should.equal('c'); + }); + + + + }); // ==== End of 'Deep copying' ==== // + });