Skip to content

Instantly share code, notes, and snippets.

@ofirgeller
Created July 18, 2017 16:55
Show Gist options
  • Save ofirgeller/91b5cc9713bf8c8d8cdf97223eec412a to your computer and use it in GitHub Desktop.
Save ofirgeller/91b5cc9713bf8c8d8cdf97223eec412a to your computer and use it in GitHub Desktop.
import * as React from 'react';
function proxyEntity(entity) {
let originalValues = {};
return new Proxy(entity, {
set: function (obj, prop, val) {
if (obj[prop] === val) {
return;
} else if (!(prop in originalValues)) {
originalValues[prop] = obj[prop];
}
obj[prop] = val;
return true;
},
get: function (obj, prop, receiver) {
switch (prop) {
case 'originalValues': return Object.assign({}, obj, originalValues);
case 'changes': {
let changes = {};
Object.keys(originalValues).forEach(k => changes[k] = obj[k]);
return changes;
}
case 'entity': return obj;
case 'hasChanges': return Object.keys(originalValues).length !== 0;
case 'undoChanges': return function () {
for (let key of Object.keys(originalValues)) {
obj[key] = originalValues[key];
}
originalValues = {};
};
default: return obj[prop];
}
}
});
}
function entity() {
var e = {
name: 'nameson',
age: 30,
height: 170
};
return e;
}
function uut() {
let e = entity();
return proxyEntity(e);
}
function changeValues(p) {
p.age = 20;
p.name = 'not_nameson';
}
describe('entity proxy', () => {
test('will not have changes before we change the values', () => {
let ep = uut();
expect(ep.hasChanges).toBe(false);
});
test('will have changes after we change the values', () => {
let ep = uut();
changeValues(ep);
expect(ep.hasChanges).toBe(true);
expect(ep.changes).toEqual({ age: 20, name: 'not_nameson' });
expect(ep.age).toBe(20);
expect(ep.name).toBe('not_nameson');
});
test('original values will contain all the original values', () => {
let ep1 = uut();
let ep2 = uut();
changeValues(ep1);
let e = entity();
expect(ep1.originalValues).toEqual(e);
});
test('undo changes will reset the values', () => {
let ep = uut();
changeValues(ep);
ep.undoChanges();
let e = entity();
expect(ep).toEqual(e);
});
test('changes and undo changes will word n times', () => {
let ep = uut();
for (let i = 0; i < 10; i++) {
ep.age = i;
expect(ep.age).toBe(i);
expect(ep.hasChanges).toBe(true);
ep.undoChanges();
expect(ep.hasChanges).toBe(false);
}
expect(ep).toEqual(entity());
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment