Home | History | Annotate | Download | only in test
      1 # Copyright (C) 2004 Python Software Foundation
      2 # Author: barry (at] python.org (Barry Warsaw)
      3 # License: http://www.opensource.org/licenses/PythonSoftFoundation.php
      4 
      5 import unittest
      6 from string import Template
      7 
      8 
      9 class Bag:
     10     pass
     11 
     12 class Mapping:
     13     def __getitem__(self, name):
     14         obj = self
     15         for part in name.split('.'):
     16             try:
     17                 obj = getattr(obj, part)
     18             except AttributeError:
     19                 raise KeyError(name)
     20         return obj
     21 
     22 
     23 class TestTemplate(unittest.TestCase):
     24     def test_regular_templates(self):
     25         s = Template('$who likes to eat a bag of $what worth $$100')
     26         self.assertEqual(s.substitute(dict(who='tim', what='ham')),
     27                          'tim likes to eat a bag of ham worth $100')
     28         self.assertRaises(KeyError, s.substitute, dict(who='tim'))
     29 
     30     def test_regular_templates_with_braces(self):
     31         s = Template('$who likes ${what} for ${meal}')
     32         d = dict(who='tim', what='ham', meal='dinner')
     33         self.assertEqual(s.substitute(d), 'tim likes ham for dinner')
     34         self.assertRaises(KeyError, s.substitute,
     35                           dict(who='tim', what='ham'))
     36 
     37     def test_escapes(self):
     38         eq = self.assertEqual
     39         s = Template('$who likes to eat a bag of $$what worth $$100')
     40         eq(s.substitute(dict(who='tim', what='ham')),
     41            'tim likes to eat a bag of $what worth $100')
     42         s = Template('$who likes $$')
     43         eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $')
     44 
     45     def test_percents(self):
     46         eq = self.assertEqual
     47         s = Template('%(foo)s $foo ${foo}')
     48         d = dict(foo='baz')
     49         eq(s.substitute(d), '%(foo)s baz baz')
     50         eq(s.safe_substitute(d), '%(foo)s baz baz')
     51 
     52     def test_stringification(self):
     53         eq = self.assertEqual
     54         s = Template('tim has eaten $count bags of ham today')
     55         d = dict(count=7)
     56         eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
     57         eq(s.safe_substitute(d), 'tim has eaten 7 bags of ham today')
     58         s = Template('tim has eaten ${count} bags of ham today')
     59         eq(s.substitute(d), 'tim has eaten 7 bags of ham today')
     60 
     61     def test_tupleargs(self):
     62         eq = self.assertEqual
     63         s = Template('$who ate ${meal}')
     64         d = dict(who=('tim', 'fred'), meal=('ham', 'kung pao'))
     65         eq(s.substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
     66         eq(s.safe_substitute(d), "('tim', 'fred') ate ('ham', 'kung pao')")
     67 
     68     def test_SafeTemplate(self):
     69         eq = self.assertEqual
     70         s = Template('$who likes ${what} for ${meal}')
     71         eq(s.safe_substitute(dict(who='tim')), 'tim likes ${what} for ${meal}')
     72         eq(s.safe_substitute(dict(what='ham')), '$who likes ham for ${meal}')
     73         eq(s.safe_substitute(dict(what='ham', meal='dinner')),
     74            '$who likes ham for dinner')
     75         eq(s.safe_substitute(dict(who='tim', what='ham')),
     76            'tim likes ham for ${meal}')
     77         eq(s.safe_substitute(dict(who='tim', what='ham', meal='dinner')),
     78            'tim likes ham for dinner')
     79 
     80     def test_invalid_placeholders(self):
     81         raises = self.assertRaises
     82         s = Template('$who likes $')
     83         raises(ValueError, s.substitute, dict(who='tim'))
     84         s = Template('$who likes ${what)')
     85         raises(ValueError, s.substitute, dict(who='tim'))
     86         s = Template('$who likes $100')
     87         raises(ValueError, s.substitute, dict(who='tim'))
     88 
     89     def test_idpattern_override(self):
     90         class PathPattern(Template):
     91             idpattern = r'[_a-z][._a-z0-9]*'
     92         m = Mapping()
     93         m.bag = Bag()
     94         m.bag.foo = Bag()
     95         m.bag.foo.who = 'tim'
     96         m.bag.what = 'ham'
     97         s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what')
     98         self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
     99 
    100     def test_pattern_override(self):
    101         class MyPattern(Template):
    102             pattern = r"""
    103             (?P<escaped>@{2})                   |
    104             @(?P<named>[_a-z][._a-z0-9]*)       |
    105             @{(?P<braced>[_a-z][._a-z0-9]*)}    |
    106             (?P<invalid>@)
    107             """
    108         m = Mapping()
    109         m.bag = Bag()
    110         m.bag.foo = Bag()
    111         m.bag.foo.who = 'tim'
    112         m.bag.what = 'ham'
    113         s = MyPattern('@bag.foo.who likes to eat a bag of @bag.what')
    114         self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham')
    115 
    116         class BadPattern(Template):
    117             pattern = r"""
    118             (?P<badname>.*)                     |
    119             (?P<escaped>@{2})                   |
    120             @(?P<named>[_a-z][._a-z0-9]*)       |
    121             @{(?P<braced>[_a-z][._a-z0-9]*)}    |
    122             (?P<invalid>@)                      |
    123             """
    124         s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what')
    125         self.assertRaises(ValueError, s.substitute, {})
    126         self.assertRaises(ValueError, s.safe_substitute, {})
    127 
    128     def test_unicode_values(self):
    129         s = Template('$who likes $what')
    130         d = dict(who=u't\xffm', what=u'f\xfe\fed')
    131         self.assertEqual(s.substitute(d), u't\xffm likes f\xfe\x0ced')
    132 
    133     def test_keyword_arguments(self):
    134         eq = self.assertEqual
    135         s = Template('$who likes $what')
    136         eq(s.substitute(who='tim', what='ham'), 'tim likes ham')
    137         eq(s.substitute(dict(who='tim'), what='ham'), 'tim likes ham')
    138         eq(s.substitute(dict(who='fred', what='kung pao'),
    139                         who='tim', what='ham'),
    140            'tim likes ham')
    141         s = Template('the mapping is $mapping')
    142         eq(s.substitute(dict(foo='none'), mapping='bozo'),
    143            'the mapping is bozo')
    144         eq(s.substitute(dict(mapping='one'), mapping='two'),
    145            'the mapping is two')
    146 
    147     def test_keyword_arguments_safe(self):
    148         eq = self.assertEqual
    149         raises = self.assertRaises
    150         s = Template('$who likes $what')
    151         eq(s.safe_substitute(who='tim', what='ham'), 'tim likes ham')
    152         eq(s.safe_substitute(dict(who='tim'), what='ham'), 'tim likes ham')
    153         eq(s.safe_substitute(dict(who='fred', what='kung pao'),
    154                         who='tim', what='ham'),
    155            'tim likes ham')
    156         s = Template('the mapping is $mapping')
    157         eq(s.safe_substitute(dict(foo='none'), mapping='bozo'),
    158            'the mapping is bozo')
    159         eq(s.safe_substitute(dict(mapping='one'), mapping='two'),
    160            'the mapping is two')
    161         d = dict(mapping='one')
    162         raises(TypeError, s.substitute, d, {})
    163         raises(TypeError, s.safe_substitute, d, {})
    164 
    165     def test_delimiter_override(self):
    166         eq = self.assertEqual
    167         raises = self.assertRaises
    168         class AmpersandTemplate(Template):
    169             delimiter = '&'
    170         s = AmpersandTemplate('this &gift is for &{who} &&')
    171         eq(s.substitute(gift='bud', who='you'), 'this bud is for you &')
    172         raises(KeyError, s.substitute)
    173         eq(s.safe_substitute(gift='bud', who='you'), 'this bud is for you &')
    174         eq(s.safe_substitute(), 'this &gift is for &{who} &')
    175         s = AmpersandTemplate('this &gift is for &{who} &')
    176         raises(ValueError, s.substitute, dict(gift='bud', who='you'))
    177         eq(s.safe_substitute(), 'this &gift is for &{who} &')
    178 
    179         class PieDelims(Template):
    180             delimiter = '@'
    181         s = PieDelims('@who likes to eat a bag of @{what} worth $100')
    182         self.assertEqual(s.substitute(dict(who='tim', what='ham')),
    183                          'tim likes to eat a bag of ham worth $100')
    184 
    185 
    186 def test_main():
    187     from test import test_support
    188     test_classes = [TestTemplate,]
    189     test_support.run_unittest(*test_classes)
    190 
    191 
    192 if __name__ == '__main__':
    193     test_main()
    194