Mercurial > genshi > genshi-test
comparison genshi/template/tests/directives.py @ 902:09cc3627654c experimental-inline
Sync `experimental/inline` branch with [source:trunk@1126].
author | cmlenz |
---|---|
date | Fri, 23 Apr 2010 21:08:26 +0000 |
parents | 1837f39efd6f |
children |
comparison
equal
deleted
inserted
replaced
830:de82830f8816 | 902:09cc3627654c |
---|---|
1 # -*- coding: utf-8 -*- | 1 # -*- coding: utf-8 -*- |
2 # | 2 # |
3 # Copyright (C) 2006-2008 Edgewall Software | 3 # Copyright (C) 2006-2010 Edgewall Software |
4 # All rights reserved. | 4 # All rights reserved. |
5 # | 5 # |
6 # This software is licensed as described in the file COPYING, which | 6 # This software is licensed as described in the file COPYING, which |
7 # you should have received as part of this distribution. The terms | 7 # you should have received as part of this distribution. The terms |
8 # are also available at http://genshi.edgewall.org/wiki/License. | 8 # are also available at http://genshi.edgewall.org/wiki/License. |
10 # This software consists of voluntary contributions made by many | 10 # This software consists of voluntary contributions made by many |
11 # individuals. For the exact contribution history, see the revision | 11 # individuals. For the exact contribution history, see the revision |
12 # history and logs, available at http://genshi.edgewall.org/log/. | 12 # history and logs, available at http://genshi.edgewall.org/log/. |
13 | 13 |
14 import doctest | 14 import doctest |
15 import re | |
15 import sys | 16 import sys |
16 import unittest | 17 import unittest |
17 | 18 |
18 from genshi.template import directives, MarkupTemplate, TextTemplate, \ | 19 from genshi.template import directives, MarkupTemplate, TextTemplate, \ |
19 TemplateRuntimeError, TemplateSyntaxError | 20 TemplateRuntimeError, TemplateSyntaxError |
30 <elem py:for="item in items" py:attrs="item"/> | 31 <elem py:for="item in items" py:attrs="item"/> |
31 </doc>""") | 32 </doc>""") |
32 items = [{'id': 1, 'class': 'foo'}, {'id': 2, 'class': 'bar'}] | 33 items = [{'id': 1, 'class': 'foo'}, {'id': 2, 'class': 'bar'}] |
33 self.assertEqual("""<doc> | 34 self.assertEqual("""<doc> |
34 <elem id="1" class="foo"/><elem id="2" class="bar"/> | 35 <elem id="1" class="foo"/><elem id="2" class="bar"/> |
35 </doc>""", str(tmpl.generate(items=items))) | 36 </doc>""", tmpl.generate(items=items).render(encoding=None)) |
36 | 37 |
37 def test_update_existing_attr(self): | 38 def test_update_existing_attr(self): |
38 """ | 39 """ |
39 Verify that an attribute value that evaluates to `None` removes an | 40 Verify that an attribute value that evaluates to `None` removes an |
40 existing attribute of that name. | 41 existing attribute of that name. |
42 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 43 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
43 <elem class="foo" py:attrs="{'class': 'bar'}"/> | 44 <elem class="foo" py:attrs="{'class': 'bar'}"/> |
44 </doc>""") | 45 </doc>""") |
45 self.assertEqual("""<doc> | 46 self.assertEqual("""<doc> |
46 <elem class="bar"/> | 47 <elem class="bar"/> |
47 </doc>""", str(tmpl.generate())) | 48 </doc>""", tmpl.generate().render(encoding=None)) |
48 | 49 |
49 def test_remove_existing_attr(self): | 50 def test_remove_existing_attr(self): |
50 """ | 51 """ |
51 Verify that an attribute value that evaluates to `None` removes an | 52 Verify that an attribute value that evaluates to `None` removes an |
52 existing attribute of that name. | 53 existing attribute of that name. |
54 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 55 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
55 <elem class="foo" py:attrs="{'class': None}"/> | 56 <elem class="foo" py:attrs="{'class': None}"/> |
56 </doc>""") | 57 </doc>""") |
57 self.assertEqual("""<doc> | 58 self.assertEqual("""<doc> |
58 <elem/> | 59 <elem/> |
59 </doc>""", str(tmpl.generate())) | 60 </doc>""", tmpl.generate().render(encoding=None)) |
60 | 61 |
61 | 62 |
62 class ChooseDirectiveTestCase(unittest.TestCase): | 63 class ChooseDirectiveTestCase(unittest.TestCase): |
63 """Tests for the `py:choose` template directive and the complementary | 64 """Tests for the `py:choose` template directive and the complementary |
64 directives `py:when` and `py:otherwise`.""" | 65 directives `py:when` and `py:otherwise`.""" |
73 <span py:when="2 == 2">2</span> | 74 <span py:when="2 == 2">2</span> |
74 <span py:when="3 == 3">3</span> | 75 <span py:when="3 == 3">3</span> |
75 </div>""") | 76 </div>""") |
76 self.assertEqual("""<div> | 77 self.assertEqual("""<div> |
77 <span>1</span> | 78 <span>1</span> |
78 </div>""", str(tmpl.generate())) | 79 </div>""", tmpl.generate().render(encoding=None)) |
79 | 80 |
80 def test_otherwise(self): | 81 def test_otherwise(self): |
81 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/" py:choose=""> | 82 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/" py:choose=""> |
82 <span py:when="False">hidden</span> | 83 <span py:when="False">hidden</span> |
83 <span py:otherwise="">hello</span> | 84 <span py:otherwise="">hello</span> |
84 </div>""") | 85 </div>""") |
85 self.assertEqual("""<div> | 86 self.assertEqual("""<div> |
86 <span>hello</span> | 87 <span>hello</span> |
87 </div>""", str(tmpl.generate())) | 88 </div>""", tmpl.generate().render(encoding=None)) |
88 | 89 |
89 def test_nesting(self): | 90 def test_nesting(self): |
90 """ | 91 """ |
91 Verify that `py:choose` blocks can be nested: | 92 Verify that `py:choose` blocks can be nested: |
92 """ | 93 """ |
102 <div> | 103 <div> |
103 <div> | 104 <div> |
104 <span>3</span> | 105 <span>3</span> |
105 </div> | 106 </div> |
106 </div> | 107 </div> |
107 </doc>""", str(tmpl.generate())) | 108 </doc>""", tmpl.generate().render(encoding=None)) |
108 | 109 |
109 def test_complex_nesting(self): | 110 def test_complex_nesting(self): |
110 """ | 111 """ |
111 Verify more complex nesting. | 112 Verify more complex nesting. |
112 """ | 113 """ |
122 <div> | 123 <div> |
123 <div> | 124 <div> |
124 <span>OK</span> | 125 <span>OK</span> |
125 </div> | 126 </div> |
126 </div> | 127 </div> |
127 </doc>""", str(tmpl.generate())) | 128 </doc>""", tmpl.generate().render(encoding=None)) |
128 | 129 |
129 def test_complex_nesting_otherwise(self): | 130 def test_complex_nesting_otherwise(self): |
130 """ | 131 """ |
131 Verify more complex nesting using otherwise. | 132 Verify more complex nesting using otherwise. |
132 """ | 133 """ |
142 <div> | 143 <div> |
143 <div> | 144 <div> |
144 <span>OK</span> | 145 <span>OK</span> |
145 </div> | 146 </div> |
146 </div> | 147 </div> |
147 </doc>""", str(tmpl.generate())) | 148 </doc>""", tmpl.generate().render(encoding=None)) |
148 | 149 |
149 def test_when_with_strip(self): | 150 def test_when_with_strip(self): |
150 """ | 151 """ |
151 Verify that a when directive with a strip directive actually strips of | 152 Verify that a when directive with a strip directive actually strips of |
152 the outer element. | 153 the outer element. |
156 <span py:otherwise="">foo</span> | 157 <span py:otherwise="">foo</span> |
157 </div> | 158 </div> |
158 </doc>""") | 159 </doc>""") |
159 self.assertEqual("""<doc> | 160 self.assertEqual("""<doc> |
160 <span>foo</span> | 161 <span>foo</span> |
161 </doc>""", str(tmpl.generate())) | 162 </doc>""", tmpl.generate().render(encoding=None)) |
162 | 163 |
163 def test_when_outside_choose(self): | 164 def test_when_outside_choose(self): |
164 """ | 165 """ |
165 Verify that a `when` directive outside of a `choose` directive is | 166 Verify that a `when` directive outside of a `choose` directive is |
166 reported as an error. | 167 reported as an error. |
203 <py:when>foo</py:when> | 204 <py:when>foo</py:when> |
204 </div> | 205 </div> |
205 </doc>""") | 206 </doc>""") |
206 self.assertEqual("""<doc> | 207 self.assertEqual("""<doc> |
207 foo | 208 foo |
208 </doc>""", str(tmpl.generate(foo='Yeah'))) | 209 </doc>""", tmpl.generate(foo='Yeah').render(encoding=None)) |
209 | 210 |
210 def test_otherwise_without_test(self): | 211 def test_otherwise_without_test(self): |
211 """ | 212 """ |
212 Verify that an `otherwise` directive can be used without a `test` | 213 Verify that an `otherwise` directive can be used without a `test` |
213 attribute. | 214 attribute. |
217 <py:otherwise>foo</py:otherwise> | 218 <py:otherwise>foo</py:otherwise> |
218 </div> | 219 </div> |
219 </doc>""") | 220 </doc>""") |
220 self.assertEqual("""<doc> | 221 self.assertEqual("""<doc> |
221 foo | 222 foo |
222 </doc>""", str(tmpl.generate())) | 223 </doc>""", tmpl.generate().render(encoding=None)) |
223 | 224 |
224 def test_as_element(self): | 225 def test_as_element(self): |
225 """ | 226 """ |
226 Verify that the directive can also be used as an element. | 227 Verify that the directive can also be used as an element. |
227 """ | 228 """ |
232 <py:when test="3 == 3">3</py:when> | 233 <py:when test="3 == 3">3</py:when> |
233 </py:choose> | 234 </py:choose> |
234 </doc>""") | 235 </doc>""") |
235 self.assertEqual("""<doc> | 236 self.assertEqual("""<doc> |
236 1 | 237 1 |
237 </doc>""", str(tmpl.generate())) | 238 </doc>""", tmpl.generate().render(encoding=None)) |
238 | 239 |
239 def test_in_text_template(self): | 240 def test_in_text_template(self): |
240 """ | 241 """ |
241 Verify that the directive works as expected in a text template. | 242 Verify that the directive works as expected in a text template. |
242 """ | 243 """ |
249 #end | 250 #end |
250 #when 3 == 3 | 251 #when 3 == 3 |
251 3 | 252 3 |
252 #end | 253 #end |
253 #end""") | 254 #end""") |
254 self.assertEqual(""" 1\n""", str(tmpl.generate())) | 255 self.assertEqual(""" 1\n""", |
256 tmpl.generate().render(encoding=None)) | |
255 | 257 |
256 | 258 |
257 class DefDirectiveTestCase(unittest.TestCase): | 259 class DefDirectiveTestCase(unittest.TestCase): |
258 """Tests for the `py:def` template directive.""" | 260 """Tests for the `py:def` template directive.""" |
259 | 261 |
268 </div> | 270 </div> |
269 ${echo('foo')} | 271 ${echo('foo')} |
270 </doc>""") | 272 </doc>""") |
271 self.assertEqual("""<doc> | 273 self.assertEqual("""<doc> |
272 <b>foo</b> | 274 <b>foo</b> |
273 </doc>""", str(tmpl.generate())) | 275 </doc>""", tmpl.generate().render(encoding=None)) |
274 | 276 |
275 def test_exec_in_replace(self): | 277 def test_exec_in_replace(self): |
276 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 278 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
277 <p py:def="echo(greeting, name='world')" class="message"> | 279 <p py:def="echo(greeting, name='world')" class="message"> |
278 ${greeting}, ${name}! | 280 ${greeting}, ${name}! |
281 </div>""") | 283 </div>""") |
282 self.assertEqual("""<div> | 284 self.assertEqual("""<div> |
283 <p class="message"> | 285 <p class="message"> |
284 hello, world! | 286 hello, world! |
285 </p> | 287 </p> |
286 </div>""", str(tmpl.generate())) | 288 </div>""", tmpl.generate().render(encoding=None)) |
287 | 289 |
288 def test_as_element(self): | 290 def test_as_element(self): |
289 """ | 291 """ |
290 Verify that the directive can also be used as an element. | 292 Verify that the directive can also be used as an element. |
291 """ | 293 """ |
295 </py:def> | 297 </py:def> |
296 ${echo('foo')} | 298 ${echo('foo')} |
297 </doc>""") | 299 </doc>""") |
298 self.assertEqual("""<doc> | 300 self.assertEqual("""<doc> |
299 <b>foo</b> | 301 <b>foo</b> |
300 </doc>""", str(tmpl.generate())) | 302 </doc>""", tmpl.generate().render(encoding=None)) |
301 | 303 |
302 def test_nested_defs(self): | 304 def test_nested_defs(self): |
303 """ | 305 """ |
304 Verify that a template function defined inside a conditional block can | 306 Verify that a template function defined inside a conditional block can |
305 be called from outside that block. | 307 be called from outside that block. |
313 </py:if> | 315 </py:if> |
314 ${echo('foo')} | 316 ${echo('foo')} |
315 </doc>""") | 317 </doc>""") |
316 self.assertEqual("""<doc> | 318 self.assertEqual("""<doc> |
317 <strong>foo</strong> | 319 <strong>foo</strong> |
318 </doc>""", str(tmpl.generate(semantic=True))) | 320 </doc>""", tmpl.generate(semantic=True).render(encoding=None)) |
319 | 321 |
320 def test_function_with_default_arg(self): | 322 def test_function_with_default_arg(self): |
321 """ | 323 """ |
322 Verify that keyword arguments work with `py:def` directives. | 324 Verify that keyword arguments work with `py:def` directives. |
323 """ | 325 """ |
325 <b py:def="echo(what, bold=False)" py:strip="not bold">${what}</b> | 327 <b py:def="echo(what, bold=False)" py:strip="not bold">${what}</b> |
326 ${echo('foo')} | 328 ${echo('foo')} |
327 </doc>""") | 329 </doc>""") |
328 self.assertEqual("""<doc> | 330 self.assertEqual("""<doc> |
329 foo | 331 foo |
330 </doc>""", str(tmpl.generate())) | 332 </doc>""", tmpl.generate().render(encoding=None)) |
331 | 333 |
332 def test_invocation_in_attribute(self): | 334 def test_invocation_in_attribute(self): |
333 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 335 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
334 <py:def function="echo(what)">${what or 'something'}</py:def> | 336 <py:def function="echo(what)">${what or 'something'}</py:def> |
335 <p class="${echo('foo')}">bar</p> | 337 <p class="${echo('foo')}">bar</p> |
336 </doc>""") | 338 </doc>""") |
337 self.assertEqual("""<doc> | 339 self.assertEqual("""<doc> |
338 <p class="foo">bar</p> | 340 <p class="foo">bar</p> |
339 </doc>""", str(tmpl.generate())) | 341 </doc>""", tmpl.generate().render(encoding=None)) |
340 | 342 |
341 def test_invocation_in_attribute_none(self): | 343 def test_invocation_in_attribute_none(self): |
342 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 344 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
343 <py:def function="echo()">${None}</py:def> | 345 <py:def function="echo()">${None}</py:def> |
344 <p class="${echo()}">bar</p> | 346 <p class="${echo()}">bar</p> |
345 </doc>""") | 347 </doc>""") |
346 self.assertEqual("""<doc> | 348 self.assertEqual("""<doc> |
347 <p>bar</p> | 349 <p>bar</p> |
348 </doc>""", str(tmpl.generate())) | 350 </doc>""", tmpl.generate().render(encoding=None)) |
349 | 351 |
350 def test_function_raising_typeerror(self): | 352 def test_function_raising_typeerror(self): |
351 def badfunc(): | 353 def badfunc(): |
352 raise TypeError | 354 raise TypeError |
353 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 355 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
366 <title>${maketitle(True)}</title> | 368 <title>${maketitle(True)}</title> |
367 </head> | 369 </head> |
368 </doc>""") | 370 </doc>""") |
369 self.assertEqual("""<doc> | 371 self.assertEqual("""<doc> |
370 <head><title>True</title></head> | 372 <head><title>True</title></head> |
371 </doc>""", str(tmpl.generate())) | 373 </doc>""", tmpl.generate().render(encoding=None)) |
372 | 374 |
373 def test_in_text_template(self): | 375 def test_in_text_template(self): |
374 """ | 376 """ |
375 Verify that the directive works as expected in a text template. | 377 Verify that the directive works as expected in a text template. |
376 """ | 378 """ |
381 ${echo('Hi', name='you')} | 383 ${echo('Hi', name='you')} |
382 """) | 384 """) |
383 self.assertEqual(""" | 385 self.assertEqual(""" |
384 Hi, you! | 386 Hi, you! |
385 | 387 |
386 """, str(tmpl.generate())) | 388 """, tmpl.generate().render(encoding=None)) |
387 | 389 |
388 def test_function_with_star_args(self): | 390 def test_function_with_star_args(self): |
389 """ | 391 """ |
390 Verify that a named template function using "star arguments" works as | 392 Verify that a named template function using "star arguments" works as |
391 expected. | 393 expected. |
400 self.assertEqual("""<doc> | 402 self.assertEqual("""<doc> |
401 <div> | 403 <div> |
402 [1, 2] | 404 [1, 2] |
403 {'a': 3, 'b': 4} | 405 {'a': 3, 'b': 4} |
404 </div> | 406 </div> |
405 </doc>""", str(tmpl.generate())) | 407 </doc>""", tmpl.generate().render(encoding=None)) |
406 | 408 |
407 | 409 |
408 class ForDirectiveTestCase(unittest.TestCase): | 410 class ForDirectiveTestCase(unittest.TestCase): |
409 """Tests for the `py:for` template directive.""" | 411 """Tests for the `py:for` template directive.""" |
410 | 412 |
422 <b>1</b> | 424 <b>1</b> |
423 <b>2</b> | 425 <b>2</b> |
424 <b>3</b> | 426 <b>3</b> |
425 <b>4</b> | 427 <b>4</b> |
426 <b>5</b> | 428 <b>5</b> |
427 </doc>""", str(tmpl.generate(items=range(1, 6)))) | 429 </doc>""", tmpl.generate(items=range(1, 6)).render(encoding=None)) |
428 | 430 |
429 def test_as_element(self): | 431 def test_as_element(self): |
430 """ | 432 """ |
431 Verify that the directive can also be used as an element. | 433 Verify that the directive can also be used as an element. |
432 """ | 434 """ |
439 <b>1</b> | 441 <b>1</b> |
440 <b>2</b> | 442 <b>2</b> |
441 <b>3</b> | 443 <b>3</b> |
442 <b>4</b> | 444 <b>4</b> |
443 <b>5</b> | 445 <b>5</b> |
444 </doc>""", str(tmpl.generate(items=range(1, 6)))) | 446 </doc>""", tmpl.generate(items=range(1, 6)).render(encoding=None)) |
445 | 447 |
446 def test_multi_assignment(self): | 448 def test_multi_assignment(self): |
447 """ | 449 """ |
448 Verify that assignment to tuples works correctly. | 450 Verify that assignment to tuples works correctly. |
449 """ | 451 """ |
453 </py:for> | 455 </py:for> |
454 </doc>""") | 456 </doc>""") |
455 self.assertEqual("""<doc> | 457 self.assertEqual("""<doc> |
456 <p>key=a, value=1</p> | 458 <p>key=a, value=1</p> |
457 <p>key=b, value=2</p> | 459 <p>key=b, value=2</p> |
458 </doc>""", str(tmpl.generate(items=dict(a=1, b=2).items()))) | 460 </doc>""", tmpl.generate(items=dict(a=1, b=2).items()) |
461 .render(encoding=None)) | |
459 | 462 |
460 def test_nested_assignment(self): | 463 def test_nested_assignment(self): |
461 """ | 464 """ |
462 Verify that assignment to nested tuples works correctly. | 465 Verify that assignment to nested tuples works correctly. |
463 """ | 466 """ |
467 </py:for> | 470 </py:for> |
468 </doc>""") | 471 </doc>""") |
469 self.assertEqual("""<doc> | 472 self.assertEqual("""<doc> |
470 <p>0: key=a, value=1</p> | 473 <p>0: key=a, value=1</p> |
471 <p>1: key=b, value=2</p> | 474 <p>1: key=b, value=2</p> |
472 </doc>""", str(tmpl.generate(items=enumerate(dict(a=1, b=2).items())))) | 475 </doc>""", tmpl.generate(items=enumerate(dict(a=1, b=2).items())) |
476 .render(encoding=None)) | |
473 | 477 |
474 def test_not_iterable(self): | 478 def test_not_iterable(self): |
475 """ | 479 """ |
476 Verify that assignment to nested tuples works correctly. | 480 Verify that assignment to nested tuples works correctly. |
477 """ | 481 """ |
526 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 530 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
527 <b py:if="foo" py:strip="">${bar}</b> | 531 <b py:if="foo" py:strip="">${bar}</b> |
528 </doc>""") | 532 </doc>""") |
529 self.assertEqual("""<doc> | 533 self.assertEqual("""<doc> |
530 Hello | 534 Hello |
531 </doc>""", str(tmpl.generate(foo=True, bar='Hello'))) | 535 </doc>""", tmpl.generate(foo=True, bar='Hello').render(encoding=None)) |
532 | 536 |
533 def test_as_element(self): | 537 def test_as_element(self): |
534 """ | 538 """ |
535 Verify that the directive can also be used as an element. | 539 Verify that the directive can also be used as an element. |
536 """ | 540 """ |
537 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 541 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
538 <py:if test="foo">${bar}</py:if> | 542 <py:if test="foo">${bar}</py:if> |
539 </doc>""") | 543 </doc>""") |
540 self.assertEqual("""<doc> | 544 self.assertEqual("""<doc> |
541 Hello | 545 Hello |
542 </doc>""", str(tmpl.generate(foo=True, bar='Hello'))) | 546 </doc>""", tmpl.generate(foo=True, bar='Hello').render(encoding=None)) |
543 | 547 |
544 | 548 |
545 class MatchDirectiveTestCase(unittest.TestCase): | 549 class MatchDirectiveTestCase(unittest.TestCase): |
546 """Tests for the `py:match` template directive.""" | 550 """Tests for the `py:match` template directive.""" |
547 | 551 |
556 </elem> | 560 </elem> |
557 <elem>Hey Joe</elem> | 561 <elem>Hey Joe</elem> |
558 </doc>""") | 562 </doc>""") |
559 self.assertEqual("""<doc> | 563 self.assertEqual("""<doc> |
560 <div class="elem">Hey Joe</div> | 564 <div class="elem">Hey Joe</div> |
561 </doc>""", str(tmpl.generate())) | 565 </doc>""", tmpl.generate().render(encoding=None)) |
562 | 566 |
563 def test_without_strip(self): | 567 def test_without_strip(self): |
564 """ | 568 """ |
565 Verify that a match template can produce the same kind of element that | 569 Verify that a match template can produce the same kind of element that |
566 it matched without entering an infinite recursion. | 570 it matched without entering an infinite recursion. |
573 </doc>""") | 577 </doc>""") |
574 self.assertEqual("""<doc> | 578 self.assertEqual("""<doc> |
575 <elem> | 579 <elem> |
576 <div class="elem">Hey Joe</div> | 580 <div class="elem">Hey Joe</div> |
577 </elem> | 581 </elem> |
578 </doc>""", str(tmpl.generate())) | 582 </doc>""", tmpl.generate().render(encoding=None)) |
579 | 583 |
580 def test_as_element(self): | 584 def test_as_element(self): |
581 """ | 585 """ |
582 Verify that the directive can also be used as an element. | 586 Verify that the directive can also be used as an element. |
583 """ | 587 """ |
587 </py:match> | 591 </py:match> |
588 <elem>Hey Joe</elem> | 592 <elem>Hey Joe</elem> |
589 </doc>""") | 593 </doc>""") |
590 self.assertEqual("""<doc> | 594 self.assertEqual("""<doc> |
591 <div class="elem">Hey Joe</div> | 595 <div class="elem">Hey Joe</div> |
592 </doc>""", str(tmpl.generate())) | 596 </doc>""", tmpl.generate().render(encoding=None)) |
593 | 597 |
594 def test_recursive_match_1(self): | 598 def test_recursive_match_1(self): |
595 """ | 599 """ |
596 Match directives are applied recursively, meaning that they are also | 600 Match directives are applied recursively, meaning that they are also |
597 applied to any content they may have produced themselves: | 601 applied to any content they may have produced themselves: |
617 </div> | 621 </div> |
618 </elem> | 622 </elem> |
619 </subelem> | 623 </subelem> |
620 </div> | 624 </div> |
621 </elem> | 625 </elem> |
622 </doc>""", str(tmpl.generate())) | 626 </doc>""", tmpl.generate().render(encoding=None)) |
623 | 627 |
624 def test_recursive_match_2(self): | 628 def test_recursive_match_2(self): |
625 """ | 629 """ |
626 When two or more match templates match the same element and also | 630 When two or more match templates match the same element and also |
627 themselves output the element they match, avoiding recursion is even | 631 themselves output the element they match, avoiding recursion is even |
643 self.assertEqual("""<html> | 647 self.assertEqual("""<html> |
644 <body> | 648 <body> |
645 <div id="header"/><h1>Foo</h1> | 649 <div id="header"/><h1>Foo</h1> |
646 <div id="footer"/> | 650 <div id="footer"/> |
647 </body> | 651 </body> |
648 </html>""", str(tmpl.generate())) | 652 </html>""", tmpl.generate().render(encoding=None)) |
649 | 653 |
650 def test_recursive_match_3(self): | 654 def test_recursive_match_3(self): |
651 tmpl = MarkupTemplate("""<test xmlns:py="http://genshi.edgewall.org/"> | 655 tmpl = MarkupTemplate("""<test xmlns:py="http://genshi.edgewall.org/"> |
652 <py:match path="b[@type='bullet']"> | 656 <py:match path="b[@type='bullet']"> |
653 <bullet>${select('*|text()')}</bullet> | 657 <bullet>${select('*|text()')}</bullet> |
669 """) | 673 """) |
670 self.assertEqual("""<test> | 674 self.assertEqual("""<test> |
671 <generic> | 675 <generic> |
672 <ul><bullet>1</bullet><bullet>2</bullet></ul> | 676 <ul><bullet>1</bullet><bullet>2</bullet></ul> |
673 </generic> | 677 </generic> |
674 </test>""", str(tmpl.generate())) | 678 </test>""", tmpl.generate().render(encoding=None)) |
675 | 679 |
676 def test_not_match_self(self): | 680 def test_not_match_self(self): |
677 """ | 681 """ |
678 See http://genshi.edgewall.org/ticket/77 | 682 See http://genshi.edgewall.org/ticket/77 |
679 """ | 683 """ |
691 self.assertEqual("""<html xmlns="http://www.w3.org/1999/xhtml"> | 695 self.assertEqual("""<html xmlns="http://www.w3.org/1999/xhtml"> |
692 <body><h1> | 696 <body><h1> |
693 Hello! | 697 Hello! |
694 Goodbye! | 698 Goodbye! |
695 </h1></body> | 699 </h1></body> |
696 </html>""", str(tmpl.generate())) | 700 </html>""", tmpl.generate().render(encoding=None)) |
697 | 701 |
698 def test_select_text_in_element(self): | 702 def test_select_text_in_element(self): |
699 """ | 703 """ |
700 See http://genshi.edgewall.org/ticket/77#comment:1 | 704 See http://genshi.edgewall.org/ticket/77#comment:1 |
701 """ | 705 """ |
717 <text> | 721 <text> |
718 Hello! | 722 Hello! |
719 </text> | 723 </text> |
720 Goodbye! | 724 Goodbye! |
721 </h1></body> | 725 </h1></body> |
722 </html>""", str(tmpl.generate())) | 726 </html>""", tmpl.generate().render(encoding=None)) |
723 | 727 |
724 def test_select_all_attrs(self): | 728 def test_select_all_attrs(self): |
725 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 729 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
726 <div py:match="elem" py:attrs="select('@*')"> | 730 <div py:match="elem" py:attrs="select('@*')"> |
727 ${select('text()')} | 731 ${select('text()')} |
730 </doc>""") | 734 </doc>""") |
731 self.assertEqual("""<doc> | 735 self.assertEqual("""<doc> |
732 <div id="joe"> | 736 <div id="joe"> |
733 Hey Joe | 737 Hey Joe |
734 </div> | 738 </div> |
735 </doc>""", str(tmpl.generate())) | 739 </doc>""", tmpl.generate().render(encoding=None)) |
736 | 740 |
737 def test_select_all_attrs_empty(self): | 741 def test_select_all_attrs_empty(self): |
738 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 742 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
739 <div py:match="elem" py:attrs="select('@*')"> | 743 <div py:match="elem" py:attrs="select('@*')"> |
740 ${select('text()')} | 744 ${select('text()')} |
743 </doc>""") | 747 </doc>""") |
744 self.assertEqual("""<doc> | 748 self.assertEqual("""<doc> |
745 <div> | 749 <div> |
746 Hey Joe | 750 Hey Joe |
747 </div> | 751 </div> |
748 </doc>""", str(tmpl.generate())) | 752 </doc>""", tmpl.generate().render(encoding=None)) |
749 | 753 |
750 def test_select_all_attrs_in_body(self): | 754 def test_select_all_attrs_in_body(self): |
751 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 755 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
752 <div py:match="elem"> | 756 <div py:match="elem"> |
753 Hey ${select('text()')} ${select('@*')} | 757 Hey ${select('text()')} ${select('@*')} |
756 </doc>""") | 760 </doc>""") |
757 self.assertEqual("""<doc> | 761 self.assertEqual("""<doc> |
758 <div> | 762 <div> |
759 Hey Joe Cool | 763 Hey Joe Cool |
760 </div> | 764 </div> |
761 </doc>""", str(tmpl.generate())) | 765 </doc>""", tmpl.generate().render(encoding=None)) |
762 | 766 |
763 def test_def_in_match(self): | 767 def test_def_in_match(self): |
764 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 768 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
765 <py:def function="maketitle(test)"><b py:replace="test" /></py:def> | 769 <py:def function="maketitle(test)"><b py:replace="test" /></py:def> |
766 <head py:match="head">${select('*')}</head> | 770 <head py:match="head">${select('*')}</head> |
767 <head><title>${maketitle(True)}</title></head> | 771 <head><title>${maketitle(True)}</title></head> |
768 </doc>""") | 772 </doc>""") |
769 self.assertEqual("""<doc> | 773 self.assertEqual("""<doc> |
770 <head><title>True</title></head> | 774 <head><title>True</title></head> |
771 </doc>""", str(tmpl.generate())) | 775 </doc>""", tmpl.generate().render(encoding=None)) |
772 | 776 |
773 def test_match_with_xpath_variable(self): | 777 def test_match_with_xpath_variable(self): |
774 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 778 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
775 <span py:match="*[name()=$tagname]"> | 779 <span py:match="*[name()=$tagname]"> |
776 Hello ${select('@name')} | 780 Hello ${select('@name')} |
779 </div>""") | 783 </div>""") |
780 self.assertEqual("""<div> | 784 self.assertEqual("""<div> |
781 <span> | 785 <span> |
782 Hello Dude | 786 Hello Dude |
783 </span> | 787 </span> |
784 </div>""", str(tmpl.generate(tagname='greeting'))) | 788 </div>""", tmpl.generate(tagname='greeting').render(encoding=None)) |
785 self.assertEqual("""<div> | 789 self.assertEqual("""<div> |
786 <greeting name="Dude"/> | 790 <greeting name="Dude"/> |
787 </div>""", str(tmpl.generate(tagname='sayhello'))) | 791 </div>""", tmpl.generate(tagname='sayhello').render(encoding=None)) |
788 | 792 |
789 def test_content_directive_in_match(self): | 793 def test_content_directive_in_match(self): |
790 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 794 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
791 <div py:match="foo">I said <q py:content="select('text()')">something</q>.</div> | 795 <div py:match="foo">I said <q py:content="select('text()')">something</q>.</div> |
792 <foo>bar</foo> | 796 <foo>bar</foo> |
793 </html>""") | 797 </html>""") |
794 self.assertEqual("""<html> | 798 self.assertEqual("""<html> |
795 <div>I said <q>bar</q>.</div> | 799 <div>I said <q>bar</q>.</div> |
796 </html>""", str(tmpl.generate())) | 800 </html>""", tmpl.generate().render(encoding=None)) |
797 | 801 |
798 def test_cascaded_matches(self): | 802 def test_cascaded_matches(self): |
799 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 803 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
800 <body py:match="body">${select('*')}</body> | 804 <body py:match="body">${select('*')}</body> |
801 <head py:match="head">${select('title')}</head> | 805 <head py:match="head">${select('title')}</head> |
804 <body><h2>Are you ready to mark up?</h2></body> | 808 <body><h2>Are you ready to mark up?</h2></body> |
805 </html>""") | 809 </html>""") |
806 self.assertEqual("""<html> | 810 self.assertEqual("""<html> |
807 <head><title>Welcome to Markup</title></head> | 811 <head><title>Welcome to Markup</title></head> |
808 <body><h2>Are you ready to mark up?</h2><hr/></body> | 812 <body><h2>Are you ready to mark up?</h2><hr/></body> |
809 </html>""", str(tmpl.generate())) | 813 </html>""", tmpl.generate().render(encoding=None)) |
810 | 814 |
811 def test_multiple_matches(self): | 815 def test_multiple_matches(self): |
812 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 816 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
813 <input py:match="form//input" py:attrs="select('@*')" | 817 <input py:match="form//input" py:attrs="select('@*')" |
814 value="${values[str(select('@name'))]}" /> | 818 value="${values[str(select('@name'))]}" /> |
834 <input value="3" type="text" name="hello_3"/> | 838 <input value="3" type="text" name="hello_3"/> |
835 </p><p> | 839 </p><p> |
836 <label>Hello_4</label> | 840 <label>Hello_4</label> |
837 <input value="4" type="text" name="hello_4"/> | 841 <input value="4" type="text" name="hello_4"/> |
838 </p></form> | 842 </p></form> |
839 </html>""", str(tmpl.generate(fields=fields, values=values))) | 843 </html>""", tmpl.generate(fields=fields, values=values) |
844 .render(encoding=None)) | |
840 | 845 |
841 def test_namespace_context(self): | 846 def test_namespace_context(self): |
842 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" | 847 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/" |
843 xmlns:x="http://www.example.org/"> | 848 xmlns:x="http://www.example.org/"> |
844 <div py:match="x:foo">Foo</div> | 849 <div py:match="x:foo">Foo</div> |
846 </html>""") | 851 </html>""") |
847 # FIXME: there should be a way to strip out unwanted/unused namespaces, | 852 # FIXME: there should be a way to strip out unwanted/unused namespaces, |
848 # such as the "x" in this example | 853 # such as the "x" in this example |
849 self.assertEqual("""<html xmlns:x="http://www.example.org/"> | 854 self.assertEqual("""<html xmlns:x="http://www.example.org/"> |
850 <div>Foo</div> | 855 <div>Foo</div> |
851 </html>""", str(tmpl.generate())) | 856 </html>""", tmpl.generate().render(encoding=None)) |
852 | 857 |
853 def test_match_with_position_predicate(self): | 858 def test_match_with_position_predicate(self): |
854 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 859 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
855 <p py:match="body/p[1]" class="first">${select('*|text()')}</p> | 860 <p py:match="body/p[1]" class="first">${select('*|text()')}</p> |
856 <body> | 861 <body> |
861 self.assertEqual("""<html> | 866 self.assertEqual("""<html> |
862 <body> | 867 <body> |
863 <p class="first">Foo</p> | 868 <p class="first">Foo</p> |
864 <p>Bar</p> | 869 <p>Bar</p> |
865 </body> | 870 </body> |
866 </html>""", str(tmpl.generate())) | 871 </html>""", tmpl.generate().render(encoding=None)) |
867 | 872 |
868 def test_match_with_closure(self): | 873 def test_match_with_closure(self): |
869 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 874 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
870 <p py:match="body//p" class="para">${select('*|text()')}</p> | 875 <p py:match="body//p" class="para">${select('*|text()')}</p> |
871 <body> | 876 <body> |
876 self.assertEqual("""<html> | 881 self.assertEqual("""<html> |
877 <body> | 882 <body> |
878 <p class="para">Foo</p> | 883 <p class="para">Foo</p> |
879 <div><p class="para">Bar</p></div> | 884 <div><p class="para">Bar</p></div> |
880 </body> | 885 </body> |
881 </html>""", str(tmpl.generate())) | 886 </html>""", tmpl.generate().render(encoding=None)) |
882 | 887 |
883 def test_match_without_closure(self): | 888 def test_match_without_closure(self): |
884 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 889 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
885 <p py:match="body/p" class="para">${select('*|text()')}</p> | 890 <p py:match="body/p" class="para">${select('*|text()')}</p> |
886 <body> | 891 <body> |
891 self.assertEqual("""<html> | 896 self.assertEqual("""<html> |
892 <body> | 897 <body> |
893 <p class="para">Foo</p> | 898 <p class="para">Foo</p> |
894 <div><p>Bar</p></div> | 899 <div><p>Bar</p></div> |
895 </body> | 900 </body> |
896 </html>""", str(tmpl.generate())) | 901 </html>""", tmpl.generate().render(encoding=None)) |
897 | 902 |
898 def test_match_with_once_attribute(self): | 903 def test_match_with_once_attribute(self): |
899 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | 904 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> |
900 <py:match path="body" once="true"><body> | 905 <py:match path="body" once="true"><body> |
901 <div id="wrap"> | 906 <div id="wrap"> |
916 </div> | 921 </div> |
917 </body> | 922 </body> |
918 <body> | 923 <body> |
919 <p>Bar</p> | 924 <p>Bar</p> |
920 </body> | 925 </body> |
921 </html>""", str(tmpl.generate())) | 926 </html>""", tmpl.generate().render(encoding=None)) |
922 | 927 |
923 def test_match_with_recursive_attribute(self): | 928 def test_match_with_recursive_attribute(self): |
924 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | 929 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> |
925 <py:match path="elem" recursive="false"><elem> | 930 <py:match path="elem" recursive="false"><elem> |
926 <div class="elem"> | 931 <div class="elem"> |
939 <subelem> | 944 <subelem> |
940 <elem/> | 945 <elem/> |
941 </subelem> | 946 </subelem> |
942 </div> | 947 </div> |
943 </elem> | 948 </elem> |
944 </doc>""", str(tmpl.generate())) | 949 </doc>""", tmpl.generate().render(encoding=None)) |
950 | |
951 # See http://genshi.edgewall.org/ticket/254/ | |
952 def test_triple_match_produces_no_duplicate_items(self): | |
953 tmpl = MarkupTemplate("""<doc xmlns:py="http://genshi.edgewall.org/"> | |
954 <div py:match="div[@id='content']" py:attrs="select('@*')" once="true"> | |
955 <ul id="tabbed_pane" /> | |
956 ${select('*')} | |
957 </div> | |
958 | |
959 <body py:match="body" once="true" buffer="false"> | |
960 ${select('*|text()')} | |
961 </body> | |
962 <body py:match="body" once="true" buffer="false"> | |
963 ${select('*|text()')} | |
964 </body> | |
965 | |
966 <body> | |
967 <div id="content"> | |
968 <h1>Ticket X</h1> | |
969 </div> | |
970 </body> | |
971 </doc>""") | |
972 output = tmpl.generate().render('xhtml', doctype='xhtml') | |
973 matches = re.findall("tabbed_pane", output) | |
974 self.assertNotEqual(None, matches) | |
975 self.assertEqual(1, len(matches)) | |
976 | |
977 def test_match_multiple_times1(self): | |
978 # See http://genshi.edgewall.org/ticket/370 | |
979 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | |
980 <py:match path="body[@id='content']/h2" /> | |
981 <head py:match="head" /> | |
982 <head py:match="head" /> | |
983 <head /> | |
984 <body /> | |
985 </html>""") | |
986 self.assertEqual("""<html> | |
987 <head/> | |
988 <body/> | |
989 </html>""", tmpl.generate().render()) | |
990 | |
991 def test_match_multiple_times2(self): | |
992 # See http://genshi.edgewall.org/ticket/370 | |
993 tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"> | |
994 <py:match path="body/div[@id='properties']" /> | |
995 <head py:match="head" /> | |
996 <head py:match="head" /> | |
997 <head/> | |
998 <body> | |
999 <div id="properties">Foo</div> | |
1000 </body> | |
1001 </html>""") | |
1002 self.assertEqual("""<html> | |
1003 <head/> | |
1004 <body> | |
1005 </body> | |
1006 </html>""", tmpl.generate().render()) | |
945 | 1007 |
946 # FIXME | 1008 # FIXME |
947 #def test_match_after_step(self): | 1009 #def test_match_after_step(self): |
948 # tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1010 # tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
949 # <span py:match="div/greeting"> | 1011 # <span py:match="div/greeting"> |
953 # </div>""") | 1015 # </div>""") |
954 # self.assertEqual("""<div> | 1016 # self.assertEqual("""<div> |
955 # <span> | 1017 # <span> |
956 # Hello Dude | 1018 # Hello Dude |
957 # </span> | 1019 # </span> |
958 # </div>""", str(tmpl.generate())) | 1020 # </div>""", tmpl.generate().render(encoding=None)) |
959 | 1021 |
960 | 1022 |
961 class ContentDirectiveTestCase(unittest.TestCase): | 1023 class ContentDirectiveTestCase(unittest.TestCase): |
962 """Tests for the `py:content` template directive.""" | 1024 """Tests for the `py:content` template directive.""" |
963 | 1025 |
993 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1055 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
994 <py:replace value="title" /> | 1056 <py:replace value="title" /> |
995 </div>""", filename='test.html') | 1057 </div>""", filename='test.html') |
996 self.assertEqual("""<div> | 1058 self.assertEqual("""<div> |
997 Test | 1059 Test |
998 </div>""", str(tmpl.generate(title='Test'))) | 1060 </div>""", tmpl.generate(title='Test').render(encoding=None)) |
999 | 1061 |
1000 | 1062 |
1001 class StripDirectiveTestCase(unittest.TestCase): | 1063 class StripDirectiveTestCase(unittest.TestCase): |
1002 """Tests for the `py:strip` template directive.""" | 1064 """Tests for the `py:strip` template directive.""" |
1003 | 1065 |
1005 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1067 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1006 <div py:strip="False"><b>foo</b></div> | 1068 <div py:strip="False"><b>foo</b></div> |
1007 </div>""") | 1069 </div>""") |
1008 self.assertEqual("""<div> | 1070 self.assertEqual("""<div> |
1009 <div><b>foo</b></div> | 1071 <div><b>foo</b></div> |
1010 </div>""", str(tmpl.generate())) | 1072 </div>""", tmpl.generate().render(encoding=None)) |
1011 | 1073 |
1012 def test_strip_empty(self): | 1074 def test_strip_empty(self): |
1013 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1075 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1014 <div py:strip=""><b>foo</b></div> | 1076 <div py:strip=""><b>foo</b></div> |
1015 </div>""") | 1077 </div>""") |
1016 self.assertEqual("""<div> | 1078 self.assertEqual("""<div> |
1017 <b>foo</b> | 1079 <b>foo</b> |
1018 </div>""", str(tmpl.generate())) | 1080 </div>""", tmpl.generate().render(encoding=None)) |
1019 | 1081 |
1020 | 1082 |
1021 class WithDirectiveTestCase(unittest.TestCase): | 1083 class WithDirectiveTestCase(unittest.TestCase): |
1022 """Tests for the `py:with` template directive.""" | 1084 """Tests for the `py:with` template directive.""" |
1023 | 1085 |
1029 </div>""") | 1091 </div>""") |
1030 self.assertEqual("""<div> | 1092 self.assertEqual("""<div> |
1031 42 | 1093 42 |
1032 84 | 1094 84 |
1033 42 | 1095 42 |
1034 </div>""", str(tmpl.generate(x=42))) | 1096 </div>""", tmpl.generate(x=42).render(encoding=None)) |
1035 | 1097 |
1036 def test_as_element(self): | 1098 def test_as_element(self): |
1037 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1099 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1038 <py:with vars="x = x * 2">${x}</py:with> | 1100 <py:with vars="x = x * 2">${x}</py:with> |
1039 </div>""") | 1101 </div>""") |
1040 self.assertEqual("""<div> | 1102 self.assertEqual("""<div> |
1041 84 | 1103 84 |
1042 </div>""", str(tmpl.generate(x=42))) | 1104 </div>""", tmpl.generate(x=42).render(encoding=None)) |
1043 | 1105 |
1044 def test_multiple_vars_same_name(self): | 1106 def test_multiple_vars_same_name(self): |
1045 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1107 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1046 <py:with vars=" | 1108 <py:with vars=" |
1047 foo = 'bar'; | 1109 foo = 'bar'; |
1050 $foo | 1112 $foo |
1051 </py:with> | 1113 </py:with> |
1052 </div>""") | 1114 </div>""") |
1053 self.assertEqual("""<div> | 1115 self.assertEqual("""<div> |
1054 baz | 1116 baz |
1055 </div>""", str(tmpl.generate(x=42))) | 1117 </div>""", tmpl.generate(x=42).render(encoding=None)) |
1056 | 1118 |
1057 def test_multiple_vars_single_assignment(self): | 1119 def test_multiple_vars_single_assignment(self): |
1058 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1120 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1059 <py:with vars="x = y = z = 1">${x} ${y} ${z}</py:with> | 1121 <py:with vars="x = y = z = 1">${x} ${y} ${z}</py:with> |
1060 </div>""") | 1122 </div>""") |
1061 self.assertEqual("""<div> | 1123 self.assertEqual("""<div> |
1062 1 1 1 | 1124 1 1 1 |
1063 </div>""", str(tmpl.generate(x=42))) | 1125 </div>""", tmpl.generate(x=42).render(encoding=None)) |
1064 | 1126 |
1065 def test_nested_vars_single_assignment(self): | 1127 def test_nested_vars_single_assignment(self): |
1066 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1128 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1067 <py:with vars="x, (y, z) = (1, (2, 3))">${x} ${y} ${z}</py:with> | 1129 <py:with vars="x, (y, z) = (1, (2, 3))">${x} ${y} ${z}</py:with> |
1068 </div>""") | 1130 </div>""") |
1069 self.assertEqual("""<div> | 1131 self.assertEqual("""<div> |
1070 1 2 3 | 1132 1 2 3 |
1071 </div>""", str(tmpl.generate(x=42))) | 1133 </div>""", tmpl.generate(x=42).render(encoding=None)) |
1072 | 1134 |
1073 def test_multiple_vars_trailing_semicolon(self): | 1135 def test_multiple_vars_trailing_semicolon(self): |
1074 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1136 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1075 <py:with vars="x = x * 2; y = x / 2;">${x} ${y}</py:with> | 1137 <py:with vars="x = x * 2; y = x / 2;">${x} ${y}</py:with> |
1076 </div>""") | 1138 </div>""") |
1077 self.assertEqual("""<div> | 1139 self.assertEqual("""<div> |
1078 84 42 | 1140 84 42 |
1079 </div>""", str(tmpl.generate(x=42))) | 1141 </div>""", tmpl.generate(x=42).render(encoding=None)) |
1080 | 1142 |
1081 def test_semicolon_escape(self): | 1143 def test_semicolon_escape(self): |
1082 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1144 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1083 <py:with vars="x = 'here is a semicolon: ;'; y = 'here are two semicolons: ;;' ;"> | 1145 <py:with vars="x = 'here is a semicolon: ;'; y = 'here are two semicolons: ;;' ;"> |
1084 ${x} | 1146 ${x} |
1086 </py:with> | 1148 </py:with> |
1087 </div>""") | 1149 </div>""") |
1088 self.assertEqual("""<div> | 1150 self.assertEqual("""<div> |
1089 here is a semicolon: ; | 1151 here is a semicolon: ; |
1090 here are two semicolons: ;; | 1152 here are two semicolons: ;; |
1091 </div>""", str(tmpl.generate())) | 1153 </div>""", tmpl.generate().render(encoding=None)) |
1092 | 1154 |
1093 def test_ast_transformation(self): | 1155 def test_ast_transformation(self): |
1094 """ | 1156 """ |
1095 Verify that the usual template expression AST transformations are | 1157 Verify that the usual template expression AST transformations are |
1096 applied despite the code being compiled to a `Suite` object. | 1158 applied despite the code being compiled to a `Suite` object. |
1102 </div>""") | 1164 </div>""") |
1103 self.assertEqual("""<div> | 1165 self.assertEqual("""<div> |
1104 <span> | 1166 <span> |
1105 42 | 1167 42 |
1106 </span> | 1168 </span> |
1107 </div>""", str(tmpl.generate(foo={'bar': 42}))) | 1169 </div>""", tmpl.generate(foo={'bar': 42}).render(encoding=None)) |
1108 | 1170 |
1109 def test_unicode_expr(self): | 1171 def test_unicode_expr(self): |
1110 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1172 tmpl = MarkupTemplate(u"""<div xmlns:py="http://genshi.edgewall.org/"> |
1111 <span py:with="weeks=(u'一', u'二', u'三', u'四', u'五', u'六', u'日')"> | 1173 <span py:with="weeks=(u'一', u'二', u'三', u'四', u'五', u'六', u'日')"> |
1112 $weeks | 1174 $weeks |
1113 </span> | 1175 </span> |
1114 </div>""") | 1176 </div>""") |
1115 self.assertEqual("""<div> | 1177 self.assertEqual(u"""<div> |
1116 <span> | 1178 <span> |
1117 一二三四五六日 | 1179 一二三四五六日 |
1118 </span> | 1180 </span> |
1119 </div>""", str(tmpl.generate())) | 1181 </div>""", tmpl.generate().render(encoding=None)) |
1120 | 1182 |
1121 def test_with_empty_value(self): | 1183 def test_with_empty_value(self): |
1122 """ | 1184 """ |
1123 Verify that an empty py:with works (useless, but legal) | 1185 Verify that an empty py:with works (useless, but legal) |
1124 """ | 1186 """ |
1125 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> | 1187 tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> |
1126 <span py:with="">Text</span></div>""") | 1188 <span py:with="">Text</span></div>""") |
1127 | 1189 |
1128 self.assertEqual("""<div> | 1190 self.assertEqual("""<div> |
1129 <span>Text</span></div>""", str(tmpl.generate())) | 1191 <span>Text</span></div>""", tmpl.generate().render(encoding=None)) |
1130 | 1192 |
1131 | 1193 |
1132 def suite(): | 1194 def suite(): |
1133 suite = unittest.TestSuite() | 1195 suite = unittest.TestSuite() |
1134 suite.addTest(doctest.DocTestSuite(directives)) | 1196 suite.addTest(doctest.DocTestSuite(directives)) |