1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/parser/xml/test/unit/test_parser.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,167 @@ 1.4 +function updateDocumentSourceMaps(source) { 1.5 + const nsIDOMNode = Components.interfaces.nsIDOMNode; 1.6 + 1.7 + const nsISAXXMLReader = Components.interfaces.nsISAXXMLReader; 1.8 + const saxReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"] 1.9 + .createInstance(nsISAXXMLReader); 1.10 + try { 1.11 + saxReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); 1.12 + saxReader.setFeature("http://xml.org/sax/features/namespace", true); 1.13 + } 1.14 + catch (e) { 1.15 + // do nothing, we'll accept it as it is. 1.16 + } 1.17 + var parseErrorLog = []; 1.18 + 1.19 + /* XXX ajvincent Because throwing an exception doesn't stop parsing, we need 1.20 + * to record errors and handle them after the parsing is finished. 1.21 + */ 1.22 + function do_parse_check(aCondition, aMsg) { 1.23 + if (!aCondition) 1.24 + parseErrorLog[parseErrorLog.length] = aMsg; 1.25 + } 1.26 + 1.27 + var contentHandler = { 1.28 + startDocument: function startDocument() { 1.29 + }, 1.30 + 1.31 + endDocument: function endDocument() { 1.32 + }, 1.33 + 1.34 + handleAttributes: function handleAttributes(aAttributes) { 1.35 + for (var i = 0; i < aAttributes.length; i++) { 1.36 + var attrNamespaceURI = aAttributes.getURI(i); 1.37 + var attrLocalName = aAttributes.getLocalName(i); 1.38 + var attrNodeName = aAttributes.getQName(i); 1.39 + var value = aAttributes.getValue(i); 1.40 + do_parse_check(attrLocalName, "Missing attribute local name"); 1.41 + do_parse_check(attrNodeName, "Missing attribute node name"); 1.42 + } 1.43 + }, 1.44 + 1.45 + startElement: function startElement(aNamespaceURI, aLocalName, aNodeName, aAttributes) { 1.46 + do_parse_check(aLocalName, "Missing element local name (startElement)"); 1.47 + do_parse_check(aNodeName, "Missing element node name (startElement)"); 1.48 + do_parse_check(aAttributes, "Missing element attributes"); 1.49 + this.handleAttributes(aAttributes); 1.50 + }, 1.51 + 1.52 + endElement: function endElement(aNamespaceURI, aLocalName, aNodeName) { 1.53 + do_parse_check(aLocalName, "Missing element local name (endElement)"); 1.54 + do_parse_check(aNodeName, "Missing element node name (endElement)"); 1.55 + }, 1.56 + 1.57 + inCDataSection: false, 1.58 + 1.59 + characters: function characters(aData) { 1.60 + }, 1.61 + 1.62 + processingInstruction: function processingInstruction(aTarget, aData) { 1.63 + do_parse_check(aTarget, "Missing processing instruction target"); 1.64 + }, 1.65 + 1.66 + ignorableWhitespace: function ignorableWhitespace(aWhitespace) { 1.67 + }, 1.68 + 1.69 + startPrefixMapping: function startPrefixMapping(aPrefix, aURI) { 1.70 + }, 1.71 + 1.72 + endPrefixMapping: function endPrefixMapping(aPrefix) { 1.73 + } 1.74 + }; 1.75 + 1.76 + var lexicalHandler = { 1.77 + comment: function comment(aContents) { 1.78 + }, 1.79 + 1.80 + startDTD: function startDTD(aName, aPublicId, aSystemId) { 1.81 + do_parse_check(aName, "Missing DTD name"); 1.82 + }, 1.83 + 1.84 + endDTD: function endDTD() { 1.85 + }, 1.86 + 1.87 + startCDATA: function startCDATA() { 1.88 + }, 1.89 + 1.90 + endCDATA: function endCDATA() { 1.91 + }, 1.92 + 1.93 + startEntity: function startEntity(aName) { 1.94 + do_parse_check(aName, "Missing entity name (startEntity)"); 1.95 + }, 1.96 + 1.97 + endEntity: function endEntity(aName) { 1.98 + do_parse_check(aName, "Missing entity name (endEntity)"); 1.99 + } 1.100 + }; 1.101 + 1.102 + var dtdHandler = { 1.103 + notationDecl: function notationDecl(aName, aPublicId, aSystemId) { 1.104 + do_parse_check(aName, "Missing notation name"); 1.105 + }, 1.106 + 1.107 + unparsedEntityDecl: 1.108 + function unparsedEntityDecl(aName, aPublicId, aSystemId, aNotationName) { 1.109 + do_parse_check(aName, "Missing entity name (unparsedEntityDecl)"); 1.110 + } 1.111 + }; 1.112 + 1.113 + var errorHandler = { 1.114 + error: function error(aLocator, aError) { 1.115 + do_parse_check(!aError, "XML error"); 1.116 + }, 1.117 + 1.118 + fatalError: function fatalError(aLocator, aError) { 1.119 + do_parse_check(!aError, "XML fatal error"); 1.120 + }, 1.121 + 1.122 + ignorableWarning: function ignorableWarning(aLocator, aError) { 1.123 + do_parse_check(!aError, "XML ignorable warning"); 1.124 + } 1.125 + }; 1.126 + 1.127 + saxReader.contentHandler = contentHandler; 1.128 + saxReader.lexicalHandler = lexicalHandler; 1.129 + saxReader.dtdHandler = dtdHandler; 1.130 + saxReader.errorHandler = errorHandler; 1.131 + 1.132 + saxReader.parseFromString(source, "application/xml"); 1.133 + 1.134 + // Just in case it leaks. 1.135 + saxReader.contentHandler = null; 1.136 + saxReader.lexicalHandler = null; 1.137 + saxReader.dtdHandler = null; 1.138 + saxReader.errorHandler = null; 1.139 + 1.140 + return parseErrorLog; 1.141 +} 1.142 + 1.143 +function do_check_true_with_dump(aCondition, aParseLog) { 1.144 + if (!aCondition) { 1.145 + dump(aParseLog.join("\n")); 1.146 + } 1.147 + do_check_true(aCondition); 1.148 +} 1.149 + 1.150 +function run_test() { 1.151 + var src; 1.152 + src = "<!DOCTYPE foo>\n<!-- all your foo are belong to bar -->"; 1.153 + src += "<foo id='foo'>\n<?foo wooly bully?>\nfoo"; 1.154 + src += "<![CDATA[foo fighters]]></foo>\n"; 1.155 + var parseErrorLog = updateDocumentSourceMaps(src); 1.156 + 1.157 + if (parseErrorLog.length > 0) { 1.158 + dump(parseErrorLog.join("\n")); 1.159 + } 1.160 + do_check_true_with_dump(parseErrorLog.length == 0, parseErrorLog); 1.161 + 1.162 + // End tag isn't well-formed. 1.163 + src = "<!DOCTYPE foo>\n<!-- all your foo are belong to bar -->"; 1.164 + src += "<foo id='foo'>\n<?foo wooly bully?>\nfoo"; 1.165 + src += "<![CDATA[foo fighters]]></foo\n"; 1.166 + 1.167 + parseErrorLog = updateDocumentSourceMaps(src); 1.168 + 1.169 + do_check_true_with_dump(parseErrorLog.length == 1 && parseErrorLog[0] == "XML fatal error", parseErrorLog); 1.170 +}