1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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, Uri2Prefixes
###############################################################################
class XmlVisitorMock(XmlVisitor):
"""
Mock class recording calls.
"""
def __init__(self, uri2Prefixes, 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, uri2Prefixes, 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(Uri2Prefixes(( )),
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()
|