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..7bff5d865459b66388164946be21553a56ef2f7c 100644 |
--- a/test/mjsunit/harmony/object-observe.js |
+++ b/test/mjsunit/harmony/object-observe.js |
@@ -65,8 +65,7 @@ function createObserver() { |
assertCallbackRecords: function(recs) { |
this.assertRecordCount(recs.length); |
for (var i = 0; i < recs.length; i++) { |
- if ('name' in recs[i]) |
- recs[i].name = String(recs[i].name); |
+ if ('name' in recs[i]) recs[i].name = String(recs[i].name); |
print(i, stringifyNoThrow(this.records[i]), stringifyNoThrow(recs[i])); |
assertSame(this.records[i].object, recs[i].object); |
assertEquals('string', typeof recs[i].type); |
@@ -105,17 +104,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 +141,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 +162,7 @@ assertFalse(protoExpandoAccessed); |
delete Object.prototype.protoExpando; |
Object.deliverChangeRecords(observer.callback); |
+ |
// Multiple records are delivered. |
reset(); |
notifier.notify({ |
@@ -178,11 +183,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 +200,7 @@ Object.getNotifier(obj).notify({ |
Object.deliverChangeRecords(observer.callback); |
observer.assertCalled(); |
+ |
// Observation can be stopped. |
reset(); |
Object.unobserve(obj, observer.callback); |
@@ -202,6 +210,7 @@ Object.getNotifier(obj).notify({ |
Object.deliverChangeRecords(observer.callback); |
observer.assertNotCalled(); |
+ |
// Multiple unobservation has no effect |
reset(); |
Object.unobserve(obj, observer.callback); |
@@ -212,6 +221,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 +235,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 +276,7 @@ observer.assertCallbackRecords([ |
{ object: obj, type: 'foo', val: 5 } |
]); |
+ |
// Observing multiple objects; records appear in order. |
reset(); |
var obj2 = {}; |
@@ -289,6 +301,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 +383,7 @@ observer.assertCallbackRecords([ |
{ object: obj, name: "a", type: "new" }, |
]); |
+ |
// Observing indexed properties. |
reset(); |
var obj = {'1': 1} |
@@ -466,8 +510,7 @@ function TestObserveNonConfigurable(obj, prop, desc) { |
Object.defineProperty(obj, prop, {value: 6}); |
Object.defineProperty(obj, prop, {value: 6}); // ignored |
Object.defineProperty(obj, prop, {value: 7}); |
- Object.defineProperty(obj, prop, |
- {enumerable: desc.enumerable}); // ignored |
+ Object.defineProperty(obj, prop, {enumerable: desc.enumerable}); // ignored |
Object.defineProperty(obj, prop, {writable: false}); |
obj[prop] = 7; // ignored |
Object.deliverChangeRecords(observer.callback); |
@@ -541,8 +584,8 @@ var properties = ["a", "1", 1, "length", "prototype", "name", "caller"]; |
// Cases that yield non-standard results. |
function blacklisted(obj, prop) { |
return (obj instanceof Int32Array && prop == 1) || |
- (obj instanceof Int32Array && prop === "length") || |
- (obj instanceof ArrayBuffer && prop == 1) |
+ (obj instanceof Int32Array && prop === "length") || |
+ (obj instanceof ArrayBuffer && prop == 1) |
} |
for (var i in objects) for (var j in properties) { |
@@ -604,6 +647,7 @@ observer.assertCallbackRecords([ |
{ object: arr3, name: 'length', type: 'reconfigured', oldValue: 5 }, |
]); |
+ |
// Assignments in loops (checking different IC states). |
reset(); |
var obj = {}; |
@@ -635,6 +679,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 +702,7 @@ observer.assertCallbackRecords([ |
{ object: arr, name: '50', type: 'new' }, |
]); |
+ |
// Tests for array methods, first on arrays and then on plain objects |
// |
// === ARRAYS === |
@@ -730,6 +776,7 @@ observer.assertCallbackRecords([ |
{ object: array, name: '2', type: 'updated', oldValue: 3 }, |
]); |
+ |
// |
// === PLAIN OBJECTS === |
// |
@@ -836,6 +883,7 @@ observer.assertCallbackRecords([ |
{ object: obj, name: '__proto__', type: 'prototype', oldValue: null }, |
]); |
+ |
// Function.prototype |
reset(); |
var fun = function(){}; |
@@ -904,7 +952,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 " + |