| <!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> |