diff --git a/mozilla/parser/xml/Makefile.in b/mozilla/parser/xml/Makefile.in index 25bf6196f34..68aef738e85 100644 --- a/mozilla/parser/xml/Makefile.in +++ b/mozilla/parser/xml/Makefile.in @@ -43,4 +43,8 @@ include $(DEPTH)/config/autoconf.mk DIRS = public src +ifdef ENABLE_TESTS +DIRS += test +endif + include $(topsrcdir)/config/rules.mk diff --git a/mozilla/parser/xml/test/Makefile.in b/mozilla/parser/xml/test/Makefile.in new file mode 100644 index 00000000000..6c8113f1773 --- /dev/null +++ b/mozilla/parser/xml/test/Makefile.in @@ -0,0 +1,67 @@ +# +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is +# Mozilla.org. +# Portions created by the Initial Developer are Copyright (C) 2005 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Boris Zbarsky (Original author) +# +# Alternatively, the contents of this file may be used under the terms of +# either of the GNU General Public License Version 2 or later (the "GPL"), +# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), +# in which case the provisions of the GPL or the LGPL are applicable instead +# of those above. If you wish to allow use of your version of this file only +# under the terms of either the GPL or the LGPL, and not to allow others to +# use your version of this file under the terms of the MPL, indicate your +# decision by deleting the provisions above and replace them with the notice +# and other provisions required by the GPL or the LGPL. If you do not delete +# the provisions above, a recipient may use your version of this file under +# the terms of any one of the MPL, the GPL or the LGPL. +# +# ***** END LICENSE BLOCK ***** + +# +# Makefile for installing and running xpcshell-based tests. You can use +# this file as template when creating tests for a new module. Don't +# forget to change the lines marked below. See +# http://developer.mozilla.org/en/docs/Writing_xpcshell-based_unit_tests +# for detailed instructions. +# + +# Note: DEPTH should be set to the relative path to mozilla/ +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +# Note: set the test module's name to test_ +MODULE = test_xmlreader + +include $(topsrcdir)/config/rules.mk + +_UNIT_FILES := $(wildcard $(srcdir)/unit/*.js) + +libs:: $(_UNIT_FILES) + $(INSTALL) $^ $(DIST)/bin/$(MODULE) + +# Note: Invoke any additional (non-xpcshell) test programs here. +check:: + $(RUN_TEST_PROGRAM) $(DIST)/bin/test_all.sh $(DIST)/bin/$(MODULE) diff --git a/mozilla/parser/xml/test/unit/test_parser.js b/mozilla/parser/xml/test/unit/test_parser.js new file mode 100644 index 00000000000..79c32bae480 --- /dev/null +++ b/mozilla/parser/xml/test/unit/test_parser.js @@ -0,0 +1,167 @@ +function updateDocumentSourceMaps(source) { + const nsIDOMNode = Components.interfaces.nsIDOMNode; + + const nsISAXXMLReader = Components.interfaces.nsISAXXMLReader; + const saxReader = Components.classes["@mozilla.org/saxparser/xmlreader;1"] + .createInstance(nsISAXXMLReader); + try { + saxReader.setFeature("http://xml.org/sax/features/namespace-prefixes", true); + saxReader.setFeature("http://xml.org/sax/features/namespace", true); + } + catch (e) { + // do nothing, we'll accept it as it is. + } + var parseErrorLog = []; + + /* XXX ajvincent Because throwing an exception doesn't stop parsing, we need + * to record errors and handle them after the parsing is finished. + */ + function do_parse_check(aCondition, aMsg) { + if (!aCondition) + parseErrorLog[parseErrorLog.length] = aMsg; + } + + var contentHandler = { + startDocument: function startDocument() { + }, + + endDocument: function endDocument() { + }, + + handleAttributes: function handleAttributes(aAttributes) { + for (var i = 0; i < aAttributes.length; i++) { + var attrNamespaceURI = aAttributes.getURI(i); + var attrLocalName = aAttributes.getLocalName(i); + var attrNodeName = aAttributes.getQName(i); + var value = aAttributes.getValue(i); + do_parse_check(attrLocalName, "Missing attribute local name"); + do_parse_check(attrNodeName, "Missing attribute node name"); + } + }, + + startElement: function startElement(aNamespaceURI, aLocalName, aNodeName, aAttributes) { + do_parse_check(aLocalName, "Missing element local name (startElement)"); + do_parse_check(aNodeName, "Missing element node name (startElement)"); + do_parse_check(aAttributes, "Missing element attributes"); + this.handleAttributes(aAttributes); + }, + + endElement: function endElement(aNamespaceURI, aLocalName, aNodeName) { + do_parse_check(aLocalName, "Missing element local name (endElement)"); + do_parse_check(aNodeName, "Missing element node name (endElement)"); + }, + + inCDataSection: false, + + characters: function characters(aData) { + }, + + processingInstruction: function processingInstruction(aTarget, aData) { + do_parse_check(aTarget, "Missing processing instruction target"); + }, + + ignorableWhitespace: function ignorableWhitespace(aWhitespace) { + }, + + startPrefixMapping: function startPrefixMapping(aPrefix, aURI) { + }, + + endPrefixMapping: function endPrefixMapping(aPrefix) { + } + }; + + var lexicalHandler = { + comment: function comment(aContents) { + }, + + startDTD: function startDTD(aName, aPublicId, aSystemId) { + do_parse_check(aName, "Missing DTD name"); + }, + + endDTD: function endDTD() { + }, + + startCDATA: function startCDATA() { + }, + + endCDATA: function endCDATA() { + }, + + startEntity: function startEntity(aName) { + do_parse_check(aName, "Missing entity name (startEntity)"); + }, + + endEntity: function endEntity(aName) { + do_parse_check(aName, "Missing entity name (endEntity)"); + } + }; + + var dtdHandler = { + notationDecl: function notationDecl(aName, aPublicId, aSystemId) { + do_parse_check(aName, "Missing notation name"); + }, + + unparsedEntityDecl: + function unparsedEntityDecl(aName, aPublicId, aSystemId, aNotationName) { + do_parse_check(aName, "Missing entity name (unparsedEntityDecl)"); + } + }; + + var errorHandler = { + error: function error(aLocator, aError) { + do_parse_check(!aError, "XML error"); + }, + + fatalError: function fatalError(aLocator, aError) { + do_parse_check(!aError, "XML fatal error"); + }, + + ignorableWarning: function ignorableWarning(aLocator, aError) { + do_parse_check(!aError, "XML ignorable warning"); + } + }; + + saxReader.contentHandler = contentHandler; + saxReader.lexicalHandler = lexicalHandler; + saxReader.dtdHandler = dtdHandler; + saxReader.errorHandler = errorHandler; + + saxReader.parseFromString(source, "application/xml"); + + // Just in case it leaks. + saxReader.contentHandler = null; + saxReader.lexicalHandler = null; + saxReader.dtdHandler = null; + saxReader.errorHandler = null; + + return parseErrorLog; +} + +function do_check_true_with_dump(aCondition, aParseLog) { + if (!aCondition) { + dump(aParseLog.join("\n")); + } + do_check_true(aCondition); +} + +function run_test() { + var src; + src = "\n"; + src += "\n\nfoo"; + src += "\n"; + var parseErrorLog = updateDocumentSourceMaps(src); + + if (parseErrorLog.length > 0) { + dump(parseErrorLog.join("\n")); + } + do_check_true_with_dump(parseErrorLog.length == 0, parseErrorLog); + + // End tag isn't well-formed. + src = "\n"; + src += "\n\nfoo"; + src += "