Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions src/ParseObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,14 @@ class ParseObject {
return stateController.getPendingOps(this._getStateIdentifier());
}

_clearPendingOps() {
/**
* @param {Array<string>} [keysToClear] - if specified, only ops matching
* these fields will be cleared
*/
_clearPendingOps(keysToClear?: Array<string>) {
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];
});
Expand Down Expand Up @@ -932,10 +936,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} [keys] - specify which fields to revert
*/
revert(): void {
this._clearPendingOps();
revert(...keys: Array<string>): void {
let keysToRevert;
if(keys.length) {
keysToRevert = [];
for(let key of keys) {
if(typeof(key) === "string") {
keysToRevert.push(key);
} else {
throw new Error("Parse.Object#revert expects either no, or a list of string, arguments.");
}
}
}
this._clearPendingOps(keysToRevert);
}

/**
Expand Down
68 changes: 68 additions & 0 deletions src/__tests__/ParseObject-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,74 @@ 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('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 fetchWithInclude', async () => {
const objectController = CoreManager.getObjectController();
const spy = jest.spyOn(
Expand Down