0001 # Copyright (C) 2004 Python Software Foundation 0002 # Author: barry@python.org (Barry Warsaw) 0003 # License: http://www.opensource.org/licenses/PythonSoftFoundation.php 0004 0005 import unittest 0006 from string import Template 0007 0008 0009 class Bag: 0010 pass 0011 0012 class Mapping: 0013 def __getitem__(self, name): 0014 obj = self 0015 for part in name.split('.'): 0016 try: 0017 obj = getattr(obj, part) 0018 except AttributeError: 0019 raise KeyError(name) 0020 return obj 0021 0022 0023 class TestTemplate(unittest.TestCase): 0024 def test_regular_templates(self): 0025 s = Template('$who likes to eat a bag of $what worth $$100') 0026 self.assertEqual(s.substitute(dict(who='tim', what='ham')), 0027 'tim likes to eat a bag of ham worth $100') 0028 self.assertRaises(KeyError, s.substitute, dict(who='tim')) 0029 0030 def test_regular_templates_with_braces(self): 0031 s = Template('$who likes ${what} for ${meal}') 0032 d = dict(who='tim', what='ham', meal='dinner') 0033 self.assertEqual(s.substitute(d), 'tim likes ham for dinner') 0034 self.assertRaises(KeyError, s.substitute, 0035 dict(who='tim', what='ham')) 0036 0037 def test_escapes(self): 0038 eq = self.assertEqual 0039 s = Template('$who likes to eat a bag of $$what worth $$100') 0040 eq(s.substitute(dict(who='tim', what='ham')), 0041 'tim likes to eat a bag of $what worth $100') 0042 s = Template('$who likes $$') 0043 eq(s.substitute(dict(who='tim', what='ham')), 'tim likes $') 0044 0045 def test_percents(self): 0046 eq = self.assertEqual 0047 s = Template('%(foo)s $foo ${foo}') 0048 d = dict(foo='baz') 0049 eq(s.substitute(d), '%(foo)s baz baz') 0050 eq(s.safe_substitute(d), '%(foo)s baz baz') 0051 0052 def test_stringification(self): 0053 eq = self.assertEqual 0054 s = Template('tim has eaten $count bags of ham today') 0055 d = dict(count=7) 0056 eq(s.substitute(d), 'tim has eaten 7 bags of ham today') 0057 eq(s.safe_substitute(d), 'tim has eaten 7 bags of ham today') 0058 s = Template('tim has eaten ${count} bags of ham today') 0059 eq(s.substitute(d), 'tim has eaten 7 bags of ham today') 0060 0061 def test_SafeTemplate(self): 0062 eq = self.assertEqual 0063 s = Template('$who likes ${what} for ${meal}') 0064 eq(s.safe_substitute(dict(who='tim')), 'tim likes ${what} for ${meal}') 0065 eq(s.safe_substitute(dict(what='ham')), '$who likes ham for ${meal}') 0066 eq(s.safe_substitute(dict(what='ham', meal='dinner')), 0067 '$who likes ham for dinner') 0068 eq(s.safe_substitute(dict(who='tim', what='ham')), 0069 'tim likes ham for ${meal}') 0070 eq(s.safe_substitute(dict(who='tim', what='ham', meal='dinner')), 0071 'tim likes ham for dinner') 0072 0073 def test_invalid_placeholders(self): 0074 raises = self.assertRaises 0075 s = Template('$who likes $') 0076 raises(ValueError, s.substitute, dict(who='tim')) 0077 s = Template('$who likes ${what)') 0078 raises(ValueError, s.substitute, dict(who='tim')) 0079 s = Template('$who likes $100') 0080 raises(ValueError, s.substitute, dict(who='tim')) 0081 0082 def test_delimiter_override(self): 0083 class PieDelims(Template): 0084 delimiter = '@' 0085 s = PieDelims('@who likes to eat a bag of @{what} worth $100') 0086 self.assertEqual(s.substitute(dict(who='tim', what='ham')), 0087 'tim likes to eat a bag of ham worth $100') 0088 0089 def test_idpattern_override(self): 0090 class PathPattern(Template): 0091 idpattern = r'[_a-z][._a-z0-9]*' 0092 m = Mapping() 0093 m.bag = Bag() 0094 m.bag.foo = Bag() 0095 m.bag.foo.who = 'tim' 0096 m.bag.what = 'ham' 0097 s = PathPattern('$bag.foo.who likes to eat a bag of $bag.what') 0098 self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham') 0099 0100 def test_pattern_override(self): 0101 class MyPattern(Template): 0102 pattern = r""" 0103 (?P<escaped>@{2}) | 0104 @(?P<named>[_a-z][._a-z0-9]*) | 0105 @{(?P<braced>[_a-z][._a-z0-9]*)} | 0106 (?P<invalid>@) 0107 """ 0108 m = Mapping() 0109 m.bag = Bag() 0110 m.bag.foo = Bag() 0111 m.bag.foo.who = 'tim' 0112 m.bag.what = 'ham' 0113 s = MyPattern('@bag.foo.who likes to eat a bag of @bag.what') 0114 self.assertEqual(s.substitute(m), 'tim likes to eat a bag of ham') 0115 0116 class BadPattern(Template): 0117 pattern = r""" 0118 (?P<badname>.*) | 0119 (?P<escaped>@{2}) | 0120 @(?P<named>[_a-z][._a-z0-9]*) | 0121 @{(?P<braced>[_a-z][._a-z0-9]*)} | 0122 (?P<invalid>@) | 0123 """ 0124 s = BadPattern('@bag.foo.who likes to eat a bag of @bag.what') 0125 self.assertRaises(ValueError, s.substitute, {}) 0126 self.assertRaises(ValueError, s.safe_substitute, {}) 0127 0128 def test_unicode_values(self): 0129 s = Template('$who likes $what') 0130 d = dict(who=u't\xffm', what=u'f\xfe\fed') 0131 self.assertEqual(s.substitute(d), u't\xffm likes f\xfe\x0ced') 0132 0133 def test_keyword_arguments(self): 0134 eq = self.assertEqual 0135 s = Template('$who likes $what') 0136 eq(s.substitute(who='tim', what='ham'), 'tim likes ham') 0137 eq(s.substitute(dict(who='tim'), what='ham'), 'tim likes ham') 0138 eq(s.substitute(dict(who='fred', what='kung pao'), 0139 who='tim', what='ham'), 0140 'tim likes ham') 0141 s = Template('the mapping is $mapping') 0142 eq(s.substitute(dict(foo='none'), mapping='bozo'), 0143 'the mapping is bozo') 0144 eq(s.substitute(dict(mapping='one'), mapping='two'), 0145 'the mapping is two') 0146 0147 def test_keyword_arguments_safe(self): 0148 eq = self.assertEqual 0149 raises = self.assertRaises 0150 s = Template('$who likes $what') 0151 eq(s.safe_substitute(who='tim', what='ham'), 'tim likes ham') 0152 eq(s.safe_substitute(dict(who='tim'), what='ham'), 'tim likes ham') 0153 eq(s.safe_substitute(dict(who='fred', what='kung pao'), 0154 who='tim', what='ham'), 0155 'tim likes ham') 0156 s = Template('the mapping is $mapping') 0157 eq(s.safe_substitute(dict(foo='none'), mapping='bozo'), 0158 'the mapping is bozo') 0159 eq(s.safe_substitute(dict(mapping='one'), mapping='two'), 0160 'the mapping is two') 0161 d = dict(mapping='one') 0162 raises(TypeError, s.substitute, d, {}) 0163 raises(TypeError, s.safe_substitute, d, {}) 0164 0165 def test_delimiter_override(self): 0166 eq = self.assertEqual 0167 raises = self.assertRaises 0168 class AmpersandTemplate(Template): 0169 delimiter = '&' 0170 s = AmpersandTemplate('this &gift is for &{who} &&') 0171 eq(s.substitute(gift='bud', who='you'), 'this bud is for you &') 0172 raises(KeyError, s.substitute) 0173 eq(s.safe_substitute(gift='bud', who='you'), 'this bud is for you &') 0174 eq(s.safe_substitute(), 'this &gift is for &{who} &') 0175 s = AmpersandTemplate('this &gift is for &{who} &') 0176 raises(ValueError, s.substitute, dict(gift='bud', who='you')) 0177 eq(s.safe_substitute(), 'this &gift is for &{who} &') 0178 0179 0180 def test_main(): 0181 from test import test_support 0182 test_classes = [TestTemplate,] 0183 test_support.run_unittest(*test_classes) 0184 0185 0186 if __name__ == '__main__': 0187 test_main() 0188
Generated by PyXR 0.9.4