Created operator

pull/2/head
Louis Chatriot 12 years ago
parent b350ae447f
commit 1917bffb9e
  1. 24
      lib/model.js
  2. 27
      test/model.test.js

@ -415,15 +415,6 @@ function getDotValue (obj, field) {
function areThingsEqual (a, b) {
var aKeys , bKeys , i;
// String against regexp
if (util.isRegExp(b)) {
if (typeof a !== 'string') {
return false
} else {
return b.test(a);
}
}
// Strings, booleans, numbers, null
if (a === null || typeof a === 'string' || typeof a === 'boolean' || typeof a === 'number' ||
b === null || typeof b === 'string' || typeof b === 'boolean' || typeof b === 'number') { return a === b; }
@ -512,6 +503,16 @@ comparisonFunctions.$nin = function (a, b) {
return !comparisonFunctions.$in(a, b);
};
comparisonFunctions.$regex = function (a, b) {
if (!util.isRegExp(b)) { throw "$regex operator called with non regular expression"; }
if (typeof a !== 'string') {
return false
} else {
return b.test(a);
}
};
comparisonFunctions.$exists = function (value, exists) {
if (exists || exists === '') { // This will be true for all values of exists except false, null, undefined and 0
exists = true; // That's strange behaviour (we should only use true/false) but that's the way Mongo does it...
@ -638,8 +639,11 @@ function matchQueryPart (obj, queryKey, queryValue) {
}
}
// Using regular expressions with basic querying
if (util.isRegExp(queryValue)) { return comparisonFunctions.$regex(objValue, queryValue); }
// queryValue is either a native value or a normal object
// Simple matching is possible
// Basic matching is possible
if (!areThingsEqual(objValue, queryValue)) { return false; }
return true;

@ -741,16 +741,41 @@ describe('Model', function () {
model.match({ test: d }, { test: r }).should.equal(false);
});
it('Can match strings', function () {
it('Can match strings using basic querying', function () {
model.match({ test: 'true' }, { test: /true/ }).should.equal(true);
model.match({ test: 'babaaaar' }, { test: /aba+r/ }).should.equal(true);
model.match({ test: 'babaaaar' }, { test: /^aba+r/ }).should.equal(false);
model.match({ test: 'true' }, { test: /t[ru]e/ }).should.equal(false);
});
it('Can match strings using the $regex operator', function () {
model.match({ test: 'true' }, { test: { $regex: /true/ } }).should.equal(true);
model.match({ test: 'babaaaar' }, { test: { $regex: /aba+r/ } }).should.equal(true);
model.match({ test: 'babaaaar' }, { test: { $regex: /^aba+r/ } }).should.equal(false);
model.match({ test: 'true' }, { test: { $regex: /t[ru]e/ } }).should.equal(false);
});
it('Will throw if $regex operator is used with a non regex value', function () {
(function () {
model.match({ test: 'true' }, { test: { $regex: 42 } })
}).should.throw();
(function () {
model.match({ test: 'true' }, { test: { $regex: 'true' } })
}).should.throw();
});
it('Can use the $regex operator in cunjunction with other operators', function () {
model.match({ test: 'helLo' }, { test: { $regex: /ll/i, $nin: ['helL', 'helLop'] } }).should.equal(true);
model.match({ test: 'helLo' }, { test: { $regex: /ll/i, $nin: ['helLo', 'helLop'] } }).should.equal(false);
});
it('Can use dot-notation', function () {
model.match({ test: { nested: 'true' } }, { 'test.nested': /true/ }).should.equal(true);
model.match({ test: { nested: 'babaaaar' } }, { 'test.nested': /^aba+r/ }).should.equal(false);
model.match({ test: { nested: 'true' } }, { 'test.nested': { $regex: /true/ } }).should.equal(true);
model.match({ test: { nested: 'babaaaar' } }, { 'test.nested': { $regex: /^aba+r/ } }).should.equal(false);
});
});

Loading…
Cancel
Save