From 2dc25d77aed7b759ebf76a2e1adbac300f936577 Mon Sep 17 00:00:00 2001 From: Slava Kim Date: Wed, 9 Oct 2013 15:02:02 -0700 Subject: [PATCH] Fix prefix check. Remove all numeric keys from sel --- packages/minimongo/minimongo_tests.js | 12 ++++++++++++ packages/minimongo/selector.js | 11 ++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/minimongo/minimongo_tests.js b/packages/minimongo/minimongo_tests.js index 8288bc8baa..1899f87501 100644 --- a/packages/minimongo/minimongo_tests.js +++ b/packages/minimongo/minimongo_tests.js @@ -2433,5 +2433,17 @@ Tinytest.add("minimongo - modifier affects selector", function (test) { notAffected({ 'foo.bar': 0 }, { $set: { 'foo.baz': 1 } }, "simplest"); affected({ 'foo.bar': 0 }, { $set: { 'foo.1': 1 } }, "simplest"); affected({ 'foo.bar': 0 }, { $set: { 'foo.2.bar': 1 } }, "simplest"); + + notAffected({ 'foo': 0 }, { $set: { 'foobaz': 1 } }, "correct prefix check"); + notAffected({ 'foobar': 0 }, { $unset: { 'foo': 1 } }, "correct prefix check"); + notAffected({ 'foo.bar': 0 }, { $unset: { 'foob': 1 } }, "correct prefix check"); + + // XXX once we consider all the array/non-array operators separately, this + // should become notAffected. Until then it's fine to let it "match" and + // affect. + //notAffected({ 'foo.3.bar': 0 }, { $set: { 'foo.2.bar': 1 } }, "observe for an array element"); + affected({ 'foo.3.bar': 0 }, { $set: { 'foo.2.bar': 1 } }, "observe for an array element"); + + affected({ 'foo.3.bar': 0 }, { $set: { 'foo.3.bar': 1 } }, "observe for an array element"); }); diff --git a/packages/minimongo/selector.js b/packages/minimongo/selector.js index a49385127b..b37b2cd2e7 100644 --- a/packages/minimongo/selector.js +++ b/packages/minimongo/selector.js @@ -802,9 +802,9 @@ LocalCollection._isSelectorAffectedByModifier = function (selector, modifier) { return _.any(modifiedPaths, function (path) { path = removeNumericsKeys(path); return _.any(meaningfulPaths, function (meaningfulPath) { - // It's full prefix - return path.indexOf(meaningfulPath) === 0 - || meaningfulPath.indexOf(path) === 0; + meaningfulPath = removeNumericsKeys(meaningfulPath); + return isPathPrefix(path, meaningfulPath) + || isPathPrefix(meaningfulPath, path); }); }); @@ -812,6 +812,11 @@ LocalCollection._isSelectorAffectedByModifier = function (selector, modifier) { return _.filter(path.split('.'), isNaN).join('.'); } + function isPathPrefix (s, t) { + var pos = t.indexOf(s); + return pos === 0 + && (pos + s.length === t.length || t[pos + s.length] === '.'); + } }; // Returns a list of key paths the given selector is looking for