<!doctype html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script src="resources/all-scopes.js"></script>
<script src="resources/function-name-scopes.js"></script>
<script src="resources/block-scopes.js"></script>
<script>
function test()
{
    function firstLine(str) {
        let newlineIndex = str.indexOf("\n");
        if (newlineIndex !== -1)
            return str.substr(0, newlineIndex);
        return str;
    }

    function scopeTypeToString(type) {
        for (let key in WI.ScopeChainNode.Type) {
            if (WI.ScopeChainNode.Type[key] === type)
                return key;
        }
        return "Unexpected Scope Type";
    }

    function harvestScopeChain(scopeChain) {
        let promises = [];
        for (let scope of scopeChain) {
            promises.push(new Promise((resolve, reject) => {
                if (scope.type === WI.ScopeChainNode.Type.Global)
                    resolve({scope, propertyDescriptors: []});
                else {
                    scope.objects[0].getDisplayablePropertyDescriptors((propertyDescriptors) => {
                        resolve({scope, propertyDescriptors});
                    });
                }
            }));
        }
        return Promise.all(promises);
    }

    function logScopeChain(scopeChain) {
        return harvestScopeChain(scopeChain)
        .then((results) => {
            InspectorTest.log("SCOPE CHAIN:");
            for (let {scope, propertyDescriptors} of results) {
                InspectorTest.log(`    ${scopeTypeToString(scope.type)}`);
                if (scope.type === WI.ScopeChainNode.Type.Global)
                    continue;

                if (!propertyDescriptors.length) {
                    InspectorTest.assert(scope.empty, "Scope should be empty if there are no property descriptors.");
                    InspectorTest.log("      (empty)");
                    continue;
                }

                for (let descriptor of propertyDescriptors)
                    InspectorTest.log(`      - ${descriptor.name}: ${firstLine(descriptor.value.description)}`);
            }
            return results;
        });
    }


    let suite = InspectorTest.createAsyncSuite("WI.ScopeChainNode");

    suite.addTestCase({
        name: "WI.ScopeChainNode.AllTypes",
        description: "Tests for each of the different scope chain node types.",
        test(resolve, reject) {
            WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.CallFramesDidChange)
            .then((event) => {
                let scopeChain = WI.debuggerManager.activeCallFrame.scopeChain;
                InspectorTest.expectThat(scopeChain.length === 13, "ScopeChain should have 13 scopes.");
                return logScopeChain(scopeChain);
            })
            .then((result) => {
                let promise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed);
                WI.debuggerManager.resume();
                return promise;
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("setTimeout(testAllScopes)");
        }
    });

    suite.addTestCase({
        name: "WI.ScopeChainNode.FunctionNameInFunctionExpression",
        description: "Tests that there should be a FunctionName scope inside a function expression.",
        test(resolve, reject) {
            WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.CallFramesDidChange)
            .then((event) => {
                let scopeChain = WI.debuggerManager.activeCallFrame.scopeChain;
                return logScopeChain(scopeChain);
            })
            .then((result) => {
                let promise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed);
                WI.debuggerManager.resume();
                return promise;
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("setTimeout(testFunctionNameScope1)");
        }
    });

    suite.addTestCase({
        name: "WI.ScopeChainNode.FunctionNameInClassMethod",
        description: "Tests that there should be a FunctionName scope inside a class method.",
        test(resolve, reject) {
            WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.CallFramesDidChange)
            .then((event) => {
                let scopeChain = WI.debuggerManager.activeCallFrame.scopeChain;
                return logScopeChain(scopeChain);
            })
            .then((result) => {
                let promise = WI.debuggerManager.awaitEvent(WI.DebuggerManager.Event.Resumed);
                WI.debuggerManager.resume();
                return promise;
            })
            .then(resolve, reject);

            InspectorTest.evaluateInPage("setTimeout(testFunctionNameScope2)");
        }
    });

    suite.addTestCase({
        name: "WI.ScopeChainNode.BlockScopes",
        description: "Tests for a Block scope inside all the different types of blocks.",
        test(resolve, reject) {
            let pauseCount = 0;
            let pauseEventsExpected = 19;
            function callFramesDidChangeListener(event) {
                if (!WI.debuggerManager.activeCallFrame)
                    return;

                pauseCount++;
                let scopeChain = WI.debuggerManager.activeCallFrame.scopeChain;

                // First, normal function scope.
                if (pauseCount === 1) {
                    InspectorTest.expectThat(scopeChain[0].type === WI.ScopeChainNode.Type.Closure, "Pause #1 - Top scope should be normal function Closure/Local scope.");
                    WI.debuggerManager.resume();
                    return;
                }

                // Last, normal function scope.
                if (pauseCount === pauseEventsExpected) {
                    InspectorTest.expectThat(scopeChain[0].type === WI.ScopeChainNode.Type.Closure, `Pause #${pauseCount} - Top scope should be normal function Closure/Local scope.`);
                    WI.debuggerManager.removeEventListener(WI.DebuggerManager.Event.ActiveCallFrameDidChange, callFramesDidChangeListener);
                    WI.debuggerManager.resume();
                    resolve();
                    return;
                }

                // The first 15 cases the top scope should be a Block scope.
                if (pauseCount <= 15) {
                    InspectorTest.expectThat(scopeChain[0].type === WI.ScopeChainNode.Type.Block, `Pause #${pauseCount} - Top scope should be Block scope.`);
                    WI.debuggerManager.resume();
                    return;
                }

                // Print out the full scope of the last few where there are nested or buried block scopes.
                InspectorTest.expectThat(scopeChain.some((scopeChain) => scopeChain.type === WI.ScopeChainNode.Type.Block), `Pause #${pauseCount} - Contains a Block scope.`);

                logScopeChain(scopeChain)
                .then((result) => {
                    WI.debuggerManager.resume();
                });
            }

            WI.debuggerManager.addEventListener(WI.DebuggerManager.Event.ActiveCallFrameDidChange, callFramesDidChangeListener);
            InspectorTest.evaluateInPage("setTimeout(testBlockScopes)");
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests for the WI.ScopeChainNode model object.</p>
</body>
</html>
