From c499f7c9dae9c3ab19bcfdbcff3dc49ff68469dc Mon Sep 17 00:00:00 2001 From: Avital Oliver Date: Mon, 20 Aug 2012 15:07:32 -0700 Subject: [PATCH] Fixes #126 -- minimingo fails on dotted queries if undefined is seen --- packages/minimongo/minimongo_tests.js | 8 ++++++++ packages/minimongo/selector.js | 8 +++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/packages/minimongo/minimongo_tests.js b/packages/minimongo/minimongo_tests.js index 13aaaf471a..b27de3a4a5 100644 --- a/packages/minimongo/minimongo_tests.js +++ b/packages/minimongo/minimongo_tests.js @@ -532,6 +532,14 @@ Tinytest.add("minimongo - selector_compiler", function (test) { match({"a.b": /a/}, {a: {b: "cat"}}); nomatch({"a.b": /a/}, {a: {b: "dog"}}); + // trying to access a dotted field that is undefined at some point + // down the chain + nomatch({"a.b": 1}, {x: 2}); + nomatch({"a.b.c": 1}, {a: {x: 2}}); + nomatch({"a.b.c": 1}, {a: {b: {x: 2}}}); + nomatch({"a.b.c": 1}, {a: {b: 1}}); + nomatch({"a.b.c": 1}, {a: {b: 0}}); + // dotted keypaths: literal objects match({"a.b": {c: 1}}, {a: {b: {c: 1}}}); nomatch({"a.b": {c: 1}}, {a: {b: {c: 2}}}); diff --git a/packages/minimongo/selector.js b/packages/minimongo/selector.js index 90fb8b3e87..00f2c3828f 100644 --- a/packages/minimongo/selector.js +++ b/packages/minimongo/selector.js @@ -384,20 +384,22 @@ LocalCollection._exprForKeypathPredicate = function (keypath, value, literals) { } // now, deal with the orthogonal concern of dotted.key.paths and the - // (potentially multi-level) array searching they require + // (potentially multi-level) array searching they require. + // while at it, make sure to not throw an exception if we hit undefined while + // drilling down through the dotted parts var ret = ''; var innermost = true; while (keyparts.length) { var part = keyparts.pop(); var formal = keyparts.length ? "x" : "doc"; if (innermost) { - ret = '(function(x){return ' + predcode + ';})(' + formal + '[' + + ret = '(function(x){return ' + predcode + ';})(' + formal + '&&' + formal + '[' + JSON.stringify(part) + '])'; innermost = false; } else { // for all but the innermost level of a dotted expression, // if the runtime type is an array, search it - ret = 'f._matches(' + formal + '[' + JSON.stringify(part) + + ret = 'f._matches(' + formal + '&&' + formal + '[' + JSON.stringify(part) + '], function(x){return ' + ret + ';})'; } }