From 17725d054bfe268fb3436761a2a8e3ee7b4ae787 Mon Sep 17 00:00:00 2001 From: Naoto Kato Date: Tue, 11 Jul 2017 19:05:04 +0900 Subject: [PATCH 1/7] [test] add test cases --- test/comparators.js | 15 ++++++++++- test/query.js | 61 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/test/comparators.js b/test/comparators.js index b3654d7..a09d5b9 100644 --- a/test/comparators.js +++ b/test/comparators.js @@ -24,12 +24,23 @@ describe('comparator', function () { it('$lt should work', function () { comparator.$lt(0,1).should.be.true; comparator.$lt(1,0).should.be.false; + + comparator.$lt(0, 2).should.be.true; + comparator.$lt(1, 2).should.be.true; + comparator.$lt(2, 2).should.be.false; + comparator.$lt(3, 2).should.be.false; }); it('$lte should work', function () { comparator.$lte(0,1).should.be.true; comparator.$lte(1,1).should.be.true; comparator.$lte(1,0).should.be.false; + + comparator.$lte(0, 2).should.be.true; + comparator.$lte(1, 2).should.be.true; + comparator.$lte(2, 2).should.be.true; + comparator.$lte(3, 2).should.be.false; + }); it('$regex should work with string regex pattern', function () { @@ -55,13 +66,15 @@ describe('comparator', function () { it('$exists should work', function () { var a = undefined - , b = {c: 'hi'}; + , b = {c: 'hi', z: 0}; comparator.$exists(a, false).should.be.true; comparator.$exists(a, true).should.be.false; comparator.$exists(b, true).should.be.true; comparator.$exists(b.c, false).should.be.false; comparator.$exists(b.a, false).should.be.true; comparator.$exists('hi', true).should.be.true; + comparator.$exists(b.z, true).should.be.true; + comparator.$exists(b.z, false).should.be.false; }); it('$mod should work', function () { diff --git a/test/query.js b/test/query.js index 47a1ac1..282402e 100644 --- a/test/query.js +++ b/test/query.js @@ -16,6 +16,17 @@ describe('Query', function () { Q.test(11, { type: 'single' }).should.be.false; }); + it('should parse a single query 2', function () { + var query = { $lt: 2 } + , Q = filtr(query); + Q.stack.should.have.length(1); + Q.test(0, { type: 'single' }).should.be.true; + Q.test(1, { type: 'single' }).should.be.true; + Q.test(2, { type: 'single' }).should.be.false; + Q.test(3, { type: 'single' }).should.be.false; + }); + + it('should parse a lengthed query', function () { var query = { $lt: 10, $gt: 5 } , Q = filtr(query); @@ -159,6 +170,13 @@ describe('Query', function () { Q.test({ hello: 'universe' }, { type: 'single' }).should.be.true; }); + it('should assume $eq if no comparator provided - string("null")', function () { + var query = { 'hello': 'null' } + , Q = filtr(query); + Q.stack.should.have.length(1); + Q.test({ hello: 'null' }, { type: 'single' }).should.be.true; + }); + it('should assume $eq if no comparator provided - number', function () { var query = { 'hello': 42 } , Q = filtr(query); @@ -166,6 +184,24 @@ describe('Query', function () { Q.test({ hello: 42 }, { type: 'single' }).should.be.true; }); + it('should assume $eq if no comparator provided - number(0)', function () { + var query = { 'hello': 0 } + , Q = filtr(query); + Q.stack.should.have.length(1); + Q.test({ hello: 0 }, { type: 'single' }).should.be.true; + Q.test({}, { type: 'single' }).should.be.false; + Q.test({ hello: null }, { type: 'single' }).should.be.false; + }); + + it('should assume $eq if no comparator provided - null', function () { + var query = { 'hello': null } + , Q = filtr(query); + Q.stack.should.have.length(1); + Q.test({ hello: 0 }, { type: 'single' }).should.be.false; + Q.test({}, { type: 'single' }).should.be.false; + Q.test({ hello: null }, { type: 'single' }).should.be.true; + }); + it('should assume $eq if no comparator provided - boolean', function () { var query = { 'hello': true } , Q = filtr(query); @@ -268,6 +304,31 @@ describe('Query', function () { Q.test({sets: ['Firefox', 'abc']}, {type: 'single'}).should.be.false; }); + it('should regexp $ne work', function () { + var query = {'sets': {$ne: /Chrome/}} + , Q = filtr(query); + Q.stack.should.have.length(1); + Q.test({sets: ['Chrome', 'abc']}, {type: 'single'}).should.be.false; + Q.test({sets: ['Firefox', 'abc']}, {type: 'single'}).should.be.true; + }); + + it('should regexp $eq work', function () { + var query = {'sets': {$eq: /Chrome/}} + , Q = filtr(query); + Q.stack.should.have.length(1); + Q.test({sets: ['Chrome', 'abc']}, {type: 'single'}).should.be.true; + Q.test({sets: ['Firefox', 'abc']}, {type: 'single'}).should.be.false; + }); + + it('should regexp $eq work', function () { + var query = {'sets': /Chrome/} + , Q = filtr(query); + Q.stack.should.have.length(1); + Q.test({sets: ['Chrome', 'abc']}, {type: 'single'}).should.be.true; + Q.test({sets: ['Firefox', 'abc']}, {type: 'single'}).should.be.false; + }); + + }); // TODO: All nesting options. From f5b5442f455501e56d6cf9ffe2330ca866d827cb Mon Sep 17 00:00:00 2001 From: Naoto Kato Date: Tue, 11 Jul 2017 19:07:38 +0900 Subject: [PATCH 2/7] support null field value --- lib/filtr.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/lib/filtr.js b/lib/filtr.js index b2bef00..269e2eb 100644 --- a/lib/filtr.js +++ b/lib/filtr.js @@ -87,11 +87,16 @@ _eq = function (a, b) { if (a instanceof Array) { return a.some(function(v) {return _eq(v, b)}) } - if (!(b instanceof RegExp)) - return a == b; - if (a == null) + if (b instanceof RegExp) { + return b.test(a); + } + if (b === null) { + return (a === null) ? true : false + } + if (a === null) { return false - return b.test(a); + } + return a == b; } _in = function (a, b) { @@ -349,12 +354,12 @@ function getPathValues (parsed, obj) { var res = obj[p]; if ( (parsed.length == 1) ) { - if (res != null) { + // if (res != null) { if(Array.isArray(res)) return res return [res] - } - return [] + // } + // return [] } if (res != null) { @@ -503,7 +508,9 @@ function parseQuery (query) { || 'number' == typeof params || 'boolean' == typeof params || Array.isArray(params) - || params instanceof RegExp) { + || params instanceof RegExp + || params === null + || params === undefined) { qry.test = parseFilter({ $eq: params }); qry.path = parsePath(cmd); } else { @@ -539,7 +546,8 @@ function parseFilter (query) { var p = params[i]; if ('string' == typeof p || 'number' == typeof p - || 'boolean' == typeof p) { + || 'boolean' == typeof p + || p === null || p === undefined) { traverse = false } else { var nq = parseQuery(p); From 887ecd7efdbeebc33d40e4d80723306f88d2b87d Mon Sep 17 00:00:00 2001 From: Naoto Kato Date: Tue, 11 Jul 2017 19:08:32 +0900 Subject: [PATCH 3/7] fix for 0 --- lib/filtr.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/filtr.js b/lib/filtr.js index 269e2eb..534874b 100644 --- a/lib/filtr.js +++ b/lib/filtr.js @@ -144,7 +144,8 @@ Filtr.comparators = { } , $exists: function (a, b) { - return !!a == b; + var f = !(a === undefined || a === null) + return f === !!b; } , $mod: function (a, b) { From cf90b903c06e1f85309488cae8f2de859d656027 Mon Sep 17 00:00:00 2001 From: Naoto Kato Date: Tue, 11 Jul 2017 19:08:48 +0900 Subject: [PATCH 4/7] fix for null string --- lib/filtr.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/filtr.js b/lib/filtr.js index 534874b..395090f 100644 --- a/lib/filtr.js +++ b/lib/filtr.js @@ -338,7 +338,7 @@ function getPathValue (parsed, obj) { function getPathValues (parsed, obj) { - if (obj == null) + if (obj === null) return []; var part = parsed[0]; From 8063fa6f32bce5dbc80a82682a9c3d8cfeadc636 Mon Sep 17 00:00:00 2001 From: Naoto Kato Date: Tue, 11 Jul 2017 19:55:01 +0900 Subject: [PATCH 5/7] null field is exists --- lib/filtr.js | 2 +- test/comparators.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/filtr.js b/lib/filtr.js index 395090f..d480f1f 100644 --- a/lib/filtr.js +++ b/lib/filtr.js @@ -144,7 +144,7 @@ Filtr.comparators = { } , $exists: function (a, b) { - var f = !(a === undefined || a === null) + var f = !(a === undefined) return f === !!b; } diff --git a/test/comparators.js b/test/comparators.js index a09d5b9..1932423 100644 --- a/test/comparators.js +++ b/test/comparators.js @@ -66,7 +66,7 @@ describe('comparator', function () { it('$exists should work', function () { var a = undefined - , b = {c: 'hi', z: 0}; + , b = {c: 'hi', z: 0, n: null}; comparator.$exists(a, false).should.be.true; comparator.$exists(a, true).should.be.false; comparator.$exists(b, true).should.be.true; @@ -75,6 +75,8 @@ describe('comparator', function () { comparator.$exists('hi', true).should.be.true; comparator.$exists(b.z, true).should.be.true; comparator.$exists(b.z, false).should.be.false; + comparator.$exists(b.n, true).should.be.true; + comparator.$exists(b.n, false).should.be.false; }); it('$mod should work', function () { From f986ebe22be734372499a11f469e9e94b067753b Mon Sep 17 00:00:00 2001 From: Naoto Kato Date: Tue, 11 Jul 2017 19:55:19 +0900 Subject: [PATCH 6/7] update package version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 07b452a..3ec64ef 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Jake Luer ", "name": "filtr", "description": "Array filtering for node.js and the browser inspired by MongoDB.", - "version": "0.3.0", + "version": "0.3.3", "repository": { "type": "git", "url": "git://github.com/logicalparadox/filtr.git" From 67152bdecbfd1f0fabde3e9d49e1d4fb63741929 Mon Sep 17 00:00:00 2001 From: Naoto Kato Date: Wed, 12 Jul 2017 11:52:55 +0900 Subject: [PATCH 7/7] fix null value query --- lib/filtr.js | 2 +- test/query.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/filtr.js b/lib/filtr.js index d480f1f..bfdee21 100644 --- a/lib/filtr.js +++ b/lib/filtr.js @@ -91,7 +91,7 @@ _eq = function (a, b) { return b.test(a); } if (b === null) { - return (a === null) ? true : false + return (a === null || a === undefined) ? true : false } if (a === null) { return false diff --git a/test/query.js b/test/query.js index 282402e..cb7a021 100644 --- a/test/query.js +++ b/test/query.js @@ -198,8 +198,10 @@ describe('Query', function () { , Q = filtr(query); Q.stack.should.have.length(1); Q.test({ hello: 0 }, { type: 'single' }).should.be.false; - Q.test({}, { type: 'single' }).should.be.false; Q.test({ hello: null }, { type: 'single' }).should.be.true; + + // https://docs.mongodb.com/v3.2/tutorial/query-for-null-fields/ + Q.test({}, { type: 'single' }).should.be.true; }); it('should assume $eq if no comparator provided - boolean', function () {