2 # -*- coding: utf-8 -*-
5 # Author: David Goodger <goodger@python.org>
6 # Copyright: This module has been placed in the public domain.
9 Test module for nodes.py.
13 from types
import ClassType
14 import DocutilsTestSupport
# must be imported before docutils
15 from DocutilsTestSupport
import nodes
, utils
20 class TextTests(unittest
.TestCase
):
23 self
.text
= nodes
.Text('Line 1.\nLine 2.')
24 self
.unicode_text
= nodes
.Text(unicode('Möhren', 'utf8'))
27 self
.assertEquals(repr(self
.text
), r
"<#text: 'Line 1.\nLine 2.'>")
30 self
.assertEquals(str(self
.text
), 'Line 1.\nLine 2.')
32 def test_unicode(self
):
33 self
.assertEquals(unicode(self
.unicode_text
), unicode('Möhren', 'utf8'))
34 self
.assertEquals(str(self
.unicode_text
), 'M\xf6hren')
36 def test_astext(self
):
37 self
.assertEquals(self
.text
.astext(), 'Line 1.\nLine 2.')
39 def test_pformat(self
):
40 self
.assertEquals(self
.text
.pformat(), 'Line 1.\nLine 2.\n')
42 def test_asciirestriction(self
):
43 self
.assertRaises(UnicodeError, nodes
.Text
, 'hol%s' % chr(224))
44 # more specifically: UnicodeDecodeError since py2.3
47 class ElementTests(unittest
.TestCase
):
50 element
= nodes
.Element()
51 self
.assertEquals(repr(element
), '<Element: >')
52 self
.assertEquals(str(element
), '<Element/>')
54 self
.assertEquals(dom
.toxml(), '<Element/>')
57 self
.assertEquals(repr(element
), '<Element: >')
58 self
.assertEquals(str(element
), '<Element attr="1"/>')
60 self
.assertEquals(dom
.toxml(), '<Element attr="1"/>')
62 self
.assertEquals(element
.pformat(), '<Element attr="1">\n')
64 element
['mark'] = u
'\u2022'
65 self
.assertEquals(repr(element
), '<Element: >')
66 self
.assertEquals(str(element
), '<Element mark="\\u2022"/>')
68 self
.assertEquals(dom
.toxml(), u
'<Element mark="\u2022"/>')
71 def test_withtext(self
):
72 element
= nodes
.Element('text\nmore', nodes
.Text('text\nmore'))
73 self
.assertEquals(repr(element
), r
"<Element: <#text: 'text\nmore'>>")
74 self
.assertEquals(str(element
), '<Element>text\nmore</Element>')
76 self
.assertEquals(dom
.toxml(), '<Element>text\nmore</Element>')
79 self
.assertEquals(repr(element
), r
"<Element: <#text: 'text\nmore'>>")
80 self
.assertEquals(str(element
),
81 '<Element attr="1">text\nmore</Element>')
83 self
.assertEquals(dom
.toxml(),
84 '<Element attr="1">text\nmore</Element>')
86 self
.assertEquals(element
.pformat(),
87 '<Element attr="1">\n text\n more\n')
90 element
= nodes
.Element()
91 element
+= nodes
.Element()
92 self
.assert_(len(element
))
94 self
.assert_(not len(element
))
96 def test_normal_attributes(self
):
97 element
= nodes
.Element()
98 self
.assert_('foo' not in element
)
99 self
.assertRaises(KeyError, element
.__getitem
__, 'foo')
100 element
['foo'] = 'sometext'
101 self
.assertEquals(element
['foo'], 'sometext')
103 self
.assertRaises(KeyError, element
.__getitem
__, 'foo')
105 def test_default_attributes(self
):
106 element
= nodes
.Element()
107 self
.assertEquals(element
['ids'], [])
108 self
.assertEquals(element
.non_default_attributes(), {})
109 self
.assert_(not element
.is_not_default('ids'))
110 self
.assert_(element
['ids'] is not nodes
.Element()['ids'])
111 element
['ids'].append('someid')
112 self
.assertEquals(element
['ids'], ['someid'])
113 self
.assertEquals(element
.non_default_attributes(),
115 self
.assert_(element
.is_not_default('ids'))
117 def test_update_basic_atts(self
):
118 element1
= nodes
.Element(ids
=['foo', 'bar'], test
=['test1'])
119 element2
= nodes
.Element(ids
=['baz', 'qux'], test
=['test2'])
120 element1
.update_basic_atts(element2
)
121 # 'ids' are appended because 'ids' is a basic attribute.
122 self
.assertEquals(element1
['ids'], ['foo', 'bar', 'baz', 'qux'])
123 # 'test' is not overwritten because it is not a basic attribute.
124 self
.assertEquals(element1
['test'], ['test1'])
126 def test_replace_self(self
):
127 parent
= nodes
.Element(ids
=['parent'])
128 child1
= nodes
.Element(ids
=['child1'])
129 grandchild
= nodes
.Element(ids
=['grandchild'])
131 child2
= nodes
.Element(ids
=['child2'])
132 twins
= [nodes
.Element(ids
=['twin%s' % i
]) for i
in (1, 2)]
134 child3
= nodes
.Element(ids
=['child3'])
135 child4
= nodes
.Element(ids
=['child4'])
136 parent
+= [child1
, child2
, child3
, child4
]
137 self
.assertEquals(parent
.pformat(), """\
138 <Element ids="parent">
139 <Element ids="child1">
140 <Element ids="grandchild">
141 <Element ids="child2">
142 <Element ids="twin1">
143 <Element ids="twin2">
144 <Element ids="child3">
145 <Element ids="child4">
147 # Replace child1 with the grandchild.
148 child1
.replace_self(child1
[0])
149 self
.assertEquals(parent
[0], grandchild
)
150 # Assert that 'ids' have been updated.
151 self
.assertEquals(grandchild
['ids'], ['grandchild', 'child1'])
152 # Replace child2 with its children.
153 child2
.replace_self(child2
[:])
154 self
.assertEquals(parent
[1:3], twins
)
155 # Assert that 'ids' have been propagated to first child.
156 self
.assertEquals(twins
[0]['ids'], ['twin1', 'child2'])
157 self
.assertEquals(twins
[1]['ids'], ['twin2'])
158 # Replace child3 with new child.
159 newchild
= nodes
.Element(ids
=['newchild'])
160 child3
.replace_self(newchild
)
161 self
.assertEquals(parent
[3], newchild
)
162 self
.assertEquals(newchild
['ids'], ['newchild', 'child3'])
163 # Crazy but possible case: Substitute child4 for itself.
164 child4
.replace_self(child4
)
165 # Make sure the 'child4' ID hasn't been duplicated.
166 self
.assertEquals(child4
['ids'], ['child4'])
167 self
.assertEquals(len(parent
), 5)
169 def test_unicode(self
):
170 node
= nodes
.Element(u
'Möhren', nodes
.Text(unicode('Möhren', 'utf8'),
171 unicode('Möhren', 'utf8')))
172 self
.assertEquals(unicode(node
), unicode('<Element>Möhren</Element>',
176 class MiscTests(unittest
.TestCase
):
178 def test_node_class_names(self
):
179 node_class_names
= []
181 c
= getattr(nodes
, x
)
182 if isinstance(c
, (type, ClassType
)) and issubclass(c
, nodes
.Node
) \
183 and len(c
.__bases
__) > 1:
184 node_class_names
.append(x
)
185 node_class_names
.sort()
186 nodes
.node_class_names
.sort()
187 self
.assertEquals(node_class_names
, nodes
.node_class_names
)
189 ids
= [('a', 'a'), ('A', 'a'), ('', ''), ('a b \n c', 'a-b-c'),
190 ('a.b.c', 'a-b-c'), (' - a - b - c - ', 'a-b-c'), (' - ', ''),
191 (u
'\u2020\u2066', ''), (u
'a \xa7 b \u2020 c', 'a-b-c'),
192 ('1', ''), ('1abc', 'abc')]
194 def test_make_id(self
):
195 for input, output
in self
.ids
:
196 normed
= nodes
.make_id(input)
197 self
.assertEquals(normed
, output
)
199 def test_traverse(self
):
202 e
[0] += nodes
.Element()
203 e
[0] += nodes
.TextElement()
204 e
[0][1] += nodes
.Text('some text')
207 self
.assertEquals(list(e
.traverse()),
208 [e
, e
[0], e
[0][0], e
[0][1], e
[0][1][0], e
[1], e
[2]])
209 self
.assertEquals(list(e
.traverse(include_self
=0)),
210 [e
[0], e
[0][0], e
[0][1], e
[0][1][0], e
[1], e
[2]])
211 self
.assertEquals(list(e
.traverse(descend
=0)),
213 self
.assertEquals(list(e
[0].traverse(descend
=0, ascend
=1)),
215 self
.assertEquals(list(e
[0][0].traverse(descend
=0, ascend
=1)),
216 [e
[0][0], e
[0][1], e
[1], e
[2]])
217 self
.assertEquals(list(e
[0][0].traverse(descend
=0, siblings
=1)),
219 self
.testlist
= e
[0:2]
220 self
.assertEquals(list(e
.traverse(condition
=self
.not_in_testlist
)),
221 [e
, e
[0][0], e
[0][1], e
[0][1][0], e
[2]])
222 # Return siblings despite siblings=0 because ascend is true.
223 self
.assertEquals(list(e
[1].traverse(ascend
=1, siblings
=0)),
225 self
.assertEquals(list(e
[0].traverse()),
226 [e
[0], e
[0][0], e
[0][1], e
[0][1][0]])
227 self
.testlist
= [e
[0][0], e
[0][1]]
228 self
.assertEquals(list(e
[0].traverse(condition
=self
.not_in_testlist
)),
230 self
.testlist
.append(e
[0][1][0])
231 self
.assertEquals(list(e
[0].traverse(condition
=self
.not_in_testlist
)),
233 self
.assertEquals(list(e
.traverse(nodes
.TextElement
)), [e
[0][1]])
235 def test_next_node(self
):
238 e
[0] += nodes
.Element()
239 e
[0] += nodes
.TextElement()
240 e
[0][1] += nodes
.Text('some text')
243 self
.testlist
= [e
[0], e
[0][1], e
[1]]
244 compare
= [(e
, e
[0][0]),
246 (e
[0][0], e
[0][1][0]),
247 (e
[0][1], e
[0][1][0]),
251 for node
, next_node
in compare
:
252 self
.assertEquals(node
.next_node(self
.not_in_testlist
, ascend
=1),
254 self
.assertEquals(e
[0][0].next_node(ascend
=1), e
[0][1])
255 self
.assertEquals(e
[2].next_node(), None)
257 def not_in_testlist(self
, x
):
258 return x
not in self
.testlist
261 grandchild
= nodes
.Text('rawsource')
262 child
= nodes
.emphasis('rawsource', grandchild
, att
='child')
263 e
= nodes
.Element('rawsource', child
, att
='e')
266 self
.assert_(e
is not e_copy
)
267 # Internal attributes (like `rawsource`) are not copied.
268 self
.assertEquals(e
.rawsource
, 'rawsource')
269 self
.assertEquals(e_copy
.rawsource
, '')
270 self
.assertEquals(e_copy
['att'], 'e')
271 # Children are not copied.
272 self
.assertEquals(len(e_copy
), 0)
274 e_deepcopy
= e
.deepcopy()
275 self
.assertEquals(e_deepcopy
.rawsource
, '')
276 self
.assertEquals(e_deepcopy
['att'], 'e')
277 # Children are copied recursively.
278 self
.assertEquals(e_deepcopy
[0][0], grandchild
)
279 self
.assert_(e_deepcopy
[0][0] is not grandchild
)
280 self
.assertEquals(e_deepcopy
[0]['att'], 'child')
283 class TreeCopyVisitorTests(unittest
.TestCase
):
286 document
= utils
.new_document('test data')
287 document
+= nodes
.paragraph('', 'Paragraph 1.')
288 blist
= nodes
.bullet_list()
289 for i
in range(1, 6):
290 item
= nodes
.list_item()
291 for j
in range(1, 4):
292 item
+= nodes
.paragraph('', 'Item %s, paragraph %s.' % (i
, j
))
295 self
.document
= document
297 def compare_trees(self
, one
, two
):
298 self
.assertEquals(one
.__class
__, two
.__class
__)
299 self
.assertNotEquals(id(one
), id(two
))
300 self
.assertEquals(len(one
.children
), len(two
.children
))
301 for i
in range(len(one
.children
)):
302 self
.compare_trees(one
.children
[i
], two
.children
[i
])
304 def test_copy_whole(self
):
305 visitor
= nodes
.TreeCopyVisitor(self
.document
)
306 self
.document
.walkabout(visitor
)
307 newtree
= visitor
.get_tree_copy()
308 self
.assertEquals(self
.document
.pformat(), newtree
.pformat())
309 self
.compare_trees(self
.document
, newtree
)
312 class MiscFunctionTests(unittest
.TestCase
):
314 names
= [('a', 'a'), ('A', 'a'), ('A a A', 'a a a'),
315 ('A a A a', 'a a a a'),
316 (' AaA\n\r\naAa\tAaA\t\t', 'aaa aaa aaa')]
318 def test_normalize_name(self
):
319 for input, output
in self
.names
:
320 normed
= nodes
.fully_normalize_name(input)
321 self
.assertEquals(normed
, output
)
323 def test_set_id_default(self
):
325 document
= utils
.new_document('test')
327 element
= nodes
.Element(names
=['test'])
328 document
.set_id(element
)
329 self
.assertEquals(element
['ids'], ['test'])
331 element
= nodes
.Element()
332 document
.set_id(element
)
333 self
.assertEquals(element
['ids'], ['id1'])
335 def test_set_id_custom(self
):
337 document
= utils
.new_document('test')
339 document
.settings
.id_prefix
= 'prefix'
340 document
.settings
.auto_id_prefix
= 'auto'
342 element
= nodes
.Element(names
=['test'])
343 document
.set_id(element
)
344 self
.assertEquals(element
['ids'], ['prefixtest'])
346 element
= nodes
.Element()
347 document
.set_id(element
)
348 self
.assertEquals(element
['ids'], ['prefixauto1'])
351 if __name__
== '__main__':