# -*- coding: utf-8 -*- """ jinja2.testsuite.loader ~~~~~~~~~~~~~~~~~~~~~~~ Test the loaders. :copyright: (c) 2010 by the Jinja Team. :license: BSD, see LICENSE for more details. """ import os import sys import tempfile import shutil import unittest from jinja2.testsuite import JinjaTestCase, dict_loader, \ package_loader, filesystem_loader, function_loader, \ choice_loader, prefix_loader from jinja2 import Environment, loaders from jinja2._compat import PYPY, PY2 from jinja2.loaders import split_template_path from jinja2.exceptions import TemplateNotFound class LoaderTestCase(JinjaTestCase): def test_dict_loader(self): env = Environment(loader=dict_loader) tmpl = env.get_template('justdict.html') assert tmpl.render().strip() == 'FOO' self.assert_raises(TemplateNotFound, env.get_template, 'missing.html') def test_package_loader(self): env = Environment(loader=package_loader) tmpl = env.get_template('test.html') assert tmpl.render().strip() == 'BAR' self.assert_raises(TemplateNotFound, env.get_template, 'missing.html') def test_filesystem_loader(self): env = Environment(loader=filesystem_loader) tmpl = env.get_template('test.html') assert tmpl.render().strip() == 'BAR' tmpl = env.get_template('foo/test.html') assert tmpl.render().strip() == 'FOO' self.assert_raises(TemplateNotFound, env.get_template, 'missing.html') def test_choice_loader(self): env = Environment(loader=choice_loader) tmpl = env.get_template('justdict.html') assert tmpl.render().strip() == 'FOO' tmpl = env.get_template('test.html') assert tmpl.render().strip() == 'BAR' self.assert_raises(TemplateNotFound, env.get_template, 'missing.html') def test_function_loader(self): env = Environment(loader=function_loader) tmpl = env.get_template('justfunction.html') assert tmpl.render().strip() == 'FOO' self.assert_raises(TemplateNotFound, env.get_template, 'missing.html') def test_prefix_loader(self): env = Environment(loader=prefix_loader) tmpl = env.get_template('a/test.html') assert tmpl.render().strip() == 'BAR' tmpl = env.get_template('b/justdict.html') assert tmpl.render().strip() == 'FOO' self.assert_raises(TemplateNotFound, env.get_template, 'missing') def test_caching(self): changed = False class TestLoader(loaders.BaseLoader): def get_source(self, environment, template): return u'foo', None, lambda: not changed env = Environment(loader=TestLoader(), cache_size=-1) tmpl = env.get_template('template') assert tmpl is env.get_template('template') changed = True assert tmpl is not env.get_template('template') changed = False env = Environment(loader=TestLoader(), cache_size=0) assert env.get_template('template') \ is not env.get_template('template') env = Environment(loader=TestLoader(), cache_size=2) t1 = env.get_template('one') t2 = env.get_template('two') assert t2 is env.get_template('two') assert t1 is env.get_template('one') t3 = env.get_template('three') assert 'one' in env.cache assert 'two' not in env.cache assert 'three' in env.cache def test_dict_loader_cache_invalidates(self): mapping = {'foo': "one"} env = Environment(loader=loaders.DictLoader(mapping)) assert env.get_template('foo').render() == "one" mapping['foo'] = "two" assert env.get_template('foo').render() == "two" def test_split_template_path(self): assert split_template_path('foo/bar') == ['foo', 'bar'] assert split_template_path('./foo/bar') == ['foo', 'bar'] self.assert_raises(TemplateNotFound, split_template_path, '../foo') class ModuleLoaderTestCase(JinjaTestCase): archive = None def compile_down(self, zip='deflated', py_compile=False): super(ModuleLoaderTestCase, self).setup() log = [] self.reg_env = Environment(loader=prefix_loader) if zip is not None: self.archive = tempfile.mkstemp(suffix='.zip')[1] else: self.archive = tempfile.mkdtemp() self.reg_env.compile_templates(self.archive, zip=zip, log_function=log.append, py_compile=py_compile) self.mod_env = Environment(loader=loaders.ModuleLoader(self.archive)) return ''.join(log) def teardown(self): super(ModuleLoaderTestCase, self).teardown() if hasattr(self, 'mod_env'): if os.path.isfile(self.archive): os.remove(self.archive) else: shutil.rmtree(self.archive) self.archive = None def test_log(self): log = self.compile_down() assert 'Compiled "a/foo/test.html" as ' \ 'tmpl_a790caf9d669e39ea4d280d597ec891c4ef0404a' in log assert 'Finished compiling templates' in log assert 'Could not compile "a/syntaxerror.html": ' \ 'Encountered unknown tag \'endif\'' in log def _test_common(self): tmpl1 = self.reg_env.get_template('a/test.html') tmpl2 = self.mod_env.get_template('a/test.html') assert tmpl1.render() == tmpl2.render() tmpl1 = self.reg_env.get_template('b/justdict.html') tmpl2 = self.mod_env.get_template('b/justdict.html') assert tmpl1.render() == tmpl2.render() def test_deflated_zip_compile(self): self.compile_down(zip='deflated') self._test_common() def test_stored_zip_compile(self): self.compile_down(zip='stored') self._test_common() def test_filesystem_compile(self): self.compile_down(zip=None) self._test_common() def test_weak_references(self): self.compile_down() tmpl = self.mod_env.get_template('a/test.html') key = loaders.ModuleLoader.get_template_key('a/test.html') name = self.mod_env.loader.module.__name__ assert hasattr(self.mod_env.loader.module, key) assert name in sys.modules # unset all, ensure the module is gone from sys.modules self.mod_env = tmpl = None try: import gc gc.collect() except: pass assert name not in sys.modules # This test only makes sense on non-pypy python 2 if PY2 and not PYPY: def test_byte_compilation(self): log = self.compile_down(py_compile=True) assert 'Byte-compiled "a/test.html"' in log tmpl1 = self.mod_env.get_template('a/test.html') mod = self.mod_env.loader.module. \ tmpl_3c4ddf650c1a73df961a6d3d2ce2752f1b8fd490 assert mod.__file__.endswith('.pyc') def test_choice_loader(self): log = self.compile_down() self.mod_env.loader = loaders.ChoiceLoader([ self.mod_env.loader, loaders.DictLoader({'DICT_SOURCE': 'DICT_TEMPLATE'}) ]) tmpl1 = self.mod_env.get_template('a/test.html') self.assert_equal(tmpl1.render(), 'BAR') tmpl2 = self.mod_env.get_template('DICT_SOURCE') self.assert_equal(tmpl2.render(), 'DICT_TEMPLATE') def test_prefix_loader(self): log = self.compile_down() self.mod_env.loader = loaders.PrefixLoader({ 'MOD': self.mod_env.loader, 'DICT': loaders.DictLoader({'test.html': 'DICT_TEMPLATE'}) }) tmpl1 = self.mod_env.get_template('MOD/a/test.html') self.assert_equal(tmpl1.render(), 'BAR') tmpl2 = self.mod_env.get_template('DICT/test.html') self.assert_equal(tmpl2.render(), 'DICT_TEMPLATE') def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(LoaderTestCase)) suite.addTest(unittest.makeSuite(ModuleLoaderTestCase)) return suite