Skip to content

Commit

Permalink
Added check if gawked object has a property setter to prevent deletion.
Browse files Browse the repository at this point in the history
Fixes #5.
  • Loading branch information
cb1kenobi committed Sep 26, 2018
1 parent 1e31c7b commit 001d177
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 6 deletions.
16 changes: 10 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,30 +56,34 @@ export default function gawk(value, parent) {
} else {
// gawk it!
gawked = new Proxy(value, {
set: (target, prop, value) => {
set: (target, prop, newValue) => {
if (prop === '__gawk__') {
throw new Error('Cannot override property \'__gawk__\'');
}

// console.log('setting', prop, value);
// console.log('setting', prop, newValue);

let changed = true;
const desc = Object.getOwnPropertyDescriptor(target, prop);

if (Object.prototype.hasOwnProperty.call(target, prop)) {
changed = target[prop] !== value;
if (desc) {
changed = target[prop] !== newValue;
const parents = isGawked(target[prop]) && target[prop].__gawk__.parents;
if (parents) {
parents.delete(gawked);
if (!parents.size) {
target[prop].__gawk__.parents = null;
}
}
if (!Array.isArray(target) || prop !== 'length') {

// if the destination property has a setter, then we can't assume we need to
// fire a delete
if (typeof desc.set !== 'function' && (!Array.isArray(target) || prop !== 'length')) {
delete target[prop];
}
}

target[prop] = gawk(value, gawked);
target[prop] = gawk(newValue, gawked);

if (changed) {
notify(gawked);
Expand Down
25 changes: 25 additions & 0 deletions test/test-watch.js
Original file line number Diff line number Diff line change
Expand Up @@ -644,4 +644,29 @@ describe('gawk.unwatch()', () => {

expect(gobj.__gawk__.previous).to.be.null;
});

it('should notify when a getter/setter property is changed', () => {
const obj = Object.defineProperty({}, 'foo', {
configurable: true,
enumerable: true,
get() {
return this._foo;
},
set(value) {
this._foo = value.toUpperCase();
}
});

obj.foo = 'bar';

const gobj = gawk(obj);
expect(gobj.foo).to.equal('BAR');

const callback = spy();
gawk.watch(gobj, callback);

gobj.foo = 'baz';
expect(callback).to.be.calledOnce;
expect(gobj.foo).to.equal('BAZ');
});
});

0 comments on commit 001d177

Please sign in to comment.