michael@0: /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /** michael@0: * Runs html5lib-formatted test cases in the browser. Requires SimpleTest. michael@0: * michael@0: * Define an array named parserDatFiles before loading this script, michael@0: * and it will load each of those dat files into an array, then run michael@0: * the test parser on each and run the tests by assigning the input michael@0: * data to an iframe's url. michael@0: * michael@0: * Your test document should have an element with id "display" and michael@0: * an iframe with id "testframe". michael@0: */ michael@0: michael@0: var functionsToRunAsync = []; michael@0: michael@0: window.addEventListener("message", function(event) { michael@0: if (event.source == window && event.data == "async-run") { michael@0: event.stopPropagation(); michael@0: var fn = functionsToRunAsync.shift(); michael@0: fn(); michael@0: } michael@0: }, true); michael@0: michael@0: function asyncRun(fn) { michael@0: functionsToRunAsync.push(fn); michael@0: window.postMessage("async-run", "*"); michael@0: } michael@0: michael@0: function writeErrorSummary(input, expected, got, isTodo) { michael@0: if (isTodo) { michael@0: $("display").appendChild(createEl('h2', null, "Unexpected Success:")); michael@0: } else { michael@0: $("display").appendChild(createEl('h2', null, "Unexpected Failure:")); michael@0: } michael@0: $("display").appendChild(createEl('br')); michael@0: $("display").appendChild(createEl('span', null, "Matched: ")); michael@0: $("display").appendChild(document.createTextNode("" + (expected == got))); michael@0: var pre = createEl('pre'); michael@0: pre.appendChild(document.createTextNode("Input: \n" + input, "\n-\n")); michael@0: pre.appendChild(document.createTextNode("Expected:\n" + expected, "\n-\n")); michael@0: pre.appendChild(document.createTextNode("Output:\n" + got + "\n-\n")); michael@0: $("display").appendChild(pre); michael@0: $("display").appendChild(createEl('hr')); michael@0: } michael@0: michael@0: /** michael@0: * Control will bounce back and forth between nextTest() and the michael@0: * event handler returned by makeTestChecker() or the callback returned by michael@0: * makeFragmentTestChecker() until the 'testcases' iterator is spent. michael@0: */ michael@0: function makeTestChecker(input, expected, errors) { michael@0: return function (e) { michael@0: var domAsString = docToTestOutput(e.target.contentDocument); michael@0: if (html5Exceptions[input]) { michael@0: todo_is(domAsString, expected, "HTML5 expected success."); michael@0: if (domAsString == expected) { michael@0: writeErrorSummary(input, expected, domAsString, true); michael@0: } michael@0: } else { michael@0: is(domAsString, expected, "HTML5 expected success."); michael@0: if (domAsString != expected) { michael@0: writeErrorSummary(input, expected, domAsString, false); michael@0: } michael@0: } michael@0: nextTest(e.target); michael@0: } michael@0: } michael@0: michael@0: function makeFragmentTestChecker(input, michael@0: expected, michael@0: errors, michael@0: fragment, michael@0: testframe) { michael@0: return function () { michael@0: var context = document.createElementNS("http://www.w3.org/1999/xhtml", michael@0: fragment); michael@0: context.innerHTML = input; michael@0: var domAsString = fragmentToTestOutput(context); michael@0: is(domAsString, expected, "HTML5 expected success. " + new Date()); michael@0: if (domAsString != expected) { michael@0: writeErrorSummary(input, expected, domAsString, false); michael@0: } michael@0: nextTest(testframe); michael@0: } michael@0: } michael@0: michael@0: var testcases; michael@0: function nextTest(testframe) { michael@0: var test = 0; michael@0: try { michael@0: var [input, output, errors, fragment] = testcases.next(); michael@0: if (fragment) { michael@0: asyncRun(makeFragmentTestChecker(input, michael@0: output, michael@0: errors, michael@0: fragment, michael@0: testframe)); michael@0: } else { michael@0: dataURL = "data:text/html;charset=utf-8," + encodeURIComponent(input); michael@0: testframe.onload = makeTestChecker(input, output, errors); michael@0: testframe.src = dataURL; michael@0: } michael@0: } catch (err if err instanceof StopIteration) { michael@0: SimpleTest.finish(); michael@0: } michael@0: } michael@0: michael@0: var testFileContents = []; michael@0: function loadNextTestFile() { michael@0: var datFile = parserDatFiles.shift(); michael@0: if (datFile) { michael@0: var xhr = new XMLHttpRequest(); michael@0: xhr.onreadystatechange = function () { michael@0: if (this.readyState == 4) { michael@0: testFileContents.push(this.responseText); michael@0: loadNextTestFile(); michael@0: } michael@0: }; michael@0: xhr.open("GET", "html5lib_tree_construction/" + datFile); michael@0: xhr.send(); michael@0: } else { michael@0: testcases = test_parser(testFileContents); michael@0: nextTest($("testframe")); michael@0: } michael@0: } michael@0: michael@0: addLoadEvent(loadNextTestFile); michael@0: SimpleTest.waitForExplicitFinish();