summaryrefslogtreecommitdiffstats
path: root/devtools/client/debugger/test/mochitest/browser_dbg-returnvalues.js
blob: a0c070ab2dee14fab0a8b0bc0b1647b2fe9f7b04 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */

"use strict";

add_task(async function () {
  const dbg = await initDebugger("doc-return-values.html");
  await togglePauseOnExceptions(dbg, true, true);

  info("Test return values");
  await testReturnValue(dbg, "to sender", [
    { label: "return_something" },
    { label: "<return>", value: uneval("to sender") },
  ]);
  await testReturnValue(dbg, "undefined", [
    { label: "return_something" },
    { label: "<return>", value: '"undefined"' },
  ]);
  await testReturnValue(dbg, 2, [
    { label: "return_something" },
    { label: "<return>", value: "2" },
  ]);
  await testReturnValue(dbg, new Error("blah"), [
    { label: "return_something" },
    { label: "<return>", value: "Restricted" },
  ]);

  info("Test throw values");
  await testThrowValue(dbg, "a fit", [
    { label: "callee" },
    // The "uneval" call here gives us the way one would write `val` as
    // a JavaScript expression, similar to the way the debugger
    // displays values, so this test works when `val` is a string.
    { label: "<exception>", value: uneval("a fit") },
  ]);
  await testThrowValue(dbg, "undefined", [
    { label: "callee" },
    { label: "<exception>", value: '"undefined"' },
  ]);
  await testThrowValue(dbg, 2, [
    { label: "callee" },
    { label: "<exception>", value: "2" },
  ]);
  await testThrowValue(dbg, new Error("blah"), [
    { label: "callee" },
    { label: "<exception>", value: "Restricted" },
  ]);
});

async function testReturnValue(dbg, val, expectedScopeNodes) {
  invokeInTab("return_something", val);
  await waitForPaused(dbg);

  // "Step in" 2 times to get to the point where the debugger can
  // see the return value.
  await stepIn(dbg);
  await stepIn(dbg);

  for (const [i, scopeNode] of expectedScopeNodes.entries()) {
    const index = i + 1;
    is(
      getScopeNodeLabel(dbg, index),
      scopeNode.label,
      `check for ${scopeNode.label}`
    );
    if (scopeNode.value) {
      is(
        getScopeNodeValue(dbg, index),
        scopeNode.value,
        `check value is ${scopeNode.value}`
      );
    }
  }

  await resume(dbg);
  assertNotPaused(dbg);
}

async function testThrowValue(dbg, val, expectedScopeNodes) {
  invokeInTab("throw_something", val);
  await waitForPaused(dbg);

  // "Step in" once to get to the point where the debugger can see the
  // exception.
  await stepIn(dbg);

  for (const [i, scopeNode] of expectedScopeNodes.entries()) {
    const index = i + 1;
    is(
      getScopeNodeLabel(dbg, index),
      scopeNode.label,
      `check for ${scopeNode.label}`
    );
    if (scopeNode.value) {
      is(
        getScopeNodeValue(dbg, index),
        scopeNode.value,
        `check exception is ${scopeNode.value}`
      );
    }
  }

  await resume(dbg);
  assertNotPaused(dbg);
}