def test_nonvolatile(self): env = Environment(extensions=['ambari_jinja2.ext.autoescape'], autoescape=True) tmpl = env.from_string('{{ {"foo": "<test>"}|xmlattr|escape }}') assert tmpl.render() == ' foo="<test>"' tmpl = env.from_string('{% autoescape false %}{{ {"foo": "<test>"}' '|xmlattr|escape }}{% endautoescape %}') assert tmpl.render() == ' foo="&lt;test&gt;"'
def test_strict_undefined(self): env = Environment(undefined=StrictUndefined) self.assert_raises(UndefinedError, env.from_string('{{ missing }}').render) self.assert_raises(UndefinedError, env.from_string('{{ missing.attribute }}').render) self.assert_raises(UndefinedError, env.from_string('{{ missing|list }}').render) self.assert_equal(env.from_string('{{ missing is not defined }}').render(), 'True') self.assert_raises(UndefinedError, env.from_string('{{ foo.missing }}').render, foo=42) self.assert_raises(UndefinedError, env.from_string('{{ not missing }}').render)
def test_finalizer(self): def finalize_none_empty(value): if value is None: value = u'' return value env = Environment(finalize=finalize_none_empty) tmpl = env.from_string('{% for item in seq %}|{{ item }}{% endfor %}') assert tmpl.render(seq=(None, 1, "foo")) == '||1|foo' tmpl = env.from_string('<{{ none }}>') assert tmpl.render() == '<>'
def test_replace(self): env = Environment() tmpl = env.from_string('{{ string|replace("o", 42) }}') assert tmpl.render(string='<foo>') == '<f4242>' env = Environment(autoescape=True) tmpl = env.from_string('{{ string|replace("o", 42) }}') assert tmpl.render(string='<foo>') == '<f4242>' tmpl = env.from_string('{{ string|replace("<", 42) }}') assert tmpl.render(string='<foo>') == '42foo>' tmpl = env.from_string('{{ string|replace("o", ">x<") }}') assert tmpl.render(string=Markup('foo')) == 'f>x<>x<'
def test_replace(self): env = Environment() tmpl = env.from_string('{{ string|replace("o", 42) }}') assert tmpl.render(string='<foo>') == '<f4242>' env = Environment(autoescape=True) tmpl = env.from_string('{{ string|replace("o", 42) }}') assert tmpl.render(string='<foo>') == '<f4242>' tmpl = env.from_string('{{ string|replace("<", 42) }}') assert tmpl.render(string='<foo>') == '42foo>' tmpl = env.from_string('{{ string|replace("o", ">x<") }}') assert tmpl.render(string=Markup('foo')) == 'f>x<>x<'
def test_loop_controls(self): env = Environment(extensions=['ambari_jinja2.ext.loopcontrols']) tmpl = env.from_string(''' {%- for item in [1, 2, 3, 4] %} {%- if item % 2 == 0 %}{% continue %}{% endif -%} {{ item }} {%- endfor %}''') assert tmpl.render() == '13' tmpl = env.from_string(''' {%- for item in [1, 2, 3, 4] %} {%- if item > 2 %}{% break %}{% endif -%} {{ item }} {%- endfor %}''') assert tmpl.render() == '12'
def test_volatile_scoping(self): env = Environment(extensions=['ambari_jinja2.ext.autoescape']) tmplsource = ''' {% autoescape val %} {% macro foo(x) %} [{{ x }}] {% endmacro %} {{ foo().__class__.__name__ }} {% endautoescape %} {{ '<testing>' }} ''' tmpl = env.from_string(tmplsource) assert tmpl.render(val=True).split()[0] == 'Markup' assert tmpl.render(val=False).split()[0] == unicode.__name__ # looking at the source we should see <testing> there in raw # (and then escaped as well) env = Environment(extensions=['ambari_jinja2.ext.autoescape']) pysource = env.compile(tmplsource, raw=True) assert '<testing>\\n' in pysource env = Environment(extensions=['ambari_jinja2.ext.autoescape'], autoescape=True) pysource = env.compile(tmplsource, raw=True) assert '<testing>\\n' in pysource
def test_erb_syntax(self): env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>') tmpl = env.from_string('''\ <%# I'm a comment, I'm not interesting %>\ <% for item in seq -%> <%= item %> <%- endfor %>''') assert tmpl.render(seq=range(5)) == '01234'
def test_php_syntax(self): env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->') tmpl = env.from_string('''\ <!-- I'm a comment, I'm not interesting -->\ <? for item in seq -?> <?= item ?> <?- endfor ?>''') assert tmpl.render(seq=range(5)) == '01234'
def test_comment_syntax(self): env = Environment('<!--', '-->', '${', '}', '<!--#', '-->') tmpl = env.from_string('''\ <!--# I'm a comment, I'm not interesting -->\ <!-- for item in seq ---> ${item} <!--- endfor -->''') assert tmpl.render(seq=range(5)) == '01234'
def test_do(self): env = Environment(extensions=['ambari_jinja2.ext.do']) tmpl = env.from_string(''' {%- set items = [] %} {%- for char in "foo" %} {%- do items.append(loop.index0 ~ char) %} {%- endfor %}{{ items|join(', ') }}''') assert tmpl.render() == '0f, 1o, 2o'
def test_join(self): tmpl = env.from_string('{{ [1, 2, 3]|join("|") }}') out = tmpl.render() assert out == '1|2|3' env2 = Environment(autoescape=True) tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}') assert tmpl.render() == '<foo><span>foo</span>'
def test_super_in_scoped_block(self): env = Environment(loader=DictLoader({ 'master.html': '{% for item in seq %}[{% block item scoped %}' '{{ item }}{% endblock %}]{% endfor %}' })) t = env.from_string('{% extends "master.html" %}{% block item %}' '{{ super() }}|{{ item * 2 }}{% endblock %}') assert t.render(seq=range(5)) == '[0|0][1|2][2|4][3|6][4|8]'
def test_php_syntax(self): env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->') tmpl = env.from_string('''\ <!-- I'm a comment, I'm not interesting -->\ <? for item in seq -?> <?= item ?> <?- endfor ?>''') assert tmpl.render(seq=range(5)) == '01234'
def test_erb_syntax(self): env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>') tmpl = env.from_string('''\ <%# I'm a comment, I'm not interesting %>\ <% for item in seq -%> <%= item %> <%- endfor %>''') assert tmpl.render(seq=range(5)) == '01234'
def test_comment_syntax(self): env = Environment('<!--', '-->', '${', '}', '<!--#', '-->') tmpl = env.from_string('''\ <!--# I'm a comment, I'm not interesting -->\ <!-- for item in seq ---> ${item} <!--- endfor -->''') assert tmpl.render(seq=range(5)) == '01234'
def test_super_in_scoped_block(self): env = Environment(loader=DictLoader({ 'master.html': '{% for item in seq %}[{% block item scoped %}' '{{ item }}{% endblock %}]{% endfor %}' })) t = env.from_string('{% extends "master.html" %}{% block item %}' '{{ super() }}|{{ item * 2 }}{% endblock %}') assert t.render(seq=range(5)) == '[0|0][1|2][2|4][3|6][4|8]'
def test_join(self): tmpl = env.from_string('{{ [1, 2, 3]|join("|") }}') out = tmpl.render() assert out == '1|2|3' env2 = Environment(autoescape=True) tmpl = env2.from_string( '{{ ["<foo>", "<span>foo</span>"|safe]|join }}') assert tmpl.render() == '<foo><span>foo</span>'
def test_autoescape_support(self): env = Environment(extensions=['ambari_jinja2.ext.autoescape', 'ambari_jinja2.ext.i18n']) env.install_gettext_callables(lambda x: u'<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_line_syntax(self): env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%') tmpl = env.from_string('''\ <%# regular comment %> % for item in seq: ${item} % endfor''') assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \ range(5) env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##') tmpl = env.from_string('''\ <%# regular comment %> % for item in seq: ${item} ## the rest of the stuff % endfor''') assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \ range(5)
def test_line_syntax(self): env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%') tmpl = env.from_string('''\ <%# regular comment %> % for item in seq: ${item} % endfor''') assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \ range(5) env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##') tmpl = env.from_string('''\ <%# regular comment %> % for item in seq: ${item} ## the rest of the stuff % endfor''') assert [int(x.strip()) for x in tmpl.render(seq=range(5)).split()] == \ range(5)
def test_with(self): env = Environment(extensions=['ambari_jinja2.ext.with_']) tmpl = env.from_string('''\ {% with a=42, b=23 -%} {{ a }} = {{ b }} {% endwith -%} {{ a }} = {{ b }}\ ''') assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] \ == ['42 = 23', '1 = 2']
def test_line_syntax_priority(self): # XXX: why is the whitespace there in front of the newline? env = Environment('{%', '%}', '${', '}', '/*', '*/', '##', '#') tmpl = env.from_string('''\ /* ignore me. I'm a multiline comment */ ## for item in seq: * ${item} # this is just extra stuff ## endfor''') assert tmpl.render(seq=[1, 2]).strip() == '* 1\n* 2' env = Environment('{%', '%}', '${', '}', '/*', '*/', '#', '##') tmpl = env.from_string('''\ /* ignore me. I'm a multiline comment */ # for item in seq: * ${item} ## this is just extra stuff ## extra stuff i just want to ignore # endfor''') assert tmpl.render(seq=[1, 2]).strip() == '* 1\n\n* 2'
def test_comments(self): env = Environment('<!--', '-->', '{', '}') tmpl = env.from_string('''\ <ul> <!--- for item in seq --> <li>{item}</li> <!--- endfor --> </ul>''') assert tmpl.render(seq=range(3)) == ("<ul>\n <li>0</li>\n " "<li>1</li>\n <li>2</li>\n</ul>")
def test_extends_output_bugs(self): env = Environment(loader=DictLoader({ 'parent.html': '(({% block title %}{% endblock %}))' })) t = env.from_string('{% if expr %}{% extends "parent.html" %}{% endif %}' '[[{% block title %}title{% endblock %}]]' '{% for item in [1, 2, 3] %}({{ item }}){% endfor %}') assert t.render(expr=False) == '[[title]](1)(2)(3)' assert t.render(expr=True) == '((title))'
def test_comments(self): env = Environment('<!--', '-->', '{', '}') tmpl = env.from_string('''\ <ul> <!--- for item in seq --> <li>{item}</li> <!--- endfor --> </ul>''') assert tmpl.render(seq=range(3)) == ("<ul>\n <li>0</li>\n " "<li>1</li>\n <li>2</li>\n</ul>")
def test_extends_output_bugs(self): env = Environment(loader=DictLoader( {'parent.html': '(({% block title %}{% endblock %}))'})) t = env.from_string( '{% if expr %}{% extends "parent.html" %}{% endif %}' '[[{% block title %}title{% endblock %}]]' '{% for item in [1, 2, 3] %}({{ item }}){% endfor %}') assert t.render(expr=False) == '[[title]](1)(2)(3)' assert t.render(expr=True) == '((title))'
def test_line_syntax_priority(self): # XXX: why is the whitespace there in front of the newline? env = Environment('{%', '%}', '${', '}', '/*', '*/', '##', '#') tmpl = env.from_string('''\ /* ignore me. I'm a multiline comment */ ## for item in seq: * ${item} # this is just extra stuff ## endfor''') assert tmpl.render(seq=[1, 2]).strip() == '* 1\n* 2' env = Environment('{%', '%}', '${', '}', '/*', '*/', '#', '##') tmpl = env.from_string('''\ /* ignore me. I'm a multiline comment */ # for item in seq: * ${item} ## this is just extra stuff ## extra stuff i just want to ignore # endfor''') assert tmpl.render(seq=[1, 2]).strip() == '* 1\n\n* 2'
def test_template_data(self): env = Environment(autoescape=True) t = env.from_string('{% macro say_hello(name) %}' '<p>Hello {{ name }}!</p>{% endmacro %}' '{{ say_hello("<blink>foo</blink>") }}') escaped_out = '<p>Hello <blink>foo</blink>!</p>' assert t.render() == escaped_out assert unicode(t.module) == escaped_out assert escape(t.module) == escaped_out assert t.module.say_hello('<blink>foo</blink>') == escaped_out assert escape(t.module.say_hello('<blink>foo</blink>')) == escaped_out
def test_template_data(self): env = Environment(autoescape=True) t = env.from_string( "{% macro say_hello(name) %}" "<p>Hello {{ name }}!</p>{% endmacro %}" '{{ say_hello("<blink>foo</blink>") }}' ) escaped_out = "<p>Hello <blink>foo</blink>!</p>" assert t.render() == escaped_out assert unicode(t.module) == escaped_out assert escape(t.module) == escaped_out assert t.module.say_hello("<blink>foo</blink>") == escaped_out assert escape(t.module.say_hello("<blink>foo</blink>")) == escaped_out
def test_scoped_setting(self): env = Environment(extensions=['ambari_jinja2.ext.autoescape'], autoescape=True) tmpl = env.from_string(''' {{ "<HelloWorld>" }} {% autoescape false %} {{ "<HelloWorld>" }} {% endautoescape %} {{ "<HelloWorld>" }} ''') assert tmpl.render().split() == \ [u'<HelloWorld>', u'<HelloWorld>', u'<HelloWorld>'] env = Environment(extensions=['ambari_jinja2.ext.autoescape'], autoescape=False) tmpl = env.from_string(''' {{ "<HelloWorld>" }} {% autoescape true %} {{ "<HelloWorld>" }} {% endautoescape %} {{ "<HelloWorld>" }} ''') assert tmpl.render().split() == \ [u'<HelloWorld>', u'<HelloWorld>', u'<HelloWorld>']
def test_debug_undefined(self): env = Environment(undefined=DebugUndefined) self.assert_equal(env.from_string('{{ missing }}').render(), '{{ missing }}') self.assert_raises(UndefinedError, env.from_string('{{ missing.attribute }}').render) self.assert_equal(env.from_string('{{ missing|list }}').render(), '[]') self.assert_equal(env.from_string('{{ missing is not defined }}').render(), 'True') self.assert_equal(env.from_string('{{ foo.missing }}').render(foo=42), u"{{ no such element: int object['missing'] }}") self.assert_equal(env.from_string('{{ not missing }}').render(), 'True')
def test_autoescape_autoselect(self): def select_autoescape(name): if name is None or '.' not in name: return False return name.endswith('.html') env = Environment(autoescape=select_autoescape, loader=DictLoader({ 'test.txt': '{{ foo }}', 'test.html': '{{ foo }}' })) t = env.get_template('test.txt') assert t.render(foo='<foo>') == '<foo>' t = env.get_template('test.html') assert t.render(foo='<foo>') == '<foo>' t = env.from_string('{{ foo }}') assert t.render(foo='<foo>') == '<foo>'
def test_stacked_locals_scoping_bug(self): env = Environment(line_statement_prefix='#') t = env.from_string('''\ # for j in [1, 2]: # set x = 1 # for i in [1, 2]: # print x # if i % 2 == 0: # set x = x + 1 # endif # endfor # endfor # if a # print 'A' # elif b # print 'B' # elif c == d # print 'C' # else # print 'D' # endif ''') assert t.render(a=0, b=False, c=42, d=42.0) == '1111C'
def test_stacked_locals_scoping_bug(self): env = Environment(line_statement_prefix='#') t = env.from_string('''\ # for j in [1, 2]: # set x = 1 # for i in [1, 2]: # print x # if i % 2 == 0: # set x = x + 1 # endif # endfor # endfor # if a # print 'A' # elif b # print 'B' # elif c == d # print 'C' # else # print 'D' # endif ''') assert t.render(a=0, b=False, c=42, d=42.0) == '1111C'
from ambari_jinja2 import Environment env = Environment(line_statement_prefix='%', variable_start_string="${", variable_end_string="}") tmpl = env.from_string("""\ % macro foo() ${caller(42)} % endmacro <ul> % for item in seq <li>${item}</li> % endfor </ul> % call(var) foo() [${var}] % endcall % filter escape <hello world> % for item in [1, 2, 3] - ${item} % endfor % endfilter """) print tmpl.render(seq=range(10))
def test_extend_late(self): env = Environment() env.add_extension('ambari_jinja2.ext.autoescape') t = env.from_string('{% autoescape true %}{{ "<test>" }}{% endautoescape %}') assert t.render() == '<test>'
class MacrosTestCase(JinjaTestCase): env = Environment(trim_blocks=True) def test_simple(self): tmpl = self.env.from_string('''\ {% macro say_hello(name) %}Hello {{ name }}!{% endmacro %} {{ say_hello('Peter') }}''') assert tmpl.render() == 'Hello Peter!' def test_scoping(self): tmpl = self.env.from_string('''\ {% macro level1(data1) %} {% macro level2(data2) %}{{ data1 }}|{{ data2 }}{% endmacro %} {{ level2('bar') }}{% endmacro %} {{ level1('foo') }}''') assert tmpl.render() == 'foo|bar' def test_arguments(self): tmpl = self.env.from_string('''\ {% macro m(a, b, c='c', d='d') %}{{ a }}|{{ b }}|{{ c }}|{{ d }}{% endmacro %} {{ m() }}|{{ m('a') }}|{{ m('a', 'b') }}|{{ m(1, 2, 3) }}''') assert tmpl.render() == '||c|d|a||c|d|a|b|c|d|1|2|3|d' def test_varargs(self): tmpl = self.env.from_string('''\ {% macro test() %}{{ varargs|join('|') }}{% endmacro %}\ {{ test(1, 2, 3) }}''') assert tmpl.render() == '1|2|3' def test_simple_call(self): tmpl = self.env.from_string('''\ {% macro test() %}[[{{ caller() }}]]{% endmacro %}\ {% call test() %}data{% endcall %}''') assert tmpl.render() == '[[data]]' def test_complex_call(self): tmpl = self.env.from_string('''\ {% macro test() %}[[{{ caller('data') }}]]{% endmacro %}\ {% call(data) test() %}{{ data }}{% endcall %}''') assert tmpl.render() == '[[data]]' def test_caller_undefined(self): tmpl = self.env.from_string('''\ {% set caller = 42 %}\ {% macro test() %}{{ caller is not defined }}{% endmacro %}\ {{ test() }}''') assert tmpl.render() == 'True' def test_include(self): self.env = Environment(loader=DictLoader( {'include': '{% macro test(foo) %}[{{ foo }}]{% endmacro %}'})) tmpl = self.env.from_string( '{% from "include" import test %}{{ test("foo") }}') assert tmpl.render() == '[foo]' def test_macro_api(self): tmpl = self.env.from_string( '{% macro foo(a, b) %}{% endmacro %}' '{% macro bar() %}{{ varargs }}{{ kwargs }}{% endmacro %}' '{% macro baz() %}{{ caller() }}{% endmacro %}') assert tmpl.module.foo.arguments == ('a', 'b') assert tmpl.module.foo.defaults == () assert tmpl.module.foo.name == 'foo' assert not tmpl.module.foo.caller assert not tmpl.module.foo.catch_kwargs assert not tmpl.module.foo.catch_varargs assert tmpl.module.bar.arguments == () assert tmpl.module.bar.defaults == () assert not tmpl.module.bar.caller assert tmpl.module.bar.catch_kwargs assert tmpl.module.bar.catch_varargs assert tmpl.module.baz.caller def test_callself(self): tmpl = self.env.from_string('{% macro foo(x) %}{{ x }}{% if x > 1 %}|' '{{ foo(x - 1) }}{% endif %}{% endmacro %}' '{{ foo(5) }}') assert tmpl.render() == '5|4|3|2|1'
def test_safe(self): env = Environment(autoescape=True) tmpl = env.from_string('{{ "<div>foo</div>"|safe }}') assert tmpl.render() == '<div>foo</div>' tmpl = env.from_string('{{ "<div>foo</div>" }}') assert tmpl.render() == '<div>foo</div>'
def test_extension_nodes(self): env = Environment(extensions=[TestExtension]) tmpl = env.from_string('{% test %}') assert tmpl.render() == 'False|42|23|{}'
def test_preprocessor_extension(self): env = Environment(extensions=[PreprocessorExtension]) tmpl = env.from_string('{[[TEST]]}') assert tmpl.render(foo=42) == '{(42)}'
def test_streamfilter_extension(self): env = Environment(extensions=[StreamFilterExtension]) env.globals['gettext'] = lambda x: x.upper() tmpl = env.from_string('Foo _(bar) Baz') out = tmpl.render() assert out == 'Foo BAR Baz'
def test_escaped(self): env = Environment(autoescape=True) tmpl = env.from_string('{{ x is escaped }}|{{ y is escaped }}') assert tmpl.render(x='foo', y=Markup('foo')) == 'False|True'
from ambari_jinja2 import Environment env = Environment(line_statement_prefix="#", variable_start_string="${", variable_end_string="}") print env.from_string("""\ <ul> # for item in range(10) <li class="${loop.cycle('odd', 'even')}">${item}</li> # endfor </ul>\ """).render()
def test_scoping(self): env = Environment(extensions=['ambari_jinja2.ext.autoescape']) tmpl = env.from_string('{% autoescape true %}{% set x = "<x>" %}{{ x }}' '{% endautoescape %}{{ x }}{{ "<y>" }}') assert tmpl.render(x=1) == '<x>1<y>'