| 1 | # -*- coding: utf-8 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2006-2007 Edgewall Software |
|---|
| 4 | # Copyright (C) 2006 Matthew Good |
|---|
| 5 | # All rights reserved. |
|---|
| 6 | # |
|---|
| 7 | # This software is licensed as described in the file COPYING, which |
|---|
| 8 | # you should have received as part of this distribution. The terms |
|---|
| 9 | # are also available at http://genshi.edgewall.org/wiki/License. |
|---|
| 10 | # |
|---|
| 11 | # This software consists of voluntary contributions made by many |
|---|
| 12 | # individuals. For the exact contribution history, see the revision |
|---|
| 13 | # history and logs, available at http://genshi.edgewall.org/log/. |
|---|
| 14 | |
|---|
| 15 | import doctest |
|---|
| 16 | import os |
|---|
| 17 | import unittest |
|---|
| 18 | |
|---|
| 19 | from genshi.core import Stream |
|---|
| 20 | from genshi.output import DocType |
|---|
| 21 | from genshi.template import MarkupTemplate, TextTemplate, NewTextTemplate |
|---|
| 22 | from genshi.template.plugin import ConfigurationError, \ |
|---|
| 23 | MarkupTemplateEnginePlugin, \ |
|---|
| 24 | TextTemplateEnginePlugin |
|---|
| 25 | |
|---|
| 26 | PACKAGE = 'genshi.template.tests' |
|---|
| 27 | |
|---|
| 28 | |
|---|
| 29 | class MarkupTemplateEnginePluginTestCase(unittest.TestCase): |
|---|
| 30 | |
|---|
| 31 | def test_init_no_options(self): |
|---|
| 32 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 33 | self.assertEqual(None, plugin.default_encoding) |
|---|
| 34 | self.assertEqual('html', plugin.default_format) |
|---|
| 35 | self.assertEqual(None, plugin.default_doctype) |
|---|
| 36 | |
|---|
| 37 | self.assertEqual([], plugin.loader.search_path) |
|---|
| 38 | self.assertEqual(True, plugin.loader.auto_reload) |
|---|
| 39 | self.assertEqual(25, plugin.loader._cache.capacity) |
|---|
| 40 | |
|---|
| 41 | def test_init_with_loader_options(self): |
|---|
| 42 | plugin = MarkupTemplateEnginePlugin(options={ |
|---|
| 43 | 'genshi.auto_reload': 'off', |
|---|
| 44 | 'genshi.max_cache_size': '100', |
|---|
| 45 | 'genshi.search_path': '/usr/share/tmpl:/usr/local/share/tmpl', |
|---|
| 46 | }) |
|---|
| 47 | self.assertEqual(['/usr/share/tmpl', '/usr/local/share/tmpl'], |
|---|
| 48 | plugin.loader.search_path) |
|---|
| 49 | self.assertEqual(False, plugin.loader.auto_reload) |
|---|
| 50 | self.assertEqual(100, plugin.loader._cache.capacity) |
|---|
| 51 | |
|---|
| 52 | def test_init_with_invalid_cache_size(self): |
|---|
| 53 | self.assertRaises(ConfigurationError, MarkupTemplateEnginePlugin, |
|---|
| 54 | options={'genshi.max_cache_size': 'thirty'}) |
|---|
| 55 | |
|---|
| 56 | def test_init_with_output_options(self): |
|---|
| 57 | plugin = MarkupTemplateEnginePlugin(options={ |
|---|
| 58 | 'genshi.default_encoding': 'iso-8859-15', |
|---|
| 59 | 'genshi.default_format': 'xhtml', |
|---|
| 60 | 'genshi.default_doctype': 'xhtml-strict', |
|---|
| 61 | }) |
|---|
| 62 | self.assertEqual('iso-8859-15', plugin.default_encoding) |
|---|
| 63 | self.assertEqual('xhtml', plugin.default_format) |
|---|
| 64 | self.assertEqual(DocType.XHTML, plugin.default_doctype) |
|---|
| 65 | |
|---|
| 66 | def test_init_with_invalid_output_format(self): |
|---|
| 67 | self.assertRaises(ConfigurationError, MarkupTemplateEnginePlugin, |
|---|
| 68 | options={'genshi.default_format': 'foobar'}) |
|---|
| 69 | |
|---|
| 70 | def test_init_with_invalid_doctype(self): |
|---|
| 71 | self.assertRaises(ConfigurationError, MarkupTemplateEnginePlugin, |
|---|
| 72 | options={'genshi.default_doctype': 'foobar'}) |
|---|
| 73 | |
|---|
| 74 | def test_load_template_from_file(self): |
|---|
| 75 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 76 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 77 | self.assertEqual('test.html', os.path.basename(tmpl.filename)) |
|---|
| 78 | assert isinstance(tmpl, MarkupTemplate) |
|---|
| 79 | |
|---|
| 80 | def test_load_template_from_string(self): |
|---|
| 81 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 82 | tmpl = plugin.load_template(None, template_string="""<p> |
|---|
| 83 | $message |
|---|
| 84 | </p>""") |
|---|
| 85 | self.assertEqual(None, tmpl.filename) |
|---|
| 86 | assert isinstance(tmpl, MarkupTemplate) |
|---|
| 87 | |
|---|
| 88 | def test_transform_with_load(self): |
|---|
| 89 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 90 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 91 | stream = plugin.transform({'message': 'Hello'}, tmpl) |
|---|
| 92 | assert isinstance(stream, Stream) |
|---|
| 93 | |
|---|
| 94 | def test_transform_without_load(self): |
|---|
| 95 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 96 | stream = plugin.transform({'message': 'Hello'}, |
|---|
| 97 | PACKAGE + '.templates.test') |
|---|
| 98 | assert isinstance(stream, Stream) |
|---|
| 99 | |
|---|
| 100 | def test_render(self): |
|---|
| 101 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 102 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 103 | output = plugin.render({'message': 'Hello'}, template=tmpl) |
|---|
| 104 | self.assertEqual("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|---|
| 105 | <html lang="en"> |
|---|
| 106 | <head> |
|---|
| 107 | <title>Test</title> |
|---|
| 108 | </head> |
|---|
| 109 | <body> |
|---|
| 110 | <h1>Test</h1> |
|---|
| 111 | <p>Hello</p> |
|---|
| 112 | </body> |
|---|
| 113 | </html>""", output) |
|---|
| 114 | |
|---|
| 115 | def test_render_with_format(self): |
|---|
| 116 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 117 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 118 | output = plugin.render({'message': 'Hello'}, format='xhtml', |
|---|
| 119 | template=tmpl) |
|---|
| 120 | self.assertEqual("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> |
|---|
| 121 | <html xmlns="http://www.w3.org/1999/xhtml" lang="en"> |
|---|
| 122 | <head> |
|---|
| 123 | <title>Test</title> |
|---|
| 124 | </head> |
|---|
| 125 | <body> |
|---|
| 126 | <h1>Test</h1> |
|---|
| 127 | <p>Hello</p> |
|---|
| 128 | </body> |
|---|
| 129 | </html>""", output) |
|---|
| 130 | |
|---|
| 131 | def test_render_with_doctype(self): |
|---|
| 132 | plugin = MarkupTemplateEnginePlugin(options={ |
|---|
| 133 | 'genshi.default_doctype': 'html-strict', |
|---|
| 134 | }) |
|---|
| 135 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 136 | output = plugin.render({'message': 'Hello'}, template=tmpl) |
|---|
| 137 | self.assertEqual("""<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> |
|---|
| 138 | <html lang="en"> |
|---|
| 139 | <head> |
|---|
| 140 | <title>Test</title> |
|---|
| 141 | </head> |
|---|
| 142 | <body> |
|---|
| 143 | <h1>Test</h1> |
|---|
| 144 | <p>Hello</p> |
|---|
| 145 | </body> |
|---|
| 146 | </html>""", output) |
|---|
| 147 | |
|---|
| 148 | def test_render_fragment_with_doctype(self): |
|---|
| 149 | plugin = MarkupTemplateEnginePlugin(options={ |
|---|
| 150 | 'genshi.default_doctype': 'html-strict', |
|---|
| 151 | }) |
|---|
| 152 | tmpl = plugin.load_template(PACKAGE + '.templates.test_no_doctype') |
|---|
| 153 | output = plugin.render({'message': 'Hello'}, template=tmpl, |
|---|
| 154 | fragment=True) |
|---|
| 155 | self.assertEqual("""<html lang="en"> |
|---|
| 156 | <head> |
|---|
| 157 | <title>Test</title> |
|---|
| 158 | </head> |
|---|
| 159 | <body> |
|---|
| 160 | <h1>Test</h1> |
|---|
| 161 | <p>Hello</p> |
|---|
| 162 | </body> |
|---|
| 163 | </html>""", output) |
|---|
| 164 | |
|---|
| 165 | def test_helper_functions(self): |
|---|
| 166 | plugin = MarkupTemplateEnginePlugin() |
|---|
| 167 | tmpl = plugin.load_template(PACKAGE + '.templates.functions') |
|---|
| 168 | output = plugin.render({'snippet': u'<b>Foo</b>'}, template=tmpl) |
|---|
| 169 | self.assertEqual("""<div> |
|---|
| 170 | False |
|---|
| 171 | bar |
|---|
| 172 | <b>Foo</b> |
|---|
| 173 | <b>Foo</b> |
|---|
| 174 | </div>""", output) |
|---|
| 175 | |
|---|
| 176 | |
|---|
| 177 | class TextTemplateEnginePluginTestCase(unittest.TestCase): |
|---|
| 178 | |
|---|
| 179 | def test_init_no_options(self): |
|---|
| 180 | plugin = TextTemplateEnginePlugin() |
|---|
| 181 | self.assertEqual(None, plugin.default_encoding) |
|---|
| 182 | self.assertEqual('text', plugin.default_format) |
|---|
| 183 | |
|---|
| 184 | self.assertEqual([], plugin.loader.search_path) |
|---|
| 185 | self.assertEqual(True, plugin.loader.auto_reload) |
|---|
| 186 | self.assertEqual(25, plugin.loader._cache.capacity) |
|---|
| 187 | |
|---|
| 188 | def test_init_with_loader_options(self): |
|---|
| 189 | plugin = TextTemplateEnginePlugin(options={ |
|---|
| 190 | 'genshi.auto_reload': 'off', |
|---|
| 191 | 'genshi.max_cache_size': '100', |
|---|
| 192 | 'genshi.search_path': '/usr/share/tmpl:/usr/local/share/tmpl', |
|---|
| 193 | }) |
|---|
| 194 | self.assertEqual(['/usr/share/tmpl', '/usr/local/share/tmpl'], |
|---|
| 195 | plugin.loader.search_path) |
|---|
| 196 | self.assertEqual(False, plugin.loader.auto_reload) |
|---|
| 197 | self.assertEqual(100, plugin.loader._cache.capacity) |
|---|
| 198 | |
|---|
| 199 | def test_init_with_output_options(self): |
|---|
| 200 | plugin = TextTemplateEnginePlugin(options={ |
|---|
| 201 | 'genshi.default_encoding': 'iso-8859-15', |
|---|
| 202 | }) |
|---|
| 203 | self.assertEqual('iso-8859-15', plugin.default_encoding) |
|---|
| 204 | |
|---|
| 205 | def test_init_with_new_syntax(self): |
|---|
| 206 | plugin = TextTemplateEnginePlugin(options={ |
|---|
| 207 | 'genshi.new_text_syntax': 'yes', |
|---|
| 208 | }) |
|---|
| 209 | self.assertEqual(NewTextTemplate, plugin.template_class) |
|---|
| 210 | tmpl = plugin.load_template(PACKAGE + '.templates.new_syntax') |
|---|
| 211 | output = plugin.render({'foo': True}, template=tmpl) |
|---|
| 212 | self.assertEqual('bar', output) |
|---|
| 213 | |
|---|
| 214 | def test_load_template_from_file(self): |
|---|
| 215 | plugin = TextTemplateEnginePlugin() |
|---|
| 216 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 217 | assert isinstance(tmpl, TextTemplate) |
|---|
| 218 | self.assertEqual('test.txt', os.path.basename(tmpl.filename)) |
|---|
| 219 | |
|---|
| 220 | def test_load_template_from_string(self): |
|---|
| 221 | plugin = TextTemplateEnginePlugin() |
|---|
| 222 | tmpl = plugin.load_template(None, template_string="$message") |
|---|
| 223 | self.assertEqual(None, tmpl.filename) |
|---|
| 224 | assert isinstance(tmpl, TextTemplate) |
|---|
| 225 | |
|---|
| 226 | def test_transform_without_load(self): |
|---|
| 227 | plugin = TextTemplateEnginePlugin() |
|---|
| 228 | stream = plugin.transform({'message': 'Hello'}, |
|---|
| 229 | PACKAGE + '.templates.test') |
|---|
| 230 | assert isinstance(stream, Stream) |
|---|
| 231 | |
|---|
| 232 | def test_transform_with_load(self): |
|---|
| 233 | plugin = TextTemplateEnginePlugin() |
|---|
| 234 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 235 | stream = plugin.transform({'message': 'Hello'}, tmpl) |
|---|
| 236 | assert isinstance(stream, Stream) |
|---|
| 237 | |
|---|
| 238 | def test_render(self): |
|---|
| 239 | plugin = TextTemplateEnginePlugin() |
|---|
| 240 | tmpl = plugin.load_template(PACKAGE + '.templates.test') |
|---|
| 241 | output = plugin.render({'message': 'Hello'}, template=tmpl) |
|---|
| 242 | self.assertEqual("""Test |
|---|
| 243 | ==== |
|---|
| 244 | |
|---|
| 245 | Hello |
|---|
| 246 | """, output) |
|---|
| 247 | |
|---|
| 248 | def test_helper_functions(self): |
|---|
| 249 | plugin = TextTemplateEnginePlugin() |
|---|
| 250 | tmpl = plugin.load_template(PACKAGE + '.templates.functions') |
|---|
| 251 | output = plugin.render({}, template=tmpl) |
|---|
| 252 | self.assertEqual("""False |
|---|
| 253 | bar |
|---|
| 254 | """, output) |
|---|
| 255 | |
|---|
| 256 | |
|---|
| 257 | def suite(): |
|---|
| 258 | suite = unittest.TestSuite() |
|---|
| 259 | suite.addTest(unittest.makeSuite(MarkupTemplateEnginePluginTestCase, 'test')) |
|---|
| 260 | suite.addTest(unittest.makeSuite(TextTemplateEnginePluginTestCase, 'test')) |
|---|
| 261 | return suite |
|---|
| 262 | |
|---|
| 263 | if __name__ == '__main__': |
|---|
| 264 | unittest.main(defaultTest='suite') |
|---|