fixed more unittests
authorArmin Ronacher <armin.ronacher@active-4.com>
Fri, 18 Apr 2008 14:41:52 +0000 (16:41 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Fri, 18 Apr 2008 14:41:52 +0000 (16:41 +0200)
--HG--
branch : trunk

jinja2/_speedups.c
jinja2/environment.py
jinja2/loaders.py
jinja2/runtime.py
tests/conftest.py
tests/test_inheritance.py
tests/test_undefined.py

index 6aad8ec905833263bd4d0794c9b1257257fc0d84..36a1404de312a50f6a3bf4cc39dc97c6a386355e 100644 (file)
@@ -115,7 +115,7 @@ static PyObject*
 escape(PyObject *self, PyObject *args)
 {
        PyObject *text = NULL, *s = NULL, *rv = NULL;
-       if (!PyArg_UnpackTuple(args, "escape", 1, 2, &text))
+       if (!PyArg_UnpackTuple(args, "escape", 1, 1, &text))
                return NULL;
 
        /* we don't have to escape integers, bools or floats */
index 1ed0464de496ed71ecf4d295addcc78d14c8a653..35b01e7af324529b4df10f507be926d9d1d8397f 100644 (file)
@@ -182,7 +182,10 @@ class Template(object):
     """Represents a template."""
 
     def __init__(self, environment, code, globals, uptodate=None):
-        namespace = {'environment': environment}
+        namespace = {
+            'environment':          environment,
+            '__jinja_template__':   self
+        }
         exec code in namespace
         self.environment = environment
         self.name = namespace['name']
@@ -191,18 +194,27 @@ class Template(object):
         self.blocks = namespace['blocks']
         self.globals = globals
 
-        # debug helpers
+        # debug and loader helpers
         self._get_debug_info = namespace['get_debug_info']
         self._uptodate = uptodate
-        namespace['__jinja_template__'] = self
 
     def render(self, *args, **kwargs):
         """Render the template into a string."""
-        return u''.join(self.generate(*args, **kwargs))
+        try:
+            return u''.join(self.generate(*args, **kwargs))
+        except:
+            # hide the `generate` frame
+            exc_type, exc_value, tb = sys.exc_info()
+            raise exc_type, exc_value, tb.tb_next
 
     def stream(self, *args, **kwargs):
         """Return a `TemplateStream` that generates the template."""
-        return TemplateStream(self.generate(*args, **kwargs))
+        try:
+            return TemplateStream(self.generate(*args, **kwargs))
+        except:
+            # hide the `generate` frame
+            exc_type, exc_value, tb = sys.exc_info()
+            raise exc_type, exc_value, tb.tb_next
 
     def generate(self, *args, **kwargs):
         """Return a generator that generates the template."""
index b621bbf27d84e2fbfb5fed355f3900c321756f7d..dc3ccfb709cf257e1915d5df539a5546a9966251 100644 (file)
@@ -39,10 +39,12 @@ class BaseLoader(object):
     """
 
     def __init__(self, cache_size=50, auto_reload=True):
-        if cache_size > 0:
-            self.cache = LRUCache(cache_size)
-        else:
+        if cache_size == 0:
             self.cache = None
+        elif cache_size < 0:
+            self.cache = {}
+        else:
+            self.cache = LRUCache(cache_size)
         self.auto_reload = auto_reload
 
     def get_source(self, environment, template):
@@ -134,7 +136,8 @@ class PackageLoader(BaseLoader):
 class DictLoader(BaseLoader):
     """Loads a template from a python dict.  Used for unittests mostly."""
 
-    def __init__(self, mapping):
+    def __init__(self, mapping, cache_size=50):
+        BaseLoader.__init__(self, cache_size, False)
         self.mapping = mapping
 
     def get_source(self, environment, template):
index e1bf486d097b110f42106067e4ab1e048ada1e37..e0630cccdd89452a04be2636f896dcb684ce0c24 100644 (file)
@@ -277,7 +277,7 @@ class Undefined(object):
                     self._undefined_name
                 )
             else:
-                hint = '%r object has no attribute %s' % (
+                hint = '%r object has no attribute %r' % (
                     self._undefined_obj.__class__.__name__,
                     self._undefined_name
                 )
index 0f1439b62009adf4c1e5360779c13e9bef67d9c4..e38299f2553a5ed70bfccd758640bc32f1958873 100644 (file)
@@ -15,7 +15,8 @@ sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
 
 import py
 from jinja2 import Environment
-from jinja2.parser import Parser
+from jinja2.loaders import BaseLoader
+from jinja2.exceptions import TemplateNotFound
 
 try:
     # This code adds support for coverage.py (see
@@ -52,45 +53,20 @@ except ImportError:
     coverage = None
 
 
-class GlobalLoader(object):
+class GlobalLoader(BaseLoader):
+    scope = globals()
 
-    def __init__(self, scope):
-        self.scope = scope
+    def get_source(self, environment, name):
+        try:
+            return self.scope[name.upper() + 'TEMPLATE'], None, None
+        except KeyError:
+            raise TemplateNotFound(name)
 
-    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())
+loader = GlobalLoader(cache_size=0)
 simple_env = Environment(trim_blocks=True, loader=loader)
 
 
-class MemcacheClient(object):
-    """
-    Helper for the loader test.
-    """
-
-    def __init__(self, hosts):
-        self.cache = {}
-
-    def get(self, name):
-        return self.cache.get(name)
-
-    def set(self, name, data, time):
-        self.cache[name] = data
-
-sys.modules['memcache'] = memcache = type(sys)('memcache')
-memcache.Client = MemcacheClient
-
-
 class Module(py.test.collect.Module):
 
     def __init__(self, *args, **kwargs):
index 53ebfac3e5024b7c170dc850617663cb32a75f5d..34e573803aa73e2294df7ac44a230909183a8b92 100644 (file)
@@ -36,15 +36,6 @@ LEVEL4TEMPLATE = '''\
 {% block block3 %}block 3 from level4{% endblock %}
 '''
 
-BROKENTEMPLATE = '''\
-{% extends "layout" %}
-{% if false %}
-  {% block block1 %}
-    this is broken
-  {% endblock %}
-{% endif %}
-'''
-
 WORKINGTEMPLATE = '''\
 {% extends "layout" %}
 {% block block1 %}
@@ -100,19 +91,5 @@ def test_super():
     assert tmpl.render() == '--INTRO--|BEFORE|[(INNER)]|AFTER'
 
 
-def test_broken(env):
-    try:
-        tmpl = env.get_template('broken')
-    except TemplateSyntaxError:
-        pass
-    else:
-        raise RuntimeError('no syntax error occured')
-
-
 def test_working(env):
     tmpl = env.get_template('working')
-
-
-def test_shortcut(env):
-    tmpl = env.from_string('{% block foo "42" %}')
-    assert tmpl.render() == '42'
index 7b312c01b64e00e26ded2063177334e560fbd759..f0544bb2a8bd836152d1681017f699a5d1f69553 100644 (file)
@@ -1,67 +1,74 @@
 # -*- coding: utf-8 -*-
 """
-    unit test for the undefined singletons
-    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    unit test for the undefined types
+    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-    :copyright: 2007 by Armin Ronacher.
+    :copyright: 2008 by Armin Ronacher.
     :license: BSD, see LICENSE for more details.
 """
 
-from jinja2 import Environment
-from jinja2.exceptions import TemplateRuntimeError
-from jinja2.datastructure import SilentUndefined, ComplainingUndefined
 
-
-silent_env = Environment(undefined_singleton=SilentUndefined)
-complaining_env = Environment(undefined_singleton=ComplainingUndefined)
-
-
-JUSTUNDEFINED = '''{{ missing }}'''
-DEFINEDUNDEFINED = '''{{ missing is defined }}|{{ given is defined }}'''
-ITERATION = '''{% for item in missing %}{{ item }}{% endfor %}'''
-CONCATENATION = '''{{ missing + [1, 2] + missing + [3] }}'''
-
-
-def test_silent_defined():
-    tmpl = silent_env.from_string(DEFINEDUNDEFINED)
-    assert tmpl.render(given=0) == 'False|True'
-
-
-def test_complaining_defined():
-    tmpl = complaining_env.from_string(DEFINEDUNDEFINED)
-    assert tmpl.render(given=0) == 'False|True'
-
-
-def test_silent_rendering():
-    tmpl = silent_env.from_string(JUSTUNDEFINED)
-    assert tmpl.render() == ''
-
-
-def test_complaining_undefined():
-    tmpl = complaining_env.from_string(JUSTUNDEFINED)
-    try:
-        tmpl.render()
-    except TemplateRuntimeError:
-        pass
-    else:
-        raise ValueError('template runtime error expected')
-
-
-def test_silent_iteration():
-    tmpl = silent_env.from_string(ITERATION)
-    assert tmpl.render() == ''
-
-
-def test_complaining_iteration():
-    tmpl = complaining_env.from_string(ITERATION)
-    try:
-        tmpl.render()
-    except TemplateRuntimeError:
-        pass
-    else:
-        raise ValueError('template runtime error expected')
-
-
-def test_concatenation():
-    tmpl = silent_env.from_string(CONCATENATION)
-    assert tmpl.render() == '[1, 2, 3]'
+test_default_undefined = '''
+>>> from jinja2 import Environment, Undefined
+>>> env = Environment(undefined=Undefined)
+>>> env.from_string('{{ missing }}').render()
+u''
+>>> env.from_string('{{ missing.attribute }}').render()
+Traceback (most recent call last):
+  ...
+UndefinedError: 'missing' is undefined
+>>> env.from_string('{{ missing|list }}').render()
+u'[]'
+>>> env.from_string('{{ missing is not defined }}').render()
+u'True'
+>>> env.from_string('{{ foo.missing }}').render(foo=42)
+u''
+>>> env.from_string('{{ not missing }}').render()
+u'True'
+'''
+
+test_debug_undefined = '''
+>>> from jinja2 import Environment, DebugUndefined
+>>> env = Environment(undefined=DebugUndefined)
+>>> env.from_string('{{ missing }}').render()
+u'{{ missing }}'
+>>> env.from_string('{{ missing.attribute }}').render()
+Traceback (most recent call last):
+  ...
+UndefinedError: 'missing' is undefined
+>>> env.from_string('{{ missing|list }}').render()
+u'[]'
+>>> env.from_string('{{ missing is not defined }}').render()
+u'True'
+>>> env.from_string('{{ foo.missing }}').render(foo=42)
+u"{{ no such element: int['missing'] }}"
+>>> env.from_string('{{ not missing }}').render()
+u'True'
+'''
+
+test_strict_undefined = '''
+>>> from jinja2 import Environment, StrictUndefined
+>>> env = Environment(undefined=StrictUndefined)
+>>> env.from_string('{{ missing }}').render()
+Traceback (most recent call last):
+  ...
+UndefinedError: 'missing' is undefined
+>>> env.from_string('{{ missing.attribute }}').render()
+Traceback (most recent call last):
+  ...
+UndefinedError: 'missing' is undefined
+>>> env.from_string('{{ missing|list }}').render()
+Traceback (most recent call last):
+  ...
+UndefinedError: 'missing' is undefined
+>>> env.from_string('{{ missing is not defined }}').render()
+u'True'
+>>> env.from_string('{{ foo.missing }}').render(foo=42)
+Traceback (most recent call last):
+  ...
+UndefinedError: 'int' object has no attribute 'missing'
+>>> env.from_string('{{ not missing }}').render()
+Traceback (most recent call last):
+  ...
+UndefinedError: 'missing' is undefined
+'''