[svn] fixed jinja inheritance bug and improved unittests
authorArmin Ronacher <armin.ronacher@active-4.com>
Sun, 18 Mar 2007 21:41:09 +0000 (22:41 +0100)
committerArmin Ronacher <armin.ronacher@active-4.com>
Sun, 18 Mar 2007 21:41:09 +0000 (22:41 +0100)
--HG--
branch : trunk

jinja/datastructure.py
jinja/translators/python.py
tests/conftest.py
tests/runtime/templates/c.html
tests/test_filters.py
tests/test_inheritance.py [new file with mode: 0644]
tests/test_macros.py [new file with mode: 0644]
tests/test_tests.py

index 2b53a5840494c7ed142c736e81d9775f67758fad..f409eb57898285a6097e9f0d37523109358b94f7 100644 (file)
@@ -56,7 +56,8 @@ class UndefinedType(object):
         return self
 
     def __iter__(self):
-        return iter(int, 0)
+        if False:
+            yield None
 
     def __getattr__(self, arg):
         return self
index 6d5b924803247e3c88e7c84096ead4fd7d772bb1..0a53a62e246b33496fa14da26d5f50fe39e9f90f 100644 (file)
@@ -257,6 +257,7 @@ class PythonTranslator(Translator):
         # root template.
         requirements_todo = []
         parent = None
+        overwrites = {}
 
         while node.extends is not None:
             # handle all requirements but not those from the
@@ -269,7 +270,6 @@ class PythonTranslator(Translator):
             parent = self.environment.loader.parse(node.extends.template,
                                                    node.filename)
             # look up all block nodes and let them override each other
-            overwrites = {}
             for n in get_nodes(nodes.Block, node):
                 overwrites[n.name] = n
             for n in get_nodes(nodes.Block, parent):
index 8ec3737d6c061b3aeb15cfc16aae5aec57379f16..aa060fa39d608c70442ac3cf731a5175bab542f9 100644 (file)
@@ -14,11 +14,29 @@ import sys
 sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
 
 import py
-from inspect import isclass
 from jinja import Environment
+from jinja.parser import Parser
 
 
-simple_env = Environment(trim_blocks=True)
+class GlobalLoader(object):
+
+    def __init__(self, scope):
+        self.scope = scope
+
+    def get_source(self, environment, name, parent, scope=None):
+        return self.scope[name.upper() + 'TEMPLATE']
+
+    def parse(self, environment, name, parent, scope=None):
+        return Parser(environment, self.get_source(environment, name,
+                      parent, scope), name).parse()
+
+    def load(self, environment, name, translator, scope=None):
+        return translator.process(environment, self.parse(environment,
+                                  name, None, scope))
+
+
+loader = GlobalLoader(globals())
+simple_env = Environment(trim_blocks=True, loader=loader)
 
 
 class Module(py.test.collect.Module):
@@ -29,27 +47,16 @@ class Module(py.test.collect.Module):
 
     def join(self, name):
         obj = getattr(self.obj, name)
-        if isclass(obj):
-            return JinjaClassCollector(name, parent=self)
-        elif hasattr(obj, 'func_code'):
+        if hasattr(obj, 'func_code'):
             return JinjaTestFunction(name, parent=self)
 
 
 class JinjaTestFunction(py.test.collect.Function):
 
     def execute(self, target, *args):
+        loader.scope = target.func_globals
         co = target.func_code
         if 'env' in co.co_varnames[:co.co_argcount]:
             target(self.parent.env, *args)
         else:
             target(*args)
-
-
-class JinjaClassCollector(py.test.collect.Class):
-
-    Function = JinjaTestFunction
-
-    def setup(self):
-        cls = self.obj
-        cls.env = self.parent.env
-        super(JinjaClassCollector, self).setup()
index 61e5a48ed9ab1cd9f36acd9fc4937df71a4115aa..1cc4f71061b95336bfd0ced357bce0b2b3419a07 100644 (file)
@@ -3,5 +3,4 @@
 {% block block3 %}from template c.html{% endblock %}
 {% block block7 %}
   nested block from b.html, overridden in c.html
-  {{ 1 / 0 }}
 {% endblock %}
index 2d728b04f6810c8cd22c38f94e626c1ea9cb739d..eab73d52e03ae1247ebd2cb9afb47fd21ec96cdf 100644 (file)
@@ -47,6 +47,8 @@ UPPER = '''{{ "foo"|upper }}'''
 URLENCODE = '''{{ "f#b"|urlencode }}'''
 URLIZE = '''{{ "foo http://www.example.com/ bar"|urlize }}'''
 WORDCOUNT = '''{{ "foo bar baz"|wordcount }}'''
+BLOCK = '''{% filter lower|escape %}<HEHE>{% endfilter %}'''
+CHAINING = '''{{ ['<foo>', '<bar>']|first|upper|escape }}'''
 
 
 def test_capitalize(env):
@@ -189,3 +191,13 @@ def test_urlize(env):
 def test_wordcount(env):
     tmpl = env.from_string(WORDCOUNT)
     assert tmpl.render() == '3'
