summaryrefslogtreecommitdiffstats
path: root/devtools/server/tests/unit/test_dbgactor.js
diff options
context:
space:
mode:
Diffstat (limited to 'devtools/server/tests/unit/test_dbgactor.js')
-rw-r--r--devtools/server/tests/unit/test_dbgactor.js116
1 files changed, 116 insertions, 0 deletions
diff --git a/devtools/server/tests/unit/test_dbgactor.js b/devtools/server/tests/unit/test_dbgactor.js
new file mode 100644
index 000000000..b22b8446b
--- /dev/null
+++ b/devtools/server/tests/unit/test_dbgactor.js
@@ -0,0 +1,116 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+var gClient;
+var gDebuggee;
+
+const xpcInspector = Cc["@mozilla.org/jsinspector;1"].getService(Ci.nsIJSInspector);
+
+function run_test()
+{
+ initTestDebuggerServer();
+ gDebuggee = testGlobal("test-1");
+ DebuggerServer.addTestGlobal(gDebuggee);
+
+ let transport = DebuggerServer.connectPipe();
+ gClient = new DebuggerClient(transport);
+ gClient.addListener("connected", function (aEvent, aType, aTraits) {
+ gClient.listTabs((aResponse) => {
+ do_check_true("tabs" in aResponse);
+ for (let tab of aResponse.tabs) {
+ if (tab.title == "test-1") {
+ test_attach_tab(tab.actor);
+ return false;
+ }
+ }
+ do_check_true(false); // We should have found our tab in the list.
+ return undefined;
+ });
+ });
+
+ gClient.connect();
+
+ do_test_pending();
+}
+
+// Attach to |aTabActor|, and check the response.
+function test_attach_tab(aTabActor)
+{
+ gClient.request({ to: aTabActor, type: "attach" }, function (aResponse) {
+ do_check_false("error" in aResponse);
+ do_check_eq(aResponse.from, aTabActor);
+ do_check_eq(aResponse.type, "tabAttached");
+ do_check_true(typeof aResponse.threadActor === "string");
+
+ test_attach_thread(aResponse.threadActor);
+ });
+}
+
+// Attach to |aThreadActor|, check the response, and resume it.
+function test_attach_thread(aThreadActor)
+{
+ gClient.request({ to: aThreadActor, type: "attach" }, function (aResponse) {
+ do_check_false("error" in aResponse);
+ do_check_eq(aResponse.from, aThreadActor);
+ do_check_eq(aResponse.type, "paused");
+ do_check_true("why" in aResponse);
+ do_check_eq(aResponse.why.type, "attached");
+
+ test_resume_thread(aThreadActor);
+ });
+}
+
+// Resume |aThreadActor|, and see that it stops at the 'debugger'
+// statement.
+function test_resume_thread(aThreadActor)
+{
+ // Allow the client to resume execution.
+ gClient.request({ to: aThreadActor, type: "resume" }, function (aResponse) {
+ do_check_false("error" in aResponse);
+ do_check_eq(aResponse.from, aThreadActor);
+ do_check_eq(aResponse.type, "resumed");
+
+ do_check_eq(xpcInspector.eventLoopNestLevel, 0);
+
+ // Now that we know we're resumed, we can make the debuggee do something.
+ Cu.evalInSandbox("var a = true; var b = false; debugger; var b = true;", gDebuggee);
+ // Now make sure that we've run the code after the debugger statement...
+ do_check_true(gDebuggee.b);
+ });
+
+ gClient.addListener("paused", function (aName, aPacket) {
+ do_check_eq(aName, "paused");
+ do_check_false("error" in aPacket);
+ do_check_eq(aPacket.from, aThreadActor);
+ do_check_eq(aPacket.type, "paused");
+ do_check_true("actor" in aPacket);
+ do_check_true("why" in aPacket);
+ do_check_eq(aPacket.why.type, "debuggerStatement");
+
+ // Reach around the protocol to check that the debuggee is in the state
+ // we expect.
+ do_check_true(gDebuggee.a);
+ do_check_false(gDebuggee.b);
+
+ do_check_eq(xpcInspector.eventLoopNestLevel, 1);
+
+ // Let the debuggee continue execution.
+ gClient.request({ to: aThreadActor, type: "resume" }, cleanup);
+ });
+}
+
+function cleanup()
+{
+ gClient.addListener("closed", function (aEvent, aResult) {
+ do_test_finished();
+ });
+
+ try {
+ let xpcInspector = Cc["@mozilla.org/jsinspector;1"].getService(Ci.nsIJSInspector);
+ do_check_eq(xpcInspector.eventLoopNestLevel, 0);
+ } catch (e) {
+ dump(e);
+ }
+
+ gClient.close();
+}