cmlenz@1: # -*- coding: utf-8 -*- cmlenz@1: # cmlenz@66: # Copyright (C) 2006 Edgewall Software cmlenz@1: # All rights reserved. cmlenz@1: # cmlenz@1: # This software is licensed as described in the file COPYING, which cmlenz@1: # you should have received as part of this distribution. The terms cmlenz@66: # are also available at http://markup.edgewall.org/wiki/License. cmlenz@1: # cmlenz@1: # This software consists of voluntary contributions made by many cmlenz@1: # individuals. For the exact contribution history, see the revision cmlenz@66: # history and logs, available at http://markup.edgewall.org/log/. cmlenz@1: cmlenz@1: import doctest cmlenz@1: import unittest cmlenz@1: import sys cmlenz@1: cmlenz@54: from markup.core import Markup, Stream cmlenz@149: from markup.template import BadDirectiveError, Template, TemplateSyntaxError cmlenz@1: cmlenz@1: cmlenz@50: class AttrsDirectiveTestCase(unittest.TestCase): cmlenz@50: """Tests for the `py:attrs` template directive.""" cmlenz@50: cmlenz@50: def test_combined_with_loop(self): cmlenz@50: """ cmlenz@50: Verify that the directive has access to the loop variables. cmlenz@50: """ cmlenz@61: tmpl = Template(""" cmlenz@50: cmlenz@50: """) cmlenz@50: items = [{'id': 1, 'class': 'foo'}, {'id': 2, 'class': 'bar'}] cmlenz@50: self.assertEqual(""" cmlenz@50: cmlenz@149: """, str(tmpl.generate(items=items))) cmlenz@50: cmlenz@54: def test_update_existing_attr(self): cmlenz@54: """ cmlenz@54: Verify that an attribute value that evaluates to `None` removes an cmlenz@54: existing attribute of that name. cmlenz@54: """ cmlenz@61: tmpl = Template(""" cmlenz@54: cmlenz@54: """) cmlenz@54: self.assertEqual(""" cmlenz@54: cmlenz@54: """, str(tmpl.generate())) cmlenz@54: cmlenz@54: def test_remove_existing_attr(self): cmlenz@54: """ cmlenz@54: Verify that an attribute value that evaluates to `None` removes an cmlenz@54: existing attribute of that name. cmlenz@54: """ cmlenz@61: tmpl = Template(""" cmlenz@54: cmlenz@54: """) cmlenz@54: self.assertEqual(""" cmlenz@54: cmlenz@54: """, str(tmpl.generate())) cmlenz@54: cmlenz@50: cmlenz@53: class ChooseDirectiveTestCase(unittest.TestCase): cmlenz@53: """Tests for the `py:choose` template directive and the complementary cmlenz@53: directives `py:when` and `py:otherwise`.""" cmlenz@53: cmlenz@53: def test_multiple_true_whens(self): cmlenz@53: """ cmlenz@53: Verify that, if multiple `py:when` bodies match, only the first is cmlenz@53: output. cmlenz@53: """ cmlenz@61: tmpl = Template("""
cmlenz@53: 1 cmlenz@53: 2 cmlenz@53: 3 cmlenz@53:
""") cmlenz@53: self.assertEqual("""
cmlenz@53: 1 cmlenz@53:
""", str(tmpl.generate())) cmlenz@53: cmlenz@53: def test_otherwise(self): cmlenz@61: tmpl = Template("""
cmlenz@53: hidden cmlenz@53: hello cmlenz@53:
""") cmlenz@53: self.assertEqual("""
cmlenz@53: hello cmlenz@53:
""", str(tmpl.generate())) cmlenz@53: cmlenz@53: def test_nesting(self): cmlenz@53: """ cmlenz@53: Verify that `py:choose` blocks can be nested: cmlenz@53: """ cmlenz@61: tmpl = Template(""" cmlenz@53:
cmlenz@53:
cmlenz@53: 2 cmlenz@53: 3 cmlenz@53:
cmlenz@53:
cmlenz@53:
""") cmlenz@53: self.assertEqual(""" cmlenz@53:
cmlenz@53:
cmlenz@53: 3 cmlenz@53:
cmlenz@53:
cmlenz@53:
""", str(tmpl.generate())) cmlenz@53: cmlenz@53: def test_when_with_strip(self): cmlenz@53: """ cmlenz@53: Verify that a when directive with a strip directive actually strips of cmlenz@53: the outer element. cmlenz@53: """ cmlenz@61: tmpl = Template(""" cmlenz@53:
cmlenz@53: foo cmlenz@53:
cmlenz@53:
""") cmlenz@53: self.assertEqual(""" cmlenz@53: foo cmlenz@53: """, str(tmpl.generate())) cmlenz@53: cmlenz@65: def test_as_element(self): cmlenz@65: """ cmlenz@65: Verify that the directive can also be used as an element. cmlenz@65: """ cmlenz@65: tmpl = Template(""" cmlenz@65: cmlenz@65: 1 cmlenz@65: 2 cmlenz@65: 3 cmlenz@65: cmlenz@65: """) cmlenz@65: self.assertEqual(""" cmlenz@65: 1 cmlenz@65: """, str(tmpl.generate())) cmlenz@65: cmlenz@53: cmlenz@50: class DefDirectiveTestCase(unittest.TestCase): cmlenz@50: """Tests for the `py:def` template directive.""" cmlenz@50: cmlenz@50: def test_function_with_strip(self): cmlenz@50: """ cmlenz@53: Verify that a named template function with a strip directive actually cmlenz@53: strips of the outer element. cmlenz@50: """ cmlenz@61: tmpl = Template(""" cmlenz@50:
cmlenz@50: ${what} cmlenz@50:
cmlenz@50: ${echo('foo')} cmlenz@50:
""") cmlenz@50: self.assertEqual(""" cmlenz@50: foo cmlenz@50: """, str(tmpl.generate())) cmlenz@50: cmlenz@90: def test_exec_in_replace(self): cmlenz@90: tmpl = Template("""
cmlenz@90:

