/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/* eslint-disable no-shadow */
"use strict";
/*
Test that debugger advances instead of pausing twice on the
same line when encountering both a watchpoint and a breakpoint.
*/
add_task(
threadFrontTest(async args => {
await testBreakpointAndSetWatchpoint(args);
await testBreakpointAndGetWatchpoint(args);
await testLoops(args);
})
);
// Test that we advance to the next line when a location
// has both a breakpoint and set watchpoint.
async
function testBreakpointAndSetWatchpoint({
commands,
threadFront,
debuggee,
}) {
async
function evaluateJS(input) {
const { result } = await commands.scriptCommand.execute(input, {
frameActor: packet.frame.actorID,
});
return result;
}
function evaluateTestCode(debuggee) {
/* eslint-disable */
Cu.evalInSandbox(
`
// 1
function stopMe(obj) {
// 2
debugger;
// 3
obj.a = 2;
// 4
debugger;
// 5
}
//
stopMe({a: 1})`,
debuggee,
"1.8",
"test_watchpoint-02.js"
);
/* eslint-disable */
}
const packet = await executeOnNextTickAndWaitForPause(
() => evaluateTestCode(debuggee),
threadFront
);
info(
"Test that we pause on the debugger statement.");
Assert.equal(packet.frame.where.line, 3);
Assert.equal(packet.why.type,
"debuggerStatement");
info(
"Add set watchpoint.");
const args = packet.frame.arguments;
const obj = args[0];
const objClient = threadFront.pauseGrip(obj);
await objClient.addWatchpoint(
"a",
"obj.a",
"set");
info(
"Add breakpoint.");
const source = await getSourceById(threadFront, packet.frame.where.actor);
const location = {
sourceUrl: source.url,
line: 4,
};
threadFront.setBreakpoint(location, {});
info(
"Test that pause occurs on breakpoint.");
const packet2 = await resumeAndWaitForPause(threadFront);
Assert.equal(packet2.frame.where.line, 4);
Assert.equal(packet2.why.type,
"breakpoint");
const packet3 = await resumeAndWaitForPause(threadFront);
info(
"Test that we pause on the second debugger statement.");
Assert.equal(packet3.frame.where.line, 5);
Assert.equal(packet3.why.type,
"debuggerStatement");
info(
"Test that the value has updated.");
const result = await evaluateJS(
"obj.a");
Assert.equal(result, 2);
info(
"Remove breakpoint and finish.");
threadFront.removeBreakpoint(location, {});
await resume(threadFront);
}
// Test that we advance to the next line when a location
// has both a breakpoint and get watchpoint.
async
function testBreakpointAndGetWatchpoint({ threadFront, debuggee }) {
function evaluateTestCode(debuggee) {
/* eslint-disable */
Cu.evalInSandbox(
`
// 1
function stopMe(obj) {
// 2
debugger;
// 3
obj.a + 4;
// 4
debugger;
// 5
}
//
stopMe({a: 1})`,
debuggee,
"1.8",
"test_watchpoint-02.js"
);
/* eslint-disable */
}
const packet = await executeOnNextTickAndWaitForPause(
() => evaluateTestCode(debuggee),
threadFront
);
info(
"Test that we pause on the debugger statement.");
Assert.equal(packet.frame.where.line, 3);
info(
"Add get watchpoint.");
const args = packet.frame.arguments;
const obj = args[0];
const objClient = threadFront.pauseGrip(obj);
await objClient.addWatchpoint(
"a",
"obj.a",
"get");
info(
"Add breakpoint.");
const source = await getSourceById(threadFront, packet.frame.where.actor);
const location = {
sourceUrl: source.url,
line: 4,
};
threadFront.setBreakpoint(location, {});
info(
"Test that pause occurs on breakpoint.");
const packet2 = await resumeAndWaitForPause(threadFront);
Assert.equal(packet2.frame.where.line, 4);
Assert.equal(packet2.why.type,
"breakpoint");
const packet3 = await resumeAndWaitForPause(threadFront);
info(
"Test that we pause on the second debugger statement.");
Assert.equal(packet3.frame.where.line, 5);
Assert.equal(packet3.why.type,
"debuggerStatement");
info(
"Remove breakpoint and finish.");
threadFront.removeBreakpoint(location, {});
await resume(threadFront);
}
// Test that we can pause multiple times
// on the same line for a watchpoint.
async
function testLoops({ commands, threadFront, debuggee }) {
async
function evaluateJS(input) {
const { result } = await commands.scriptCommand.execute(input, {
frameActor: packet.frame.actorID,
});
return result;
}
function evaluateTestCode(debuggee) {
/* eslint-disable */
Cu.evalInSandbox(
`
// 1
function stopMe(obj) {
// 2
let i = 0;
// 3
debugger;
// 4
while (i++ < 2) {
// 5
obj.a = 2;
// 6
}
// 7
debugger;
// 8
}
//
stopMe({a: 1})`,
debuggee,
"1.8",
"test_watchpoint-02.js"
);
/* eslint-disable */
}
const packet = await executeOnNextTickAndWaitForPause(
() => evaluateTestCode(debuggee),
threadFront
);
info(
"Test that we pause on the debugger statement.");
Assert.equal(packet.frame.where.line, 4);
Assert.equal(packet.why.type,
"debuggerStatement");
info(
"Add set watchpoint.");
const args = packet.frame.arguments;
const obj = args[0];
const objClient = threadFront.pauseGrip(obj);
await objClient.addWatchpoint(
"a",
"obj.a",
"set");
info(
"Test that watchpoint triggers pause on set.");
const packet2 = await resumeAndWaitForPause(threadFront);
Assert.equal(packet2.frame.where.line, 6);
Assert.equal(packet2.why.type,
"setWatchpoint");
let result = await evaluateJS(
"obj.a");
Assert.equal(result, 1);
info(
"Test that watchpoint triggers pause on set (2nd time).");
const packet3 = await resumeAndWaitForPause(threadFront);
Assert.equal(packet3.frame.where.line, 6);
Assert.equal(packet3.why.type,
"setWatchpoint");
let result2 = await evaluateJS(
"obj.a");
Assert.equal(result2, 2);
info(
"Test that we pause on second debugger statement.");
const packet4 = await resumeAndWaitForPause(threadFront);
Assert.equal(packet4.frame.where.line, 8);
Assert.equal(packet4.why.type,
"debuggerStatement");
await resume(threadFront);
}