Index: test/mjsunit/harmony/object-observe.js |
diff --git a/test/mjsunit/harmony/object-observe.js b/test/mjsunit/harmony/object-observe.js |
index 48205822554db40ec8815f69c30d3db0d9cc44e0..d0b1075653afae4b00451e1a62bde1f3dc7591b4 100644 |
--- a/test/mjsunit/harmony/object-observe.js |
+++ b/test/mjsunit/harmony/object-observe.js |
@@ -105,17 +105,20 @@ Object.defineProperty(changeRecordWithAccessor, 'name', { |
enumerable: true |
}) |
+ |
// Object.observe |
assertThrows(function() { Object.observe("non-object", observer.callback); }, TypeError); |
assertThrows(function() { Object.observe(obj, nonFunction); }, TypeError); |
assertThrows(function() { Object.observe(obj, frozenFunction); }, TypeError); |
assertEquals(obj, Object.observe(obj, observer.callback)); |
+ |
// Object.unobserve |
assertThrows(function() { Object.unobserve(4, observer.callback); }, TypeError); |
assertThrows(function() { Object.unobserve(obj, nonFunction); }, TypeError); |
assertEquals(obj, Object.unobserve(obj, observer.callback)); |
+ |
// Object.getNotifier |
var notifier = Object.getNotifier(obj); |
assertSame(notifier, Object.getNotifier(obj)); |
@@ -139,11 +142,13 @@ assertFalse(recordCreated); |
notifier.notify(changeRecordWithAccessor); |
assertFalse(recordCreated); // not observed yet |
+ |
// Object.deliverChangeRecords |
assertThrows(function() { Object.deliverChangeRecords(nonFunction); }, TypeError); |
Object.observe(obj, observer.callback); |
+ |
// notify uses to [[CreateOwnProperty]] to create changeRecord; |
reset(); |
var protoExpandoAccessed = false; |
@@ -158,6 +163,7 @@ assertFalse(protoExpandoAccessed); |
delete Object.prototype.protoExpando; |
Object.deliverChangeRecords(observer.callback); |
+ |
// Multiple records are delivered. |
reset(); |
notifier.notify({ |
@@ -178,11 +184,13 @@ observer.assertCallbackRecords([ |
{ object: obj, name: 'bar', type: 'deleted', expando2: 'str' } |
]); |
+ |
// No delivery takes place if no records are pending |
reset(); |
Object.deliverChangeRecords(observer.callback); |
observer.assertNotCalled(); |
+ |
// Multiple observation has no effect. |
reset(); |
Object.observe(obj, observer.callback); |
@@ -193,6 +201,7 @@ Object.getNotifier(obj).notify({ |
Object.deliverChangeRecords(observer.callback); |
observer.assertCalled(); |
+ |
// Observation can be stopped. |
reset(); |
Object.unobserve(obj, observer.callback); |
@@ -202,6 +211,7 @@ Object.getNotifier(obj).notify({ |
Object.deliverChangeRecords(observer.callback); |
observer.assertNotCalled(); |
+ |
// Multiple unobservation has no effect |
reset(); |
Object.unobserve(obj, observer.callback); |
@@ -212,6 +222,7 @@ Object.getNotifier(obj).notify({ |
Object.deliverChangeRecords(observer.callback); |
observer.assertNotCalled(); |
+ |
// Re-observation works and only includes changeRecords after of call. |
reset(); |
Object.getNotifier(obj).notify({ |
@@ -225,6 +236,7 @@ records = undefined; |
Object.deliverChangeRecords(observer.callback); |
observer.assertRecordCount(1); |
+ |
// Observing a continuous stream of changes, while itermittantly unobserving. |
reset(); |
Object.observe(obj, observer.callback); |
@@ -265,6 +277,7 @@ observer.assertCallbackRecords([ |
{ object: obj, type: 'foo', val: 5 } |
]); |
+ |
// Observing multiple objects; records appear in order. |
reset(); |
var obj2 = {}; |
@@ -289,6 +302,37 @@ observer.assertCallbackRecords([ |
{ object: obj3, type: 'foo3' } |
]); |
+ |
+// Recursive observation. |
+var obj = {a: 1}; |
+var callbackCount = 0; |
+function recursiveObserver(r) { |
+ assertEquals(1, r.length); |
+ ++callbackCount; |
+ if (r[0].oldValue < 100) ++obj[r[0].name]; |
+} |
+Object.observe(obj, recursiveObserver); |
+++obj.a; |
+Object.deliverChangeRecords(recursiveObserver); |
+assertEquals(100, callbackCount); |
+ |
+var obj1 = {a: 1}; |
+var obj2 = {a: 1}; |
+var recordCount = 0; |
+function recursiveObserver2(r) { |
+ recordCount += r.length; |
+ if (r[0].oldValue < 100) { |
+ ++obj1.a; |
+ ++obj2.a; |
+ } |
+} |
+Object.observe(obj1, recursiveObserver2); |
+Object.observe(obj2, recursiveObserver2); |
+++obj1.a; |
+Object.deliverChangeRecords(recursiveObserver2); |
+assertEquals(199, recordCount); |
+ |
+ |
// Observing named properties. |
reset(); |
var obj = {a: 1} |
@@ -340,6 +384,7 @@ observer.assertCallbackRecords([ |
{ object: obj, name: "a", type: "new" }, |
]); |
+ |
// Observing indexed properties. |
reset(); |
var obj = {'1': 1} |
@@ -604,6 +649,7 @@ observer.assertCallbackRecords([ |
{ object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, |
]); |
+ |
// Assignments in loops (checking different IC states). |
reset(); |
var obj = {}; |
@@ -635,6 +681,7 @@ observer.assertCallbackRecords([ |
{ object: obj, name: "4", type: "new" }, |
]); |
+ |
// Adding elements past the end of an array should notify on length |
reset(); |
var arr = [1, 2, 3]; |
@@ -657,6 +704,7 @@ observer.assertCallbackRecords([ |
{ object: arr, name: '50', type: 'new' }, |
]); |
+ |
// Tests for array methods, first on arrays and then on plain objects |
// |
// === ARRAYS === |
@@ -730,6 +778,7 @@ observer.assertCallbackRecords([ |
{ object: array, name: '2', type: 'updated', oldValue: 3 }, |
]); |
+ |
// |
// === PLAIN OBJECTS === |
// |
@@ -836,6 +885,7 @@ observer.assertCallbackRecords([ |
{ object: obj, name: '__proto__', type: 'prototype', oldValue: null }, |
]); |
+ |
// Function.prototype |
reset(); |
var fun = function(){}; |
@@ -904,7 +954,6 @@ for (var b1 = 0; b1 < 2; ++b1) |
for (var b3 = 0; b3 < 2; ++b3) |
TestFastElements(b1 != 0, b2 != 0, b3 != 0); |
- |
function TestFastElementsLength(polymorphic, optimize, oldSize, newSize) { |
var setLength = eval( |
"(function setLength(a, n) { a.length = n " + |