<!doctype html>
<html>
<head>
<script src="../../resources/js-test-pre.js"></script>
<style>
testcase {
    background-color: red;
}
</style>
<style id="style">
</style>
</head>
<body>
    <div style="display:none">
        <testcase id="testcase1"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase2"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase3"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase4"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase5"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase6"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase7"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase8"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase9"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase10"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase11"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase12"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase13"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase14"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase15"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase16"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase17"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase18"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase19"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
        <testcase id="testcase20"><div><div><div><div><div><div><div><div><span></span></div></div></div></div></div></div></div></div></testcase>
    </div>
</body>
<script>
description('Test chaining many :nth-child() selectors. This verifies register allocation is correct.');

function testQuerySelector(selector, expectedIds) {
    shouldBe("document.querySelectorAll('" + selector + "').length", '' + expectedIds.length);
    for (var i = 0; i < expectedIds.length; ++i)
        shouldBeEqualToString("document.querySelectorAll('" + selector + "')[" + i + "].id", expectedIds[i]);
}

function testStyling(selector, expectedIds) {
    var stylingElement = document.getElementById("style");
    stylingElement.innerHTML = '' + selector + ' { background-color: rgb(10, 100, 200); }';

    var allTestCases = document.querySelectorAll("testcase");
    for (var i = 0; i < allTestCases.length; ++i) {
        var expectMatch = expectedIds.indexOf(allTestCases[i].id) >= 0;
        shouldBeEqualToString('getComputedStyle(document.querySelectorAll("testcase")[' + i + ']).backgroundColor', expectMatch ? 'rgb(10, 100, 200)' : 'rgb(255, 0, 0)');
    }

    stylingElement.innerHTML = '';
}

function testSelector(selector, expectedIds) {
    debug("Testing \"" + selector + "\"");
    testQuerySelector("testcase" + selector, expectedIds);
    testStyling("testcase" + selector, expectedIds);

    // Test the same request with a backtracking register.
    shouldBe("document.querySelectorAll('div>testcase" + selector + ">div>div>div span').length", '' + expectedIds.length);

    debug("");
}

// The :nth-child() should not completely overlap to ensure all of them are executed.

// All positive B.
testSelector(":nth-child(-n+21 of testcase):nth-child(odd of testcase):nth-child(-2n+21 of testcase):nth-child(3n+1 of testcase):nth-child(-3n+22 of testcase):nth-child(4n+1 of testcase):nth-child(-5n+51 of testcase)", ["testcase1"]);

// All negative B.
testSelector(":nth-child(2n-200 of testcase):nth-child(3n-1 of testcase):nth-child(4n-38 of testcase):nth-child(5n-98 of testcase)", ["testcase2"]);

// All positive A.
testSelector(":nth-child(even of testcase):nth-child(3n of testcase):nth-child(4n-2 of testcase):nth-child(5n+1 of testcase)", ["testcase6"]);

// All negative A.
testSelector(":nth-child(-n+9000 of testcase):nth-child(-2n+683 of testcase):nth-child(-3n+31 of testcase):nth-child(-4n+47 of testcase):nth-child(-5n+107 of testcase):nth-child(-6n+73 of testcase):nth-child(-7n+70 of testcase)", ["testcase7"]);

// Positive and Negative B.
testSelector(":nth-child(odd of testcase):nth-child(3n+1 of testcase):nth-child(4n-1 of testcase):nth-child(5n+4 of testcase)", ["testcase19"]);

// Positive and Negative A.
testSelector(":nth-child(-n+1500 of testcase):nth-child(2n+1 of testcase):nth-child(-3n+45 of testcase):nth-child(4n+3 of testcase):nth-child(-5n+1545 of testcase)", ["testcase15"]);

// Everything.
testSelector(":nth-child(n+2 of testcase):nth-child(-n+6000 of testcase):nth-child(n-2 of testcase):nth-child(2n of testcase):nth-child(-2n+20 of testcase):nth-child(2n+2 of testcase):nth-child(3n+1 of testcase):nth-child(-3n+49 of testcase):nth-child(3n-92 of testcase):nth-child(4n+2 of testcase):nth-child(-4n+50 of testcase)", ["testcase10"]);
</script>
<script src="../../resources/js-test-post.js"></script>
</html>
