def test_relative_load(self): loader = DictLoader({ "a/1.html": "{% include '2.html' %}", "a/2.html": "{% include '../b/3.html' %}", "b/3.html": "ok", }) self.assertEqual(loader.load("a/1.html").generate(), b"ok")
def test_include(self): loader = DictLoader({ "index.html": '{% include "header.html" %}\nbody text', "header.html": "header text", }) self.assertEqual( loader.load("index.html").generate(), b"header text\nbody text")
def test_unextended_block(self): loader = DictLoader(self.templates) name = "<script>" self.assertEqual( loader.load("escaped_block.html").generate(name=name), b"base: <script>") self.assertEqual( loader.load("unescaped_block.html").generate(name=name), b"base: <script>")
def test_details(self): loader = DictLoader({ "foo.html": "\n\n{{", }) with self.assertRaises(ParseError) as cm: loader.load("foo.html") self.assertEqual("Missing end expression }} at foo.html:3", str(cm.exception)) self.assertEqual("foo.html", cm.exception.filename) self.assertEqual(3, cm.exception.lineno)
def test_error_line_number_expression(self): loader = DictLoader({"test.html": """one two{{1/0}} three """}) try: loader.load("test.html").generate() self.fail("did not get expected exception") except ZeroDivisionError: self.assertTrue("# test.html:2" in traceback.format_exc())
def test_error_line_number_extends_base_error(self): loader = DictLoader({ "base.html": "{{1/0}}", "sub.html": "{% extends 'base.html' %}", }) try: loader.load("sub.html").generate() self.fail("did not get expected exception") except ZeroDivisionError: exc_stack = traceback.format_exc() self.assertTrue("# base.html:1" in exc_stack)
def test_error_line_number_include(self): loader = DictLoader({ "base.html": "{% include 'sub.html' %}", "sub.html": "{{1/0}}", }) try: loader.load("base.html").generate() self.fail("did not get expected exception") except ZeroDivisionError: self.assertTrue( "# sub.html:1 (via base.html:1)" in traceback.format_exc())
def test_multi_includes(self): loader = DictLoader({ "a.html": "{% include 'b.html' %}", "b.html": "{% include 'c.html' %}", "c.html": "{{1/0}}", }) try: loader.load("a.html").generate() self.fail("did not get expected exception") except ZeroDivisionError: self.assertTrue("# c.html:1 (via b.html:1, a.html:1)" in traceback.format_exc())
def test_manual_minimize_whitespace(self): # Whitespace including newlines is allowed within template tags # and directives, and this is one way to avoid long lines while # keeping extra whitespace out of the rendered output. loader = DictLoader({ 'foo.txt': """\ {% for i in items %}{% if i > 0 %}, {% end %}{# #}{{i }}{% end %}""", }) self.assertEqual( loader.load("foo.txt").generate(items=range(5)), b"0, 1, 2, 3, 4")
def test_whitespace_directive(self): loader = DictLoader({ "foo.html": """\ {% whitespace oneline %} {% for i in range(3) %} {{ i }} {% end %} {% whitespace all %} pre\tformatted """ }) self.assertEqual( loader.load("foo.html").generate(), b" 0 1 2 \n pre\tformatted\n")
def test_extends(self): loader = DictLoader({ "base.html": """\ <title>{% block title %}default title{% end %}</title> <body>{% block body %}default body{% end %}</body> """, "page.html": """\ {% extends "base.html" %} {% block title %}page title{% end %} {% block body %}page body{% end %} """, }) self.assertEqual( loader.load("page.html").generate(), b"<title>page title</title>\n<body>page body</body>\n")
def test_error_line_number_module(self): loader = DictLoader( { "base.html": "{% module Template('sub.html') %}", "sub.html": "{{1/0}}", }, namespace={ "_tt_modules": ObjectDict(Template=lambda path, **kwargs: loader.load(path). generate(**kwargs)) }) try: loader.load("base.html").generate() self.fail("did not get expected exception") except ZeroDivisionError: exc_stack = traceback.format_exc() self.assertTrue('# base.html:1' in exc_stack) self.assertTrue('# sub.html:1' in exc_stack)
def test_raw_expression(self): loader = DictLoader(self.templates) def render(name): return loader.load(name).generate(name='<>&"') self.assertEqual(render("raw_expression.html"), b"expr: <>&"\n" b"raw: <>&\"")
def test_error_line_number_extends_sub_error(self): loader = DictLoader({ "base.html": "{% block 'block' %}{% end %}", "sub.html": """ {% extends 'base.html' %} {% block 'block' %} {{1/0}} {% end %} """ }) try: loader.load("sub.html").generate() self.fail("did not get expected exception") except ZeroDivisionError: self.assertTrue( "# sub.html:4 (via base.html:1)" in traceback.format_exc())
def test_extended_block(self): loader = DictLoader(self.templates) def render(name): return loader.load(name).generate(name="<script>") self.assertEqual(render("escaped_extends_unescaped.html"), b"base: <script>") self.assertEqual(render("escaped_overrides_unescaped.html"), b"extended: <script>") self.assertEqual(render("unescaped_extends_escaped.html"), b"base: <script>") self.assertEqual(render("unescaped_overrides_escaped.html"), b"extended: <script>")
def test_custom_escape(self): loader = DictLoader( {"foo.py": "{% autoescape py_escape %}s = {{ name }}\n"}) def py_escape(s): self.assertEqual(type(s), bytes) return repr(native_str(s)) def render(template, name): return loader.load(template).generate(py_escape=py_escape, name=name) self.assertEqual(render("foo.py", "<html>"), b"s = '<html>'\n") self.assertEqual(render("foo.py", "';sys.exit()"), b"""s = "';sys.exit()"\n""") self.assertEqual(render("foo.py", ["not a string"]), b"""s = "['not a string']"\n""")
def test_default_off(self): loader = DictLoader(self.templates, autoescape=None) name = "Bobby <table>s" self.assertEqual( loader.load("escaped.html").generate(name=name), b"Bobby <table>s") self.assertEqual( loader.load("unescaped.html").generate(name=name), b"Bobby <table>s") self.assertEqual( loader.load("default.html").generate(name=name), b"Bobby <table>s") self.assertEqual( loader.load("include.html").generate(name=name), b"escaped: Bobby <table>s\n" b"unescaped: Bobby <table>s\n" b"default: Bobby <table>s\n")
def test_whitespace_by_filename(self): # Default whitespace handling depends on the template filename. loader = DictLoader({ "foo.html": " \n\t\n asdf\t ", "bar.js": " \n\n\n\t qwer ", "baz.txt": "\t zxcv\n\n", "include.html": " {% include baz.txt %} \n ", "include.txt": "\t\t{% include foo.html %} ", }) # HTML and JS files have whitespace compressed by default. self.assertEqual(loader.load("foo.html").generate(), b"\nasdf ") self.assertEqual(loader.load("bar.js").generate(), b"\nqwer ") # TXT files do not. self.assertEqual(loader.load("baz.txt").generate(), b"\t zxcv\n\n") # Each file maintains its own status even when included in # a file of the other type. self.assertEqual( loader.load("include.html").generate(), b" \t zxcv\n\n\n") self.assertEqual( loader.load("include.txt").generate(), b"\t\t\nasdf ")
def test_whitespace_by_loader(self): templates = { "foo.html": "\t\tfoo\n\n", "bar.txt": "\t\tbar\n\n", } loader = DictLoader(templates, whitespace='all') self.assertEqual(loader.load("foo.html").generate(), b"\t\tfoo\n\n") self.assertEqual(loader.load("bar.txt").generate(), b"\t\tbar\n\n") loader = DictLoader(templates, whitespace='single') self.assertEqual(loader.load("foo.html").generate(), b" foo\n") self.assertEqual(loader.load("bar.txt").generate(), b" bar\n") loader = DictLoader(templates, whitespace='oneline') self.assertEqual(loader.load("foo.html").generate(), b" foo ") self.assertEqual(loader.load("bar.txt").generate(), b" bar ")
def test_custom_namespace(self): loader = DictLoader({"test.html": "{{ inc(5) }}"}, namespace={"inc": lambda x: x + 1}) self.assertEqual(loader.load("test.html").generate(), b"6")
def test_non_ascii_name(self): loader = DictLoader({u"t\u00e9st.html": "hello"}) self.assertEqual(loader.load(u"t\u00e9st.html").generate(), b"hello")