<html>
<head>
<script src="../http/tests/inspector/inspector-test.js"></script>
<script>

function test()
{
    InspectorTest.runTestSuite([
        function binaryIndexOfTest(next)
        {
            var testArrays = [
                [],
                [1],
                [1, 10],
                [1, 10, 11, 12, 13, 14, 100],
                [-100, -50, 0, 50, 100],
                [-100, -14, -13, -12, -11, -10, -1]
            ];
     
            function testArray(array)
            {
                function comparator(a, b)
                {
                    return a < b ? -1 : (a > b ? 1 : 0);
                }
     
                for (var i = -100; i <= 100; ++i) {
                    var reference = array.indexOf(i);
                    var actual = array.binaryIndexOf(i, comparator);
                    InspectorTest.assertEquals(reference, actual, "binaryIndexOf");
                }
                return true;
            }
     
            for (var i = 0, l = testArrays.length; i < l; ++i)
                testArray(testArrays[i]);
            next();
        },

        function qselectTest(next)
        {
            var testArrays = [
                [],
                [0],
                [0, 0, 0, 0, 0, 0, 0, 0],
                [4, 3, 2, 1],
                [1, 2, 3, 4, 5],
                [-1, 3, 2, 7, 7, 7, 10, 12, 3, 4, -1, 2]
            ];

            function testArray(array)
            {
                function compare(a, b)
                {
                    return a - b;
                }
                var sorted = array.slice(0).sort(compare);

                var reference = {
                    min: sorted[0],
                    median: sorted[Math.floor(sorted.length / 2)],
                    max: sorted[sorted.length - 1]
                }

                var actual = {
                    min: array.slice(0).qselect(0),
                    median: array.slice(0).qselect(Math.floor(array.length / 2)),
                    max: array.slice(0).qselect(array.length - 1)
                }
                InspectorTest.addResult("Array: " + JSON.stringify(array));
                InspectorTest.addResult("Reference: " + JSON.stringify(reference));
                InspectorTest.addResult("Actual:    " + JSON.stringify(actual));
            }
            for (var i = 0, l = testArrays.length; i < l; ++i)
                testArray(testArrays[i]);
            next();
        },

        function sortRangeTest(next)
        {
            var testArrays = [
                [],
                [1],
                [2, 1],
                [6, 4, 2, 7, 10, 15, 1],
                [10, 44, 3, 6, 56, 66, 10, 55, 32, 56, 2, 5]
            ];

            function testArray(array)
            {
                function comparator(a, b)
                {
                    return a < b ? -1 : (a > b ? 1 : 0);
                }

                function compareArrays(a, b, message)
                {
                    InspectorTest.assertEquals(JSON.stringify(a), JSON.stringify(b), message);
                }

                for (var left = 0, l = array.length - 1; left < l; ++left) {
                     for (var right = left + 1, r = array.length; right < r; ++right)
                          for (var count = 1, k = right - left + 1; count <= k; ++count) {
                              var actual = array.slice(0);
                              actual.sortRange(comparator, left, right, count);
                              compareArrays(array.slice(0, left), actual.slice(0, left), "left " + left + " " + right + " " + count);
                              compareArrays(array.slice(right + 1), actual.slice(right + 1), "right " + left + " " + right + " " + count);
                              var middle = array.slice(left, right + 1);
                              middle.sort(comparator);
                              compareArrays(middle.slice(0, count), actual.slice(left, left + count), "sorted " + left + " " + right + " " + count);
                              actualRest = actual.slice(left + count, right + 1);
                              actualRest.sort(comparator);
                              compareArrays(middle.slice(count), actualRest, "unsorted " + left + " " + right + " " + count);
                          }
                }
            }

            for (var i = 0, len = testArrays.length; i < len; ++i)
                testArray(testArrays[i]);
            next();
        }
    ]);
}

</script>
</head>

<body onload="runTest()">
<p>
This test checks Web Inspector utilities.
</p>

</body>
</html>
