From 7312d12e94217129fe2a6e7474b01dbb3912ba80 Mon Sep 17 00:00:00 2001 From: Omair Vaiyani Date: Fri, 27 Apr 2018 14:25:33 +0100 Subject: [PATCH 1/4] Allow specific keys to be reverted in unsaved objects --- src/ParseObject.js | 26 +++++++++++++---- src/__tests__/ParseObject-test.js | 47 +++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/ParseObject.js b/src/ParseObject.js index 997394756..9c87452ce 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -224,10 +224,14 @@ class ParseObject { return stateController.getPendingOps(this._getStateIdentifier()); } - _clearPendingOps() { + /** + * @param {Array} [keysToClear] - if specified, only ops matching + * these fields will be cleared + */ + _clearPendingOps(keysToClear?: Array) { var pending = this._getPendingOps(); var latest = pending[pending.length - 1]; - var keys = Object.keys(latest); + var keys = keysToClear || Object.keys(latest); keys.forEach((key) => { delete latest[key]; }); @@ -935,10 +939,22 @@ class ParseObject { } /** - * Clears any changes to this object made since the last call to save() + * Clears any (or specific) changes to this object made since the last call to save() + * @param {String|Array|...String} [keys] - specify which fields to revert */ - revert(): void { - this._clearPendingOps(); + revert(...keys?: Array): void { + let _keysToRevert; + if(keys.length) { + _keysToRevert = []; + keys.forEach((key) => { + if (Array.isArray(key)) { + _keysToRevert = _keysToRevert.concat(key); + } else { + _keysToRevert.push(key); + } + }); + } + this._clearPendingOps(_keysToRevert); } /** diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index 9432036a5..e2fd5a9db 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -845,6 +845,49 @@ describe('ParseObject', () => { expect(o.op('count')).toBe(undefined); }); + it('can revert a specific field in unsaved ops', () => { + var o = ParseObject.fromJSON({ + className: 'Item', + objectId: 'canrevertspecific', + count: 5 + }); + o.set({ cool: true }); + o.increment('count'); + expect(o.get('cool')).toBe(true); + expect(o.get('count')).toBe(6); + o.revert('cool'); + expect(o.get('cool')).toBe(undefined); + expect(o.op('cool')).toBe(undefined); + expect(o.get('count')).toBe(6); + expect(o.op('count')).not.toBe(undefined); + }); + + it('can revert multiple fields in unsaved ops', () => { + var o = ParseObject.fromJSON({ + className: 'Item', + objectId: 'canrevertmultiple', + count: 5, + age: 18, + gender: 'female' + }); + o.set({ cool: true, gender: 'male' }); + o.increment('count'); + o.increment('age'); + expect(o.get('cool')).toBe(true); + expect(o.get('count')).toBe(6); + expect(o.get('age')).toBe(19); + expect(o.get('gender')).toBe('male'); + o.revert('age', 'count', ['gender']); + expect(o.get('cool')).toBe(true); + expect(o.op('cool')).not.toBe(undefined); + expect(o.get('count')).toBe(5); + expect(o.op('count')).toBe(undefined); + expect(o.get('age')).toBe(18); + expect(o.op('age')).toBe(undefined); + expect(o.get('gender')).toBe('female'); + expect(o.op('gender')).toBe(undefined); + }); + it('can save the object', (done) => { CoreManager.getRESTController()._setXHR( mockXHR([{ @@ -886,7 +929,7 @@ describe('ParseObject', () => { done(); }); }); - + it('interpolates delete operations', (done) => { CoreManager.getRESTController()._setXHR( mockXHR([{ @@ -1866,7 +1909,7 @@ describe('ParseObject (unique instance mode)', () => { o2.add('tags', '#nofilter'); expect(o2.get('tags')).toEqual(['#tbt', '#nofilter']); - + o2.revert(); o2.addUnique('tags', '#tbt'); expect(o2.get('tags')).toEqual(['#tbt']); From f1d9ae7e05a0ad3b7b7fc247ee72fc465916d511 Mon Sep 17 00:00:00 2001 From: Omair Vaiyani Date: Wed, 17 Oct 2018 10:22:17 +0100 Subject: [PATCH 2/4] fix(Parse.Object): disallow array params in 'revert' Contains general cleanup and type fixes. --- src/ParseObject.js | 24 ++++++++++++------------ src/__tests__/ParseObject-test.js | 27 ++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/ParseObject.js b/src/ParseObject.js index 9c87452ce..6d3f1c774 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -225,10 +225,10 @@ class ParseObject { } /** - * @param {Array} [keysToClear] - if specified, only ops matching + * @param {Array} [keysToClear] - if specified, only ops matching * these fields will be cleared */ - _clearPendingOps(keysToClear?: Array) { + _clearPendingOps(keysToClear?: Array) { var pending = this._getPendingOps(); var latest = pending[pending.length - 1]; var keys = keysToClear || Object.keys(latest); @@ -940,21 +940,21 @@ class ParseObject { /** * Clears any (or specific) changes to this object made since the last call to save() - * @param {String|Array|...String} [keys] - specify which fields to revert + * @param {string} [keys] - specify which fields to revert */ - revert(...keys?: Array): void { - let _keysToRevert; + revert(...keys: Array): void { + let keysToRevert; if(keys.length) { - _keysToRevert = []; - keys.forEach((key) => { - if (Array.isArray(key)) { - _keysToRevert = _keysToRevert.concat(key); + keysToRevert = []; + for(let key of keys) { + if(typeof(key) === "string") { + keysToRevert.push(key); } else { - _keysToRevert.push(key); + throw new Error("Parse.Object#revert expects either no, or a list of string, arguments."); } - }); + } } - this._clearPendingOps(_keysToRevert); + this._clearPendingOps(keysToRevert); } /** diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index e2fd5a9db..2c23c4dfb 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -877,7 +877,7 @@ describe('ParseObject', () => { expect(o.get('count')).toBe(6); expect(o.get('age')).toBe(19); expect(o.get('gender')).toBe('male'); - o.revert('age', 'count', ['gender']); + o.revert('age', 'count', 'gender'); expect(o.get('cool')).toBe(true); expect(o.op('cool')).not.toBe(undefined); expect(o.get('count')).toBe(5); @@ -888,6 +888,31 @@ describe('ParseObject', () => { expect(o.op('gender')).toBe(undefined); }); + it('throws if an array is provided', () => { + var o = ParseObject.fromJSON({ + className: 'Item', + objectId: 'throwforarray', + count: 5, + age: 18, + gender: 'female' + }); + o.set({ cool: true, gender: 'male' }); + + const err = "Parse.Object#revert expects either no, or a list of string, arguments."; + + expect(function() { + o.revert(['age']) + }).toThrow(err); + + expect(function() { + o.revert([]) + }).toThrow(err); + + expect(function() { + o.revert('gender', ['age']) + }).toThrow(err); + }); + it('can save the object', (done) => { CoreManager.getRESTController()._setXHR( mockXHR([{ From ff5876c957eef352fb4f0d370524eb96e1fee883 Mon Sep 17 00:00:00 2001 From: Omair Vaiyani Date: Mon, 12 Nov 2018 09:48:31 +0000 Subject: [PATCH 3/4] chore(Parse.Object): use const in test cases --- src/__tests__/ParseObject-test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/__tests__/ParseObject-test.js b/src/__tests__/ParseObject-test.js index eaf9d3d83..ef0fd58b0 100644 --- a/src/__tests__/ParseObject-test.js +++ b/src/__tests__/ParseObject-test.js @@ -852,7 +852,7 @@ describe('ParseObject', () => { }); it('can revert a specific field in unsaved ops', () => { - var o = ParseObject.fromJSON({ + const o = ParseObject.fromJSON({ className: 'Item', objectId: 'canrevertspecific', count: 5 @@ -869,7 +869,7 @@ describe('ParseObject', () => { }); it('can revert multiple fields in unsaved ops', () => { - var o = ParseObject.fromJSON({ + const o = ParseObject.fromJSON({ className: 'Item', objectId: 'canrevertmultiple', count: 5, @@ -895,7 +895,7 @@ describe('ParseObject', () => { }); it('throws if an array is provided', () => { - var o = ParseObject.fromJSON({ + const o = ParseObject.fromJSON({ className: 'Item', objectId: 'throwforarray', count: 5, From 49146e78a98282373ef6a769334863bcdf070da2 Mon Sep 17 00:00:00 2001 From: Omair Vaiyani Date: Mon, 12 Nov 2018 09:49:30 +0000 Subject: [PATCH 4/4] chore(Parse.Object): use const in for-loop --- src/ParseObject.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ParseObject.js b/src/ParseObject.js index 4fd5c4b60..fa5faa01f 100644 --- a/src/ParseObject.js +++ b/src/ParseObject.js @@ -943,7 +943,7 @@ class ParseObject { let keysToRevert; if(keys.length) { keysToRevert = []; - for(let key of keys) { + for(const key of keys) { if(typeof(key) === "string") { keysToRevert.push(key); } else {