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