blob: 6b6c7760fdf9a459ba4ad7cd2651f80adc4d3af5 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
// Use classes so the corresponding RemoteObject has a nicer preview.
Root = new (class Root { });
Root.Root = Root;
Root.C = new (class C { });
Root.B = new (class B { });
Root.B.C = Root.C;
Root.A = new (class A { });
Root.A.b = Root.B;
Root.A.C = Root.C;
Root.ArrayItem = new (class ArrayItem { });
Root.Array = new Array([Root.ArrayItem]);
Root.MapKey = new (class MapKey { });
Root.MapValue = new (class MapValue { });
Root.Map = new Map([[Root.MapKey, Root.MapValue]]);
Root.SetItem = new (class SetItem { });
Root.Set = new Set([Root.SetItem]);
Root.WeakMapKey = new (class WeakMapKey { });
Root.WeakMapValue = new (class WeakMapValue { });
Root.WeakMap = new WeakMap([[Root.WeakMapKey, Root.WeakMapValue]]);
Root.WeakSetItem = new (class WeakSetItem { });
Root.WeakSet = new WeakSet([Root.WeakSetItem]);
Root.Promise = new Promise(() => {});
Root.PromiseThen = Root.Promise.then(() => {});
Root.PromiseCatch = Root.Promise.catch(() => {});
Root.PromiseFinally = Root.Promise.finally(() => {});
Root.EventListenerCallback = () => {};
Root.EventListenerTarget = document.createElement("div");
Root.EventListenerTarget.id = "event-listener-target";
Root.EventListenerTarget.addEventListener("custom", Root.EventListenerCallback);
Root.SymbolReferenceObject = new (class SymbolReferenceObject { });
Root.SymbolReferenceHolder = new (class SymbolReferenceHolder { });
Root.SymbolReferenceHolder[Symbol("symbol-reference")] = Root.SymbolReferenceObject;
Root.MultipleReferenceObject = new (class MultipleReferenceObject { });
Root.MultipleReferenceHolder = Array(1000).fill().map((item, i) => {
let holder = Function(`return new (class C${i} { })`)(); // create different dynamic classes so they're distinguishable in object previews
holder.MultipleReferenceObject = Root.MultipleReferenceObject;
return holder;
});
Root.RepeatedReferenceObject = new (class RepeatedReferenceObject { });
Root.RepeatedReferenceHolder = new (class RepeatedReferenceHolder { });
for (let i = 0; i < 1000; ++i)
Root.RepeatedReferenceHolder[i] = Root.RepeatedReferenceObject;
function test() {
function queryHolders(target, callback) {
WI.runtimeManager.evaluateInInspectedWindow(`queryHolders(${target})`, {objectGroup: "test", includeCommandLineAPI: true, generatePreview: true}, callback);
}
let suite = InspectorTest.createAsyncSuite("CommandLineAPI.queryHolders");
function addTest(target) {
suite.addTestCase({
name: `CommandLineAPI.queryHolders.${target}`,
test(resolve, reject) {
queryHolders("Root." + target, (remoteObject, wasThrown, savedResultIndex) => {
if (wasThrown) {
InspectorTest.fail("An exception was thrown.");
InspectorTest.log(remoteObject.description);
resolve();
return;
}
InspectorTest.assert(remoteObject.type === "object", "The result should be an object.");
InspectorTest.assert(remoteObject.subtype === "array", "The result should be an array object.");
if (remoteObject.preview.propertyPreviews.length < 5) {
let propertyPreviews = remoteObject.preview.propertyPreviews.map((preview) => preview.value || preview.subtype || preview.type);
propertyPreviews.sort();
InspectorTest.log("[" + propertyPreviews.join(", ") + "] (" + remoteObject.preview.size + ")");
} else
InspectorTest.log("[<filtered>] (" + remoteObject.preview.size + ")");
resolve();
});
}
});
}
addTest(`Root`);
addTest(`A`);
addTest(`B`);
addTest(`C`);
addTest(`Array`);
addTest(`ArrayItem`);
addTest(`Map`);
addTest(`MapKey`);
addTest(`MapValue`);
addTest(`Set`);
addTest(`SetItem`);
addTest(`WeakMap`);
addTest(`WeakMapKey`);
addTest(`WeakMapValue`);
addTest(`WeakSet`);
addTest(`WeakSetItem`);
addTest(`Promise`);
addTest(`PromiseThen`);
addTest(`PromiseCatch`);
addTest(`PromiseFinally`);
addTest(`EventListenerCallback`);
addTest(`SymbolReferenceObject`);
addTest(`MultipleReferenceObject`);
addTest(`RepeatedReferenceObject`);
suite.addTestCase({
name: "CommandLineAPI.queryHolders.OnlyHeldByDebugger",
async test() {
let savedResult = null;
{
let [remoteObject, wasThrown, savedResultIndex] = await promisify((callback) => {
WI.runtimeManager.evaluateInInspectedWindow(`new (class OnlyHeldByDebugger { })`, {
objectGroup: "test",
includeCommandLineAPI: true,
generatePreview: true,
saveResult: true,
}, callback);
});
InspectorTest.assert(!wasThrown);
if (wasThrown)
InspectorTest.log(remoteObject.description);
savedResult = "$" + savedResultIndex;
}
{
let [remoteObject, wasThrown, savedResultIndex] = await promisify((callback) => {
queryHolders(savedResult, callback);
});
InspectorTest.assert(!wasThrown);
if (wasThrown)
InspectorTest.log(remoteObject.description);
InspectorTest.assert(remoteObject.type === "object", "The result should be an object.");
InspectorTest.assert(remoteObject.subtype === "array", "The result should be an array object.");
InspectorTest.expectEqual(remoteObject.size, 0, `The result should have 0 items.`);
}
}
});
suite.addTestCase({
name: "CommandLineAPI.queryHolders.NonObject",
test(resolve, reject) {
const target = `"test"`;
queryHolders(target, (remoteObject, wasThrown, savedResultIndex) => {
InspectorTest.expectTrue(wasThrown, "Should produce an exception.");
InspectorTest.log("Error: " + remoteObject.description);
resolve();
});
}
});
suite.addTestCase({
name: "CommandLineAPI.queryHolders.NoParameter",
test(resolve, reject) {
const target = ``;
queryHolders(target, (remoteObject, wasThrown, savedResultIndex) => {
if (wasThrown) {
InspectorTest.fail("An exception was thrown.");
InspectorTest.log(remoteObject.description);
reject();
return;
}
InspectorTest.expectEqual(remoteObject.type, "undefined", "The result should be undefined.");
resolve();
});
}
});
suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests for the `queryHolders` function in the Command Line API.</p>
</body>
</html>