Mercurial > genshi > genshi-test
annotate genshi/tests/path.py @ 818:eab11d35c769
Merged soc2008-xpath branch back into trunk.
author | cmlenz |
---|---|
date | Wed, 11 Mar 2009 17:03:03 +0000 |
parents | 8bcd86cd6c10 |
children | 7ad34db77566 |
rev | line source |
---|---|
1 | 1 # -*- coding: utf-8 -*- |
2 # | |
66
822089ae65ce
Switch copyright to Edgewall and URLs to markup.edgewall.org.
cmlenz
parents:
38
diff
changeset
|
3 # Copyright (C) 2006 Edgewall Software |
1 | 4 # All rights reserved. |
5 # | |
6 # This software is licensed as described in the file COPYING, which | |
7 # you should have received as part of this distribution. The terms | |
230 | 8 # are also available at http://genshi.edgewall.org/wiki/License. |
1 | 9 # |
10 # This software consists of voluntary contributions made by many | |
11 # individuals. For the exact contribution history, see the revision | |
230 | 12 # history and logs, available at http://genshi.edgewall.org/log/. |
1 | 13 |
14 import doctest | |
15 import unittest | |
16 | |
230 | 17 from genshi.input import XML |
818 | 18 from genshi.path import Path, PathParser, PathSyntaxError, GenericStrategy, \ |
19 SingleStepStrategy, SimplePathStrategy | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
20 |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
21 |
818 | 22 class FakePath(Path): |
23 def __init__(self, strategy): | |
24 self.strategy = strategy | |
25 def test(self, ignore_context = False): | |
26 return self.strategy.test(ignore_context) | |
27 | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
28 class PathTestCase(unittest.TestCase): |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
29 |
818 | 30 strategies = [GenericStrategy, SingleStepStrategy, SimplePathStrategy] |
31 def _create_path(self, expression, expected): | |
32 return path | |
33 | |
34 def _test_strategies(self, stream, path, render, | |
35 namespaces=None, variables=None): | |
36 for strategy in self.strategies: | |
37 if not strategy.supports(path): | |
38 continue | |
39 s = strategy(path) | |
40 rendered = FakePath(s).select(stream,namespaces=namespaces, | |
41 variables=variables).render() | |
42 msg = "Bad render using %s strategy"%str(strategy) | |
43 msg += "\nExpected:\t'%s'"%render | |
44 msg += "\nRendered:\t'%s'"%rendered | |
45 self.assertEqual(render, rendered, msg) | |
46 | |
47 def _test_expression(self, text, expected, stream=None, render="", | |
48 namespaces=None, variables=None): | |
49 path = Path(text) | |
50 if expected is not None: | |
51 self.assertEqual(expected, repr(path)) | |
52 | |
53 if stream is None: | |
54 return | |
55 | |
56 rendered = path.select(stream, namespaces=namespaces, | |
57 variables=variables).render() | |
58 msg = "Bad render using whole path" | |
59 msg += "\nExpected:\t'%s'"%render | |
60 msg += "\nRendered:\t'%s'"%rendered | |
61 self.assertEqual(render, rendered, msg) | |
62 | |
63 if len(path.paths) == 1: | |
64 self._test_strategies(stream, path.paths[0], render, | |
65 namespaces=namespaces, variables=variables) | |
66 | |
67 | |
111
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
68 def test_error_no_absolute_path(self): |
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
69 self.assertRaises(PathSyntaxError, Path, '/root') |
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
70 |
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
71 def test_error_unsupported_axis(self): |
137 | 72 self.assertRaises(PathSyntaxError, Path, '..') |
111
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
73 self.assertRaises(PathSyntaxError, Path, 'parent::ma') |
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
74 |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
75 def test_1step(self): |
38
fec9f4897415
Fix for #2 (incorrect context node in path expressions). Still some paths that produce incorrect results, but the common case seems to work now.
cmlenz
parents:
27
diff
changeset
|
76 xml = XML('<root><elem/></root>') |
137 | 77 |
818 | 78 self._test_expression( 'elem', |
79 '<Path "child::elem">', | |
80 xml, | |
81 '<elem/>') | |
137 | 82 |
818 | 83 self._test_expression( 'elem', |
84 '<Path "child::elem">', | |
85 xml, | |
86 '<elem/>') | |
137 | 87 |
818 | 88 self._test_expression( 'child::elem', |
89 '<Path "child::elem">', | |
90 xml, | |
91 '<elem/>') | |
92 | |
93 self._test_expression( '//elem', | |
94 '<Path "descendant-or-self::elem">', | |
95 xml, | |
96 '<elem/>') | |
97 | |
98 self._test_expression( 'descendant::elem', | |
99 '<Path "descendant::elem">', | |
100 xml, | |
101 '<elem/>') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
102 |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
103 def test_1step_self(self): |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
104 xml = XML('<root><elem/></root>') |
137 | 105 |
818 | 106 self._test_expression( '.', |
107 '<Path "self::node()">', | |
108 xml, | |
109 '<root><elem/></root>') | |
137 | 110 |
818 | 111 self._test_expression( 'self::node()', |
112 '<Path "self::node()">', | |
113 xml, | |
114 '<root><elem/></root>') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
115 |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
116 def test_1step_wildcard(self): |
38
fec9f4897415
Fix for #2 (incorrect context node in path expressions). Still some paths that produce incorrect results, but the common case seems to work now.
cmlenz
parents:
27
diff
changeset
|
117 xml = XML('<root><elem/></root>') |
137 | 118 |
818 | 119 self._test_expression( '*', |
120 '<Path "child::*">', | |
121 xml, | |
122 '<elem/>') | |
137 | 123 |
818 | 124 self._test_expression( 'child::*', |
125 '<Path "child::*">', | |
126 xml, | |
127 '<elem/>') | |
137 | 128 |
818 | 129 self._test_expression( 'child::node()', |
130 '<Path "child::node()">', | |
131 xml, | |
132 '<elem/>') | |
133 | |
134 self._test_expression( '//*', | |
135 '<Path "descendant-or-self::*">', | |
136 xml, | |
137 '<root><elem/></root>') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
138 |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
139 def test_1step_attribute(self): |
818 | 140 self._test_expression( '@foo', |
141 '<Path "attribute::foo">', | |
142 XML('<root/>'), | |
143 '') | |
138 | 144 |
111
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
145 xml = XML('<root foo="bar"/>') |
138 | 146 |
818 | 147 self._test_expression( '@foo', |
148 '<Path "attribute::foo">', | |
149 xml, | |
150 'bar') | |
151 | |
152 self._test_expression( './@foo', | |
153 '<Path "self::node()/attribute::foo">', | |
154 xml, | |
155 'bar') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
156 |
111
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
157 def test_1step_text(self): |
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
158 xml = XML('<root>Hey</root>') |
138 | 159 |
818 | 160 self._test_expression( 'text()', |
161 '<Path "child::text()">', | |
162 xml, | |
163 'Hey') | |
138 | 164 |
818 | 165 self._test_expression( './text()', |
166 '<Path "self::node()/child::text()">', | |
167 xml, | |
168 'Hey') | |
138 | 169 |
818 | 170 self._test_expression( '//text()', |
171 '<Path "descendant-or-self::text()">', | |
172 xml, | |
173 'Hey') | |
174 | |
175 self._test_expression( './/text()', | |
176 '<Path "self::node()/descendant-or-self::node()/child::text()">', | |
177 xml, | |
178 'Hey') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
179 |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
180 def test_2step(self): |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
181 xml = XML('<root><foo/><bar/></root>') |
818 | 182 self._test_expression('*', None, xml, '<foo/><bar/>') |
183 self._test_expression('bar', None, xml, '<bar/>') | |
184 self._test_expression('baz', None, xml, '') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
185 |
145
56d534eb53f9
* Fix error in expression evaluation when the expression evaluates to an iterable that does not produce event tuples.
cmlenz
parents:
138
diff
changeset
|
186 def test_2step_attribute(self): |
56d534eb53f9
* Fix error in expression evaluation when the expression evaluates to an iterable that does not produce event tuples.
cmlenz
parents:
138
diff
changeset
|
187 xml = XML('<elem class="x"><span id="joe">Hey Joe</span></elem>') |
818 | 188 self._test_expression('@*', None, xml, 'x') |
189 self._test_expression('./@*', None, xml, 'x') | |
190 self._test_expression('.//@*', None, xml, 'xjoe') | |
191 self._test_expression('*/@*', None, xml, 'joe') | |
145
56d534eb53f9
* Fix error in expression evaluation when the expression evaluates to an iterable that does not produce event tuples.
cmlenz
parents:
138
diff
changeset
|
192 |
215 | 193 xml = XML('<elem><foo id="1"/><foo id="2"/></elem>') |
818 | 194 self._test_expression('@*', None, xml, '') |
195 self._test_expression('foo/@*', None, xml, '12') | |
145
56d534eb53f9
* Fix error in expression evaluation when the expression evaluates to an iterable that does not produce event tuples.
cmlenz
parents:
138
diff
changeset
|
196 |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
197 def test_2step_complex(self): |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
198 xml = XML('<root><foo><bar/></foo></root>') |
138 | 199 |
818 | 200 self._test_expression( 'foo/bar', |
201 '<Path "child::foo/child::bar">', | |
202 xml, | |
203 '<bar/>') | |
138 | 204 |
818 | 205 self._test_expression( './bar', |
206 '<Path "self::node()/child::bar">', | |
207 xml, | |
208 '') | |
145
56d534eb53f9
* Fix error in expression evaluation when the expression evaluates to an iterable that does not produce event tuples.
cmlenz
parents:
138
diff
changeset
|
209 |
818 | 210 self._test_expression( 'foo/*', |
211 '<Path "child::foo/child::*">', | |
212 xml, | |
213 '<bar/>') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
214 |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
215 xml = XML('<root><foo><bar id="1"/></foo><bar id="2"/></root>') |
818 | 216 self._test_expression( './bar', |
217 '<Path "self::node()/child::bar">', | |
218 xml, | |
219 '<bar id="2"/>') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
220 |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
221 def test_2step_text(self): |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
222 xml = XML('<root><item>Foo</item></root>') |
138 | 223 |
818 | 224 self._test_expression( 'item/text()', |
225 '<Path "child::item/child::text()">', | |
226 xml, | |
227 'Foo') | |
138 | 228 |
818 | 229 self._test_expression( '*/text()', |
230 '<Path "child::*/child::text()">', | |
231 xml, | |
232 'Foo') | |
138 | 233 |
818 | 234 self._test_expression( '//text()', |
235 '<Path "descendant-or-self::text()">', | |
236 xml, | |
237 'Foo') | |
238 | |
239 self._test_expression( './text()', | |
240 '<Path "self::node()/child::text()">', | |
241 xml, | |
242 '') | |
145
56d534eb53f9
* Fix error in expression evaluation when the expression evaluates to an iterable that does not produce event tuples.
cmlenz
parents:
138
diff
changeset
|
243 |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
244 xml = XML('<root><item>Foo</item><item>Bar</item></root>') |
818 | 245 self._test_expression( 'item/text()', |
246 '<Path "child::item/child::text()">', | |
247 xml, | |
248 'FooBar') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
249 |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
250 def test_3step(self): |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
251 xml = XML('<root><foo><bar/></foo></root>') |
818 | 252 self._test_expression( 'foo/*', |
253 '<Path "child::foo/child::*">', | |
254 xml, | |
255 '<bar/>') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
256 |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
257 def test_3step_complex(self): |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
258 xml = XML('<root><foo><bar/></foo></root>') |
818 | 259 self._test_expression( '*/bar', |
260 '<Path "child::*/child::bar">', | |
261 xml, | |
262 '<bar/>') | |
138 | 263 |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
264 xml = XML('<root><foo><bar id="1"/></foo><bar id="2"/></root>') |
818 | 265 self._test_expression( '//bar', |
266 '<Path "descendant-or-self::bar">', | |
267 xml, | |
268 '<bar id="1"/><bar id="2"/>') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
269 |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
270 def test_node_type_comment(self): |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
271 xml = XML('<root><!-- commented --></root>') |
818 | 272 self._test_expression( 'comment()', |
273 '<Path "child::comment()">', | |
274 xml, | |
275 '<!-- commented -->') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
276 |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
277 def test_node_type_text(self): |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
278 xml = XML('<root>Some text <br/>in here.</root>') |
818 | 279 self._test_expression( 'text()', |
280 '<Path "child::text()">', | |
281 xml, | |
282 'Some text in here.') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
283 |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
284 def test_node_type_node(self): |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
285 xml = XML('<root>Some text <br/>in here.</root>') |
818 | 286 self._test_expression( 'node()', |
287 '<Path "child::node()">', | |
288 xml, | |
289 'Some text <br/>in here.',) | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
290 |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
291 def test_node_type_processing_instruction(self): |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
292 xml = XML('<?python x = 2 * 3 ?><root><?php echo("x") ?></root>') |
138 | 293 |
818 | 294 self._test_expression( '//processing-instruction()', |
295 '<Path "descendant-or-self::processing-instruction()">', | |
296 xml, | |
297 '<?python x = 2 * 3 ?><?php echo("x") ?>') | |
138 | 298 |
818 | 299 self._test_expression( 'processing-instruction()', |
300 '<Path "child::processing-instruction()">', | |
301 xml, | |
302 '<?php echo("x") ?>') | |
303 | |
304 self._test_expression( 'processing-instruction("php")', | |
305 '<Path "child::processing-instruction(\"php\")">', | |
306 xml, | |
307 '<?php echo("x") ?>') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
308 |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
309 def test_simple_union(self): |
259
6f11ad260890
Fix bug in evaluating XPath expressions using the union operator `|`, which caused any path but the first to get out of sync with the event stream, and the whole thing returning too few results.
cmlenz
parents:
234
diff
changeset
|
310 xml = XML("""<body>1<br />2<br />3<br /></body>""") |
818 | 311 self._test_expression( '*|text()', |
312 '<Path "child::*|child::text()">', | |
313 xml, | |
314 '1<br/>2<br/>3<br/>') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
315 |
121
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
316 def test_predicate_name(self): |
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
317 xml = XML('<root><foo/><bar/></root>') |
818 | 318 self._test_expression('*[name()="foo"]', None, xml, '<foo/>') |
121
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
319 |
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
320 def test_predicate_localname(self): |
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
321 xml = XML('<root><foo xmlns="NS"/><bar/></root>') |
818 | 322 self._test_expression('*[local-name()="foo"]', None, xml, |
323 '<foo xmlns="NS"/>') | |
121
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
324 |
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
325 def test_predicate_namespace(self): |
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
326 xml = XML('<root><foo xmlns="NS"/><bar/></root>') |
818 | 327 self._test_expression('*[namespace-uri()="NS"]', None, xml, |
328 '<foo xmlns="NS"/>') | |
121
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
329 |
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
330 def test_predicate_not_name(self): |
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
331 xml = XML('<root><foo/><bar/></root>') |
818 | 332 self._test_expression('*[not(name()="foo")]', None, xml, '<bar/>') |
121
22a7080ed242
Added support for the XPath functions `name()`, `namespace-uri()`, `local-name()`, and `not()`.
cmlenz
parents:
111
diff
changeset
|
333 |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
334 def test_predicate_attr(self): |
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
335 xml = XML('<root><item/><item important="very"/></root>') |
818 | 336 self._test_expression('item[@important]', None, xml, |
337 '<item important="very"/>') | |
338 self._test_expression('item[@important="very"]', None, xml, | |
339 '<item important="very"/>') | |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
340 |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
341 def test_predicate_attr_equality(self): |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
342 xml = XML('<root><item/><item important="notso"/></root>') |
818 | 343 self._test_expression('item[@important="very"]', None, xml, '') |
344 self._test_expression('item[@important!="very"]', None, xml, | |
345 '<item/><item important="notso"/>') | |
162
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
346 |
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
347 def test_predicate_attr_greater_than(self): |
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
348 xml = XML('<root><item priority="3"/></root>') |
818 | 349 self._test_expression('item[@priority>3]', None, xml, '') |
350 self._test_expression('item[@priority>2]', None, xml, | |
351 '<item priority="3"/>') | |
162
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
352 |
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
353 def test_predicate_attr_less_than(self): |
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
354 xml = XML('<root><item priority="3"/></root>') |
818 | 355 self._test_expression('item[@priority<3]', None, xml, '') |
356 self._test_expression('item[@priority<4]', None, xml, | |
357 '<item priority="3"/>') | |
1 | 358 |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
359 def test_predicate_attr_and(self): |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
360 xml = XML('<root><item/><item important="very"/></root>') |
818 | 361 self._test_expression('item[@important and @important="very"]', |
362 None, xml, '<item important="very"/>') | |
363 self._test_expression('item[@important and @important="notso"]', | |
364 None, xml, '') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
365 |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
366 def test_predicate_attr_or(self): |
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
367 xml = XML('<root><item/><item important="very"/></root>') |
818 | 368 self._test_expression('item[@urgent or @important]', None, xml, |
369 '<item important="very"/>') | |
370 self._test_expression('item[@urgent or @notso]', None, xml, '') | |
106
61fa4cadb766
Complete rewrite of the XPath parsing, which was a mess before. Closes #19.
cmlenz
parents:
66
diff
changeset
|
371 |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
372 def test_predicate_boolean_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
373 xml = XML('<root><foo>bar</foo></root>') |
818 | 374 self._test_expression('*[boolean("")]', None, xml, '') |
375 self._test_expression('*[boolean("yo")]', None, xml, '<foo>bar</foo>') | |
376 self._test_expression('*[boolean(0)]', None, xml, '') | |
377 self._test_expression('*[boolean(42)]', None, xml, '<foo>bar</foo>') | |
378 self._test_expression('*[boolean(false())]', None, xml, '') | |
379 self._test_expression('*[boolean(true())]', None, xml, | |
380 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
381 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
382 def test_predicate_ceil_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
383 xml = XML('<root><foo>bar</foo></root>') |
818 | 384 self._test_expression('*[ceiling("4.5")=5]', None, xml, |
385 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
386 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
387 def test_predicate_concat_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
388 xml = XML('<root><foo>bar</foo></root>') |
818 | 389 self._test_expression('*[name()=concat("f", "oo")]', None, xml, |
390 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
391 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
392 def test_predicate_contains_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
393 xml = XML('<root><foo>bar</foo></root>') |
818 | 394 self._test_expression('*[contains(name(), "oo")]', None, xml, |
395 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
396 |
534
cccb6c748609
Add XPath `matches()` function which, of course, supports the Python regular
athomas
parents:
413
diff
changeset
|
397 def test_predicate_matches_function(self): |
cccb6c748609
Add XPath `matches()` function which, of course, supports the Python regular
athomas
parents:
413
diff
changeset
|
398 xml = XML('<root><foo>bar</foo><bar>foo</bar></root>') |
818 | 399 self._test_expression('*[matches(name(), "foo|bar")]', None, xml, |
400 '<foo>bar</foo><bar>foo</bar>') | |
534
cccb6c748609
Add XPath `matches()` function which, of course, supports the Python regular
athomas
parents:
413
diff
changeset
|
401 |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
402 def test_predicate_false_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
403 xml = XML('<root><foo>bar</foo></root>') |
818 | 404 self._test_expression('*[false()]', None, xml, '') |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
405 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
406 def test_predicate_floor_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
407 xml = XML('<root><foo>bar</foo></root>') |
818 | 408 self._test_expression('*[floor("4.5")=4]', None, xml, |
409 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
410 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
411 def test_predicate_normalize_space_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
412 xml = XML('<root><foo>bar</foo></root>') |
818 | 413 self._test_expression('*[normalize-space(" foo bar ")="foo bar"]', |
414 None, xml, '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
415 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
416 def test_predicate_number_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
417 xml = XML('<root><foo>bar</foo></root>') |
818 | 418 self._test_expression('*[number("3.0")=3]', None, xml, |
419 '<foo>bar</foo>') | |
420 self._test_expression('*[number("3.0")=3.0]', None, xml, | |
421 '<foo>bar</foo>') | |
422 self._test_expression('*[number("0.1")=.1]', None, xml, | |
423 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
424 |
162
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
425 def test_predicate_round_function(self): |
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
426 xml = XML('<root><foo>bar</foo></root>') |
818 | 427 self._test_expression('*[round("4.4")=4]', None, xml, |
428 '<foo>bar</foo>') | |
429 self._test_expression('*[round("4.6")=5]', None, xml, | |
430 '<foo>bar</foo>') | |
162
f767cf98e3e3
Implement the XPath relational operators and the `round()` function.
cmlenz
parents:
155
diff
changeset
|
431 |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
432 def test_predicate_starts_with_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
433 xml = XML('<root><foo>bar</foo></root>') |
818 | 434 self._test_expression('*[starts-with(name(), "f")]', None, xml, |
435 '<foo>bar</foo>') | |
436 self._test_expression('*[starts-with(name(), "b")]', None, xml, '') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
437 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
438 def test_predicate_string_length_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
439 xml = XML('<root><foo>bar</foo></root>') |
818 | 440 self._test_expression('*[string-length(name())=3]', None, xml, |
441 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
442 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
443 def test_predicate_substring_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
444 xml = XML('<root><foo>bar</foo></root>') |
818 | 445 self._test_expression('*[substring(name(), 1)="oo"]', None, xml, |
446 '<foo>bar</foo>') | |
447 self._test_expression('*[substring(name(), 1, 1)="o"]', None, xml, | |
448 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
449 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
450 def test_predicate_substring_after_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
451 xml = XML('<root><foo>bar</foo></root>') |
818 | 452 self._test_expression('*[substring-after(name(), "f")="oo"]', None, xml, |
453 '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
454 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
455 def test_predicate_substring_before_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
456 xml = XML('<root><foo>bar</foo></root>') |
818 | 457 self._test_expression('*[substring-before(name(), "oo")="f"]', |
458 None, xml, '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
459 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
460 def test_predicate_translate_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
461 xml = XML('<root><foo>bar</foo></root>') |
818 | 462 self._test_expression('*[translate(name(), "fo", "ba")="baa"]', |
463 None, xml, '<foo>bar</foo>') | |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
464 |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
465 def test_predicate_true_function(self): |
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
466 xml = XML('<root><foo>bar</foo></root>') |
818 | 467 self._test_expression('*[true()]', None, xml, '<foo>bar</foo>') |
155
50d4b08017df
* String literals in XPath expressions that contains spaces are now tokenizes correctly.
cmlenz
parents:
145
diff
changeset
|
468 |
179
a2e0a7986d19
Implemented support for XPath variables in predicates (#31).
cmlenz
parents:
164
diff
changeset
|
469 def test_predicate_variable(self): |
a2e0a7986d19
Implemented support for XPath variables in predicates (#31).
cmlenz
parents:
164
diff
changeset
|
470 xml = XML('<root><foo>bar</foo></root>') |
a2e0a7986d19
Implemented support for XPath variables in predicates (#31).
cmlenz
parents:
164
diff
changeset
|
471 variables = {'bar': 'foo'} |
818 | 472 self._test_expression('*[name()=$bar]', None, xml, '<foo>bar</foo>', |
473 variables = variables) | |
224
e4dad1145f84
Implement support for namespace prefixes in XPath expressions.
cmlenz
parents:
216
diff
changeset
|
474 |
228
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
475 def test_predicate_position(self): |
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
476 xml = XML('<root><foo id="a1"/><foo id="a2"/><foo id="a3"/></root>') |
818 | 477 self._test_expression('*[2]', None, xml, '<foo id="a2"/>') |
228
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
478 |
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
479 def test_predicate_attr_and_position(self): |
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
480 xml = XML('<root><foo/><foo id="a1"/><foo id="a2"/></root>') |
818 | 481 self._test_expression('*[@id][2]', None, xml, '<foo id="a2"/>') |
228
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
482 |
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
483 def test_predicate_position_and_attr(self): |
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
484 xml = XML('<root><foo/><foo id="a1"/><foo id="a2"/></root>') |
818 | 485 self._test_expression('*[1][@id]', None, xml, '') |
486 self._test_expression('*[2][@id]', None, xml, '<foo id="a1"/>') | |
487 | |
488 def test_predicate_advanced_position(self): | |
489 xml = XML('<root><a><b><c><d><e/></d></c></b></a></root>') | |
490 self._test_expression( 'descendant-or-self::*/' | |
491 'descendant-or-self::*/' | |
492 'descendant-or-self::*[2]/' | |
493 'self::*/descendant::*[3]', None, xml, | |
494 '<d><e/></d>') | |
495 | |
496 def test_predicate_child_position(self): | |
497 xml = XML('\ | |
498 <root><a><b>1</b><b>2</b><b>3</b></a><a><b>4</b><b>5</b></a></root>') | |
499 self._test_expression('//a/b[2]', None, xml, '<b>2</b><b>5</b>') | |
500 self._test_expression('//a/b[3]', None, xml, '<b>3</b>') | |
228
f79b20a50919
Add support for position predicates in XPath expressions.
cmlenz
parents:
224
diff
changeset
|
501 |
224
e4dad1145f84
Implement support for namespace prefixes in XPath expressions.
cmlenz
parents:
216
diff
changeset
|
502 def test_name_with_namespace(self): |
e4dad1145f84
Implement support for namespace prefixes in XPath expressions.
cmlenz
parents:
216
diff
changeset
|
503 xml = XML('<root xmlns:f="FOO"><f:foo>bar</f:foo></root>') |
818 | 504 self._test_expression('f:foo', '<Path "child::f:foo">', xml, |
505 '<foo xmlns="FOO">bar</foo>', | |
506 namespaces = {'f': 'FOO'}) | |
224
e4dad1145f84
Implement support for namespace prefixes in XPath expressions.
cmlenz
parents:
216
diff
changeset
|
507 |
e4dad1145f84
Implement support for namespace prefixes in XPath expressions.
cmlenz
parents:
216
diff
changeset
|
508 def test_wildcard_with_namespace(self): |
e4dad1145f84
Implement support for namespace prefixes in XPath expressions.
cmlenz
parents:
216
diff
changeset
|
509 xml = XML('<root xmlns:f="FOO"><f:foo>bar</f:foo></root>') |
818 | 510 self._test_expression('f:*', '<Path "child::f:*">', xml, |
511 '<foo xmlns="FOO">bar</foo>', | |
512 namespaces = {'f': 'FOO'}) | |
224
e4dad1145f84
Implement support for namespace prefixes in XPath expressions.
cmlenz
parents:
216
diff
changeset
|
513 |
384 | 514 def test_predicate_termination(self): |
515 """ | |
516 Verify that a patch matching the self axis with a predicate doesn't | |
517 cause an infinite loop. See <http://genshi.edgewall.org/ticket/82>. | |
518 """ | |
519 xml = XML('<ul flag="1"><li>a</li><li>b</li></ul>') | |
818 | 520 self._test_expression('.[@flag="1"]/*', None, xml, |
521 '<li>a</li><li>b</li>') | |
384 | 522 |
523 xml = XML('<ul flag="1"><li>a</li><li>b</li></ul>') | |
818 | 524 self._test_expression('.[@flag="0"]/*', None, xml, '') |
384 | 525 |
410
3460b04daeac
Improve the handling of namespaces in serialization.
cmlenz
parents:
384
diff
changeset
|
526 def test_attrname_with_namespace(self): |
3460b04daeac
Improve the handling of namespaces in serialization.
cmlenz
parents:
384
diff
changeset
|
527 xml = XML('<root xmlns:f="FOO"><foo f:bar="baz"/></root>') |
818 | 528 self._test_expression('foo[@f:bar]', None, xml, |
529 '<foo xmlns:ns1="FOO" ns1:bar="baz"/>', | |
530 namespaces={'f': 'FOO'}) | |
410
3460b04daeac
Improve the handling of namespaces in serialization.
cmlenz
parents:
384
diff
changeset
|
531 |
3460b04daeac
Improve the handling of namespaces in serialization.
cmlenz
parents:
384
diff
changeset
|
532 def test_attrwildcard_with_namespace(self): |
3460b04daeac
Improve the handling of namespaces in serialization.
cmlenz
parents:
384
diff
changeset
|
533 xml = XML('<root xmlns:f="FOO"><foo f:bar="baz"/></root>') |
818 | 534 self._test_expression('foo[@f:*]', None, xml, |
535 '<foo xmlns:ns1="FOO" ns1:bar="baz"/>', | |
536 namespaces={'f': 'FOO'}) | |
537 def test_self_and_descendant(self): | |
538 xml = XML('<root><foo/></root>') | |
539 self._test_expression('self::root', None, xml, '<root><foo/></root>') | |
540 self._test_expression('self::foo', None, xml, '') | |
541 self._test_expression('descendant::root', None, xml, '') | |
542 self._test_expression('descendant::foo', None, xml, '<foo/>') | |
543 self._test_expression('descendant-or-self::root', None, xml, | |
544 '<root><foo/></root>') | |
545 self._test_expression('descendant-or-self::foo', None, xml, '<foo/>') | |
179
a2e0a7986d19
Implemented support for XPath variables in predicates (#31).
cmlenz
parents:
164
diff
changeset
|
546 |
818 | 547 def test_long_simple_paths(self): |
548 xml = XML('<root><a><b><a><d><a><b><a><b><a><b><a><c>!' | |
549 '</c></a></b></a></b></a></b></a></d></a></b></a></root>') | |
550 self._test_expression('//a/b/a/b/a/c', None, xml, '<c>!</c>') | |
551 self._test_expression('//a/b/a/c', None, xml, '<c>!</c>') | |
552 self._test_expression('//a/c', None, xml, '<c>!</c>') | |
553 self._test_expression('//c', None, xml, '<c>!</c>') | |
554 # Please note that a//b is NOT the same as a/descendant::b | |
555 # it is a/descendant-or-self::node()/b, which SimplePathStrategy | |
556 # does NOT support | |
557 self._test_expression('a/b/descendant::a/c', None, xml, '<c>!</c>') | |
558 self._test_expression('a/b/descendant::a/d/descendant::a/c', | |
559 None, xml, '<c>!</c>') | |
560 self._test_expression('a/b/descendant::a/d/a/c', None, xml, '') | |
561 self._test_expression('//d/descendant::b/descendant::b/descendant::b' | |
562 '/descendant::c', None, xml, '<c>!</c>') | |
563 self._test_expression('//d/descendant::b/descendant::b/descendant::b' | |
564 '/descendant::b/descendant::c', None, xml, '') | |
565 def _test_support(self, strategy_class, text): | |
566 path = PathParser(text, None, -1).parse()[0] | |
567 return strategy_class.supports(path) | |
568 def test_simple_strategy_support(self): | |
569 self.assert_(self._test_support(SimplePathStrategy, 'a/b')) | |
570 self.assert_(self._test_support(SimplePathStrategy, 'self::a/b')) | |
571 self.assert_(self._test_support(SimplePathStrategy, 'descendant::a/b')) | |
572 self.assert_(self._test_support(SimplePathStrategy, | |
573 'descendant-or-self::a/b')) | |
574 self.assert_(self._test_support(SimplePathStrategy, '//a/b')) | |
575 self.assert_(self._test_support(SimplePathStrategy, 'a/@b')) | |
576 self.assert_(self._test_support(SimplePathStrategy, 'a/text()')) | |
577 | |
578 # a//b is a/descendant-or-self::node()/b | |
579 self.assert_(not self._test_support(SimplePathStrategy, 'a//b')) | |
580 self.assert_(not self._test_support(SimplePathStrategy, 'node()/@a')) | |
581 self.assert_(not self._test_support(SimplePathStrategy, '@a')) | |
582 self.assert_(not self._test_support(SimplePathStrategy, 'foo:bar')) | |
583 self.assert_(not self._test_support(SimplePathStrategy, 'a/@foo:bar')) | |
1 | 584 |
585 def suite(): | |
586 suite = unittest.TestSuite() | |
111
8a4d9064f363
Some fixes and more unit tests for the XPath engine.
cmlenz
parents:
106
diff
changeset
|
587 suite.addTest(doctest.DocTestSuite(Path.__module__)) |
26
039fc5b87405
* Split out the XPath tests into a separate `unittest`-based file.
cmlenz
parents:
1
diff
changeset
|
588 suite.addTest(unittest.makeSuite(PathTestCase, 'test')) |
1 | 589 return suite |
590 | |
591 if __name__ == '__main__': | |
592 unittest.main(defaultTest='suite') |