diff --git a/lib/model.js b/lib/model.js index c112a8e..9638af5 100644 --- a/lib/model.js +++ b/lib/model.js @@ -99,8 +99,10 @@ function deserialize (rawData) { /** * Deep copy a DB object + * The optional strictKeys flag (defaulting to false) indicates whether to copy everything or only fields + * where the keys are valid, i.e. don't begin with $ and don't contain a . */ -function deepCopy (obj) { +function deepCopy (obj, strictKeys) { var res; if ( typeof obj === 'boolean' || @@ -113,14 +115,16 @@ function deepCopy (obj) { if (util.isArray(obj)) { res = []; - obj.forEach(function (o) { res.push(deepCopy(o)); }); + obj.forEach(function (o) { res.push(deepCopy(o, strictKeys)); }); return res; } if (typeof obj === 'object') { res = {}; Object.keys(obj).forEach(function (k) { - res[k] = deepCopy(obj[k]); + if (!strictKeys || (k[0] !== '$' && k.indexOf('.') === -1)) { + res[k] = deepCopy(obj[k], strictKeys); + } }); return res; } diff --git a/test/model.test.js b/test/model.test.js index ac642ed..bc92e4f 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -260,6 +260,22 @@ describe('Model', function () { b[0].hello.should.equal('another'); a[0].hello.should.equal('world'); }); + + it('Without the strictKeys option, everything gets deep copied', function () { + var a = { a: 4, $e: 'rrr', 'eee.rt': 42, nested: { yes: 1, 'tt.yy': 2, $nopenope: 3 }, array: [{ 'rr.hh': 1 }, { yes: true }, { $yes: false }] } + , b = model.deepCopy(a) + ; + + assert.deepEqual(a, b); + }); + + it('With the strictKeys option, only valid keys gets deep copied', function () { + var a = { a: 4, $e: 'rrr', 'eee.rt': 42, nested: { yes: 1, 'tt.yy': 2, $nopenope: 3 }, array: [{ 'rr.hh': 1 }, { yes: true }, { $yes: false }] } + , b = model.deepCopy(a, true) + ; + + assert.deepEqual(b, { a: 4, nested: { yes: 1 }, array: [{}, { yes: true }, {}] }); + }); }); // ==== End of 'Deep copying' ==== //