<html>
<head>
	<script src="../../resources/js-test-pre.js"></script>
</head>

<body>
	<p id="description"></p>
	<p id="console"></p>

<script>
if (!this.alert) {
    debug = print;
    description = print;
}

description(
'This test checks line and column numbers in stack traces for correctness.'
);

testId = 0;
function printStack(stackTrace) {
    debug("--> Case " + testId + " Stack Trace:")
    stackTrace = stackTrace.split("\n");
    var length = Math.min(stackTrace.length, 20);
    for (var i = 0; i < length; i++) {
        var indexOfAt = stackTrace[i].indexOf('@')
        var indexOfLastSlash = stackTrace[i].lastIndexOf('/');
        if (indexOfLastSlash == -1)
            indexOfLastSlash = indexOfAt
        var functionName = stackTrace[i].substring(0, indexOfAt);
        var fileName = stackTrace[i].substring(indexOfLastSlash + 1);
        debug("    " + i + "   " + functionName + " at " + fileName);
    }
    debug('');
}
</script>

<!-- Case 1: Throw and print stack: -->
<script>testId++;</script>
    <script>try { throw new Error(); } catch (e) { printStack(e.stack); }</script>

<!-- Case 2: Same program as Case 1 but indented. -->
<script>testId++;</script>
        <script>try { throw new Error(); } catch (e) { printStack(e.stack); }</script>

<!-- Case 3: Same program indented on the same line. -->
<script>testId++;</script>
<script>try { throw new Error(); } catch (e) { printStack(e.stack); }</script>   <script>try { throw new Error(); } catch (e) { printStack(e.stack); }</script>

<!-- Case 4: Throw inside a Function. -->
<script>testId++;</script>
<script>
try {
    function doThrow4() { throw new Error(); }
    doThrow4();
} catch(e) {
    printStack(e.stack);
}
</script>

<!-- Case 5: Function wrapping a Function. -->
<script>testId++;</script>
<script>
function doThrow5() { try { function innerFunc() { throw new Error(); } innerFunc(); } catch (e) { printStack(e.stack); }}; doThrow5();
</script>

<!-- Case 6: Same inner function body as Case 5. -->
<script>testId++;</script>
<script>
function doThrow6() { try { function innerFunc() { throw new Error(); } innerFunc(); } catch (e) { printStack(e.stack); }}; doThrow6();
</script>

<!-- Case 7: Case 1 redone with a Function Expression. -->
<script>testId++;</script>
    <script>try { (function () { throw new Error(); })(); } catch (e) { printStack(e.stack); }</script>
<!-- Case 8: Case 2 redone with a Function Expression. -->
<script>testId++;</script>
            <script>try { (function () { throw new Error(); })(); } catch (e) { printStack(e.stack); }</script>

<!-- Case 9: Case 3 redone with a Function Expression. -->
<script>testId++;</script>
        <script>try { (function () { throw new Error(); })(); } catch (e) { printStack(e.stack); }</script>   <script>try { (function () { throw new Error(); })(); } catch (e) { printStack(e.stack); }</script>

<!-- Case 10: Function Expression as multiple lines. -->
<script>testId++;</script>
<script>
try {
    (function () {
        throw new Error();
     })();
} catch(e) {
    printStack(e.stack);
}
</script>

<!-- Case 11: Case 4 redone with a Function wrapping Function Expression. -->
<script>testId++;</script>
<script>
try {
    function doThrow11() {
        (function () { throw new Error(); })();
    }
    doThrow11();
} catch(e) {
    printStack(e.stack);
}
</script>

<!-- Case 12: A Function Expression wrapping a Function Expression. -->
<script>testId++;</script>
<script>
try { (function () {(function () { throw new Error(); })();})(); } catch (e) { printStack(e.stack); }
</script>

<!-- Case 13: Same function body as Case 12. -->
<script>testId++;</script>
<script>
try { (function () {(function () { throw new Error(); })();})(); } catch (e) { printStack(e.stack); }
</script>

<!-- Case 14: Function Expression in a Function Expression in a Function. -->
<script>testId++;</script>
<script>
try { function doThrow14() {(function () { (function () { throw new Error(); })();})();} doThrow14(); } catch (e) { printStack(e.stack); }
</script>

<!-- Case 15: Throw in an Eval. -->
<script>testId++;</script>
<script>
eval("try { throw new Error(); } catch(e) { printStack(e.stack); }");
</script>

<!-- Case 16: Multiple lines in an Eval. -->
<script>testId++;</script>
<script>
eval("\n" +
"try {\n" +
"    function doThrow16() {throw new Error();}\n" +
"    doThrow16();\n" +
"} catch(e) {\n" +
"    printStack(e.stack);\n" +
"}\n" +
"");
</script>

<!-- Case 17: Function Expression in an Eval. -->
<script>testId++;</script>
<script>
eval("try { (function () { throw new Error();})(); } catch(e) { printStack(e.stack); }");
</script>

<!-- Case 18: Multiple lines with a Function Expression in an Eval. -->
<script>testId++;</script>
<script>
eval("\n" +
"try {\n" +
"    (function () { throw new Error();})();\n" +
"} catch(e) {\n" +
"    printStack(e.stack);\n" +
"}\n" +
"");
</script>

<!-- Case 19: Binary op with type coersion on strcat. -->
<script>testId++;</script>
<script>
try {
    testObj19 = {
        toString: function() {
            var result = ("Hello " + "World") + this;
            b = 5;
            return result;
        },
        run: function() {
            return testObj19.toString();
        }
    };
    testObj19.run();
} catch(e) {
    printStack(e.stack);
}
</script>

<!-- Case 20: BinaryOp with type coersion on comparison. -->
<script>testId++;</script>
<script>
try {
    function test20() {
        var f = function g() {
            if (this != 10) f();
        };
        var a = f();
    }

    test20();
} catch(e) {
    printStack(e.stack);
}
</script>

<!-- Case 21: Regression test from https://bugs.webkit.org/show_bug.cgi?id=118662 -->
<script>testId++;</script>
<script>
try {
    eval(
        "function toFuzz21() {\n" +
        "    if (PriorityQueue.prototype.doSort() instanceof (this ^= function () {})) return 2;\n" +
        "}\n" +
        "toFuzz21();"
    );
} catch(e) {
    printStack(e.stack);
}
</script>

<!-- Case 22: Regression test from https://bugs.webkit.org/show_bug.cgi?id=118664 -->
<script>testId++;</script>
<script>
try {
    function toFuzz22() {
        var conf = new ConfigObject({})
        for (conf in str1.localeCompare) {
        }
    }
    toFuzz22();
} catch(e) {
    printStack(e.stack);
}
</script>

<!-- Now do it all over with a loaded script file. -->
<script>testId = 0;</script>
	<script src="script-tests/line-column-numbers.js"></script>

	<script src="../../resources/js-test-post.js"></script>
</body>
</html>
