1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/parser/htmlparser/tests/mochitest/parser_datreader.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,207 @@ 1.4 +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- 1.5 + * This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/** 1.10 + * A test suite that runs WHATWG HTML parser tests. 1.11 + * The tests are from html5lib. 1.12 + * 1.13 + * http://html5lib.googlecode.com/ 1.14 + */ 1.15 + 1.16 +/** 1.17 + * A few utility functions. 1.18 + */ 1.19 +function log(entry) { 1.20 + 1.21 +} 1.22 + 1.23 +function startsWith(s, s2) { 1.24 + return s.indexOf(s2)==0; 1.25 +} 1.26 + 1.27 +function trimString(s) { 1.28 + return(s.replace(/^\s+/,'').replace(/\s+$/,'')); 1.29 +} 1.30 + 1.31 +/** 1.32 + * Parses an individual testcase into an array containing the input 1.33 + * string, a string representing the expected tree (DOM), and a list 1.34 + * of error messages. 1.35 + * 1.36 + * @param A string containing a single testcase 1.37 + */ 1.38 +function parseTestcase(testcase) { 1.39 + var lines = testcase.split("\n"); 1.40 + 1.41 + /* check that the first non-empty, non-comment line is #data */ 1.42 + for each (var line in lines) { 1.43 + if (!line || startsWith(line, "##")) { 1.44 + continue; 1.45 + } 1.46 + if (line == "#data") 1.47 + break; 1.48 + log(lines); 1.49 + throw "Unknown test format." 1.50 + } 1.51 + 1.52 + var input = []; 1.53 + var output = []; 1.54 + var errors = []; 1.55 + var fragment = []; 1.56 + var currentList = input; 1.57 + for each (var line in lines) { 1.58 + if (startsWith(line, "##todo")) { 1.59 + todo(false, line.substring(6)); 1.60 + continue; 1.61 + } 1.62 + if (!(startsWith(line, "#error") || 1.63 + startsWith(line, "#document") || 1.64 + startsWith(line, "#document-fragment") || 1.65 + startsWith(line, "#data"))) { 1.66 + currentList.push(line); 1.67 + } else if (line == "#errors") { 1.68 + currentList = errors; 1.69 + } else if (line == "#document") { 1.70 + currentList = output; 1.71 + } else if (line == "#document-fragment") { 1.72 + currentList = fragment; 1.73 + } 1.74 + } 1.75 + while (!output[output.length - 1]) { 1.76 + output.pop(); // zap trailing blank lines 1.77 + } 1.78 + //logger.log(input.length, output.length, errors.length); 1.79 + return [input.join("\n"), output.join("\n"), errors, fragment[0]]; 1.80 +} 1.81 + 1.82 +/** 1.83 + * A generator function that accepts a list of strings. Each list 1.84 + * member corresponds to the contents of a ".dat" file from the 1.85 + * html5lib test suite. 1.86 + * 1.87 + * @param The list of strings 1.88 + */ 1.89 +function test_parser(testlist) { 1.90 + for each (var testgroup in testlist) { 1.91 + var tests = testgroup.split("#data\n"); 1.92 + tests = ["#data\n" + test for each(test in tests) if (test)]; 1.93 + for each (var test in tests) { 1.94 + yield parseTestcase(test); 1.95 + } 1.96 + } 1.97 +} 1.98 + 1.99 +/** 1.100 + * Transforms a DOM document to a string matching the format in 1.101 + * the test cases. 1.102 + * 1.103 + * @param the DOM document 1.104 + */ 1.105 +function docToTestOutput(doc) { 1.106 + var walker = doc.createTreeWalker(doc, NodeFilter.SHOW_ALL, null); 1.107 + return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline 1.108 +} 1.109 + 1.110 +/** 1.111 + * Creates a walker for a fragment that skips over the root node. 1.112 + * 1.113 + * @param an element 1.114 + */ 1.115 +function createFragmentWalker(elt) { 1.116 + return elt.ownerDocument.createTreeWalker(elt, NodeFilter.SHOW_ALL, 1.117 + function (node) { 1.118 + return elt == node ? NodeFilter.FILTER_SKIP : NodeFilter.FILTER_ACCEPT; 1.119 + }); 1.120 +} 1.121 + 1.122 +/** 1.123 + * Transforms the descendants of an element to a string matching the format 1.124 + * in the test cases. 1.125 + * 1.126 + * @param an element 1.127 + */ 1.128 +function fragmentToTestOutput(elt) { 1.129 + var walker = createFragmentWalker(elt); 1.130 + return addLevels(walker, "", "| ").slice(0,-1); // remove the last newline 1.131 +} 1.132 + 1.133 +function addLevels(walker, buf, indent) { 1.134 + if(walker.firstChild()) { 1.135 + do { 1.136 + buf += indent; 1.137 + switch (walker.currentNode.nodeType) { 1.138 + case Node.ELEMENT_NODE: 1.139 + buf += "<" 1.140 + var ns = walker.currentNode.namespaceURI; 1.141 + if ("http://www.w3.org/1998/Math/MathML" == ns) { 1.142 + buf += "math "; 1.143 + } else if ("http://www.w3.org/2000/svg" == ns) { 1.144 + buf += "svg "; 1.145 + } else if ("http://www.w3.org/1999/xhtml" != ns) { 1.146 + buf += "otherns "; 1.147 + } 1.148 + buf += walker.currentNode.localName + ">"; 1.149 + if (walker.currentNode.hasAttributes()) { 1.150 + var valuesByName = {}; 1.151 + var attrs = walker.currentNode.attributes; 1.152 + for (var i = 0; i < attrs.length; ++i) { 1.153 + var localName = attrs[i].localName; 1.154 + var name; 1.155 + var attrNs = attrs[i].namespaceURI; 1.156 + if (null == attrNs) { 1.157 + name = localName; 1.158 + } else if ("http://www.w3.org/XML/1998/namespace" == attrNs) { 1.159 + name = "xml " + localName; 1.160 + } else if ("http://www.w3.org/1999/xlink" == attrNs) { 1.161 + name = "xlink " + localName; 1.162 + } else if ("http://www.w3.org/2000/xmlns/" == attrNs) { 1.163 + name = "xmlns " + localName; 1.164 + } else { 1.165 + name = "otherns " + localName; 1.166 + } 1.167 + valuesByName[name] = attrs[i].value; 1.168 + } 1.169 + var keys = Object.keys(valuesByName).sort(); 1.170 + for (var i = 0; i < keys.length; ++i) { 1.171 + buf += "\n" + indent + " " + keys[i] + 1.172 + "=\"" + valuesByName[keys[i]] +"\""; 1.173 + } 1.174 + } 1.175 + break; 1.176 + case Node.DOCUMENT_TYPE_NODE: 1.177 + buf += "<!DOCTYPE " + walker.currentNode.name; 1.178 + if (walker.currentNode.publicId || walker.currentNode.systemId) { 1.179 + buf += " \""; 1.180 + buf += walker.currentNode.publicId; 1.181 + buf += "\" \""; 1.182 + buf += walker.currentNode.systemId; 1.183 + buf += "\""; 1.184 + } 1.185 + buf += ">"; 1.186 + break; 1.187 + case Node.COMMENT_NODE: 1.188 + buf += "<!-- " + walker.currentNode.nodeValue + " -->"; 1.189 + break; 1.190 + case Node.TEXT_NODE: 1.191 + buf += "\"" + walker.currentNode.nodeValue + "\""; 1.192 + break; 1.193 + } 1.194 + buf += "\n"; 1.195 + // In the case of template elements, children do not get inserted as 1.196 + // children of the template element, instead they are inserted 1.197 + // as children of the template content (which is a document fragment). 1.198 + if (walker.currentNode instanceof HTMLTemplateElement) { 1.199 + buf += indent + " content\n"; 1.200 + // Walk through the template content. 1.201 + var templateWalker = createFragmentWalker(walker.currentNode.content); 1.202 + buf = addLevels(templateWalker, buf, indent + " "); 1.203 + } 1.204 + buf = addLevels(walker, buf, indent + " "); 1.205 + } while(walker.nextSibling()); 1.206 + walker.parentNode(); 1.207 + } 1.208 + return buf; 1.209 +} 1.210 +