Bug 1958081 - [devtools] Migrate object inspector to the new JS objects test framework. r=devtools-reviewers,nchevobbe

Differential Revision: https://phabricator.services.mozilla.com/D245074
This commit is contained in:
Alexandre Poirot
2025-05-13 12:30:38 +00:00
committed by apoirot@mozilla.com
parent 833ef8762c
commit a5749b35e9
3 changed files with 857 additions and 670 deletions

View File

@@ -527,6 +527,9 @@ fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and
["browser_webconsole_object_inspector_entries.js"]
fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled
support-files = ["browser_webconsole_object_inspector_entries.snapshot.mjs"]
https_first_disabled = true # JS HttpServer doesn't support https
skip-if = ["http3"] # JS HttpServer doesn't support http3
["browser_webconsole_object_inspector_getters.js"]
fail-if = ["a11y_checks"] # Bug 1849028 clicked element may not be focusable and/or labeled

View File

@@ -3,678 +3,101 @@
"use strict";
// Check expanding/collapsing object with entries (Maps, Sets, URLSearchParams, …) in the console.
const TEST_URI = `https://example.com/document-builder.sjs?html=${encodeURIComponent(
`<!DOCTYPE html><h1>Object Inspector on Object with entries</h1>`
)}`;
const { ELLIPSIS } = require("resource://devtools/shared/l10n.js");
add_task(async function () {
// This will make it so we'll have stable MIDI devices reported
await pushPref("midi.testing", true);
await pushPref("dom.webmidi.enabled", true);
await pushPref("midi.prompt.testing", true);
await pushPref("media.navigator.permission.disabled", true);
// enable custom highlight API
await pushPref("dom.customHighlightAPI.enabled", true);
// enable custom state
await pushPref("dom.element.customstateset.enabled", true);
const hud = await openNewTabAndConsole(TEST_URI);
logAllStoreChanges(hud);
const taskResult = await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[],
async function () {
const formData = new content.FormData();
formData.append("a", 1);
formData.append("a", 2);
formData.append("b", 3);
const midiAccess = Cu.waiveXrays(
await content.wrappedJSObject.navigator.requestMIDIAccess()
);
content.CSS.highlights.set("search", new content.Highlight());
content.CSS.highlights.set("glow", new content.Highlight());
content.CSS.highlights.set("anchor", new content.Highlight());
content.customElements.define(
"fx-test",
class extends content.HTMLElement {}
);
const { states } = content.document
.createElement("fx-test")
.attachInternals();
states.add("custom-state");
states.add("another-custom-state");
content.wrappedJSObject.console.log(
"oi-entries-test",
new Map(
Array.from({ length: 2 }).map((el, i) => [
{ key: i },
content.document,
])
),
new Map(Array.from({ length: 20 }).map((el, i) => [Symbol(i), i])),
new Map(Array.from({ length: 331 }).map((el, i) => [Symbol(i), i])),
new Set(Array.from({ length: 2 }).map((el, i) => ({ value: i }))),
new Set(Array.from({ length: 20 }).map((el, i) => i)),
new Set(Array.from({ length: 222 }).map((el, i) => i)),
new content.URLSearchParams([
["a", 1],
["a", 2],
["b", 3],
["b", 3],
["b", 5],
["c", "this is 6"],
["d", 7],
["e", 8],
["f", 9],
["g", 10],
["h", 11],
]),
new content.Headers({ a: 1, b: 2, c: 3 }),
formData,
midiAccess.inputs,
midiAccess.outputs,
content.CSS.highlights,
states
);
return {
midi: {
inputs: [...midiAccess.inputs.values()].map(input => ({
id: input.id,
name: input.name,
type: input.type,
manufacturer: input.manufacturer,
})),
outputs: [...midiAccess.outputs.values()].map(output => ({
id: output.id,
name: output.name,
type: output.type,
manufacturer: output.manufacturer,
})),
},
};
}
);
const node = await waitFor(() =>
findConsoleAPIMessage(hud, "oi-entries-test")
);
const objectInspectors = [...node.querySelectorAll(".tree")];
is(
objectInspectors.length,
13,
"There is the expected number of object inspectors"
);
const [
smallMapOi,
mapOi,
largeMapOi,
smallSetOi,
setOi,
largeSetOi,
urlSearchParamsOi,
headersOi,
formDataOi,
midiInputsOi,
midiOutputsOi,
highlightsRegistryOi,
customStateSetOi,
] = objectInspectors;
await testSmallMap(smallMapOi);
await testMap(mapOi);
await testLargeMap(largeMapOi);
await testSmallSet(smallSetOi);
await testSet(setOi);
await testLargeSet(largeSetOi);
await testUrlSearchParams(urlSearchParamsOi);
await testHeaders(headersOi);
await testFormData(formDataOi);
await testMidiInputs(midiInputsOi, taskResult.midi.inputs);
await testMidiOutputs(midiOutputsOi, taskResult.midi.outputs);
await testHighlightsRegistry(highlightsRegistryOi);
await testCustomStateSet(customStateSetOi);
const { JSObjectsTestUtils, CONTEXTS } = ChromeUtils.importESModule(
"resource://testing-common/JSObjectsTestUtils.sys.mjs"
);
add_setup(function () {
JSObjectsTestUtils.init(this);
});
async function testSmallMap(oi) {
info("Expanding the Map");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
const EXPECTED_VALUES_FILE =
"browser_webconsole_object_inspector_entries.snapshot.mjs";
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
add_task(async function () {
// nsHttpServer does not support https
// eslint-disable-next-line @microsoft/sdl/no-insecure-url
const hud = await openNewTabAndConsole("http://example.com");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
let count = 0;
await JSObjectsTestUtils.runTest(
EXPECTED_VALUES_FILE,
async function ({ context, expression }) {
if (context == CONTEXTS.CHROME) {
return undefined;
}
await SpecialPowers.spawn(
gBrowser.selectedBrowser,
[expression, count],
async function (exp, i) {
let value;
try {
value = content.eval(exp);
} catch (e) {
value = e;
}
content.console.log("test message " + i, value);
}
);
const messageNode = await waitFor(() =>
findConsoleAPIMessage(hud, "test message " + count)
);
count++;
const oi = messageNode.querySelector(".tree");
if (oi) {
const preview = [];
// Expand the root node, otherwise the object is collapsed by default.
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
// Do a first lookup to expand all the "<entries>" nodes,
// as well as their immediate first entries.
// This will generate new ".tree-node"'s.
for (const node of oi.querySelectorAll(".tree-node")) {
const label = node.textContent.replace(/\u200B/g, "");
if (label == "<entries>") {
await expandObjectInspectorNode(node);
const firstEntry = node.nextSibling;
if (isObjectInspectorNodeExpandable(firstEntry)) {
await expandObjectInspectorNode(firstEntry);
}
}
}
// Generate a human-friendly representation of the state of the object inspector
for (const node of oi.querySelectorAll(".tree-node")) {
const label = node.textContent.replace(/\u200B/g, "");
let icon = "\u251C "; // "|-" character
if (isObjectInspectorNodeExpandable(node)) {
icon = node
.querySelector(".theme-twisty")
.classList.contains("open")
? "▼ "
: "▶︎ ";
}
const level = node.getAttribute("aria-level");
const indent = " ".repeat(parseInt(level, 10) - 1);
preview.push(indent + icon + label);
}
// Help debug the test by scrolling to the very last node,
// so that the object inspector is fully visible.
const nodes = oi.querySelectorAll(".node");
const lastNode = nodes[nodes.length - 1];
lastNode.scrollIntoView();
return preview;
}
// If this is a primitive data type, there won't be an object inspector,
// but only a simple Rep that we can only stringify.
const object = messageNode.querySelectorAll(".message-body > *")[1];
return object.textContent;
}
);
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 6 nodes, the 4 original ones, and the 2 entries.
is(oiNodes.length, 6, "There is the expected number of nodes in the tree");
info("Expand first entry");
await expandObjectInspectorNode(oiNodes[3]);
oiNodes = oi.querySelectorAll(".tree-node");
/*
* ▼ Map (2)
* | size: 2
* | ▼ <entries>
* | | ▼ 0: {…} -> HTMLDocument
* | | | ▶︎ <key>: Object {…}
* | | | ▶︎ <value>: HTMLDocument
* | | ▶︎ 1: {…} -> HTMLDocument
* | ▶︎ <prototype>
*/
is(oiNodes.length, 8, "There is the expected number of nodes in the tree");
info("Expand <key> for first entry");
await expandObjectInspectorNode(oiNodes[4]);
oiNodes = oi.querySelectorAll(".tree-node");
/*
* ▼ Map (2)
* | size: 2
* | ▼ <entries>
* | | ▼ 0: {…} -> HTMLDocument
* | | | ▼ <key>: Object {…}
* | | | | key: 0
* | | | | ▶︎ <prototype>
* | | | ▶︎ <value>: HTMLDocument
* | | ▶︎ 1: {…} -> HTMLDocument
* | ▶︎ <prototype>
*/
is(oiNodes.length, 10, "There is the expected number of nodes in the tree");
info("Expand <value> for first entry");
await expandObjectInspectorNode(oiNodes[7]);
oiNodes = oi.querySelectorAll(".tree-node");
Assert.greater(oiNodes.length, 10, "The document node was expanded");
}
async function testMap(oi) {
info("Expanding the Map");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 24 nodes, the 4 original ones, and the 20 entries.
is(oiNodes.length, 24, "There is the expected number of nodes in the tree");
}
async function testLargeMap(oi) {
info("Expanding the large map");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 8 nodes, the 4 original ones, and the 4 buckets.
is(oiNodes.length, 8, "There is the expected number of nodes in the tree");
is(oiNodes[3].textContent, `[0${ELLIPSIS}99]`);
is(oiNodes[4].textContent, `[100${ELLIPSIS}199]`);
is(oiNodes[5].textContent, `[200${ELLIPSIS}299]`);
is(oiNodes[6].textContent, `[300${ELLIPSIS}330]`);
}
async function testSmallSet(oi) {
info("Expanding the Set");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 6 nodes, the 4 original ones, and the 2 entries.
is(oiNodes.length, 6, "There is the expected number of nodes in the tree");
info("Expand first entry");
await expandObjectInspectorNode(oiNodes[3]);
oiNodes = oi.querySelectorAll(".node");
/*
* ▼ Set (2)
* | size: 2
* | ▼ <entries>
* | | ▼ 0: {…}
* | | | | value: 0
* | | | ▶︎ <prototype>
* | | ▶︎ 1: {…}
* | ▶︎ <prototype>
*/
is(oiNodes.length, 8, "There is the expected number of nodes in the tree");
}
async function testSet(oi) {
info("Expanding the Set");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the Set");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 24 nodes, the 4 original ones, and the 20 entries.
is(oiNodes.length, 24, "There is the expected number of nodes in the tree");
}
async function testLargeSet(oi) {
info("Expanding the large Set");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the Set");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 7 nodes, the 4 original ones, and the 3 buckets.
is(oiNodes.length, 7, "There is the expected number of nodes in the tree");
is(oiNodes[3].textContent, `[0${ELLIPSIS}99]`);
is(oiNodes[4].textContent, `[100${ELLIPSIS}199]`);
is(oiNodes[5].textContent, `[200${ELLIPSIS}221]`);
}
async function testUrlSearchParams(oi) {
is(
oi.textContent,
`URLSearchParams(11) { a → "1", a → "2", b → "3", b → "3", b → "5", c → "this is 6", d → "7", e → "8", f → "9", g → "10", ${ELLIPSIS} }`,
"URLSearchParams has expected content"
);
info("Expanding the URLSearchParams");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the URLSearchParams");
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 14 nodes, the 4 original ones, and the 11 entries.
is(oiNodes.length, 15, "There is the expected number of nodes in the tree");
is(
oiNodes[3].textContent,
`0: a → "1"`,
"First entry is displayed as expected"
);
is(
oiNodes[4].textContent,
`1: a → "2"`,
`Second "a" entry is also display although it has the same name as the first entry`
);
is(
oiNodes[5].textContent,
`2: b → "3"`,
`Third entry is the expected one...`
);
is(
oiNodes[6].textContent,
`3: b → "3"`,
`As well as fourth, even though both name and value are similar`
);
is(
oiNodes[7].textContent,
`4: b → "5"`,
`Fifth entry is displayed as expected`
);
is(
oiNodes[8].textContent,
`5: c → "this is 6"`,
`Sixth entry is displayed as expected`
);
}
async function testHeaders(oi) {
is(
oi.textContent,
`Headers(3) { a → "1", b → "2", c → "3" }`,
"Headers has expected content"
);
info("Expanding the Headers");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 3 nodes: the root, entries and the proto.
is(oiNodes.length, 3, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[1];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the Headers");
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 6 nodes, the 3 original ones, and the 3 entries.
is(oiNodes.length, 6, "There is the expected number of nodes in the tree");
is(oiNodes[2].textContent, `a: "1"`, "First entry is displayed as expected");
is(
oiNodes[3].textContent,
`b: "2"`,
`Second "a" entry is also display although it has the same name as the first entry`
);
is(oiNodes[4].textContent, `c: "3"`, `Third entry is the expected one...`);
}
async function testFormData(oi) {
is(
oi.textContent,
`FormData(3) { a → "1", a → "2", b → "3" }`,
"FormData has expected content"
);
info("Expanding the FormData");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 3 nodes: the root, entries and the proto.
is(oiNodes.length, 3, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[1];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the FormData");
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 6 nodes, the 3 original ones, and the 3 entries.
is(oiNodes.length, 6, "There is the expected number of nodes in the tree");
is(
oiNodes[2].textContent,
`0: a → "1"`,
"First entry is displayed as expected"
);
is(
oiNodes[3].textContent,
`1: a → "2"`,
`Second "a" entry is also display although it has the same name as the first entry`
);
is(
oiNodes[4].textContent,
`2: b → "3"`,
`Third entry entry is displayed as expected`
);
}
async function testMidiInputs(oi, midiInputs) {
const [input] = midiInputs;
is(
oi.textContent,
`MIDIInputMap { "${input.id}" → MIDIInput }`,
"MIDIInputMap has expected content"
);
info("Expanding the MIDIInputMap");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the MIDIInputMap");
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 5 nodes, the 4 original ones, and the entry.
is(oiNodes.length, 5, "There is the expected number of nodes in the tree");
is(
oiNodes[3].textContent,
`"${input.id}": MIDIInput { id: "${input.id}", manufacturer: "${input.manufacturer}", name: "${input.name}", ${ELLIPSIS} }`,
"First entry is displayed as expected"
);
}
async function testMidiOutputs(oi, midiOutputs) {
is(
oi.textContent,
`MIDIOutputMap(3) { "${midiOutputs[0].id}" → MIDIOutput, "${midiOutputs[1].id}" → MIDIOutput, "${midiOutputs[2].id}" → MIDIOutput }`,
"MIDIOutputMap has expected content"
);
info("Expanding the MIDIOutputMap");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the MIDIOutputMap");
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 7 nodes, the 4 original ones, and the 3 entries.
is(oiNodes.length, 7, "There is the expected number of nodes in the tree");
is(
oiNodes[3].textContent,
`"${midiOutputs[0].id}": MIDIOutput { id: "${midiOutputs[0].id}", manufacturer: "${midiOutputs[0].manufacturer}", name: "${midiOutputs[0].name}", ${ELLIPSIS} }`,
"First entry is displayed as expected"
);
is(
oiNodes[4].textContent,
`"${midiOutputs[1].id}": MIDIOutput { id: "${midiOutputs[1].id}", manufacturer: "${midiOutputs[1].manufacturer}", name: "${midiOutputs[1].name}", ${ELLIPSIS} }`,
"Second entry is displayed as expected"
);
is(
oiNodes[5].textContent,
`"${midiOutputs[2].id}": MIDIOutput { id: "${midiOutputs[2].id}", manufacturer: "${midiOutputs[2].manufacturer}", name: "${midiOutputs[2].name}", ${ELLIPSIS} }`,
"Third entry is displayed as expected"
);
}
async function testHighlightsRegistry(oi) {
is(
oi.textContent,
`HighlightRegistry(3) { search → Highlight, glow → Highlight, anchor → Highlight }`,
"HighlightRegistry has expected content"
);
info("Expanding the HighlightRegistry");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
info("Expanding the <entries> leaf of the HighlightRegistry");
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 7 nodes, the 4 original ones, and the 3 entries.
is(oiNodes.length, 7, "There is the expected number of nodes in the tree");
is(
oiNodes[3].querySelector(".node").textContent,
`0: search → Highlight { priority: 0, type: "highlight", size: 0 }`,
"First entry is displayed as expected"
);
is(
oiNodes[4].querySelector(".node").textContent,
`1: glow → Highlight { priority: 0, type: "highlight", size: 0 }`,
`Second entry is displayed as expected`
);
is(
oiNodes[5].querySelector(".node").textContent,
`2: anchor → Highlight { priority: 0, type: "highlight", size: 0 }`,
`Third entry entry is displayed as expected`
);
info("Expand last entry");
await expandObjectInspectorNode(oiNodes[5]);
oiNodes = oi.querySelectorAll(".tree-node");
// There are now 9 nodes, the 7 original ones, <key> and <value>
is(oiNodes.length, 9, "There is the expected number of nodes in the tree");
is(
oiNodes[6].querySelector(".node").textContent,
`<key>: "anchor"`,
`Got expected key node`
);
is(
oiNodes[7].querySelector(".node").textContent,
`<value>: Highlight { priority: 0, type: "highlight", size: 0 }`,
`Got expected value node`
);
info("Expand Highlight object");
await expandObjectInspectorNode(oiNodes[7]);
oiNodes = oi.querySelectorAll(".node");
// There are now 13 nodes, the 9 previous ones, and all the properties of the Highlight object
is(oiNodes.length, 13, "There is the expected number of nodes in the tree");
is(oiNodes[8].textContent, `priority: 0`, `Got expected priority property`);
is(oiNodes[9].textContent, `size: 0`, `Got expected size property`);
is(
oiNodes[10].textContent,
`type: "highlight"`,
`Got expected type property`
);
is(
oiNodes[11].textContent,
`<prototype>: HighlightPrototype { add: add(), clear: clear(), delete: delete(), … }`,
`Got expected prototype property`
);
}
async function testCustomStateSet(oi) {
info("Expanding the CustomStateSet");
await expandObjectInspectorNode(oi.querySelector(".tree-node"));
let oiNodes = oi.querySelectorAll(".tree-node");
// There are 4 nodes: the root, size, entries and the proto.
is(oiNodes.length, 4, "There is the expected number of nodes in the tree");
info("Expanding the <entries> leaf of the map");
const entriesNode = oiNodes[2];
is(
entriesNode.querySelector(".node").textContent,
"<entries>",
"There is the expected <entries> node"
);
await expandObjectInspectorNode(entriesNode);
oiNodes = oi.querySelectorAll(".node");
// There are now 6 nodes, the 4 original ones, and the 2 entries.
is(oiNodes.length, 6, "There is the expected number of nodes in the tree");
is(
oiNodes[3].textContent,
`0: "custom-state"`,
`Got expected first entry item`
);
is(
oiNodes[4].textContent,
`1: "another-custom-state"`,
`Got expected second entry item`
);
}
});

View File

@@ -0,0 +1,761 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* THIS FILE IS AUTOGENERATED. DO NOT MODIFY BY HAND.
*
* More info in https://firefox-source-docs.mozilla.org/devtools/tests/js-object-tests.html
*/
export default [
// undefined
"undefined",
// null
"null",
// true
"true",
// false
"false",
// NaN
"NaN",
// "abc"
"abc",
// "鼬ú"
"鼬ú",
// 42
"42",
// -42
"-42",
// -0
"-0",
// Infinity
"Infinity",
// BigInt(1000000000000000000)
"1000000000000000000n",
// 1n
"1n",
// -2n
"-2n",
// 0n
"0n",
// ({})
[
"▼ Object { }",
" ▶︎ <prototype>: Object { … }"
],
// ({ foo: "bar"})
[
"▼ Object { foo: \"bar\" }",
" ├ foo: \"bar\"",
" ▶︎ <prototype>: Object { … }"
],
// []
[
"▼ Array []",
" ├ length: 0",
" ▶︎ <prototype>: Array []"
],
// [1]
[
"▼ Array [ 1 ]",
" ├ 0: 1",
" ├ length: 1",
" ▶︎ <prototype>: Array []"
],
// ["foo"]
[
"▼ Array [ \"foo\" ]",
" ├ 0: \"foo\"",
" ├ length: 1",
" ▶︎ <prototype>: Array []"
],
// new BigInt64Array()
[
"▼ BigInt64Array []",
" ▶︎ buffer: ArrayBuffer { byteLength: 0 }",
" ├ byteLength: 0",
" ├ byteOffset: 0",
" ├ length: 0",
" ▶︎ <prototype>: BigInt64Array.prototype { … }"
],
// const a = new BigInt64Array(1);
// a[0] = BigInt(42);
// a;
//
[
"▼ BigInt64Array [ 42n ]",
" ├ 0: 42n",
" ▶︎ buffer: ArrayBuffer { byteLength: 8 }",
" ├ byteLength: 8",
" ├ byteOffset: 0",
" ├ length: 1",
" ▶︎ <prototype>: BigInt64Array.prototype { … }"
],
// new Map(
// Array.from({ length: 2 }).map((el, i) => [
// { key: i },
// { object: 42 },
// ])
// )
[
"▼ Map { {…} → {…}, {…} → {…} }",
" ├ size: 2",
" ▼ <entries>",
" ▼ 0: Object { key: 0 } → Object { object: 42 }",
" ▶︎ <key>: Object { key: 0 }",
" ▶︎ <value>: Object { object: 42 }",
" ▶︎ 1: Object { key: 1 } → Object { object: 42 }",
" ▶︎ <prototype>: Map.prototype { … }"
],
// new Map(Array.from({ length: 20 }).map((el, i) => [Symbol(i), i]))
[
"▼ Map(20) { Symbol(\"0\") → 0, Symbol(\"1\") → 1, Symbol(\"2\") → 2, Symbol(\"3\") → 3, Symbol(\"4\") → 4, Symbol(\"5\") → 5, Symbol(\"6\") → 6, Symbol(\"7\") → 7, Symbol(\"8\") → 8, Symbol(\"9\") → 9, … }",
" ├ size: 20",
" ▼ <entries>",
" ▼ 0: Symbol(\"0\") → 0",
" ├ <key>: Symbol(\"0\")",
" ├ <value>: 0",
" ▶︎ 1: Symbol(\"1\") → 1",
" ▶︎ 2: Symbol(\"2\") → 2",
" ▶︎ 3: Symbol(\"3\") → 3",
" ▶︎ 4: Symbol(\"4\") → 4",
" ▶︎ 5: Symbol(\"5\") → 5",
" ▶︎ 6: Symbol(\"6\") → 6",
" ▶︎ 7: Symbol(\"7\") → 7",
" ▶︎ 8: Symbol(\"8\") → 8",
" ▶︎ 9: Symbol(\"9\") → 9",
" ▶︎ 10: Symbol(\"10\") → 10",
" ▶︎ 11: Symbol(\"11\") → 11",
" ▶︎ 12: Symbol(\"12\") → 12",
" ▶︎ 13: Symbol(\"13\") → 13",
" ▶︎ 14: Symbol(\"14\") → 14",
" ▶︎ 15: Symbol(\"15\") → 15",
" ▶︎ 16: Symbol(\"16\") → 16",
" ▶︎ 17: Symbol(\"17\") → 17",
" ▶︎ 18: Symbol(\"18\") → 18",
" ▶︎ 19: Symbol(\"19\") → 19",
" ▶︎ <prototype>: Map.prototype { … }"
],
// new Map(Array.from({ length: 331 }).map((el, i) => [Symbol(i), i]))
[
"▼ Map(331) { Symbol(\"0\") → 0, Symbol(\"1\") → 1, Symbol(\"2\") → 2, Symbol(\"3\") → 3, Symbol(\"4\") → 4, Symbol(\"5\") → 5, Symbol(\"6\") → 6, Symbol(\"7\") → 7, Symbol(\"8\") → 8, Symbol(\"9\") → 9, … }",
" ├ size: 331",
" ▼ <entries>",
" ▼ [0…99]",
" ▶︎ 0: Symbol(\"0\") → 0",
" ▶︎ 1: Symbol(\"1\") → 1",
" ▶︎ 2: Symbol(\"2\") → 2",
" ▶︎ 3: Symbol(\"3\") → 3",
" ▶︎ 4: Symbol(\"4\") → 4",
" ▶︎ 5: Symbol(\"5\") → 5",
" ▶︎ 6: Symbol(\"6\") → 6",
" ▶︎ 7: Symbol(\"7\") → 7",
" ▶︎ 8: Symbol(\"8\") → 8",
" ▶︎ 9: Symbol(\"9\") → 9",
" ▶︎ 10: Symbol(\"10\") → 10",
" ▶︎ 11: Symbol(\"11\") → 11",
" ▶︎ 12: Symbol(\"12\") → 12",
" ▶︎ 13: Symbol(\"13\") → 13",
" ▶︎ 14: Symbol(\"14\") → 14",
" ▶︎ 15: Symbol(\"15\") → 15",
" ▶︎ 16: Symbol(\"16\") → 16",
" ▶︎ 17: Symbol(\"17\") → 17",
" ▶︎ 18: Symbol(\"18\") → 18",
" ▶︎ 19: Symbol(\"19\") → 19",
" ▶︎ 20: Symbol(\"20\") → 20",
" ▶︎ 21: Symbol(\"21\") → 21",
" ▶︎ 22: Symbol(\"22\") → 22",
" ▶︎ 23: Symbol(\"23\") → 23",
" ▶︎ 24: Symbol(\"24\") → 24",
" ▶︎ 25: Symbol(\"25\") → 25",
" ▶︎ 26: Symbol(\"26\") → 26",
" ▶︎ 27: Symbol(\"27\") → 27",
" ▶︎ 28: Symbol(\"28\") → 28",
" ▶︎ 29: Symbol(\"29\") → 29",
" ▶︎ 30: Symbol(\"30\") → 30",
" ▶︎ 31: Symbol(\"31\") → 31",
" ▶︎ 32: Symbol(\"32\") → 32",
" ▶︎ 33: Symbol(\"33\") → 33",
" ▶︎ 34: Symbol(\"34\") → 34",
" ▶︎ 35: Symbol(\"35\") → 35",
" ▶︎ 36: Symbol(\"36\") → 36",
" ▶︎ 37: Symbol(\"37\") → 37",
" ▶︎ 38: Symbol(\"38\") → 38",
" ▶︎ 39: Symbol(\"39\") → 39",
" ▶︎ 40: Symbol(\"40\") → 40",
" ▶︎ 41: Symbol(\"41\") → 41",
" ▶︎ 42: Symbol(\"42\") → 42",
" ▶︎ 43: Symbol(\"43\") → 43",
" ▶︎ 44: Symbol(\"44\") → 44",
" ▶︎ 45: Symbol(\"45\") → 45",
" ▶︎ 46: Symbol(\"46\") → 46",
" ▶︎ 47: Symbol(\"47\") → 47",
" ▶︎ 48: Symbol(\"48\") → 48",
" ▶︎ 49: Symbol(\"49\") → 49",
" ▶︎ 50: Symbol(\"50\") → 50",
" ▶︎ 51: Symbol(\"51\") → 51",
" ▶︎ 52: Symbol(\"52\") → 52",
" ▶︎ 53: Symbol(\"53\") → 53",
" ▶︎ 54: Symbol(\"54\") → 54",
" ▶︎ 55: Symbol(\"55\") → 55",
" ▶︎ 56: Symbol(\"56\") → 56",
" ▶︎ 57: Symbol(\"57\") → 57",
" ▶︎ 58: Symbol(\"58\") → 58",
" ▶︎ 59: Symbol(\"59\") → 59",
" ▶︎ 60: Symbol(\"60\") → 60",
" ▶︎ 61: Symbol(\"61\") → 61",
" ▶︎ 62: Symbol(\"62\") → 62",
" ▶︎ 63: Symbol(\"63\") → 63",
" ▶︎ 64: Symbol(\"64\") → 64",
" ▶︎ 65: Symbol(\"65\") → 65",
" ▶︎ 66: Symbol(\"66\") → 66",
" ▶︎ 67: Symbol(\"67\") → 67",
" ▶︎ 68: Symbol(\"68\") → 68",
" ▶︎ 69: Symbol(\"69\") → 69",
" ▶︎ 70: Symbol(\"70\") → 70",
" ▶︎ 71: Symbol(\"71\") → 71",
" ▶︎ 72: Symbol(\"72\") → 72",
" ▶︎ 73: Symbol(\"73\") → 73",
" ▶︎ 74: Symbol(\"74\") → 74",
" ▶︎ 75: Symbol(\"75\") → 75",
" ▶︎ 76: Symbol(\"76\") → 76",
" ▶︎ 77: Symbol(\"77\") → 77",
" ▶︎ 78: Symbol(\"78\") → 78",
" ▶︎ 79: Symbol(\"79\") → 79",
" ▶︎ 80: Symbol(\"80\") → 80",
" ▶︎ 81: Symbol(\"81\") → 81",
" ▶︎ 82: Symbol(\"82\") → 82",
" ▶︎ 83: Symbol(\"83\") → 83",
" ▶︎ 84: Symbol(\"84\") → 84",
" ▶︎ 85: Symbol(\"85\") → 85",
" ▶︎ 86: Symbol(\"86\") → 86",
" ▶︎ 87: Symbol(\"87\") → 87",
" ▶︎ 88: Symbol(\"88\") → 88",
" ▶︎ 89: Symbol(\"89\") → 89",
" ▶︎ 90: Symbol(\"90\") → 90",
" ▶︎ 91: Symbol(\"91\") → 91",
" ▶︎ 92: Symbol(\"92\") → 92",
" ▶︎ 93: Symbol(\"93\") → 93",
" ▶︎ 94: Symbol(\"94\") → 94",
" ▶︎ 95: Symbol(\"95\") → 95",
" ▶︎ 96: Symbol(\"96\") → 96",
" ▶︎ 97: Symbol(\"97\") → 97",
" ▶︎ 98: Symbol(\"98\") → 98",
" ▶︎ 99: Symbol(\"99\") → 99",
" ▶︎ [100…199]",
" ▶︎ [200…299]",
" ▶︎ [300…330]",
" ▶︎ <prototype>: Map.prototype { … }"
],
// new Set(Array.from({ length: 2 }).map((el, i) => ({ value: i })))
[
"▼ Set [ {…}, {…} ]",
" ├ size: 2",
" ▼ <entries>",
" ▼ 0: Object { value: 0 }",
" ├ value: 0",
" ▶︎ <prototype>: Object { … }",
" ▶︎ 1: Object { value: 1 }",
" ▶︎ <prototype>: Set.prototype { … }"
],
// new Set(Array.from({ length: 20 }).map((el, i) => i))
[
"▼ Set(20) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, … ]",
" ├ size: 20",
" ▼ <entries>",
" ├ 0: 0",
" ├ 1: 1",
" ├ 2: 2",
" ├ 3: 3",
" ├ 4: 4",
" ├ 5: 5",
" ├ 6: 6",
" ├ 7: 7",
" ├ 8: 8",
" ├ 9: 9",
" ├ 10: 10",
" ├ 11: 11",
" ├ 12: 12",
" ├ 13: 13",
" ├ 14: 14",
" ├ 15: 15",
" ├ 16: 16",
" ├ 17: 17",
" ├ 18: 18",
" ├ 19: 19",
" ▶︎ <prototype>: Set.prototype { … }"
],
// new Set(Array.from({ length: 222 }).map((el, i) => i))
[
"▼ Set(222) [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, … ]",
" ├ size: 222",
" ▼ <entries>",
" ▼ [0…99]",
" ├ 0: 0",
" ├ 1: 1",
" ├ 2: 2",
" ├ 3: 3",
" ├ 4: 4",
" ├ 5: 5",
" ├ 6: 6",
" ├ 7: 7",
" ├ 8: 8",
" ├ 9: 9",
" ├ 10: 10",
" ├ 11: 11",
" ├ 12: 12",
" ├ 13: 13",
" ├ 14: 14",
" ├ 15: 15",
" ├ 16: 16",
" ├ 17: 17",
" ├ 18: 18",
" ├ 19: 19",
" ├ 20: 20",
" ├ 21: 21",
" ├ 22: 22",
" ├ 23: 23",
" ├ 24: 24",
" ├ 25: 25",
" ├ 26: 26",
" ├ 27: 27",
" ├ 28: 28",
" ├ 29: 29",
" ├ 30: 30",
" ├ 31: 31",
" ├ 32: 32",
" ├ 33: 33",
" ├ 34: 34",
" ├ 35: 35",
" ├ 36: 36",
" ├ 37: 37",
" ├ 38: 38",
" ├ 39: 39",
" ├ 40: 40",
" ├ 41: 41",
" ├ 42: 42",
" ├ 43: 43",
" ├ 44: 44",
" ├ 45: 45",
" ├ 46: 46",
" ├ 47: 47",
" ├ 48: 48",
" ├ 49: 49",
" ├ 50: 50",
" ├ 51: 51",
" ├ 52: 52",
" ├ 53: 53",
" ├ 54: 54",
" ├ 55: 55",
" ├ 56: 56",
" ├ 57: 57",
" ├ 58: 58",
" ├ 59: 59",
" ├ 60: 60",
" ├ 61: 61",
" ├ 62: 62",
" ├ 63: 63",
" ├ 64: 64",
" ├ 65: 65",
" ├ 66: 66",
" ├ 67: 67",
" ├ 68: 68",
" ├ 69: 69",
" ├ 70: 70",
" ├ 71: 71",
" ├ 72: 72",
" ├ 73: 73",
" ├ 74: 74",
" ├ 75: 75",
" ├ 76: 76",
" ├ 77: 77",
" ├ 78: 78",
" ├ 79: 79",
" ├ 80: 80",
" ├ 81: 81",
" ├ 82: 82",
" ├ 83: 83",
" ├ 84: 84",
" ├ 85: 85",
" ├ 86: 86",
" ├ 87: 87",
" ├ 88: 88",
" ├ 89: 89",
" ├ 90: 90",
" ├ 91: 91",
" ├ 92: 92",
" ├ 93: 93",
" ├ 94: 94",
" ├ 95: 95",
" ├ 96: 96",
" ├ 97: 97",
" ├ 98: 98",
" ├ 99: 99",
" ▶︎ [100…199]",
" ▶︎ [200…221]",
" ▶︎ <prototype>: Set.prototype { … }"
],
// new Temporal.Instant(355924804000000000n)
[
"▼ Temporal.Instant 1981-04-12T12:00:04Z",
" ▶︎ <prototype>: Object { … }"
],
// new Temporal.PlainDate(2021, 7, 1, "coptic")
[
"▼ Temporal.PlainDate 2021-07-01[u-ca=coptic]",
" ▶︎ <prototype>: Object { … }"
],
// new Temporal.PlainDateTime(2021, 7, 1, 0, 0, 0, 0, 0, 0, "gregory")
[
"▼ Temporal.PlainDateTime 2021-07-01T00:00:00[u-ca=gregory]",
" ▶︎ <prototype>: Object { … }"
],
// new Temporal.PlainMonthDay(7, 1, "chinese")
[
"▼ Temporal.PlainMonthDay 1972-07-01[u-ca=chinese]",
" ▶︎ <prototype>: Object { … }"
],
// new Temporal.PlainTime(4, 20)
[
"▼ Temporal.PlainTime 04:20:00",
" ▶︎ <prototype>: Object { … }"
],
// new Temporal.PlainYearMonth(2021, 7, "indian")
[
"▼ Temporal.PlainYearMonth 2021-07-01[u-ca=indian]",
" ▶︎ <prototype>: Object { … }"
],
// new Temporal.ZonedDateTime(0n, "America/New_York")
[
"▼ Temporal.ZonedDateTime 1969-12-31T19:00:00-05:00[America/New_York]",
" ▶︎ <prototype>: Object { … }"
],
// Temporal.Duration.from({ years: 1 })
[
"▼ Temporal.Duration P1Y",
" ▶︎ <prototype>: Object { … }"
],
// myPolicy.createHTML("hello")
[
"▼ TrustedHTML \"<my-policy>hello</my-policy>\"",
" ▶︎ <prototype>: TrustedHTMLPrototype { toJSON: toJSON(), toString: toString(), … }"
],
// myPolicy.createScript("const hello = 'world'")
[
"▼ TrustedScript \"/* myPolicy */ const hello = 'world'\"",
" ▶︎ <prototype>: TrustedScriptPrototype { toJSON: toJSON(), toString: toString(), … }"
],
// myPolicy.createScriptURL("https://example.com/trusted")
[
"▼ TrustedScriptURL https://example.com/trusted?myPolicy",
" ▶︎ <prototype>: TrustedScriptURLPrototype { toJSON: toJSON(), toString: toString(), … }"
],
// const formData = new FormData();
// formData.append("a", 1);
// formData.append("a", 2);
// formData.append("b", 3);
// formData;
//
[
"▼ FormData(3) { a → \"1\", a → \"2\", b → \"3\" }",
" ▼ <entries>",
" ▼ 0: a → \"1\"",
" ├ <key>: \"a\"",
" ├ <value>: \"1\"",
" ▶︎ 1: a → \"2\"",
" ▶︎ 2: b → \"3\"",
" ▶︎ <prototype>: FormDataPrototype { append: append(), delete: delete(), get: get(), … }"
],
// customElements.define("fx-test", class extends HTMLElement {});
// const { states } = document.createElement("fx-test").attachInternals();
// states.add("custom-state");
// states.add("another-custom-state");
// states;
//
[
"▼ CustomStateSet [ \"custom-state\", \"another-custom-state\" ]",
" ├ size: 2",
" ▼ <entries>",
" ├ 0: \"custom-state\"",
" ├ 1: \"another-custom-state\"",
" ▶︎ <prototype>: CustomStateSetPrototype { add: add(), delete: delete(), clear: clear(), … }"
],
// CSS.highlights.set("search", new Highlight());
// CSS.highlights.set("glow", new Highlight());
// CSS.highlights.set("anchor", new Highlight());
// CSS.highlights;
//
[
"▼ HighlightRegistry(3) { search → Highlight, glow → Highlight, anchor → Highlight }",
" ├ size: 3",
" ▼ <entries>",
" ▼ 0: search → Highlight { priority: 0, type: \"highlight\", size: 0 }",
" ├ <key>: \"search\"",
" ▶︎ <value>: Highlight { priority: 0, type: \"highlight\", size: 0 }",
" ▶︎ 1: glow → Highlight { priority: 0, type: \"highlight\", size: 0 }",
" ▶︎ 2: anchor → Highlight { priority: 0, type: \"highlight\", size: 0 }",
" ▶︎ <prototype>: HighlightRegistryPrototype { set: set(), clear: clear(), delete: delete(), … }"
],
// new URLSearchParams([
// ["a", 1],
// ["a", 2],
// ["b", 3],
// ["b", 3],
// ["b", 5],
// ["c", "this is 6"],
// ["d", 7],
// ["e", 8],
// ["f", 9],
// ["g", 10],
// ["h", 11],
// ])
[
"▼ URLSearchParams(11) { a → \"1\", a → \"2\", b → \"3\", b → \"3\", b → \"5\", c → \"this is 6\", d → \"7\", e → \"8\", f → \"9\", g → \"10\", … }",
" ├ size: 11",
" ▼ <entries>",
" ▼ 0: a → \"1\"",
" ├ <key>: \"a\"",
" ├ <value>: \"1\"",
" ▶︎ 1: a → \"2\"",
" ▶︎ 2: b → \"3\"",
" ▶︎ 3: b → \"3\"",
" ▶︎ 4: b → \"5\"",
" ▶︎ 5: c → \"this is 6\"",
" ▶︎ 6: d → \"7\"",
" ▶︎ 7: e → \"8\"",
" ▶︎ 8: f → \"9\"",
" ▶︎ 9: g → \"10\"",
" ▶︎ 10: h → \"11\"",
" ▶︎ <prototype>: URLSearchParamsPrototype { append: append(), delete: delete(), get: get(), … }"
],
// new Error("foo")
"Error: foo",
// throw new Error("Long error ".repeat(10000));
"Error: Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error Long error…",
// throw `“https://evil.com/?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa“ is evil and “https://not-so-evil.com/?bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb“ is not good either`;
//
"“https://evil.com/?aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa“ is evil and “https://not-so-evil.com/?bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb“ is not good either",
// Error("bar")
"Error: bar",
// function bar() {
// asdf();
// }
// function foo() {
// bar();
// }
//
// foo();
//
"ReferenceError: asdf is not defined",
// eval("let a, a")
"SyntaxError: redeclaration of let a",
// throw "";
"<empty string>",
// throw false;
"false",
// throw undefined;
"undefined",
// throw 0;
"0",
// throw { vegetable: "cucumber" };
[
"▼ Object { vegetable: \"cucumber\" }",
" ├ vegetable: \"cucumber\"",
" ▶︎ <prototype>: Object { … }"
],
// throw Symbol("potato");
"Symbol(\"potato\")",
// var err = new Error("pineapple");
// err.name = "JuicyError";
// err.flavor = "delicious";
// throw err;
//
"JuicyError: pineapple",
// var originalError = new SyntaxError("original error");
// var err = new Error("something went wrong", {
// cause: originalError,
// });
// throw err;
//
"Error: something went wrongCaused by: SyntaxError: original error",
// var a = new Error("err-a");
// var b = new Error("err-b", { cause: a });
// var c = new Error("err-c", { cause: b });
// var d = new Error("err-d", { cause: c });
// throw d;
//
"Error: err-dCaused by: Error: err-cCaused by: Error: err-bCaused by: Error: err-a",
// var a = new Error("err-a", { cause: b });
// var b = new Error("err-b", { cause: a });
// throw b;
//
"Error: err-bCaused by: Error: err-aCaused by: Error: err-bCaused by: Error: err-a",
// throw new Error("null cause", { cause: null });
"Error: null causeCaused by: null",
// throw new Error("number cause", { cause: 0 });
"Error: number causeCaused by: 0",
// throw new Error("string cause", { cause: "cause message" });
"Error: string causeCaused by: \"cause message\"",
// throw new Error("object cause", {
// cause: { code: 234, message: "ERR_234" },
// });
//
"Error: object causeCaused by: Object { … }",
// Promise.reject("")
[
"▼ Promise { <state>: \"rejected\", <reason>: \"\" }",
" ├ <state>: \"rejected\"",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject("tomato")
[
"▼ Promise { <state>: \"rejected\", <reason>: \"tomato\" }",
" ├ <state>: \"rejected\"",
" ├ <reason>: \"tomato\"",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject(false)
[
"▼ Promise { <state>: \"rejected\", <reason>: false }",
" ├ <state>: \"rejected\"",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject(0)
[
"▼ Promise { <state>: \"rejected\", <reason>: 0 }",
" ├ <state>: \"rejected\"",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject(null)
[
"▼ Promise { <state>: \"rejected\", <reason>: null }",
" ├ <state>: \"rejected\"",
" ├ <reason>: null",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject(undefined)
[
"▼ Promise { <state>: \"rejected\", <reason>: undefined }",
" ├ <state>: \"rejected\"",
" ├ <reason>: undefined",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject(Symbol("potato"))
[
"▼ Promise { <state>: \"rejected\", <reason>: Symbol(\"potato\") }",
" ├ <state>: \"rejected\"",
" ├ <reason>: Symbol(\"potato\")",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject({vegetable: "cucumber"})
[
"▼ Promise { <state>: \"rejected\", <reason>: {…} }",
" ├ <state>: \"rejected\"",
" ▶︎ <reason>: Object { vegetable: \"cucumber\" }",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.reject(new Error("pumpkin"))
[
"▼ Promise { <state>: \"rejected\", <reason>: Error }",
" ├ <state>: \"rejected\"",
" ▶︎ <reason>: Error: pumpkin",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// var err = new Error("pineapple");
// err.name = "JuicyError";
// err.flavor = "delicious";
// Promise.reject(err);
//
[
"▼ Promise { <state>: \"rejected\", <reason>: JuicyError }",
" ├ <state>: \"rejected\"",
" ▶︎ <reason>: JuicyError: pineapple",
" ▶︎ <prototype>: Promise.prototype { … }"
],
// Promise.resolve().then(() => {
// try {
// unknownFunc();
// } catch(e) {
// throw new Error("something went wrong", { cause: e })
// }
// })
[
"▼ Promise { <state>: \"pending\" }",
" ├ <state>: \"rejected\"",
" ▶︎ <reason>: Error: something went wrong",
" ▶︎ <prototype>: Promise.prototype { … }"
],
];