1
// Comprehensive test of get/setVariable on many kinds of environments and
4
load(libdir + "asserts.js");
7
// global bindings and bindings on the global prototype chain
10
"Object.prototype.x = VAL; @@",
12
// let, catch, and comprehension bindings
14
"{ let x = VAL; @@ }",
15
"let (x = VAL) { @@ }",
16
"try { throw VAL; } catch (x) { @@ }",
17
"try { throw VAL; } catch (x) { @@ }",
18
"for (let x of [VAL]) { @@ }",
19
"for each (let x in [VAL]) { @@ }",
20
"switch (0) { default: let x = VAL; @@ }",
21
"[function () { @@ }() for (x of [VAL])];",
22
// "((function () { @@ })() for (x of [VAL])).next();", // bug 709367
25
"function f(x) { @@ } f(VAL);",
26
"function f([w, x]) { @@ } f([0, VAL]);",
27
"function f({v: x}) { @@ } f({v: VAL});",
28
"function f([w, {v: x}]) { @@ } f([0, {v: VAL}]);",
30
// bindings in functions
31
"function f() { var x = VAL; @@ } f();",
32
"function f() { let x = VAL; @@ } f();",
33
"function f([x]) { let x = VAL; @@ } f(['fail']);",
34
"function f(x) { { let x = VAL; @@ } } f('fail');",
35
"function f() { function x() {} x = VAL; @@ } f();",
38
"function f(s) { eval(s); @@ } f('var x = VAL');",
39
"function f(s) { let (x = 'fail') { eval(s); } x = VAL; @@ } f('var x;');",
40
"var x = VAL; function f(s) { eval('var x = 0;'); eval(s); @@ } f('delete x;');",
41
"function f(obj) { with (obj) { @@ } } f({x: VAL});",
42
"function f(obj) { with (obj) { @@ } } f(Object.create({x: VAL}));",
43
"function f(b) { if (b) { function x(){} } x = VAL; @@ } f(1);",
48
function test(code, debugStmts, followupStmts) {
52
var g = newGlobal('new-compartment');
53
g.eval("function debugMe() { var x = 'wrong-x'; debugger; }");
56
var dbg = Debugger(g);
57
dbg.onDebuggerStatement = function (frame) {
58
if (frame.callee !== null && frame.callee.name == 'debugMe')
60
var env = frame.environment.find("x");
61
assertEq(env.getVariable("x"), val)
62
assertEq(env.setVariable("x", 'ok'), undefined);
63
assertEq(env.getVariable("x"), 'ok');
65
// setVariable cannot create new variables.
66
assertThrowsInstanceOf(function () { env.setVariable("newVar", 0); }, TypeError);
70
code = code.replace("@@", debugStmts);
71
if (followupStmts !== undefined)
72
code += " " + followupStmts;
73
code = code.replace(/VAL/g, uneval(val));
78
for (var s of cases) {
79
// Test triggering the debugger right in the scope in which x is bound.
80
test(s, "debugger; assertEq(x, 'ok');");
82
// Test calling a function that triggers the debugger.
83
test(s, "debugMe(); assertEq(x, 'ok');");
85
// Test triggering the debugger from a scope nested in x's scope.
86
test(s, "let (y = 'irrelevant') { (function (z) { let (zz = y) { debugger; }})(); } assertEq(x, 'ok');"),
88
// Test closing over the variable and triggering the debugger later, after
89
// leaving the variable's scope.
90
test(s, "capture = {dbg: function () { debugger; }, get x() { return x; }};",
91
"assertEq(capture.x, VAL); capture.dbg(); assertEq(capture.x, 'ok');");