diff --git a/.gitignore b/.gitignore index 3c3629e..eb79dd5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ node_modules +.idea diff --git a/index.js b/index.js index 723421e..daa8bfa 100644 --- a/index.js +++ b/index.js @@ -109,7 +109,7 @@ function updateDel(obj, path) { } function _update(current, path, fn) { - var match = path.match(/^([{\w\d:_-}]+)\.?(.+)?$/); + var match = path.match(/^([{\w\d:_\-}]+)\.?(.+)?$/); var key = match[1], rest = match[2]; if (isLookupKey(key)) { diff --git a/test.js b/test.js index d2c73ba..978e32e 100644 --- a/test.js +++ b/test.js @@ -130,6 +130,21 @@ describe('update', function() { }, 'no object found by {id:2}. autocreate is not supported'); }); }); + + context('when lookup key or value has `-`', function() { + it('performs lookup and carefully sets deeply nested item', function() { + var item1 = { 'item-name': 'item-1', baz: 2 }; + var item2 = { 'item-name': 'item-2', baz: 3 }; + var obj = { foo: { bar: [item1, item2] } }; + var upd = update(obj, 'foo.bar.{item-name:item-2}.baz', 5); + + assert.equal(upd.foo.bar[1].baz, 5); + assert.notStrictEqual(upd.foo.bar[1], item2, 'updated item should not be updated in place'); + assert.strictEqual(upd.foo.bar[0], item1, 'items in the collection should not be cloned'); + assert.notStrictEqual(upd.foo.bar, obj.foo.bar, 'collection should not be updated in place'); + assert.notStrictEqual(upd.foo, obj.foo, 'object should not be updated in place'); + }); + }); }); describe('update.unshift', function() {