From d8792bce06e2728de3d9f0d4f861dff6c0dad33d Mon Sep 17 00:00:00 2001 From: KungD Date: Thu, 16 Oct 2014 08:05:19 +0200 Subject: [PATCH 1/5] add $delete command to addons.update --- docs/docs/09.6-update.md | 1 + src/addons/__tests__/update-test.js | 11 ++++++++++- src/addons/update.js | 16 +++++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/docs/docs/09.6-update.md b/docs/docs/09.6-update.md index 2169ba5c1c654..c51c01a58dd55 100644 --- a/docs/docs/09.6-update.md +++ b/docs/docs/09.6-update.md @@ -62,6 +62,7 @@ The `$`-prefixed keys are called *commands*. The data structure they are "mutati * `{$set: any}` replace the target entirely. * `{$merge: object}` merge the keys of `object` with the target. * `{$apply: function}` passes in the current value to the function and updates it with the new returned value. + * `{$delete: string} deletes the given key or array of keys from the target. ## Examples diff --git a/src/addons/__tests__/update-test.js b/src/addons/__tests__/update-test.js index 3c5dda7752557..606e0baf98d6a 100644 --- a/src/addons/__tests__/update-test.js +++ b/src/addons/__tests__/update-test.js @@ -79,6 +79,15 @@ describe('update', function() { ); }); + it('should support delete', function() { + expect(update({a:1,b:2}, {$delete:'b'})).toEqual({a:1}); + expect(update({a:1,b:2,c:3}, {$delete:['a','c']})).toEqual({b:2}); + expect(update.bind(null, 2, {$delete: 'foo'})).toThrow( + 'Invariant Violation: update(): expected target of $delete to be an ' + + 'object; got 2.' + ); + }); + it('should support deep updates', function() { expect(update({a: 'b', c: {d: 'e'}}, {c: {d: {$set: 'f'}}})).toEqual({ a: 'b', @@ -90,7 +99,7 @@ describe('update', function() { expect(update.bind(null, {a: 'b'}, {a: 'c'})).toThrow( 'Invariant Violation: update(): You provided a key path to update() ' + 'that did not contain one of $push, $unshift, $splice, $set, $merge, ' + - '$apply. Did you forget to include {$set: ...}?' + '$apply, $delete. Did you forget to include {$set: ...}?' ); }); }); diff --git a/src/addons/update.js b/src/addons/update.js index dded114ea41fd..b5b3b298051f2 100644 --- a/src/addons/update.js +++ b/src/addons/update.js @@ -30,6 +30,7 @@ var COMMAND_SPLICE = keyOf({$splice: null}); var COMMAND_SET = keyOf({$set: null}); var COMMAND_MERGE = keyOf({$merge: null}); var COMMAND_APPLY = keyOf({$apply: null}); +var COMMAND_DELETE = keyOf({$delete: null}); var ALL_COMMANDS_LIST = [ COMMAND_PUSH, @@ -37,7 +38,8 @@ var ALL_COMMANDS_LIST = [ COMMAND_SPLICE, COMMAND_SET, COMMAND_MERGE, - COMMAND_APPLY + COMMAND_APPLY, + COMMAND_DELETE ]; var ALL_COMMANDS_SET = {}; @@ -151,6 +153,18 @@ function update(value, spec) { nextValue = spec[COMMAND_APPLY](nextValue); } + if (spec.hasOwnProperty(COMMAND_DELETE)) { + invariant( + nextValue && typeof nextValue === 'object', + 'update(): expected target of %s to be an object; got %s.', + COMMAND_DELETE, + nextValue + ); + [].concat(spec[COMMAND_DELETE]).forEach(function(delKey){ + delete nextValue[delKey]; + }); + } + for (var k in spec) { if (!(ALL_COMMANDS_SET.hasOwnProperty(k) && ALL_COMMANDS_SET[k])) { nextValue[k] = update(value[k], spec[k]); From f2d366b8be10c7a56ff39c015477028b4f0db28c Mon Sep 17 00:00:00 2001 From: KungD Date: Thu, 16 Oct 2014 08:09:08 +0200 Subject: [PATCH 2/5] add non-existing key to test --- src/addons/__tests__/update-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addons/__tests__/update-test.js b/src/addons/__tests__/update-test.js index 606e0baf98d6a..d52195cf5b30d 100644 --- a/src/addons/__tests__/update-test.js +++ b/src/addons/__tests__/update-test.js @@ -81,7 +81,7 @@ describe('update', function() { it('should support delete', function() { expect(update({a:1,b:2}, {$delete:'b'})).toEqual({a:1}); - expect(update({a:1,b:2,c:3}, {$delete:['a','c']})).toEqual({b:2}); + expect(update({a:1,b:2,c:3}, {$delete:['a','c','d']})).toEqual({b:2}); expect(update.bind(null, 2, {$delete: 'foo'})).toThrow( 'Invariant Violation: update(): expected target of $delete to be an ' + 'object; got 2.' From c79749aeca9467fc9e2d76a4b31366921ff1bc1b Mon Sep 17 00:00:00 2001 From: KungD Date: Thu, 16 Oct 2014 10:44:52 +0200 Subject: [PATCH 3/5] allow object of keys and array targets --- docs/docs/09.6-update.md | 2 +- src/addons/__tests__/update-test.js | 4 +++- src/addons/update.js | 26 +++++++++++++++++++++----- 3 files changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/docs/09.6-update.md b/docs/docs/09.6-update.md index c51c01a58dd55..e8d46128bd6ad 100644 --- a/docs/docs/09.6-update.md +++ b/docs/docs/09.6-update.md @@ -62,7 +62,7 @@ The `$`-prefixed keys are called *commands*. The data structure they are "mutati * `{$set: any}` replace the target entirely. * `{$merge: object}` merge the keys of `object` with the target. * `{$apply: function}` passes in the current value to the function and updates it with the new returned value. - * `{$delete: string} deletes the given key or array of keys from the target. + * `{$delete: string} deletes the given key or array/object of keys from the target. If target is array, values are set to `null`. ## Examples diff --git a/src/addons/__tests__/update-test.js b/src/addons/__tests__/update-test.js index d52195cf5b30d..d45463d24449e 100644 --- a/src/addons/__tests__/update-test.js +++ b/src/addons/__tests__/update-test.js @@ -82,9 +82,11 @@ describe('update', function() { it('should support delete', function() { expect(update({a:1,b:2}, {$delete:'b'})).toEqual({a:1}); expect(update({a:1,b:2,c:3}, {$delete:['a','c','d']})).toEqual({b:2}); + expect(update({a:1,b:2,c:3}, {$delete:{'a':'','b':''}})).toEqual({c:3}); + expect(update(['a','b','c'], {$delete:[1,'foo',5]})).toEqual(['a',null,'c']); expect(update.bind(null, 2, {$delete: 'foo'})).toThrow( 'Invariant Violation: update(): expected target of $delete to be an ' + - 'object; got 2.' + 'object or array; got 2.' ); }); diff --git a/src/addons/update.js b/src/addons/update.js index b5b3b298051f2..9c1feb33c154c 100644 --- a/src/addons/update.js +++ b/src/addons/update.js @@ -154,15 +154,31 @@ function update(value, spec) { } if (spec.hasOwnProperty(COMMAND_DELETE)) { + var arg = spec[COMMAND_DELETE], delKeys; + if (Array.isArray(arg)){ + delKeys = arg; + } else if (typeof arg === 'object') { + delKeys = Object.keys(arg); + } else { + delKeys = [arg]; + } invariant( - nextValue && typeof nextValue === 'object', - 'update(): expected target of %s to be an object; got %s.', + nextValue && (Array.isArray(nextValue) || typeof nextValue === 'object'), + 'update(): expected target of %s to be an object or array; got %s.', COMMAND_DELETE, nextValue ); - [].concat(spec[COMMAND_DELETE]).forEach(function(delKey){ - delete nextValue[delKey]; - }); + if (Array.isArray(nextValue)){ + delKeys.forEach(function(i){ + if (delKeys.propertyIsEnumerable(i)) { + nextValue[i] = null; + } + }); + } else { + delKeys.forEach(function(delKey){ + delete nextValue[delKey]; + }); + } } for (var k in spec) { From 2f5b2d42467e93e9d2f0ddc47cd3b5b640ab5e4e Mon Sep 17 00:00:00 2001 From: KungD Date: Thu, 16 Oct 2014 10:52:25 +0200 Subject: [PATCH 4/5] bug fix --- src/addons/update.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/addons/update.js b/src/addons/update.js index 9c1feb33c154c..e310034c491d5 100644 --- a/src/addons/update.js +++ b/src/addons/update.js @@ -170,7 +170,7 @@ function update(value, spec) { ); if (Array.isArray(nextValue)){ delKeys.forEach(function(i){ - if (delKeys.propertyIsEnumerable(i)) { + if (nextValue.propertyIsEnumerable(i)) { nextValue[i] = null; } }); From 965ae39e5ccbbe0acaf3a4f6d9e0fc3c1d0f7dd7 Mon Sep 17 00:00:00 2001 From: KungD Date: Thu, 16 Oct 2014 11:07:04 +0200 Subject: [PATCH 5/5] change name to unset --- docs/docs/09.6-update.md | 2 +- src/addons/__tests__/update-test.js | 16 ++++++++-------- src/addons/update.js | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/docs/09.6-update.md b/docs/docs/09.6-update.md index e8d46128bd6ad..f1ee73b15e8c5 100644 --- a/docs/docs/09.6-update.md +++ b/docs/docs/09.6-update.md @@ -62,7 +62,7 @@ The `$`-prefixed keys are called *commands*. The data structure they are "mutati * `{$set: any}` replace the target entirely. * `{$merge: object}` merge the keys of `object` with the target. * `{$apply: function}` passes in the current value to the function and updates it with the new returned value. - * `{$delete: string} deletes the given key or array/object of keys from the target. If target is array, values are set to `null`. + * `{$unset: string} deletes the given key or array/object of keys from the target. If target is an array, values are set to `null`. ## Examples diff --git a/src/addons/__tests__/update-test.js b/src/addons/__tests__/update-test.js index d45463d24449e..b8e67435ec692 100644 --- a/src/addons/__tests__/update-test.js +++ b/src/addons/__tests__/update-test.js @@ -79,13 +79,13 @@ describe('update', function() { ); }); - it('should support delete', function() { - expect(update({a:1,b:2}, {$delete:'b'})).toEqual({a:1}); - expect(update({a:1,b:2,c:3}, {$delete:['a','c','d']})).toEqual({b:2}); - expect(update({a:1,b:2,c:3}, {$delete:{'a':'','b':''}})).toEqual({c:3}); - expect(update(['a','b','c'], {$delete:[1,'foo',5]})).toEqual(['a',null,'c']); - expect(update.bind(null, 2, {$delete: 'foo'})).toThrow( - 'Invariant Violation: update(): expected target of $delete to be an ' + + it('should support unset', function() { + expect(update({a:1,b:2}, {$unset:'b'})).toEqual({a:1}); + expect(update({a:1,b:2,c:3}, {$unset:['a','c','d']})).toEqual({b:2}); + expect(update({a:1,b:2,c:3}, {$unset:{'a':'','b':''}})).toEqual({c:3}); + expect(update(['a','b','c'], {$unset:[1,'foo',5]})).toEqual(['a',null,'c']); + expect(update.bind(null, 2, {$unset: 'foo'})).toThrow( + 'Invariant Violation: update(): expected target of $unset to be an ' + 'object or array; got 2.' ); }); @@ -101,7 +101,7 @@ describe('update', function() { expect(update.bind(null, {a: 'b'}, {a: 'c'})).toThrow( 'Invariant Violation: update(): You provided a key path to update() ' + 'that did not contain one of $push, $unshift, $splice, $set, $merge, ' + - '$apply, $delete. Did you forget to include {$set: ...}?' + '$apply, $unset. Did you forget to include {$set: ...}?' ); }); }); diff --git a/src/addons/update.js b/src/addons/update.js index e310034c491d5..e7224da686cce 100644 --- a/src/addons/update.js +++ b/src/addons/update.js @@ -30,7 +30,7 @@ var COMMAND_SPLICE = keyOf({$splice: null}); var COMMAND_SET = keyOf({$set: null}); var COMMAND_MERGE = keyOf({$merge: null}); var COMMAND_APPLY = keyOf({$apply: null}); -var COMMAND_DELETE = keyOf({$delete: null}); +var COMMAND_DELETE = keyOf({$unset: null}); var ALL_COMMANDS_LIST = [ COMMAND_PUSH,