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

function generateErrorNativeCallInBetween()
{
    return [42].map(generateTypeError)[0];
}

var _globalTypeError = generateTypeError();
var _globalErrorWithNativeCalls = generateErrorNativeCallInBetween();
var _globalAnonymousFunctionError = null;
(function() {
    var object = {};
    try {
        object.methodDoesntExist();
    } catch(e) {
        _globalAnonymousFunctionError = e.stack;
    }
})();

function test()
{
    let suite = InspectorTest.createAsyncSuite("WI.StackTrace.isLikelyStackTrace");

    suite.addTestCase({
        name: "notStacktrace",
        test(resolve, reject) {
            let result = WI.StackTrace.isLikelyStackTrace("Messages:42\nUnread:16");
            InspectorTest.expectFalse(result, "Should NOT be a stacktrace.");
            resolve();
        }
    });

    suite.addTestCase({
        name: "WI.StackTrace.isLikelyStackTrace.TypeError",
        async test() {
            let result = await InspectorTest.evaluateInPage(`_globalTypeError`);
            InspectorTest.expectThat(WI.StackTrace.isLikelyStackTrace(result), "Should be a stacktrace.");
        }
    });

    suite.addTestCase({
        name: "WI.StackTrace.isLikelyStackTrace.AnonymousFunctionError",
        async test() {
            let result = await InspectorTest.evaluateInPage(`_globalAnonymousFunctionError`);
            InspectorTest.expectThat(WI.StackTrace.isLikelyStackTrace(result), "Should be a stacktrace.");
        }
    });

    suite.addTestCase({
        name: "WI.StackTrace.isLikelyStackTrace.NativeFunctionCallsError",
        async test() {
            let result = await InspectorTest.evaluateInPage(`_globalErrorWithNativeCalls`);
            InspectorTest.expectThat(WI.StackTrace.isLikelyStackTrace(result), "Should be a stacktrace.");
        }
    });

    suite.addTestCase({
        name: "WI.StackTrace.isLikelyStackTrace.ValidStackStrings",
        async test() {
            const strings = [
                "a@file:///ex.html:10:6\nb@file:///ex.html:7:6\nglobal code@file:///ex.html:12:2",
                "global code@file:///ex.html:12:2\na@file:///ex.html:10:6\nb@file:///ex.html:7:6",
                "global code@file:///ex.html:1:1\nmap@[native code]",
            ];

            for (let string of strings)
                InspectorTest.expectThat(WI.StackTrace.isLikelyStackTrace(string), `${JSON.stringify(string)} should be a stacktrace.`);
        }
    });

    suite.addTestCase({
        name: "WI.StackTrace.isLikelyStackTrace.InvalidStackStrings",
        async test() {
            const strings = [
                "video:1:2",
                "video/mp4:1:2",
                "video/mp4 : 11:22:33-44:55:66",
                "http://video:1:2",
                "http://video/mp4:1:2",
                "http://video/mp4 : 11:22:33-44:55:66",
            ];

            for (let string of strings)
                InspectorTest.expectThat(!WI.StackTrace.isLikelyStackTrace(string), `${JSON.stringify(string)} should not be a stacktrace.`);
        }
    });

    suite.runTestCasesAndFinish();
}
</script>
</head>
<body onload="runTest()">
<p>Test stack trace detection heuristic.</p>
</body>
</html>
