Deep copy finished and tested

pull/2/head
Louis Chatriot 12 years ago
parent e2b73d9e6f
commit ae8b43aad4
  1. 26
      lib/customUtils.js
  2. 2
      lib/datastore.js
  3. 33
      lib/model.js
  4. 35
      test/model.test.js

@ -14,7 +14,7 @@ function ensureDirectoryExists (dir, cb) {
, parts, currentPart , 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(); } if (dir.toTreat.length === 0) { return callback(); }
parts = dir.toTreat.split(path.sep); 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.ensureDirectoryExists = ensureDirectoryExists;
module.exports.uid = uid; module.exports.uid = uid;
module.exports.deepCopy = deepCopy;

@ -193,7 +193,7 @@ Datastore.prototype.persistWholeDatabase = function (data, cb) {
* For now the updateQuery only replaces the object * For now the updateQuery only replaces the object
*/ */
Datastore.modify = function (obj, updateQuery) { Datastore.modify = function (obj, updateQuery) {
updateQuery = customUtils.deepCopy(updateQuery); updateQuery = model.deepCopy(updateQuery);
updateQuery._id = obj._id; updateQuery._id = obj._id;
return updateQuery; return updateQuery;
}; };

@ -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 // Interface
module.exports.serialize = serialize; module.exports.serialize = serialize;
module.exports.deserialize = deserialize; module.exports.deserialize = deserialize;
module.exports.deepCopy = deepCopy;

@ -114,4 +114,39 @@ describe('Model', function () {
}); // ==== End of 'Serialization, deserialization' ==== // }); // ==== 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' ==== //
}); });

Loading…
Cancel
Save