summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsmerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2013-11-20 01:00:45 +0000
committersmerten <smerten@929543f6-e4f2-0310-98a6-ba3bd3dd1d04>2013-11-20 01:00:45 +0000
commit72e1dd03e1f4910c9724722150fa86a6b140a518 (patch)
treeafe0370a2f51fb433634ac9a490c66b1b6678e26
parentc30948c3cf01caa70300099c39a2a40aaa2ea74a (diff)
downloaddocutils-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.py27
-rw-r--r--sandbox/docutils_xml/global.log363
-rw-r--r--sandbox/docutils_xml/tag.log2
-rw-r--r--sandbox/docutils_xml/test/test_parsers/__init__.py14
-rw-r--r--sandbox/docutils_xml/test/test_parsers/test_XmlParser.py332
-rw-r--r--sandbox/docutils_xml/test/test_parsers/test_XmlVisitor.py129
-rw-r--r--sandbox/docutils_xml/version.py2
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'