<title>html5lib test runner</title>
<script>
// Copyright (c) 2008 Geoffrey Sneddon
// 
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// 
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
// 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
</script>
<script src=../resources/dump-as-markup.js></script>
<style>
.overview:hover {
background: #ccc;
}
iframe {
display: none;
}
</style>
<p>Script did not run</p>
<iframe></iframe>
<script>
if (window.layoutTestController)
    layoutTestController.waitUntilDone();
Markup.noAutoDump();
Markup.useHTML5libOutputFormat();

var test_files = [
        // 'resources/tests1.dat',
        // 'resources/tests2.dat',
        // 'resources/tests3.dat',
        // 'resources/tests4.dat',
        // 'resources/tests5.dat',
        // 'resources/tests6.dat',
        // 'resources/tests7.dat',
        // 'resources/tests8.dat',
        // 'resources/tests9.dat',
        // 'resources/tests10.dat',
        // 'resources/tests11.dat',
        // 'resources/tests12.dat',
        // 'resources/tests14.dat',
        // 'resources/tests15.dat',
        // 'resources/tests16.dat',
        'resources/webkit01.dat',
        // 'resources/doctype01.dat',
        // 'resources/scriptdata01.dat',
        // 'resources/entities01.dat',
        // 'resources/comments01.dat'
    ],
    tests = [],
    iframe = document.getElementsByTagName("iframe")[0],
    stat = document.getElementsByTagName("p")[0].firstChild,
    file = "",
    test_number = 1,
    subtest_number = 0,
    fail_list = [],
    log = "";

iframe.contentWindow.document.open()
iframe.contentWindow.document.write("Test");
iframe.contentWindow.document.close();
var write = iframe.contentWindow.document.lastChild.lastChild.lastChild !== null;
var ignoreTitle = iframe.contentWindow.document.getElementsByTagName("title")[0] !== undefined;

window.onload = function()
{
    stat.data = "Running";
    run();
}

function run()
{
    var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
    if (file = test_files.shift())
    {
        stat.data = "Retriving " + file;
        test_number = 1;
        fail_list = [];
        log = "";
        xhr.open("GET", file);
        xhr.onreadystatechange = function()
        {
            if (xhr.readyState === 4)
            {
                tests = xhr.responseText.split(/(?:^|\n\n)#data\n/);
                tests.shift();
                test();
            }
        }
        xhr.send(null);
    } else {
        if (window.layoutTestController)
            layoutTestController.notifyDone();
    }
}

function test()
{
    var input, errorsStart, fragmentStart, contextElement, domStart, dom;
    if (data = tests.shift())
    {
        subtest_number = 0;
        stat.data = "Running test " + test_number + " of " + (test_number + tests.length) + " in " + file;
        errorsStart = data.indexOf("\n#errors\n");
        if (errorsStart !== -1)
        {
            input = data.substring(0, errorsStart);
            fragmentStart = data.indexOf("\n#document-fragment\n")
            domStart = data.indexOf("\n#document\n")
            if (fragmentStart !== -1)
            {
                contextElement = data.substring(fragmentStart + 20, domStart);
            }
            if (domStart !== -1)
            {
                dom = data.substring(domStart + 11);
                if (dom.substring(dom.length - 1) === "\n")
                {
                    dom = dom.substring(0, dom.length - 1);
                }
                run_test(input, contextElement, dom);
                return;
            }
        }
        alert("Invalid test: " + data);
        test();
        return;
    }
    else
    {
        stat.data = "Finished running " + file;
        var overview = document.createElement("p");
        if (fail_list.length)
        {
            overview.innerHTML = file + ":<br>" + fail_list.join("<br>");
            overview.className = "overview";
            overview.title = "Click for more details";
            overview.onclick = function()
            {
                this.nextSibling.style.display = this.nextSibling.style.display == "none" ? "block" : "none";
            }
            var detail = document.createElement("pre");
            detail.appendChild(document.createTextNode(log.substring(2)));
            detail.style.display = "none";
            document.body.appendChild(overview);
            document.body.appendChild(detail);
        }
        else
        {
            overview.innerHTML = file + ": PASS";
            document.body.appendChild(overview);
        }
        stat.data = "";
        run();
    }
}

function run_test(input, contextElement, expected)
{
    while (++subtest_number < input.length) {
        lower_input = input.substring(0, subtest_number);
        upper_input = input.substring(subtest_number, input.length);
        if (contextElement)
        {
            var element = document.createElement(contextElement);
            try
            {
                element.innerHTML = input;
            }
            catch(e) {}
            process_result(input, element, expected);
        }
        else if (write)
        {
            iframe.contentWindow.document.open();
            try
            {
                iframe.contentWindow.document.write(lower_input);
                iframe.contentWindow.document.write(upper_input);
            }
            catch(e) {}
            iframe.contentWindow.document.close();
            if (ignoreTitle)
            {
                var title = iframe.contentWindow.document.getElementsByTagName("title")[0];
                if (!title.innerHTML)
                {
                    title.parentElement.removeChild(title);
                }
            }
            process_result(input, iframe.contentWindow.document, expected);
        }
        else
        {
            iframe.onload = function()
            {
                if (ignoreTitle)
                {
                    var title = iframe.contentWindow.document.getElementsByTagName("title")[0];
                    if (!title.innerHTML)
                    {
                        title.parentElement.removeChild(title);
                    }
                }
                process_result(input, iframe.contentWindow.document, expected, true);
            }
            iframe.src = "data:text/html," + encodeURIComponent(input);
            break;
        }
    }
    test();
}

function process_result(input, result, expected, async)
{
    result = Markup.get(result);
    if (result !== expected)
    {
        fail_list.push(test_number + "." + subtest_number);
        log += "\n\nTest " + (test_number) + " of " + (test_number + tests.length) + " in " + file + " failed. Input:\n" + input + "\nGot:\n" + result + "\nExpected:\n" + expected;
    }
    test_number++;
    if (async)
        test();
}
</script>
