parser/htmlparser/tests/mochitest/parser_datreader.js

changeset 0
6474c204b198
     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 +

mercurial