Debug = debug.Debug
let test_name;
let listener_delegate;
let listener_called;
let exception;
let begin_test_count = 0;
let end_test_count = 0;
let break_count = 0;
function listener(event, exec_state, event_data, data) {
try {
if (event == Debug.DebugEvent.Break) {
break_count++;
listener_called = true;
listener_delegate(exec_state);
}
} catch (e) {
exception = e;
print(e, e.stack);
}
}
Debug.setListener(listener);
function BeginTest(name) {
test_name = name;
listener_called = false;
exception = null;
begin_test_count++;
}
function EndTest() {
assertTrue(listener_called, "listener not called for " + test_name);
assertNull(exception, test_name + " / " + exception);
end_test_count++;
}
BeginTest("Check that 'x' resolves correctly and 'a' is written correctly");
var a = "a";
function f1() {
var x = 1;
(() => x);
var y = "y";
var z = "z";
(function () {
var x = 2;
(function () {
y;
debugger;
})();
})();
return y;
}
listener_delegate = function(exec_state) {
for (var i = 0; i < exec_state.frameCount() - 1; i++) {
var frame = exec_state.frame(i);
var value;
try {
value = frame.evaluate("x").value();
} catch (e) {
value = e.name;
}
print(frame.sourceLineText());
var expected = frame.sourceLineText().match(/\/\/ (.*$)/)[1];
assertEquals(String(expected), String(value));
}
assertEquals("[object global]",
String(exec_state.frame(0).evaluate("this").value()));
assertEquals("y", exec_state.frame(0).evaluate("y").value());
assertEquals("a", exec_state.frame(0).evaluate("a").value());
exec_state.frame(0).evaluate("a = 'A'");
assertThrows(() => exec_state.frame(0).evaluate("z"), ReferenceError);
}
f1();
assertEquals("A", a);
a = "a";
EndTest();
BeginTest("Check that a context-allocated 'this' works")
function f2() {
var x = 1;
(() => x);
var y = "y";
var z = "z";
(function() {
var x = 2;
(() => {
y;
a;
this;
debugger;
})();
})();
return y;
};
f2();
assertEquals("A", a);
EndTest();
BeginTest("Check that we don't get confused with nested scopes");
function f3() {
var x = 1;
(() => x);
(function() {
var x = 2;
(function() {
{
let x = 3;
(() => x);
}
debugger;
})();
})();
}
listener_delegate = function(exec_state) {
assertThrows(() => exec_state.frame(0).evaluate("x").value());
}
f3();
EndTest();
BeginTest("Check that stack-allocated variable is unavailable");
function f4() {
let a = 1;
let b = 2;
let c = 3;
() => a + c;
return function g() {
let a = 2;
return function h() {
b;
debugger;
}
}
}
listener_delegate = function(exec_state) {
assertEquals(2, exec_state.frame(0).evaluate("b").value());
assertEquals(3, exec_state.frame(0).evaluate("c").value())
assertThrows(() => exec_state.frame(0).evaluate("a").value());
};
(f4())()();
EndTest();
BeginTest("Check that block lists on the closure boundary work as expected");
function f5() {
let a = 1;
() => a;
return function g() {
let a = 2;
{
let b = 3;
return function h() {
debugger;
}
}
}
}
listener_delegate = function(exec_state) {
assertThrows(() => exec_state.frame(0).evaluate("a").value());
};
(f5())()();
EndTest();
BeginTest("Check that outer functions also get the correct block list calculated");
let break_position;
function f6() {
let a = 1;
return function g() {
if (break_position === 2) debugger;
let a = 2; (() => a);
return function h() {
if (break_position === 1) debugger;
}
}
}
listener_delegate = function (exec_state) {
assertEquals(2, exec_state.frame(0).evaluate("a").value());
}
break_position = 1;
(f6())()();
EndTest();
BeginTest("Check that outer functions also get the correct block list calculated (continued)");
listener_delegate = function (exec_state) {
assertThrows(() => exec_state.frame(0).evaluate("a").value());
}
break_position = 2;
(f6())()();
EndTest();
BeginTest("Check that 'inner' block lists, calculated on a previous pause, don't block the lookup");
function f7(o) {
let a = 1;
with (o) {
if (break_position === 2) debugger;
(function g() {
if (break_position === 1) debugger;
})();
}
}
listener_delegate = function (exec_state) {
assertThrows(() => exec_state.frame(0).evaluate("a").value());
}
break_position = 1;
f7({});
EndTest();
BeginTest("Check that 'inner' block lists, calculated on a previous pause, don't block the lookup (continued)");
listener_delegate = function (exec_state) {
assertEquals(1, exec_state.frame(0).evaluate("a").value());
}
break_position = 2;
f7({});
EndTest();
assertEquals(begin_test_count, break_count,
'one or more tests did not enter the debugger');
assertEquals(begin_test_count, end_test_count,
'one or more tests did not have its result checked');