cmlenz@90: ${greeting}, ${name}! cmlenz@90:

cmlenz@90:
cmlenz@90:
""") cmlenz@90: self.assertEqual("""
cmlenz@90:

cmlenz@90: hello, world! cmlenz@90:

cmlenz@90:
""", str(tmpl.generate())) cmlenz@90: cmlenz@65: def test_as_element(self): cmlenz@65: """ cmlenz@65: Verify that the directive can also be used as an element. cmlenz@65: """ cmlenz@65: tmpl = Template(""" cmlenz@65: cmlenz@65: ${what} cmlenz@65: cmlenz@65: ${echo('foo')} cmlenz@65: """) cmlenz@65: self.assertEqual(""" cmlenz@65: foo cmlenz@65: """, str(tmpl.generate())) cmlenz@65: cmlenz@50: cmlenz@51: class ForDirectiveTestCase(unittest.TestCase): cmlenz@53: """Tests for the `py:for` template directive.""" cmlenz@51: cmlenz@51: def test_loop_with_strip(self): cmlenz@51: """ cmlenz@53: Verify that the combining the `py:for` directive with `py:strip` works cmlenz@53: correctly. cmlenz@51: """ cmlenz@61: tmpl = Template(""" cmlenz@51:
cmlenz@51: ${item} cmlenz@51:
cmlenz@51:
""") cmlenz@51: self.assertEqual(""" cmlenz@51: 1 cmlenz@51: 2 cmlenz@51: 3 cmlenz@51: 4 cmlenz@51: 5 cmlenz@149: """, str(tmpl.generate(items=range(1, 6)))) cmlenz@51: cmlenz@65: def test_as_element(self): cmlenz@65: """ cmlenz@65: Verify that the directive can also be used as an element. cmlenz@65: """ cmlenz@65: tmpl = Template(""" cmlenz@65: cmlenz@65: ${item} cmlenz@65: cmlenz@65: """) cmlenz@65: self.assertEqual(""" cmlenz@65: 1 cmlenz@65: 2 cmlenz@65: 3 cmlenz@65: 4 cmlenz@65: 5 cmlenz@149: """, str(tmpl.generate(items=range(1, 6)))) cmlenz@65: cmlenz@65: cmlenz@65: class IfDirectiveTestCase(unittest.TestCase): cmlenz@65: """Tests for the `py:if` template directive.""" cmlenz@65: cmlenz@65: def test_loop_with_strip(self): cmlenz@65: """ cmlenz@65: Verify that the combining the `py:if` directive with `py:strip` works cmlenz@65: correctly. cmlenz@65: """ cmlenz@65: tmpl = Template(""" cmlenz@65: ${bar} cmlenz@65: """) cmlenz@65: self.assertEqual(""" cmlenz@65: Hello cmlenz@149: """, str(tmpl.generate(foo=True, bar='Hello'))) cmlenz@65: cmlenz@65: def test_as_element(self): cmlenz@65: """ cmlenz@65: Verify that the directive can also be used as an element. cmlenz@65: """ cmlenz@65: tmpl = Template(""" cmlenz@65: ${bar} cmlenz@65: """) cmlenz@65: self.assertEqual(""" cmlenz@65: Hello cmlenz@149: """, str(tmpl.generate(foo=True, bar='Hello'))) cmlenz@65: cmlenz@51: cmlenz@36: class MatchDirectiveTestCase(unittest.TestCase): cmlenz@36: """Tests for the `py:match` template directive.""" cmlenz@36: cmlenz@50: def test_with_strip(self): cmlenz@50: """ cmlenz@50: Verify that a match template can produce the same kind of element that cmlenz@50: it matched without entering an infinite recursion. cmlenz@50: """ cmlenz@61: tmpl = Template(""" cmlenz@50: cmlenz@50:
${select('*/text()')}
cmlenz@50:
cmlenz@50: Hey Joe cmlenz@50:
""") cmlenz@50: self.assertEqual(""" cmlenz@50:
Hey Joe
cmlenz@50:
""", str(tmpl.generate())) cmlenz@50: cmlenz@36: def test_without_strip(self): cmlenz@36: """ cmlenz@36: Verify that a match template can produce the same kind of element that cmlenz@36: it matched without entering an infinite recursion. cmlenz@36: """ cmlenz@61: tmpl = Template(""" cmlenz@36: cmlenz@36:
${select('*/text()')}
cmlenz@36:
cmlenz@36: Hey Joe cmlenz@37:
""") cmlenz@36: self.assertEqual(""" cmlenz@36: cmlenz@36:
Hey Joe
cmlenz@36:
cmlenz@36:
""", str(tmpl.generate())) cmlenz@36: cmlenz@65: def test_as_element(self): cmlenz@65: """ cmlenz@65: Verify that the directive can also be used as an element. cmlenz@65: """ cmlenz@65: tmpl = Template(""" cmlenz@65: cmlenz@65:
${select('*/text()')}
cmlenz@65:
cmlenz@65: Hey Joe cmlenz@65:
""") cmlenz@65: self.assertEqual(""" cmlenz@65:
Hey Joe
cmlenz@65:
""", str(tmpl.generate())) cmlenz@65: cmlenz@36: def test_recursive_match_1(self): cmlenz@36: """ cmlenz@36: Match directives are applied recursively, meaning that they are also cmlenz@36: applied to any content they may have produced themselves: cmlenz@36: """ cmlenz@61: tmpl = Template(""" cmlenz@36: cmlenz@36:
cmlenz@36: ${select('*/*')} cmlenz@36:
cmlenz@36:
cmlenz@36: cmlenz@36: cmlenz@36: cmlenz@36: cmlenz@36: cmlenz@37:
""") cmlenz@36: self.assertEqual(""" cmlenz@36: cmlenz@36:
cmlenz@36: cmlenz@36: cmlenz@36:
cmlenz@36:
cmlenz@36:
cmlenz@36:
cmlenz@36:
cmlenz@36:
cmlenz@36:
""", str(tmpl.generate())) cmlenz@36: cmlenz@36: def test_recursive_match_2(self): cmlenz@36: """ cmlenz@36: When two or more match templates match the same element and also cmlenz@36: themselves output the element they match, avoiding recursion is even cmlenz@36: more complex, but should work. cmlenz@36: """ cmlenz@61: tmpl = Template(""" cmlenz@36: cmlenz@36: