parser/htmlparser/tests/mochitest/parser_datreader.js

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /**
michael@0 7 * A test suite that runs WHATWG HTML parser tests.
michael@0 8 * The tests are from html5lib.
michael@0 9 *
michael@0 10 * http://html5lib.googlecode.com/
michael@0 11 */
michael@0 12
michael@0 13 /**
michael@0 14 * A few utility functions.
michael@0 15 */
michael@0 16 function log(entry) {
michael@0 17
michael@0 18 }
michael@0 19
michael@0 20 function startsWith(s, s2) {
michael@0 21 return s.indexOf(s2)==0;
michael@0 22 }
michael@0 23
michael@0 24 function trimString(s) {
michael@0 25 return(s.replace(/^\s+/,'').replace(/\s+$/,''));
michael@0 26 }
michael@0 27
michael@0 28 /**
michael@0 29 * Parses an individual testcase into an array containing the input
michael@0 30 * string, a string representing the expected tree (DOM), and a list
michael@0 31 * of error messages.
michael@0 32 *
michael@0 33 * @param A string containing a single testcase
michael@0 34 */
michael@0 35 function parseTestcase(testcase) {
michael@0 36 var lines = testcase.split("\n");
michael@0 37
michael@0 38 /* check that the first non-empty, non-comment line is #data */
michael@0 39 for each (var line in lines) {
michael@0 40 if (!line || startsWith(line, "##")) {
michael@0 41 continue;
michael@0 42 }
michael@0 43 if (line == "#data")
michael@0 44 break;
michael@0 45 log(lines);
michael@0 46 throw "Unknown test format."
michael@0 47 }
michael@0 48
michael@0 49 var input = [];
michael@0 50 var output = [];
michael@0 51 var errors = [];
michael@0 52 var fragment = [];
michael@0 53 var currentList = input;
michael@0 54 for each (var line in lines) {
michael@0 55 if (startsWith(line, "##todo")) {
michael@0 56 todo(false, line.substring(6));
michael@0 57 continue;
michael@0 58 }
michael@0 59 if (!(startsWith(line, "#error") ||
michael@0 60 startsWith(line, "#document") ||
michael@0 61 startsWith(line, "#document-fragment") ||
michael@0 62 startsWith(line, "#data"))) {
michael@0 63 currentList.push(line);
michael@0 64 } else if (line == "#errors") {
michael@0 65 currentList = errors;
michael@0 66 } else if (line == "#document") {
michael@0 67 currentList = output;
michael@0 68 } else if (line == "#document-fragment") {
michael@0 69 currentList = fragment;
michael@0 70 }
michael@0 71 }
michael@0 72 while (!output[output.length - 1]) {
michael@0 73 output.pop(); // zap trailing blank lines
michael@0 74 }
michael@0 75 //logger.log(input.length, output.length, errors.length);
michael@0 76 return [input.join("\n"), output.join("\n"), errors, fragment[0]];
michael@0 77 }
michael@0 78
michael@0 79 /**
michael@0 80 * A generator function that accepts a list of strings. Each list
michael@0 81 * member corresponds to the contents of a ".dat" file from the
michael@0 82 * html5lib test suite.
michael@0 83 *
michael@0 84 * @param The list of strings
michael@0 85 */
michael@0 86 function test_parser(testlist) {
michael@0 87 for each (var testgroup in testlist) {
michael@0 88 var tests = testgroup.split("#data\n");
michael@0 89 tests = ["#data\n" + test for each(test in tests) if (test)];
michael@0 90 for each (var test in tests) {
michael@0 91 yield parseTestcase(test);
michael@0 92 }
michael@0 93 }
michael@0 94 }
michael@0 95
michael@0 96 /**
michael@0 97 * Transforms a DOM document to a string matching the format in
michael@0 98 * the test cases.
michael@0 99 *
michael@0 100 * @param the DOM document
michael@0 101 */
michael@0 102 function docToTestOutput(doc) {
michael@0 103 var walker = doc.createTreeWalker(doc, NodeFilter.SHOW_ALL, null);
michael@0 104 return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline
michael@0 105 }
michael@0 106
michael@0 107 /**
michael@0 108 * Creates a walker for a fragment that skips over the root node.
michael@0 109 *
michael@0 110 * @param an element
michael@0 111 */
michael@0 112 function createFragmentWalker(elt) {
michael@0 113 return elt.ownerDocument.createTreeWalker(elt, NodeFilter.SHOW_ALL,
michael@0 114 function (node) {
michael@0 115 return elt == node ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT;
michael@0 116 });
michael@0 117 }
michael@0 118
michael@0 119 /**
michael@0 120 * Transforms the descendants of an element to a string matching the format
michael@0 121 * in the test cases.
michael@0 122 *
michael@0 123 * @param an element
michael@0 124 */
michael@0 125 function fragmentToTestOutput(elt) {
michael@0 126 var walker = createFragmentWalker(elt);
michael@0 127 return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline
michael@0 128 }
michael@0 129
michael@0 130 function addLevels(walker, buf, indent) {
michael@0 131 if(walker.firstChild()) {
michael@0 132 do {
michael@0 133 buf += indent;
michael@0 134 switch (walker.currentNode.nodeType) {
michael@0 135 case Node.ELEMENT_NODE:
michael@0 136 buf += "<"
michael@0 137 var ns = walker.currentNode.namespaceURI;
michael@0 138 if ("http://www.w3.org/1998/Math/MathML" == ns) {
michael@0 139 buf += "math ";
michael@0 140 } else if ("http://www.w3.org/2000/svg" == ns) {
michael@0 141 buf += "svg ";
michael@0 142 } else if ("http://www.w3.org/1999/xhtml" != ns) {
michael@0 143 buf += "otherns ";
michael@0 144 }
michael@0 145 buf += walker.currentNode.localName + ">";
michael@0 146 if (walker.currentNode.hasAttributes()) {
michael@0 147 var valuesByName = {};
michael@0 148 var attrs = walker.currentNode.attributes;
michael@0 149 for (var i = 0; i < attrs.length; ++i) {
michael@0 150 var localName = attrs[i].localName;
michael@0 151 var name;
michael@0 152 var attrNs = attrs[i].namespaceURI;
michael@0 153 if (null == attrNs) {
michael@0 154 name = localName;
michael@0 155 } else if ("http://www.w3.org/XML/1998/namespace" == attrNs) {
michael@0 156 name = "xml " + localName;
michael@0 157 } else if ("http://www.w3.org/1999/xlink" == attrNs) {
michael@0 158 name = "xlink " + localName;
michael@0 159 } else if ("http://www.w3.org/2000/xmlns/" == attrNs) {
michael@0 160 name = "xmlns " + localName;
michael@0 161 } else {
michael@0 162 name = "otherns " + localName;
michael@0 163 }
michael@0 164 valuesByName[name] = attrs[i].value;
michael@0 165 }
michael@0 166 var keys = Object.keys(valuesByName).sort();
michael@0 167 for (var i = 0; i < keys.length; ++i) {
michael@0 168 buf += "\n" + indent + " " + keys[i] +
michael@0 169 "=\"" + valuesByName[keys[i]] +"\"";
michael@0 170 }
michael@0 171 }
michael@0 172 break;
michael@0 173 case Node.DOCUMENT_TYPE_NODE:
michael@0 174 buf += "<!DOCTYPE " + walker.currentNode.name;
michael@0 175 if (walker.currentNode.publicId || walker.currentNode.systemId) {
michael@0 176 buf += " \"";
michael@0 177 buf += walker.currentNode.publicId;
michael@0 178 buf += "\" \"";
michael@0 179 buf += walker.currentNode.systemId;
michael@0 180 buf += "\"";
michael@0 181 }
michael@0 182 buf += ">";
michael@0 183 break;
michael@0 184 case Node.COMMENT_NODE:
michael@0 185 buf += "<!-- " + walker.currentNode.nodeValue + " -->";
michael@0 186 break;
michael@0 187 case Node.TEXT_NODE:
michael@0 188 buf += "\"" + walker.currentNode.nodeValue + "\"";
michael@0 189 break;
michael@0 190 }
michael@0 191 buf += "\n";
michael@0 192 // In the case of template elements, children do not get inserted as
michael@0 193 // children of the template element, instead they are inserted
michael@0 194 // as children of the template content (which is a document fragment).
michael@0 195 if (walker.currentNode instanceof HTMLTemplateElement) {
michael@0 196 buf += indent + " content\n";
michael@0 197 // Walk through the template content.
michael@0 198 var templateWalker = createFragmentWalker(walker.currentNode.content);
michael@0 199 buf = addLevels(templateWalker, buf, indent + " ");
michael@0 200 }
michael@0 201 buf = addLevels(walker, buf, indent + " ");
michael@0 202 } while(walker.nextSibling());
michael@0 203 walker.parentNode();
michael@0 204 }
michael@0 205 return buf;
michael@0 206 }
michael@0 207

mercurial