diff options
author | smerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2013-11-20 01:00:45 +0000 |
---|---|---|
committer | smerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04> | 2013-11-20 01:00:45 +0000 |
commit | 72e1dd03e1f4910c9724722150fa86a6b140a518 (patch) | |
tree | afe0370a2f51fb433634ac9a490c66b1b6678e26 | |
parent | c30948c3cf01caa70300099c39a2a40aaa2ea74a (diff) | |
download | docutils-72e1dd03e1f4910c9724722150fa86a6b140a518.tar.gz |
Added tests for XmlParser and XmlVisitor.
git-svn-id: http://svn.code.sf.net/p/docutils/code/trunk@7729 929543f6-e4f2-0310-98a6-ba3bd3dd1d04
-rw-r--r-- | sandbox/docutils_xml/docutils_xml/parsers/xml.py | 27 | ||||
-rw-r--r-- | sandbox/docutils_xml/global.log | 363 | ||||
-rw-r--r-- | sandbox/docutils_xml/tag.log | 2 | ||||
-rw-r--r-- | sandbox/docutils_xml/test/test_parsers/__init__.py | 14 | ||||
-rw-r--r-- | sandbox/docutils_xml/test/test_parsers/test_XmlParser.py | 332 | ||||
-rw-r--r-- | sandbox/docutils_xml/test/test_parsers/test_XmlVisitor.py | 129 | ||||
-rw-r--r-- | sandbox/docutils_xml/version.py | 2 |
7 files changed, 861 insertions, 8 deletions
diff --git a/sandbox/docutils_xml/docutils_xml/parsers/xml.py b/sandbox/docutils_xml/docutils_xml/parsers/xml.py index 1de562a40..4a4bddb4c 100644 --- a/sandbox/docutils_xml/docutils_xml/parsers/xml.py +++ b/sandbox/docutils_xml/docutils_xml/parsers/xml.py @@ -226,11 +226,14 @@ class XmlParser(docutils.parsers.Parser): A generic XML parser for parsing XML input populating the Docutils doctree. """ - ns2Prefix = { } + ns2Prefixes = { } """ - :type: { unicode: unicode, ... } + :type: { unicode: unicode | ( unicode, ... ) , ... } - Map namespace URI to namespace tag name. Usually overridden in subclasses. + Map namespace URI to one or more namespace prefixes. In case a unique + prefix is needed for a namespace the first one is used. + + Usually overridden in subclasses. """ visitorClass = XmlVisitor @@ -248,8 +251,11 @@ class XmlParser(docutils.parsers.Parser): # This is a global setting in etree which is problematic because it is # shared. However, this should work since it is overridden every time # before it is used. - [ etree.register_namespace(prefix, uri) - for ( uri, prefix ) in self.ns2Prefix.items() ] + for ( uri, prefixes ) in self.ns2Prefixes.items(): + if isinstance(prefixes, basestring): + prefixes = ( prefixes, ) + for prefix in prefixes: + etree.register_namespace(prefix, uri) inDoc = etree.fromstring(inputstring) self.walk(inDoc, self.visitorClass(self, document)) self.finish_parse() @@ -272,6 +278,7 @@ class XmlParser(docutils.parsers.Parser): stop = False skipDeparture = False someChildren = None + beep = False try: try: visitor.visit(elem) @@ -290,6 +297,8 @@ class XmlParser(docutils.parsers.Parser): stop = True break except docutils.nodes.SkipSiblings: + # Implies SkipDeparture for the child because it is caught only + # by the parent pass except docutils.nodes.SkipChildren: pass @@ -314,5 +323,11 @@ class XmlParser(docutils.parsers.Parser): prefix = None # elem.prefix would also work for lxml but using the namespace is saver if qName.namespace: - prefix = self.ns2Prefix.get(qName.namespace, None) + prefixes = self.ns2Prefixes.get(qName.namespace, None) + if prefixes is None: + prefix = None + elif isinstance(prefixes, basestring): + prefix = prefixes + else: + prefix = prefixes[0] return ( prefix, qName.localname ) diff --git a/sandbox/docutils_xml/global.log b/sandbox/docutils_xml/global.log index d231904d1..5ebb59650 100644 --- a/sandbox/docutils_xml/global.log +++ b/sandbox/docutils_xml/global.log @@ -1,4 +1,367 @@ ************************************** +Date: Wed Nov 20 01:55:31 CET 2013 +Author: stefan +Tag: docutils_xml_1_26 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/docutils_xml/parsers +In directory theowa:/home/stefan/free/docutils_xml/docutils_xml/parsers + +Modified Files: + xml.py + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Added tests for SomeChildren. +************************************** +Date: Wed Nov 20 01:18:54 CET 2013 +Author: stefan +Tag: docutils_xml_1_25 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Added tests for remaining control options for walk() except +SomeChildren. +************************************** +Date: Wed Nov 20 01:12:21 CET 2013 +Author: stefan +Tag: docutils_xml_1_24 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/docutils_xml/parsers +In directory theowa:/home/stefan/free/docutils_xml/docutils_xml/parsers + +Modified Files: + xml.py + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Added some tests controlling walk(). +************************************** +Date: Wed Nov 20 00:32:44 CET 2013 +Author: stefan +Tag: docutils_xml_1_23 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Added code to support control over XmlParser.walk(). +************************************** +Date: Wed Nov 20 00:13:05 CET 2013 +Author: stefan +Tag: docutils_xml_1_22 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Attributes are considered in tests. +************************************** +Date: Tue Nov 19 23:45:18 CET 2013 +Author: stefan +Tag: docutils_xml_1_21 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/docutils_xml/parsers +In directory theowa:/home/stefan/free/docutils_xml/docutils_xml/parsers + +Modified Files: + xml.py + +-------------------------------------- +Log Message: +Debugging. +************************************** +Date: Tue Nov 19 23:29:25 CET 2013 +Author: stefan +Tag: docutils_xml_1_20 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test +In directory theowa:/home/stefan/free/docutils_xml/test + +Modified Files: + Makefile + +-------------------------------------- +Log Message: +Debugging. +************************************** +Date: Tue Nov 19 23:28:14 CET 2013 +Author: stefan +Tag: docutils_xml_1_19 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/docutils_xml/parsers +In directory theowa:/home/stefan/free/docutils_xml/docutils_xml/parsers + +Modified Files: + xml.py + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +A namespace can have more than one prefix. +************************************** +Date: Tue Nov 19 23:04:26 CET 2013 +Author: stefan +Tag: docutils_xml_1_18 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Added test uncovering a problem: The mapping XmlParser.ns2Prefix is +ambiguous because a namespace may use several prefixes. +************************************** +Date: Tue Nov 19 22:40:03 CET 2013 +Author: stefan +Tag: docutils_xml_1_17 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Added tests. +************************************** +Date: Tue Nov 19 22:31:00 CET 2013 +Author: stefan +Tag: docutils_xml_1_16 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Refactoring: Cleaned up imports. +************************************** +Date: Tue Nov 19 22:29:03 CET 2013 +Author: stefan +Tag: docutils_xml_1_15 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Refactoring: XmlParser tests use DocutilsTestSupport infrastructure. +************************************** +Date: Tue Nov 19 22:12:57 CET 2013 +Author: stefan +Tag: docutils_xml_1_14 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlParser.py test_XmlVisitor.py + +-------------------------------------- +Log Message: +Refactoring: Beautification. +************************************** +Date: Tue Nov 19 22:05:50 CET 2013 +Author: stefan +Tag: docutils_xml_1_13 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_XmlVisitor.py +Added Files: + test_XmlParser.py + +-------------------------------------- +Log Message: +Renamed `test_xml.py` to `test_XmlVisitor.py` and split off +`test_XmlParser.py`. +************************************** +Date: Tue Nov 19 22:00:16 CET 2013 +Author: stefan +Tag: docutils_xml_1_12 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_xml.py + +-------------------------------------- +Log Message: +Added todos. +************************************** +Date: Tue Nov 19 21:47:22 CET 2013 +Author: stefan +Tag: docutils_xml_1_11 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_xml.py + +-------------------------------------- +Log Message: +Minor improvement. +************************************** +Date: Tue Nov 19 21:35:05 CET 2013 +Author: stefan +Tag: docutils_xml_1_10 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_xml.py + +-------------------------------------- +Log Message: +Added first test for XmlParser. +************************************** +Date: Tue Nov 19 20:13:01 CET 2013 +Author: stefan +Tag: docutils_xml_1_9 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory theowa:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_xml.py + +-------------------------------------- +Log Message: +Removed superfluous stuff. +************************************** +Date: Sun Nov 17 19:59:27 CET 2013 +Author: stefan +Tag: docutils_xml_1_8 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory eskebo:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_xml.py + +-------------------------------------- +Log Message: +Added tests. +************************************** +Date: Sat Nov 16 20:32:04 CET 2013 +Author: stefan +Tag: docutils_xml_1_7 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory eskebo:/home/stefan/free/docutils_xml/test/test_parsers + +Modified Files: + test_xml.py + +-------------------------------------- +Log Message: +Added tests. +************************************** +Date: Sat Nov 16 19:27:43 CET 2013 +Author: stefan +Tag: docutils_xml_1_6 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test/test_parsers +In directory eskebo:/home/stefan/free/docutils_xml/test/test_parsers + +Added Files: + __init__.py test_xml.py + +-------------------------------------- +Log Message: +Added very first unit test. +************************************** +Date: Sat Nov 16 16:46:16 CET 2013 +Author: stefan +Tag: docutils_xml_1_5 + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml +In directory eskebo:/home/stefan/free/docutils_xml + +Modified Files: + Makefile + +-------------------------------------- +Update of /home/stefan/vault/sm/docutils_xml/test +In directory eskebo:/home/stefan/free/docutils_xml/test + +Added Files: + .cvsignore Makefile + +-------------------------------------- +Log Message: +Added Docutils test infrastructure. +************************************** Date: Sat Nov 16 13:51:23 CET 2013 Author: stefan Tag: docutils_xml_1_4 diff --git a/sandbox/docutils_xml/tag.log b/sandbox/docutils_xml/tag.log index 519da394a..444c60ef8 100644 --- a/sandbox/docutils_xml/tag.log +++ b/sandbox/docutils_xml/tag.log @@ -1 +1 @@ -docutils_xml_1_4 +docutils_xml_1_26 diff --git a/sandbox/docutils_xml/test/test_parsers/__init__.py b/sandbox/docutils_xml/test/test_parsers/__init__.py new file mode 100644 index 000000000..46fc50e06 --- /dev/null +++ b/sandbox/docutils_xml/test/test_parsers/__init__.py @@ -0,0 +1,14 @@ +import os +import os.path +import sys + +sys.path.insert(0, os.path.abspath(os.path.dirname(__file__))) +prev = '' +while sys.path[0] != prev: + try: + import DocutilsTestSupport + break + except ImportError: + prev = sys.path[0] + sys.path[0] = os.path.dirname(prev) +sys.path.pop(0) diff --git a/sandbox/docutils_xml/test/test_parsers/test_XmlParser.py b/sandbox/docutils_xml/test/test_parsers/test_XmlParser.py new file mode 100644 index 000000000..bccd1c789 --- /dev/null +++ b/sandbox/docutils_xml/test/test_parsers/test_XmlParser.py @@ -0,0 +1,332 @@ +# Copyright (C) 2013 Stefan Merten + +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2 of the License, +# or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +""" +Test XmlParser. +""" + +import unittest +import docutils.frontend +from docutils.nodes import Text + +from __init__ import DocutilsTestSupport + +from docutils_xml.parsers.xml import XmlVisitor, XmlParser, SomeChildren + +############################################################################### + +class XmlVisitorMock(XmlVisitor): + """ + Mock class recording calls in document. + """ + + depth = 0 + """ + :type: int + + Current indentation depth. + """ + + indent = u" " + """ + :type: unicode + + Indentation to use for one step. + """ + + currentPrefix = None + """ + :type: str + + The prefix of the current call. + """ + + currentTag = None + """ + :type: str + + The tag of the current call. + """ + + def __recordVisit(self, elem): + ( pfx, nm ) = self.parser.elem2PrefixName(elem) + attrs = "" + for attr in sorted(elem.keys()): + attrs += " %s=%r" % ( attr, elem.get(attr) ) + self.document += Text("%s{ %s:%s%s\n" + % ( self.depth * self.indent, + self.currentPrefix, self.currentTag, + attrs)) + self.depth += 1 + control = elem.get('control', None) + if control in ( 'SkipNode', 'SkipDeparture', 'SkipSiblings', + 'SkipChildren', 'StopTraversal' ): + e = eval("docutils.nodes.%s()" % ( control, )) + try: + raise e + except ( docutils.nodes.SkipNode, docutils.nodes.SkipSiblings ): + self.depth -= 1 + raise + elif control == 'SomeChildren': + tags = [ child.split(':', 1) + for child in elem.get('controlSomeChildren', '').split() ] + raise SomeChildren(tags) + return None + + def __recordDepart(self, elem): + ( pfx, nm ) = self.parser.elem2PrefixName(elem) + self.depth -= 1 + self.document += Text("%s} %s:%s\n" + % ( self.depth * self.indent, + self.currentPrefix, self.currentTag )) + return None + + def __getattr__(self, name): + ( currentType, self.currentPrefix, + self.currentTag ) = name.split('_', 2) + if currentType == 'visit': + return self.__recordVisit + else: + return self.__recordDepart + +############################################################################### + +class XmlParserMock(XmlParser): + """ + Mock class recording visited nodes in the output document. + """ + + ns2Prefixes = { u'urn:example': ( u'ex', u'alias', u'int', ), + # u'urn:empty': u'', # Empty tag is not accepted by lxml + u'urn:other': u'ot', + } + + visitorClass = XmlVisitorMock + +############################################################################### + +class XmlParserTestCase(DocutilsTestSupport.ParserTestCase): + """ + Output checker for XmlParser. + """ + + parser = XmlParserMock() + """Parser shared by all XmlParserTestCases.""" + + option_parser = docutils.frontend.OptionParser(components=( + XmlParserMock, )) + +############################################################################### + +class XmlParserTestSuite(DocutilsTestSupport.ParserTestSuite): + + test_case_class = XmlParserTestCase + +############################################################################### + +totest = {} + +totest['simple'] = ( + ( u"""<?xml version="1.0"?> +<rootOnly/> +""", + """<document source="test data"> + { :rootOnly + } :rootOnly +""" ), + ( u"""<?xml version="1.0"?> +<root> + <embedded/> +</root> +""", + """<document source="test data"> + { :root + { :embedded + } :embedded + } :root +""" ), + ( u"""<?xml version="1.0"?> +<root> + <one/> + <two/> +</root> +""", + """<document source="test data"> + { :root + { :one + } :one + { :two + } :two + } :root +""" ), + ( u"""<?xml version="1.0"?> +<rootOnly otherAttr='moreContent' attribute="content"/> +""", + """<document source="test data"> + { :rootOnly attribute='content' otherAttr='moreContent' + } :rootOnly +""" ), + ) + +totest['namespace'] = ( + ( u"""<?xml version="1.0"?> +<root + xmlns:int="urn:example" + xmlns:alias="urn:example" + xmlns:ot="urn:other"> + <int:one/> + <alias:two/> + <ot:three/> +</root> +""", + """<document source="test data"> + { :root + { ex:one + } ex:one + { ex:two + } ex:two + { ot:three + } ot:three + } :root +""" ), + ) + +totest['SkipNode'] = ( + ( u"""<?xml version="1.0"?> +<root control='SkipNode'> + <one/> + <two/> +</root> +""", + """<document source="test data"> + { :root control='SkipNode' +""" ), + ) + +totest['SkipDeparture'] = ( + ( u"""<?xml version="1.0"?> +<root control='SkipDeparture'> + <one/> + <two/> +</root> +""", + """<document source="test data"> + { :root control='SkipDeparture' + { :one + } :one + { :two + } :two +""" ), + ) + +totest['SkipSiblings'] = ( + ( u"""<?xml version="1.0"?> +<root> + <one control='SkipSiblings'/> + <two/> +</root> +""", + """<document source="test data"> + { :root + { :one control='SkipSiblings' + } :root +""" ), + ) + +totest['SkipChildren'] = ( + ( u"""<?xml version="1.0"?> +<root control='SkipChildren'> + <one/> + <two/> +</root> +""", + """<document source="test data"> + { :root control='SkipChildren' + } :root +""" ), + ) + +totest['StopTraversal'] = ( + ( u"""<?xml version="1.0"?> +<root> + <one control='StopTraversal'/> + <two/> +</root> +""", + """<document source="test data"> + { :root + { :one control='StopTraversal' + } :one + } :root +""" ), + ) + +totest['SomeChildren'] = ( + # Take care to use namespaced children + ( u"""<?xml version="1.0"?> +<root xmlns:int="urn:example" + control='SomeChildren'> + <int:one/> + <int:two/> +</root> +""", + """<document source="test data"> + { :root control='SomeChildren' + } :root +""" ), + ( u"""<?xml version="1.0"?> +<root xmlns:int="urn:example" + control='SomeChildren' controlSomeChildren='ex:one'> + <int:one/> + <int:two/> +</root> +""", + """<document source="test data"> + { :root control='SomeChildren' controlSomeChildren='ex:one' + { ex:one + } ex:one + } :root +""" ), + ( u"""<?xml version="1.0"?> +<root xmlns:int="urn:example" + control='SomeChildren' controlSomeChildren='ex:one ex:two ex:three'> + <int:one/> + <int:two/> +</root> +""", + """<document source="test data"> + { :root control='SomeChildren' controlSomeChildren='ex:one ex:two ex:three' + { ex:one + } ex:one + { ex:two + } ex:two + } :root +""" ), + ) + +############################################################################### + +def suite(): + s = XmlParserTestSuite() + s.generateTests(totest) + return s + +############################################################################### + +if __name__ == '__main__': + import unittest + unittest.main(defaultTest='suite') diff --git a/sandbox/docutils_xml/test/test_parsers/test_XmlVisitor.py b/sandbox/docutils_xml/test/test_parsers/test_XmlVisitor.py new file mode 100644 index 000000000..154c299a3 --- /dev/null +++ b/sandbox/docutils_xml/test/test_parsers/test_XmlVisitor.py @@ -0,0 +1,129 @@ +# Copyright (C) 2013 Stefan Merten + +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published +# by the Free Software Foundation; either version 2 of the License, +# or (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +""" +Test XmlVisitor. +""" + +import unittest +from lxml import etree +import docutils.nodes, docutils.utils + +from docutils_xml.parsers.xml import XmlVisitor, XmlParser + +############################################################################### + +class XmlVisitorMock(XmlVisitor): + """ + Mock class recording calls. + """ + + def __init__(self, parser, document): + + self.calls = [ ] + """ + :type: [ ( str, ( ... ), { str: ..., ... } ) ] + + Sequence of calls seen. Each entry is a tuple consisting of the name of + the method calles, the array of positional arguments given and a dict + with the keyword arguments. + """ + + self.currentCall = None + """ + :type: str + + The name of the current call. + """ + + XmlVisitor.__init__(self, parser, document) + + def __record(self, *args, **kwargs): + self.calls.append(( self.currentCall, args, kwargs )) + return None + + def __getattr__(self, name): + if 'default' in name: + # Pass through attributes containing "default" so the default + # method is chosen + raise AttributeError("Should use *Default method") + self.currentCall = name + return self.__record + + def visitDefault(self, elem): + self.currentCall = 'visitDefault' + self.__record(elem) + + def departDefault(self, elem): + self.currentCall = 'departDefault' + self.__record(elem) + +############################################################################### + +class XmlVisitorTests(unittest.TestCase): + + def setUp(self): + self.visitor = XmlVisitorMock(XmlParser(), + docutils.utils.new_document(None)) + + def test__init__(self): + self.assertIsInstance(XmlVisitor(None, None), XmlVisitor) + self.assertIsInstance(self.visitor, XmlVisitor) + self.assertEqual(len(self.visitor.stack), 1) + + def test_dummyMethod(self): + with self.assertRaises(NotImplementedError): + self.visitor.event_prefix_tag(None) + + def test_visit(self): + rootElem = etree.Element('root') + dashedElem = etree.SubElement(rootElem, 'da-sh-ed') + defaultElem = etree.SubElement(rootElem, 'default') + self.visitor.visit(rootElem) + self.visitor.visit(dashedElem) + self.visitor.visit(defaultElem) + self.assertEqual(self.visitor.calls, [ + ( 'visit__root', ( rootElem, ), { } ), + ( 'visit__dashed', ( dashedElem, ), { } ), + ( 'visitDefault', ( defaultElem, ), { } ), + ]) + # TODO Tests with namespaces + + def test_depart(self): + rootElem = etree.Element('root') + defaultElem = etree.SubElement(rootElem, 'default') + self.visitor.depart(rootElem) + self.visitor.depart(defaultElem) + self.assertEqual(self.visitor.calls, [ + ( 'depart__root', ( rootElem, ), { } ), + ( 'departDefault', ( defaultElem, ), { } ), + ]) + + def test_stack(self): + self.assertIsInstance(self.visitor.push(docutils.nodes.Text('bla')), + docutils.nodes.document) + with self.assertRaises(AssertionError): + self.visitor.push(None) + self.assertIsInstance(self.visitor.pop(), docutils.nodes.Text) + self.assertIsInstance(self.visitor.pop(), docutils.nodes.document) + with self.assertRaises(IndexError): + self.visitor.pop() + +############################################################################### + +if __name__ == '__main__': + unittest.main() diff --git a/sandbox/docutils_xml/version.py b/sandbox/docutils_xml/version.py index b5e7c18f7..d4f4d8123 100644 --- a/sandbox/docutils_xml/version.py +++ b/sandbox/docutils_xml/version.py @@ -1 +1 @@ -version = '0.0' +version = '0.1.1' |