+
+
+def test_block(env):
+    tmpl = env.from_string(BLOCK)
+    assert tmpl.render() == '&lt;hehe&gt;'
+
+
+def test_chaining(env):
+    tmpl = env.from_string(CHAINING)
+    assert tmpl.render() == '&lt;FOO&gt;'
diff --git a/tests/test_inheritance.py b/tests/test_inheritance.py
new file mode 100644 (file)
index 0000000..96a1065
--- /dev/null
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+"""
+    unit test for the inheritance
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+    :copyright: 2007 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+
+LAYOUTTEMPLATE = '''\
+|{% block block1 %}block 1 from layout{% endblock %}
+|{% block block2 %}block 2 from layout{% endblock %}
+|{% block block3 %}
+{% block block4 %}nested block 4 from layout{% endblock %}
+{% endblock %}|'''
+
+LEVEL1TEMPLATE = '''\
+{% extends "layout" %}
+{% block block1 %}block 1 from level1{% endblock %}'''
+
+LEVEL2TEMPLATE = '''\
+{% extends "level1" %}
+{% block block2 %}{% block block5 %}nested block 5 from level2{%
+endblock %}{% endblock %}'''
+
+LEVEL3TEMPLATE = '''\
+{% extends "level2" %}
+{% block block5 %}block 5 from level3{% endblock %}
+{% block block4 %}block 4 from level3{% endblock %}
+'''
+
+LEVEL4TEMPLATE = '''\
+{% extends "level3" %}
+{% block block3 %}block 3 from level4{% endblock %}
+'''
+
+
+def test_layout(env):
+    tmpl = env.get_template('layout')
+    assert tmpl.render() == ('|block 1 from layout|block 2 from '
+                             'layout|nested block 4 from layout|')
+
+
+def test_level1(env):
+    tmpl = env.get_template('level1')
+    assert tmpl.render() == ('|block 1 from level1|block 2 from '
+                             'layout|nested block 4 from layout|')
+
+
+def test_level2(env):
+    tmpl = env.get_template('level2')
+    assert tmpl.render() == ('|block 1 from level1|nested block 5 from '
+                             'level2|nested block 4 from layout|')
+
+
+def test_level3(env):
+    tmpl = env.get_template('level3')
+    assert tmpl.render() == ('|block 1 from level1|block 5 from level3|'
+                             'block 4 from level3|')
+
+
+def test_level4(env):
+    tmpl = env.get_template('level4')
+    assert tmpl.render() == ('|block 1 from level1|block 5 from '
+                             'level3|block 3 from level4|')
diff --git a/tests/test_macros.py b/tests/test_macros.py
new file mode 100644 (file)
index 0000000..c28499b
--- /dev/null
@@ -0,0 +1,54 @@
+# -*- coding: utf-8 -*-
+"""
+    unit test for the macros
+    ~~~~~~~~~~~~~~~~~~~~~~~~
+
+    :copyright: 2007 by Armin Ronacher.
+    :license: BSD, see LICENSE for more details.
+"""
+
+SIMPLE = '''\
+{% macro say_hello name %}Hello {{ name }}!{% endmacro %}
+{{ say_hello('Peter') }}\
+'''
+
+KWARGSFAILURE = '''\
+{% macro foo bar %}...{% endmacro %}
+{{ foo(bar='blub') }}\
+'''
+
+SCOPING = '''\
+{% macro level1 data1 %}
+{% macro level2 data2 %}{{ data1 }}|{{ data2 }}{% endmacro %}
+{{ level2('bar') }}{% endmacro %}
+{{ level1('foo') }}|{{ level2('bar') }}\
+'''
+
+ARGUMENTS = '''\
+{% macro m a, b, c='c', d='d' %}{{ a }}|{{ b }}|{{ c }}|{{ d }}{% endmacro %}
+{{ m() }}|{{ m('a') }}|{{ m('a', 'b') }}|{{ m(1, 2, 3) }}\
+'''
+
+def test_simple(env):
+    tmpl = env.from_string(SIMPLE)
+    assert tmpl.render() == 'Hello Peter!'
+
+
+def test_kwargs_failure(env):
+    tmpl = env.from_string(KWARGSFAILURE)
+    try:
+        tmpl.render()
+    except TypeError, e:
+        pass
+    else:
+        raise AssertionError('kwargs failure test failed')
+
+
+def test_scoping(env):
+    tmpl = env.from_string(SCOPING)
+    assert tmpl.render() == 'foo|bar|'
+
+
+def test_arguments(env):
+    tmpl = env.from_string(ARGUMENTS)
+    assert tmpl.render() == '||c|d|a||c|d|a|b|c|d|1|2|3|d'
index 22bdec4d69f605d2a1b5a8b7a5045a86b237a76f..387f3fbfdb4a7cb38c06765587c322a627e84bd1 100644 (file)
@@ -59,4 +59,3 @@ def test_sequence(env):
 def test_upper(env):
     tmpl = env.from_string(UPPER)
     assert tmpl.render() == 'True|False'
-