1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
// Test that the watch handler is not called recursively for the same object
// and property.
(function() {
var obj1 = {}, obj2 = {};
var handler_entry_count = 0;
var handler_exit_count = 0;
obj1.watch('x', handler);
obj1.watch('y', handler);
obj2.watch('x', handler);
obj1.x = 1;
assertEq(handler_entry_count, 3);
assertEq(handler_exit_count, 3);
function handler(id) {
handler_entry_count++;
assertEq(handler_exit_count, 0);
switch (true) {
case this === obj1 && id === "x":
assertEq(handler_entry_count, 1);
obj2.x = 3;
assertEq(handler_exit_count, 2);
break;
case this === obj2 && id === "x":
assertEq(handler_entry_count, 2);
obj1.y = 4;
assertEq(handler_exit_count, 1);
break;
default:
assertEq(this, obj1);
assertEq(id, "y");
assertEq(handler_entry_count, 3);
// We expect no more watch handler invocations
obj1.x = 5;
obj1.y = 6;
obj2.x = 7;
assertEq(handler_exit_count, 0);
break;
}
++handler_exit_count;
assertEq(handler_entry_count, 3);
}
})();
// Test that run-away recursion in watch handlers is properly handled.
(function() {
var obj = {};
var i = 0;
try {
handler();
throw new Error("Unreachable");
} catch(e) {
assertEq(e instanceof InternalError, true);
}
function handler() {
var prop = "a" + ++i;
obj.watch(prop, handler);
obj[prop] = 2;
}
})();
|