From f7e3916693cbdeacf99e2856fe660b0c8e5f8e00 Mon Sep 17 00:00:00 2001 From: Louis Chatriot Date: Wed, 22 May 2013 18:54:52 +0200 Subject: [PATCH] Specific function to get value by dot notation --- lib/model.js | 22 ++++++++-------------- test/model.test.js | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/lib/model.js b/lib/model.js index 74f92e6..edf121d 100644 --- a/lib/model.js +++ b/lib/model.js @@ -231,7 +231,9 @@ function modify (obj, updateQuery) { // ============================================================== /** - * Check whether things are equal + * Check whether 'things' are equal + * Things are defined as any native types (string, number, boolean, null, date) and objects + * In the case of object, we check deep equality * Returns true if they are, false otherwise */ function areThingsEqual (a, b) { @@ -248,7 +250,8 @@ function areThingsEqual (a, b) { // undefined (no match since they mean field doesn't exist and can't be serialized) if (util.isArray(a) || util.isArray(b) || a === undefined || b === undefined) { return false; } - // a and b should be objects + // Objects (check for deep equality) + // a and b should be objects at this point try { aKeys = Object.keys(a); bKeys = Object.keys(b); @@ -256,7 +259,6 @@ function areThingsEqual (a, b) { return false; } - // Objects if (aKeys.length !== bKeys.length) { return false; } for (i = 0; i < aKeys.length; i += 1) { if (bKeys.indexOf(aKeys[i]) === -1) { return false; } @@ -279,7 +281,7 @@ function getDotValue (obj, field) { if (fieldParts.length === 1) { return obj[fieldParts[0]]; } else { - return matcherFunctions.$eq(obj[fieldParts[0]], fieldParts.slice(1)); + return getDotValue(obj[fieldParts[0]], fieldParts.slice(1)); } } @@ -291,19 +293,10 @@ function getDotValue (obj, field) { * @param {Model} value */ matcherFunctions.$eq = function (obj, field, value) { - var fieldParts = typeof field === 'string' ? field.split('.') : field; - - if (!obj) { return false; } // field cannot be empty here so that means there is no match - - if (fieldParts.length === 1) { - return areThingsEqual(obj[fieldParts[0]], value); - } else { - return matcherFunctions.$eq(obj[fieldParts[0]], fieldParts.slice(1), value); - } + return areThingsEqual(getDotValue(obj, field), value); }; - /** * Tell if a given document matches a query */ @@ -325,5 +318,6 @@ module.exports.deserialize = deserialize; module.exports.deepCopy = deepCopy; module.exports.checkObject = checkObject; module.exports.modify = modify; +module.exports.getDotValue = getDotValue; module.exports.match = match; module.exports.areThingsEqual = areThingsEqual; diff --git a/test/model.test.js b/test/model.test.js index 49432cd..81dbadb 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -376,6 +376,22 @@ describe('Model', function () { }); + + describe('Getting a fields value in dot notation', function () { + + it('Return first-level and nested values', function () { + model.getDotValue({ hello: 'world' }, 'hello').should.equal('world'); + model.getDotValue({ hello: 'world', type: { planet: true, blue: true } }, 'type.planet').should.equal(true); + }); + + it('Return undefined if the field cannot be found in the object', function () { + assert.isUndefined(model.getDotValue({ hello: 'world' }, 'helloo')); + assert.isUndefined(model.getDotValue({ hello: 'world', type: { planet: true } }, 'type.plane')); + }); + + }); + + describe('$eq', function () { it('Can find documents with simple fields', function () {