Run `./2to3.py -w jinja2`
[jinja2.git] / jinja2 / testsuite / ext.py
index 13069732381541621e02de62a614d06f73cb6ef2..bfbb38630e70e8a590306588b7ab42f49c091feb 100644 (file)
@@ -11,7 +11,7 @@
 import re
 import unittest
 
-from jinja2.testsuite import JinjaTestCase, filesystem_loader
+from jinja2.testsuite import JinjaTestCase
 
 from jinja2 import Environment, DictLoader, contextfunction, nodes
 from jinja2.exceptions import TemplateAssertionError
@@ -23,7 +23,7 @@ from jinja2.utils import next
 try:
     from io import BytesIO
 except ImportError:
-    from StringIO import StringIO as BytesIO
+    from io import StringIO as BytesIO
 
 
 importable_object = 23
@@ -38,7 +38,7 @@ i18n_templates = {
                   '{% trans %}watch out{% endtrans %}{% endblock %}',
     'plural.html': '{% trans user_count %}One user online{% pluralize %}'
                    '{{ user_count }} users online{% endtrans %}',
-    'stringformat.html': '{{ _("User: %(num)d")|format(num=user_count) }}'
+    'stringformat.html': '{{ _("User: %(num)s")|format(num=user_count) }}'
 }
 
 newstyle_i18n_templates = {
@@ -48,20 +48,29 @@ newstyle_i18n_templates = {
                   '{% trans %}watch out{% endtrans %}{% endblock %}',
     'plural.html': '{% trans user_count %}One user online{% pluralize %}'
                    '{{ user_count }} users online{% endtrans %}',
-    'stringformat.html': '{{ _("User: %(num)d", num=user_count) }}',
-    'ngettext.html': '{{ ngettext("%(num)d apple", "%(num)d apples", apples) }}'
+    'stringformat.html': '{{ _("User: %(num)s", num=user_count) }}',
+    'ngettext.html': '{{ ngettext("%(num)s apple", "%(num)s apples", apples) }}',
+    'ngettext_long.html': '{% trans num=apples %}{{ num }} apple{% pluralize %}'
+                          '{{ num }} apples{% endtrans %}',
+    'transvars1.html': '{% trans %}User: {{ num }}{% endtrans %}',
+    'transvars2.html': '{% trans num=count %}User: {{ num }}{% endtrans %}',
+    'transvars3.html': '{% trans count=num %}User: {{ count }}{% endtrans %}',
+    'novars.html': '{% trans %}%(hello)s{% endtrans %}',
+    'vars.html': '{% trans %}{{ foo }}%(foo)s{% endtrans %}',
+    'explicitvars.html': '{% trans foo="42" %}%(foo)s{% endtrans %}'
 }
 
 
 languages = {
     'de': {
-        'missing':                      u'fehlend',
-        'watch out':                    u'pass auf',
-        'One user online':              u'Ein Benutzer online',
-        '%(user_count)s users online':  u'%(user_count)s Benutzer online',
-        'User: %(num)d':                u'Benutzer: %(num)d',
-        '%(num)d apple':                u'%(num)d Apfel',
-        '%(num)d apples':               u'%(num)d Äpfel'
+        'missing':                      'fehlend',
+        'watch out':                    'pass auf',
+        'One user online':              'Ein Benutzer online',
+        '%(user_count)s users online':  '%(user_count)s Benutzer online',
+        'User: %(num)s':                'Benutzer: %(num)s',
+        'User: %(count)s':              'Benutzer: %(count)s',
+        '%(num)s apple':                '%(num)s Apfel',
+        '%(num)s apples':               '%(num)s Äpfel'
     }
 }
 
@@ -158,6 +167,12 @@ class StreamFilterExtension(Extension):
 
 class ExtensionsTestCase(JinjaTestCase):
 
+    def test_extend_late(self):
+        env = Environment()
+        env.add_extension('jinja2.ext.autoescape')
+        t = env.from_string('{% autoescape true %}{{ "<test>" }}{% endautoescape %}')
+        assert t.render() == '&lt;test&gt;'
+
     def test_loop_controls(self):
         env = Environment(extensions=['jinja2.ext.loopcontrols'])
 
@@ -207,7 +222,7 @@ class ExtensionsTestCase(JinjaTestCase):
         original = Environment(extensions=[TestExtension])
         overlay = original.overlay()
         for env in original, overlay:
-            for ext in env.extensions.itervalues():
+            for ext in env.extensions.values():
                 assert ext.environment is env
 
     def test_preprocessor_extension(self):
@@ -263,9 +278,9 @@ class InternationalizationTestCase(JinjaTestCase):
         {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
         '''.encode('ascii')) # make python 3 happy
         assert list(babel_extract(source, ('gettext', 'ngettext', '_'), [], {})) == [
-            (2, 'gettext', u'Hello World', []),
-            (3, 'gettext', u'Hello World', []),
-            (4, 'ngettext', (u'%(users)s user', u'%(users)s users', None), [])
+            (2, 'gettext', 'Hello World', []),
+            (3, 'gettext', 'Hello World', []),
+            (4, 'ngettext', ('%(users)s user', '%(users)s users', None), [])
         ]
 
     def test_comment_extract(self):
@@ -278,9 +293,9 @@ class InternationalizationTestCase(JinjaTestCase):
         {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
         '''.encode('utf-8')) # make python 3 happy
         assert list(babel_extract(source, ('gettext', 'ngettext', '_'), ['trans', ':'], {})) == [
-            (3, 'gettext', u'Hello World', ['first']),
-            (4, 'gettext', u'Hello World', ['second']),
-            (6, 'ngettext', (u'%(users)s user', u'%(users)s users', None), ['third'])
+            (3, 'gettext', 'Hello World', ['first']),
+            (4, 'gettext', 'Hello World', ['second']),
+            (6, 'ngettext', ('%(users)s user', '%(users)s users', None), ['third'])
         ]
 
 
@@ -309,7 +324,49 @@ class NewstyleInternationalizationTestCase(JinjaTestCase):
     def test_newstyle_plural(self):
         tmpl = newstyle_i18n_env.get_template('ngettext.html')
         assert tmpl.render(LANGUAGE='de', apples=1) == '1 Apfel'
-        assert tmpl.render(LANGUAGE='de', apples=5) == u'5 Äpfel'
+        assert tmpl.render(LANGUAGE='de', apples=5) == '5 Äpfel'
+
+    def test_autoescape_support(self):
+        env = Environment(extensions=['jinja2.ext.autoescape',
+                                      'jinja2.ext.i18n'])
+        env.install_gettext_callables(lambda x: '<strong>Wert: %(name)s</strong>',
+                                      lambda s, p, n: s, newstyle=True)
+        t = env.from_string('{% autoescape ae %}{{ gettext("foo", name='
+                            '"<test>") }}{% endautoescape %}')
+        assert t.render(ae=True) == '<strong>Wert: &lt;test&gt;</strong>'
+        assert t.render(ae=False) == '<strong>Wert: <test></strong>'
+
+    def test_num_used_twice(self):
+        tmpl = newstyle_i18n_env.get_template('ngettext_long.html')
+        assert tmpl.render(apples=5, LANGUAGE='de') == '5 Äpfel'
+
+    def test_num_called_num(self):
+        source = newstyle_i18n_env.compile('''
+            {% trans num=3 %}{{ num }} apple{% pluralize
+            %}{{ num }} apples{% endtrans %}
+        ''', raw=True)
+        # quite hacky, but the only way to properly test that.  The idea is
+        # that the generated code does not pass num twice (although that
+        # would work) for better performance.  This only works on the
+        # newstyle gettext of course
+        assert re.search(r"l_ngettext, u?'\%\(num\)s apple', u?'\%\(num\)s "
+                         r"apples', 3", source) is not None
+
+    def test_trans_vars(self):
+        t1 = newstyle_i18n_env.get_template('transvars1.html')
+        t2 = newstyle_i18n_env.get_template('transvars2.html')
+        t3 = newstyle_i18n_env.get_template('transvars3.html')
+        assert t1.render(num=1, LANGUAGE='de') == 'Benutzer: 1'
+        assert t2.render(count=23, LANGUAGE='de') == 'Benutzer: 23'
+        assert t3.render(num=42, LANGUAGE='de') == 'Benutzer: 42'
+
+    def test_novars_vars_escaping(self):
+        t = newstyle_i18n_env.get_template('novars.html')
+        assert t.render() == '%(hello)s'
+        t = newstyle_i18n_env.get_template('vars.html')
+        assert t.render(foo='42') == '42%(foo)s'
+        t = newstyle_i18n_env.get_template('explicitvars.html')
+        assert t.render() == '%(foo)s'
 
 
 class AutoEscapeTestCase(JinjaTestCase):
@@ -325,7 +382,7 @@ class AutoEscapeTestCase(JinjaTestCase):
             {{ "<HelloWorld>" }}
         ''')
         assert tmpl.render().split() == \
-            [u'&lt;HelloWorld&gt;', u'<HelloWorld>', u'&lt;HelloWorld&gt;']
+            ['&lt;HelloWorld&gt;', '<HelloWorld>', '&lt;HelloWorld&gt;']
 
         env = Environment(extensions=['jinja2.ext.autoescape'],
                           autoescape=False)
@@ -337,7 +394,7 @@ class AutoEscapeTestCase(JinjaTestCase):
             {{ "<HelloWorld>" }}
         ''')
         assert tmpl.render().split() == \
-            [u'<HelloWorld>', u'&lt;HelloWorld&gt;', u'<HelloWorld>']
+            ['<HelloWorld>', '&lt;HelloWorld&gt;', '<HelloWorld>']
 
     def test_nonvolatile(self):
         env = Environment(extensions=['jinja2.ext.autoescape'],
@@ -375,7 +432,7 @@ class AutoEscapeTestCase(JinjaTestCase):
         '''
         tmpl = env.from_string(tmplsource)
         assert tmpl.render(val=True).split()[0] == 'Markup'
-        assert tmpl.render(val=False).split()[0] == unicode.__name__
+        assert tmpl.render(val=False).split()[0] == str.__name__
 
         # looking at the source we should see <testing> there in raw
         # (and then escaped as well)