// 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; } })();