Chromium Code Reviews| Index: test/mjsunit/harmony/object-observe.js |
| diff --git a/test/mjsunit/harmony/object-observe.js b/test/mjsunit/harmony/object-observe.js |
| index 263154a406a525a1dd652f8da1dda5363ed74901..ba97099345ddcfb6aba1058a7729c82ff0886ad3 100644 |
| --- a/test/mjsunit/harmony/object-observe.js |
| +++ b/test/mjsunit/harmony/object-observe.js |
| @@ -88,7 +88,11 @@ function createObserver() { |
| } |
| var observer = createObserver(); |
| +var observer2 = createObserver(); |
| + |
| assertEquals("function", typeof observer.callback); |
| +assertEquals("function", typeof observer2.callback); |
| + |
| var obj = {}; |
| function frozenFunction() {} |
| @@ -109,9 +113,15 @@ Object.defineProperty(changeRecordWithAccessor, 'name', { |
| assertThrows(function() { Object.observe("non-object", observer.callback); }, TypeError); |
| assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); |
| assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); |
| +assertThrows(function() { Object.observe(obj, function() {}, 1); }, TypeError); |
| +assertThrows(function() { Object.observe(obj, function() {}, [undefined]); }, TypeError); |
| +assertThrows(function() { Object.observe(obj, function() {}, [1]); }, TypeError); |
| +assertThrows(function() { Object.observe(obj, function() {}, ['foo', null]); }, TypeError); |
| +assertEquals(obj, Object.observe(obj, observer.callback, ['foo', 'bar', 'baz'])); |
| +assertEquals(obj, Object.observe(obj, observer.callback, [])); |
| +assertEquals(obj, Object.observe(obj, observer.callback, undefined)); |
| assertEquals(obj, Object.observe(obj, observer.callback)); |
| - |
| // Object.unobserve |
| assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError); |
| assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError); |
| @@ -130,6 +140,20 @@ assertTrue(notifyDesc.writable); |
| assertFalse(notifyDesc.enumerable); |
| assertThrows(function() { notifier.notify({}); }, TypeError); |
| assertThrows(function() { notifier.notify({ type: 4 }); }, TypeError); |
| + |
| +assertThrows(function() { notifier.performChange(1, function(){}); }, TypeError); |
| +assertThrows(function() { notifier.performChange(undefined, function(){}); }, TypeError); |
| +assertThrows(function() { notifier.performChange('foo', undefined); }, TypeError); |
| +assertThrows(function() { notifier.performChange('foo', 'bar'); }, TypeError); |
| +var testSelf = {}; |
| +notifier.performChange('foo', function() { |
| + assertTrue(testSelf === this); |
| +}, testSelf); |
| +var self = this; |
| +notifier.performChange('foo', function() { |
| + assertTrue(self === this); |
| +}); |
| + |
| var notify = notifier.notify; |
| assertThrows(function() { notify.call(undefined, { type: 'a' }); }, TypeError); |
| assertThrows(function() { notify.call(null, { type: 'a' }); }, TypeError); |
| @@ -195,7 +219,7 @@ reset(); |
| Object.observe(obj, observer.callback); |
| Object.observe(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| }); |
| Object.deliverChangeRecords(observer.callback); |
| observer.assertCalled(); |
| @@ -205,7 +229,7 @@ observer.assertCalled(); |
| reset(); |
| Object.unobserve(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| }); |
| Object.deliverChangeRecords(observer.callback); |
| observer.assertNotCalled(); |
| @@ -216,7 +240,7 @@ reset(); |
| Object.unobserve(obj, observer.callback); |
| Object.unobserve(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| }); |
| Object.deliverChangeRecords(observer.callback); |
| observer.assertNotCalled(); |
| @@ -225,11 +249,11 @@ observer.assertNotCalled(); |
| // Re-observation works and only includes changeRecords after of call. |
| reset(); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| }); |
| Object.observe(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| }); |
| records = undefined; |
| Object.deliverChangeRecords(observer.callback); |
| @@ -240,40 +264,223 @@ observer.assertRecordCount(1); |
| reset(); |
| Object.observe(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| val: 1 |
| }); |
| Object.unobserve(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| val: 2 |
| }); |
| Object.observe(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| val: 3 |
| }); |
| Object.unobserve(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| val: 4 |
| }); |
| Object.observe(obj, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo', |
| + type: 'updated', |
| val: 5 |
| }); |
| Object.unobserve(obj, observer.callback); |
| Object.deliverChangeRecords(observer.callback); |
| observer.assertCallbackRecords([ |
| - { object: obj, type: 'foo', val: 1 }, |
| - { object: obj, type: 'foo', val: 3 }, |
| - { object: obj, type: 'foo', val: 5 } |
| + { object: obj, type: 'updated', val: 1 }, |
| + { object: obj, type: 'updated', val: 3 }, |
| + { object: obj, type: 'updated', val: 5 } |
| +]); |
| + |
| +// Accept |
| +reset(); |
| +Object.observe(obj, observer.callback, []); |
| +Object.getNotifier(obj).notify({ |
| + type: 'new' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'updated' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'deleted' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'reconfigured' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'prototype' |
| +}); |
| +Object.deliverChangeRecords(observer.callback); |
| +observer.assertNotCalled(); |
| + |
| +reset(); |
| +Object.observe(obj, observer.callback, ['new', 'deleted', 'prototype']); |
| +Object.getNotifier(obj).notify({ |
| + type: 'new' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'updated' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'deleted' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'deleted' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'reconfigured' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'prototype' |
| +}); |
| +Object.deliverChangeRecords(observer.callback); |
| +observer.assertCallbackRecords([ |
| + { object: obj, type: 'new' }, |
| + { object: obj, type: 'deleted' }, |
| + { object: obj, type: 'deleted' }, |
| + { object: obj, type: 'prototype' } |
| +]); |
| + |
| +reset(); |
| +Object.observe(obj, observer.callback, ['updated', 'foo']); |
| +Object.getNotifier(obj).notify({ |
| + type: 'new' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'updated' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'deleted' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'foo' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'bar' |
| +}); |
| +Object.getNotifier(obj).notify({ |
| + type: 'foo' |
| +}); |
| +Object.deliverChangeRecords(observer.callback); |
| +observer.assertCallbackRecords([ |
| + { object: obj, type: 'updated' }, |
| + { object: obj, type: 'foo' }, |
| + { object: obj, type: 'foo' } |
| +]); |
| + |
| +reset(); |
| +function Thingy (a, b, c) { |
|
rossberg
2013/05/14 14:19:59
Nit: spurious space
rafaelw
2013/05/14 18:20:24
Done.
|
| + this.a = a; |
| + this.b = b; |
| +} |
| + |
| +Thingy.MULTIPLY = 'multiply'; |
| +Thingy.INCREMENT = 'increment'; |
| +Thingy.INCREMENT_AND_MULTIPLY = 'incrementAndMultiply'; |
| + |
| +Thingy.prototype = { |
| + increment: function(amount) { |
| + var notifier = Object.getNotifier(this); |
| + |
| + notifier.performChange(Thingy.INCREMENT, function() { |
| + this.a += amount; |
| + this.b += amount; |
| + }, this); |
| + |
| + notifier.notify({ |
| + object: this, |
| + type: Thingy.INCREMENT, |
| + incremented: amount |
| + }); |
| + }, |
| + |
| + multiply: function(amount) { |
| + var notifier = Object.getNotifier(this); |
| + |
| + notifier.performChange(Thingy.MULTIPLY, function() { |
| + this.a *= amount; |
| + this.b *= amount; |
| + }, this); |
| + |
| + notifier.notify({ |
| + object: this, |
| + type: Thingy.MULTIPLY, |
| + multiplied: amount |
| + }); |
| + }, |
| + |
| + incrementAndMultiply: function(incAmount, multAmount) { |
| + var notifier = Object.getNotifier(this); |
| + |
| + notifier.performChange(Thingy.INCREMENT_AND_MULTIPLY, function() { |
| + this.increment(incAmount); |
| + this.multiply(multAmount); |
| + }, this); |
| + |
| + notifier.notify({ |
| + object: this, |
| + type: Thingy.INCREMENT_AND_MULTIPLY, |
| + incremented: incAmount, |
| + multiplied: multAmount |
| + }); |
| + } |
| +} |
| + |
| +Thingy.observe = function(thingy, callback) { |
| + Object.observe(thingy, callback, [Thingy.INCREMENT, |
| + Thingy.MULTIPLY, |
| + Thingy.INCREMENT_AND_MULTIPLY, |
| + 'updated']); |
| +} |
| + |
| +Thingy.unobserve = function(thingy, callback) { |
| + Object.unobserve(thingy); |
| +} |
| + |
| +var thingy = new Thingy(2, 4); |
| + |
| +Object.observe(thingy, observer.callback); |
| +Thingy.observe(thingy, observer2.callback); |
| +thingy.increment(3); // { a: 5, b: 7 } |
| +thingy.b++; // { a: 5, b: 8 } |
| +thingy.multiply(2); // { a: 10, b: 16 } |
| +thingy.a++; // { a: 11, b: 16 } |
| +thingy.incrementAndMultiply(2, 2); // { a: 26, b: 36 } |
| + |
| +Object.deliverChangeRecords(observer.callback); |
| +Object.deliverChangeRecords(observer2.callback); |
| +observer.assertCallbackRecords([ |
| + { object: thingy, type: 'updated', name: 'a', oldValue: 2 }, |
| + { object: thingy, type: 'updated', name: 'b', oldValue: 4 }, |
| + { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, |
| + { object: thingy, type: 'updated', name: 'a', oldValue: 5 }, |
| + { object: thingy, type: 'updated', name: 'b', oldValue: 8 }, |
| + { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, |
| + { object: thingy, type: 'updated', name: 'a', oldValue: 11 }, |
| + { object: thingy, type: 'updated', name: 'b', oldValue: 16 }, |
| + { object: thingy, type: 'updated', name: 'a', oldValue: 13 }, |
| + { object: thingy, type: 'updated', name: 'b', oldValue: 18 }, |
| +]); |
| + |
| +observer2.assertCallbackRecords([ |
| + { object: thingy, type: Thingy.INCREMENT, incremented: 3 }, |
| + { object: thingy, type: 'updated', name: 'b', oldValue: 7 }, |
| + { object: thingy, type: Thingy.MULTIPLY, multiplied: 2 }, |
| + { object: thingy, type: 'updated', name: 'a', oldValue: 10 }, |
| + { |
| + object: thingy, |
| + type: Thingy.INCREMENT_AND_MULTIPLY, |
| + incremented: 2, |
| + multiplied: 2 |
| + } |
| ]); |
|
rossberg
2013/05/14 14:19:59
Can we also add a test that nests performChanges o
rafaelw
2013/05/14 18:20:24
Done.
|
| @@ -285,20 +492,20 @@ Object.observe(obj, observer.callback); |
| Object.observe(obj3, observer.callback); |
| Object.observe(obj2, observer.callback); |
| Object.getNotifier(obj).notify({ |
| - type: 'foo1', |
| + type: 'new', |
| }); |
| Object.getNotifier(obj2).notify({ |
| - type: 'foo2', |
| + type: 'updated', |
| }); |
| Object.getNotifier(obj3).notify({ |
| - type: 'foo3', |
| + type: 'deleted', |
| }); |
| Object.observe(obj3, observer.callback); |
| Object.deliverChangeRecords(observer.callback); |
| observer.assertCallbackRecords([ |
| - { object: obj, type: 'foo1' }, |
| - { object: obj2, type: 'foo2' }, |
| - { object: obj3, type: 'foo3' } |
| + { object: obj, type: 'new' }, |
| + { object: obj2, type: 'updated' }, |
| + { object: obj3, type: 'deleted' } |
| ]); |