<!DOCTYPE html>
<html>
<head>
<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
<script>
function typeError() {
    let object = {};
    try {
        object.propertyDoesnt.exist;
    } catch (e) {
        console.trace();
        return e.stack;
    }
}

function triggerTypeError() {
    return typeError();
}

function triggerTypeErrorWithNativeCallInBetween() {
    return [42].map(typeError)[0];
}

let _anonymousFunctionError = null;

(function() {
    let object = {};
    try {
        object.methodDoesntExist();
    } catch (e) {
        _anonymousFunctionError = e.stack;
    }
})();

function getAnonymousFunctionError() {
    return _anonymousFunctionError;
}

function* generator1() {
    yield* generator2();
}

function* generator2() {
    yield typeError();
}

function triggerGeneratorError() {
    return generator1().next().value;
}

function test()
{
    function stripFilePaths(stackTrace) {
        for (let frame of stackTrace) {
            if (typeof frame.url === "string")
                frame.url = frame.url.replace(/^.+?LayoutTests/, "");
        }
        return stackTrace;
    }

    function stripCallFramesAfterEval(stackTrace) {
        for (let i = 0; i < stackTrace.length; ++i) {
            let frame = stackTrace[i];
            if (frame.programCode)
                return stackTrace.slice(0, i + 1);
        }
        return stackTrace;
    }

    function stripPayloadAfterGlobalCode(stackTrace) {
        for (let i = 0; i < stackTrace.length; ++i) {
            let frame = stackTrace[i];
            if (frame.functionName === "global code")
                return stackTrace.slice(0, i + 1);
        }
        return stackTrace;
    }

    WI.consoleManager.addEventListener(WI.ConsoleManager.Event.MessageAdded, (event) => {
        InspectorTest.log("\nconsole.trace():");

        let stackTrace = [];
        let callFramesBeforeEval = stripCallFramesAfterEval(event.data.message.stackTrace.callFrames);
        for (let callFrame of callFramesBeforeEval) {
            let lineNumber = callFrame.sourceCodeLocation ? callFrame.sourceCodeLocation.lineNumber : null;
            let columnNumber = callFrame.sourceCodeLocation ? callFrame.sourceCodeLocation.columnNumber : null;
            stackTrace.push({
                lineNumber: lineNumber,
                columnNumber: columnNumber,
                functionName: callFrame.functionName,
                nativeCode: callFrame.nativeCode,
                programCode: callFrame.programCode,
            });
        }

        InspectorTest.log(JSON.stringify(stackTrace, null, 4));
    });
    

    let suite = InspectorTest.createAsyncSuite("ConsoleTraceAndJavaScriptStackTrace");

    function addTestCase({name, expression}) {
        suite.addTestCase({
            name,
            test(resolve, reject) {
                InspectorTest.evaluateInPage(expression, (error, result) => {
                    InspectorTest.assert(!error, error);
                    InspectorTest.log("\nError object:");
                    let stackTrace = stripFilePaths(stripPayloadAfterGlobalCode(WI.StackTrace._parseStackTrace(result)));
                    InspectorTest.log(JSON.stringify(stackTrace, null, 4));
                    resolve();
                });
            }
        });
    }

    addTestCase({
        name: "ConsoleTraceAndJavaScriptStackTrace.BasicError",
        expression: "triggerTypeError()",
    });

    addTestCase({
        name: "ConsoleTraceAndJavaScriptStackTrace.ErrorInNativeCall",
        expression: "triggerTypeErrorWithNativeCallInBetween()",
    });

    addTestCase({
        name: "ConsoleTraceAndJavaScriptStackTrace.ErrorInAnonymousFunction",
        expression: "getAnonymousFunctionError()",
    });

    addTestCase({
        name: "ConsoleTraceAndJavaScriptStackTrace.ErrorInGenerator",
        expression: "triggerGeneratorError()",
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Tests that we can parse the stack trace format used by JavaScriptCore and the contents of Error / console.trace stack traces.</p>
</body>
</html>
