diff --git a/lib/model.js b/lib/model.js index ff4c4b7..accdc16 100644 --- a/lib/model.js +++ b/lib/model.js @@ -640,6 +640,23 @@ logicalOperators.$not = function (obj, query) { }; +/** + * Use a function to match + * @param {Model} obj + * @param {Query} query + */ +logicalOperators.$where = function (obj, func) { + var result; + + if (!_.isFunction(func)) { throw "$where operator used without a function"; } + + result = func.call(obj); + if (!_.isBoolean(result)) { throw "$where function must return boolean"; } + + return result; +}; + + /** * Tell if a given document matches a query * @param {Object} obj Document to check diff --git a/test/model.test.js b/test/model.test.js index aae3bfb..06f5a4c 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -1172,6 +1172,24 @@ describe('Model', function () { }); + describe('Logical operator $where', function () { + + it('Function should match and not match correctly', function () { + model.match({ a: 4}, { $where: function () { return this.a === 4; } }).should.equal(true); + model.match({ a: 4}, { $where: function () { return this.a === 5; } }).should.equal(false); + }); + + it('Should throw an error if the $where function is not, in fact, a function', function () { + (function () { model.match({ a: 4 }, { $where: 'not a function' }); }).should.throw(); + }); + + it('Should throw an error if the $where function returns a non-boolean', function () { + (function () { model.match({ a: 4 }, { $where: function () { return 'not a boolean'; } }); }).should.throw(); + }); + + }); + + describe('Array fields', function () { it('Field equality', function () {