def test_filter_compat_safestrings(): """Test filter compatibility layer with respect to safe strings. """ from coffin.common import env env.autoescape = True # Jinja-style safe output strings are considered "safe" by both engines assert env.from_string('{{ "<b>"|jinja_safe_output }}').render() == '<b>' # TODO: The below actually works regardless of our converting between # the same string types: Jinja's Markup() strings are actually immune # to Django's escape() attempt, since they have a custom version of # replace() that operates on an already escaped version. assert Template( '{% load compat_filters %}{{ "<b>"|jinja_safe_output }}').render( Context()) == '<b>' # Unsafe, unmarked output strings are considered "unsafe" by both engines assert env.from_string('{{ "<b>"|unsafe_output }}').render() == '<b>' assert Template( '{% load compat_filters %}{{ "<b>"|unsafe_output }}').render( Context()) == '<b>' # Django-style safe output strings are considered "safe" by both engines assert env.from_string('{{ "<b>"|django_safe_output }}').render() == '<b>' assert Template( '{% load compat_filters %}{{ "<b>"|django_safe_output }}').render( Context()) == '<b>'
def test_filters(): """Test availability of registered filters. """ # Filter registered with a Coffin library is available in Django and Jinja2 assert env.from_string('a{{ "b"|foo }}c').render() == 'a{foo}c' assert Template('{% load foo_filter %}a{{ "b"|foo }}c').render( Context()) == 'a{foo}c' # Filter registered with a Django library is not available in Jinja2 Template('{% load foo_filter_django %}{{ "b"|foo_django }}').render( Context()) assert_raises(Jinja2TemplateAssertionError, env.from_string, 'a{{ "b"|foo_django }}c') # Some filters, while registered with a Coffin library, are only # available in Jinja2: # - when using @environmentfilter env.from_string('{{ "b"|environment }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|environment }}') # - when using @contextfilter env.from_string('{{ "b"|context }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|context }}') # - when requiring more than one argument env.from_string('{{ "b"|multiarg(1,2) }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|multiarg }}') # - when Jinja2-exclusivity is explicitly requested env.from_string('{{ "b"|jinja_forced }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|jinja_forced }}') # [bug] Jinja2-exclusivity caused the compatibility layer to be not # applied, causing for example safe strings to be escaped. assert env.from_string('{{ "><"|django_jinja_forced }}').render() == '><'
def test_filters(): """Test availability of registered filters. """ # Filter registered with a Coffin library is available in Django and Jinja2 assert env.from_string('a{{ "b"|foo }}c').render() == 'a{foo}c' assert Template('{% load foo_filter %}a{{ "b"|foo }}c').render(Context()) == 'a{foo}c' # Filter registered with a Django library is not available in Jinja2 Template('{% load foo_filter_django %}{{ "b"|foo_django }}').render(Context()) assert_raises(Jinja2TemplateAssertionError, env.from_string, 'a{{ "b"|foo_django }}c') # Some filters, while registered with a Coffin library, are only # available in Jinja2: # - when using @environmentfilter env.from_string('{{ "b"|environment }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|environment }}') # - when using @contextfilter env.from_string('{{ "b"|context }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|context }}') # - when requiring more than one argument env.from_string('{{ "b"|multiarg(1,2) }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|multiarg }}') # - when Jinja2-exclusivity is explicitly requested env.from_string('{{ "b"|jinja_forced }}') assert_raises(Exception, Template, '{% load jinjafilters %}{{ "b"|jinja_forced }}') # [bug] Jinja2-exclusivity caused the compatibility layer to be not # applied, causing for example safe strings to be escaped. assert env.from_string('{{ "><"|django_jinja_forced }}').render() == '><'
def test_nodes_and_extensions(): """Test availability of registered nodes/extensions. """ from coffin.common import env # Jinja2 extensions, loaded from a Coffin library assert env.from_string('a{% foo %}b').render() == 'a{foo}b' assert env.from_string('a{% foo_ex %}b').render() == 'a{my_foo}b' # Django tags, loaded from a Coffin library assert Template('{% load foo_tag %}a{% foo_coffin %}b').render({}) == 'a{foo}b'
def test_nodes_and_extensions(): """Test availability of registered nodes/extensions. """ from coffin.common import env # Jinja2 extensions, loaded from a Coffin library assert env.from_string('a{% foo %}b').render() == 'a{foo}b' assert env.from_string('a{% foo_ex %}b').render() == 'a{my_foo}b' # Django tags, loaded from a Coffin library assert Template('{% load foo_tag %}a{% foo_coffin %}b').render( {}) == 'a{foo}b'
def test_markup(): from coffin.template import add_to_builtins as add_to_coffin_builtins from django.template import add_to_builtins as add_to_django_builtins add_to_coffin_builtins('coffin.contrib.markup.templatetags.markup') add_to_django_builtins('coffin.contrib.markup.templatetags.markup') # Make sure filters will be available in both Django and Coffin. # Note that we do not assert the result - if markdown is not installed, # the filter will just return the input text. We don't care, we simple # want to check the filter is available. env.from_string('{{ "**Title**"|markdown }}').render() # '\n<p><strong>Title</strong>\n</p>\n\n\n' Template('{{ "**Title**"|markdown }}').render(Context())
def test_filter_compat_other(): """Test other features of the filter compatibility layer. """ # A Django filter with @needs_autoescape works in Jinja2 env.autoescape = True assert env.from_string('{{ "b"|needing_autoescape }}').render() == 'True' env.autoescape = False assert env.from_string('{{ "b"|needing_autoescape }}').render() == 'False' # [bug] @needs_autoescape also (still) works correctly in Django assert Template('{% load compat_filters %}{{ "b"|needing_autoescape }}').render(Context()) == 'True' # TODO: test @stringfilter
def test_markup(): from coffin.template import add_to_builtins as add_to_coffin_builtins from django.template import add_to_builtins as add_to_django_builtins add_to_coffin_builtins('coffin.contrib.markup.templatetags.markup') add_to_django_builtins('coffin.contrib.markup.templatetags.markup') # Make sure filters will be available in both Django and Coffin. # Note that we do not assert the result - if markdown is not installed, # the filter will just return the input text. We don't care, we simple # want to check the filter is available. env.from_string('{{ "**Title**"|markdown }}').render( ) # '\n<p><strong>Title</strong>\n</p>\n\n\n' Template('{{ "**Title**"|markdown }}').render(Context())
def test_filter_compat_other(): """Test other features of the filter compatibility layer. """ # A Django filter with @needs_autoescape works in Jinja2 from coffin.common import env env.autoescape = True assert env.from_string('{{ "b"|needing_autoescape }}').render() == 'True' env.autoescape = False assert env.from_string('{{ "b"|needing_autoescape }}').render() == 'False' # [bug] @needs_autoescape also (still) works correctly in Django assert Template( '{% load compat_filters %}{{ "b"|needing_autoescape }}').render( Context()) == 'True'
def test_filter_compat_other(): """Test other features of the filter compatibility layer. """ # A Django filter with @needs_autoescape works in Jinja2 from coffin.common import env env.autoescape = True assert env.from_string('{{ "b"|needing_autoescape }}').render() == 'True' env.autoescape = False assert env.from_string('{{ "b"|needing_autoescape }}').render() == 'False' # [bug] @needs_autoescape also (still) works correctly in Django assert Template('{% load compat_filters %}{{ "b"|needing_autoescape }}').render(Context()) == 'True' # The Django filters can handle "Undefined" values assert env.from_string('{{ doesnotexist|django_raw_output }}').render() == ''
def test_objects(): """For coffin, global objects can be registered. """ from coffin.common import env # Jinja2 global objects, loaded from a Coffin library assert env.from_string('{{ hello("John") }}').render() == 'Hello John'
def get_template_from_string(source): """ Does not support then ``name`` and ``origin`` parameters from the Django version. """ from coffin.common import env return env.from_string(source)
def __new__(cls, template_string, origin=None, name=None): # We accept the "origin" and "name" arguments, but discard them # right away - Jinja's Template class (apparently) stores no # equivalent information. from coffin.common import env return env.from_string(template_string, template_class=cls)
def process_response(self, request, response): if settings.DEBUG and not isinstance(response, HttpResponse): template = env.from_string(ERROR_PAGE) return HttpResponseServerError(template.render({ 'response': response, })) return response
def process_response(self, request, response): if settings.DEBUG and not isinstance(response, HttpResponse): template = env.from_string(ERROR_PAGE) return HttpResponseServerError( template.render({ 'response': response, })) return response
def test_filter_compat_escapetrings(): """Test filter compatibility layer with respect to strings flagged as "wanted for escaping". """ env.autoescape = False # Django-style "force escaping" works in both engines assert env.from_string('{{ "<b>"|django_escape_output }}').render() == '<b>' assert Template('{% load compat_filters %}{{ "<b>"|django_escape_output }}').render(Context()) == '<b>'
def test_filter_compat_safestrings(): """Test filter compatibility layer with respect to safe strings. """ env.autoescape = True # Jinja-style safe output strings are considered "safe" by both engines assert env.from_string('{{ "<b>"|jinja_safe_output }}').render() == '<b>' # TODO: The below actually works regardless of our converting between # the same string types: Jinja's Markup() strings are actually immune # to Django's escape() attempt, since they have a custom version of # replace() that operates on an already escaped version. assert Template('{% load compat_filters %}{{ "<b>"|jinja_safe_output }}').render(Context()) == '<b>' # Unsafe, unmarked output strings are considered "unsafe" by both engines assert env.from_string('{{ "<b>"|unsafe_output }}').render() == '<b>' assert Template('{% load compat_filters %}{{ "<b>"|unsafe_output }}').render(Context()) == '<b>' # Django-style safe output strings are considered "safe" by both engines assert env.from_string('{{ "<b>"|django_safe_output }}').render() == '<b>' assert Template('{% load compat_filters %}{{ "<b>"|django_safe_output }}').render(Context()) == '<b>'
def test_filter_compat_escapetrings(): """Test filter compatibility layer with respect to strings flagged as "wanted for escaping". """ from coffin.common import env env.autoescape = False # Django-style "force escaping" works in both engines assert env.from_string( '{{ "<b>"|django_escape_output }}').render() == '<b>' assert Template( '{% load compat_filters %}{{ "<b>"|django_escape_output }}').render( Context()) == '<b>'
def test_date_stuff(): assert r('a{{ d|date("Y") }}b', {'d': date(2007, 01, 01)}) == 'a2007b' assert r('a{{ d|time("H") }}b', {'d': datetime(2007, 01, 01, 12, 01, 01)}) == 'a12b' # TODO: timesince, timeuntil # Make sure the date filters can handle unset values gracefully. # While generally we'd like to be explicit instead of hiding errors, # this is a particular case where it makes sense. for f in ('date', 'time', 'timesince', 'timeuntil'): assert r('a{{ d|%s }}b' % f) == 'ab' assert r('a{{ d|%s }}b' % f, {'d': None}) == 'ab' # given an empty string though (wrong type), an error would be raced assert_raises(Exception, env.from_string('a{{ d|%s }}b' % f).render, {'d': ''})
def test_date_stuff(): from coffin.common import env assert r('a{{ d|date("Y") }}b', {'d': date(2007, 01, 01)}) == 'a2007b' assert r('a{{ d|time("H") }}b', {'d': datetime(2007, 01, 01, 12, 01, 01)}) == 'a12b' # TODO: timesince, timeuntil # Make sure the date filters can handle unset values gracefully. # While generally we'd like to be explicit instead of hiding errors, # this is a particular case where it makes sense. for f in ('date', 'time', 'timesince', 'timeuntil'): assert r('a{{ d|%s }}b' % f) == 'ab' assert r('a{{ d|%s }}b' % f, {'d': None}) == 'ab' # given an empty string though (wrong type), an error would be raced assert_raises(Exception, env.from_string('a{{ d|%s }}b' % f).render, {'d': ''})
def __new__(cls, template_string, origin=None, name=None, source=None): # We accept the "origin" and "name" arguments, but discard them # right away - Jinja's Template class (apparently) stores no # equivalent information. # source is expected to be a Django Template Loader source, it is not # required but helps to provide useful stacktraces when executing # Jinja code from Django templates from coffin.common import env try: template = env.from_string(template_string, template_class=cls) template.source = source return template except _jinja2_exceptions.TemplateSyntaxError, e: raise _generate_django_exception(e, source)
def r(s, context={}): return env.from_string(s).render(context)
def r(s, context={}): from coffin.common import env return env.from_string(s).render(context)