Index: test/cctest/test-object-observe.cc |
diff --git a/test/cctest/test-object-observe.cc b/test/cctest/test-object-observe.cc |
index 7e0eb47493ac26c9180a3bb8958d595b4291932e..2321bb22ffb202a678368f810d5f6eb0b238c6ee 100644 |
--- a/test/cctest/test-object-observe.cc |
+++ b/test/cctest/test-object-observe.cc |
@@ -60,25 +60,108 @@ TEST(PerIsolateState) { |
"var calls = 0;" |
"var observer = function(records) { count = records.length; calls++ };" |
"var obj = {};" |
- "Object.observe(obj, observer);" |
- "Object.notify(obj, {type: 'a'});"); |
+ "Object.observe(obj, observer);"); |
Handle<Value> observer = CompileRun("observer"); |
Handle<Value> obj = CompileRun("obj"); |
+ Handle<Value> notify_fun1 = CompileRun( |
+ "(function() { Object.notify(obj, {type: 'a'}); })"); |
+ Handle<Value> notify_fun2; |
{ |
LocalContext context2; |
context2->Global()->Set(String::New("obj"), obj); |
- CompileRun("Object.notify(obj, {type: 'b'});"); |
+ notify_fun2 = CompileRun( |
+ "(function() { Object.notify(obj, {type: 'b'}); })"); |
} |
+ Handle<Value> notify_fun3; |
{ |
LocalContext context3; |
context3->Global()->Set(String::New("obj"), obj); |
- CompileRun("Object.notify(obj, {type: 'c'});"); |
+ notify_fun3 = CompileRun( |
+ "(function() { Object.notify(obj, {type: 'c'}); })"); |
} |
{ |
LocalContext context4; |
context4->Global()->Set(String::New("observer"), observer); |
- CompileRun("Object.deliverChangeRecords(observer)"); |
+ context4->Global()->Set(String::New("fun1"), notify_fun1); |
+ context4->Global()->Set(String::New("fun2"), notify_fun2); |
+ context4->Global()->Set(String::New("fun3"), notify_fun3); |
+ CompileRun("fun1(); fun2(); fun3(); Object.deliverChangeRecords(observer)"); |
} |
CHECK_EQ(1, CompileRun("calls")->Int32Value()); |
CHECK_EQ(3, CompileRun("count")->Int32Value()); |
} |
+ |
+TEST(EndOfMicrotaskDelivery) { |
+ HarmonyIsolate isolate; |
+ HandleScope scope; |
+ LocalContext context; |
+ CompileRun( |
+ "var obj = {};" |
+ "var count = 0;" |
+ "var observer = function(records) { count = records.length };" |
+ "Object.observe(obj, observer);" |
+ "Object.notify(obj, {type: 'a'});"); |
+ CHECK_EQ(1, CompileRun("count")->Int32Value()); |
+} |
+ |
+TEST(DeliveryOrdering) { |
+ HarmonyIsolate isolate; |
+ HandleScope scope; |
+ LocalContext context; |
+ CompileRun( |
+ "var obj1 = {};" |
+ "var obj2 = {};" |
+ "var ordering = [];" |
+ "function observer2() { ordering.push(2); };" |
+ "function observer1() { ordering.push(1); };" |
+ "function observer3() { ordering.push(3); };" |
+ "Object.observe(obj1, observer1);" |
+ "Object.observe(obj1, observer2);" |
+ "Object.observe(obj1, observer3);" |
+ "Object.notify(obj1, {type: 'a'});"); |
+ CHECK_EQ(3, CompileRun("ordering.length")->Int32Value()); |
+ CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); |
+ CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
+ CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); |
+ CompileRun( |
+ "ordering = [];" |
+ "Object.observe(obj2, observer3);" |
+ "Object.observe(obj2, observer2);" |
+ "Object.observe(obj2, observer1);" |
+ "Object.notify(obj2, {type: 'b'});"); |
+ CHECK_EQ(3, CompileRun("ordering.length")->Int32Value()); |
+ CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); |
+ CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
+ CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); |
+} |
+ |
+TEST(DeliveryOrderingReentrant) { |
+ HarmonyIsolate isolate; |
+ HandleScope scope; |
+ LocalContext context; |
+ CompileRun( |
+ "var obj = {};" |
+ "var reentered = false;" |
+ "var ordering = [];" |
+ "function observer1() { ordering.push(1); };" |
+ "function observer2() {" |
+ " if (!reentered) {" |
+ " Object.notify(obj, {type: 'b'});" |
+ " reentered = true;" |
+ " }" |
+ " ordering.push(2);" |
+ "};" |
+ "function observer3() { ordering.push(3); };" |
+ "Object.observe(obj, observer1);" |
+ "Object.observe(obj, observer2);" |
+ "Object.observe(obj, observer3);" |
+ "Object.notify(obj, {type: 'a'});"); |
+ CHECK_EQ(5, CompileRun("ordering.length")->Int32Value()); |
+ CHECK_EQ(1, CompileRun("ordering[0]")->Int32Value()); |
+ CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
+ CHECK_EQ(3, CompileRun("ordering[2]")->Int32Value()); |
+ // Note that we re-deliver to observers 1 and 2, while observer3 |
+ // already received the second record during the first round. |
+ CHECK_EQ(1, CompileRun("ordering[3]")->Int32Value()); |
+ CHECK_EQ(2, CompileRun("ordering[1]")->Int32Value()); |
+} |