diff --git a/packages/minimongo/minimongo_tests.js b/packages/minimongo/minimongo_tests.js index 3a2d2260eb..5b3e1a5dd0 100644 --- a/packages/minimongo/minimongo_tests.js +++ b/packages/minimongo/minimongo_tests.js @@ -2380,3 +2380,37 @@ Tinytest.add("minimongo - $near operator tests", function (test) { }); }); +Tinytest.add("minimongo - modifier affects selector", function (test) { + function testSelectorPaths (sel, paths, desc) { + test.isTrue(_.isEqual(LocalCollection._getSelectorPaths(sel), paths), desc); + } + + testSelectorPaths({ + foo: { + bar: 3, + baz: 42 + } + }, ['foo'], "literal"); + + testSelectorPaths({ + foo: 42, + bar: 33 + }, ['foo', 'bar'], "literal"); + + testSelectorPaths({ + foo: [ 'something' ], + bar: "asdf" + }, ['foo', 'bar'], "literal"); + + testSelectorPaths({ + a: { $lt: 3 }, + b: "you know, literal", + 'path.is.complicated': { $not: { $regex: 'acme.*corp' } } + }, ['a', 'b', 'path.is.complicated'], "literal + operators"); + + testSelectorPaths({ + $or: [{ 'a.b': 1 }, { 'a.b.c': { $lt: 22 } }, + {$and: [{ 'x.d': { $ne: 5, $gte: 433 } }, { 'a.b': 234 }]}] + }, ['a.b', 'a.b.c', 'x.d'], 'group operators + duplicates'); +}); + diff --git a/packages/minimongo/selector.js b/packages/minimongo/selector.js index 4bdead6640..74729b7152 100644 --- a/packages/minimongo/selector.js +++ b/packages/minimongo/selector.js @@ -811,15 +811,17 @@ LocalCollection._isSelectorAffectedByModifier = function (selector, modifier) { return _.filter(path.split('.'), isNaN).join('.'); } - function getPaths (sel, parentKeys) { - parentKeys = parentKeys || []; - return _.chain(sel).map(function (v, k) { - // we don't know how to handle $where because it can be anything - if (k === "$where") - return ''; // matches everything - if (_.has(LOGICAL_OPERATORS, k)) - return getPaths(v, parentKeys.concat(k)); - return parentKeys.concat(k).join('.'); - }).flatten().uniq().value(); - } +}; + +// Returns a list of key paths the given selector is looking for +var getPaths = LocalCollection._getSelectorPaths = function (sel, parentKeys) { + parentKeys = parentKeys || []; + return _.chain(sel).map(function (v, k) { + // we don't know how to handle $where because it can be anything + if (k === "$where") + return ''; // matches everything + if (_.has(LOGICAL_OPERATORS, k)) + return _.map(v, function (x) { return getPaths(x, parentKeys); }); + return parentKeys.concat(k).join('.'); + }).flatten().uniq().value(); };