summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/basic/testWatchRecursion.js
blob: e5d5877df97c5f3572722dcfe354b3b0e46e53b2 (plain)
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;
    }
})();