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
try:
from io import BytesIO
except ImportError:
- from StringIO import StringIO as BytesIO
+ from io import StringIO as BytesIO
importable_object = 23
'{% 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 = {
'{% 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'
}
}
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() == '<test>'
+
def test_loop_controls(self):
env = Environment(extensions=['jinja2.ext.loopcontrols'])
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):
{% 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):
{% 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'])
]
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: <test></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):
{{ "<HelloWorld>" }}
''')
assert tmpl.render().split() == \
- [u'<HelloWorld>', u'<HelloWorld>', u'<HelloWorld>']
+ ['<HelloWorld>', '<HelloWorld>', '<HelloWorld>']
env = Environment(extensions=['jinja2.ext.autoescape'],
autoescape=False)
{{ "<HelloWorld>" }}
''')
assert tmpl.render().split() == \
- [u'<HelloWorld>', u'<HelloWorld>', u'<HelloWorld>']
+ ['<HelloWorld>', '<HelloWorld>', '<HelloWorld>']
def test_nonvolatile(self):
env = Environment(extensions=['jinja2.ext.autoescape'],
'''
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)