NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

lexnparse.py (10217B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\jinja2\testsuite\lexnparse.py
      2 import sys
      3 import unittest
      4 from jinja2.testsuite import JinjaTestCase
      5 from jinja2 import Environment, Template, TemplateSyntaxError, UndefinedError, nodes
      6 env = Environment()
      7 if sys.version_info < (3, 0):
      8 
      9     def jinja_string_repr(string):
     10         return repr(string)[1:]
     11 
     12 
     13 else:
     14     jinja_string_repr = repr
     15 
     16 class LexerTestCase(JinjaTestCase):
     17 
     18     def test_raw1(self):
     19         tmpl = env.from_string('{% raw %}foo{% endraw %}|{%raw%}{{ bar }}|{% baz %}{%       endraw    %}')
     20 
     21     def test_raw2(self):
     22         tmpl = env.from_string('1  {%- raw -%}   2   {%- endraw -%}   3')
     23 
     24     def test_balancing(self):
     25         env = Environment('{%', '%}', '${', '}')
     26         tmpl = env.from_string("{% for item in seq\n            %}${{'foo': item}|upper}{% endfor %}")
     27 
     28     def test_comments(self):
     29         env = Environment('<!--', '-->', '{', '}')
     30         tmpl = env.from_string('<ul>\n<!--- for item in seq -->\n  <li>{item}</li>\n<!--- endfor -->\n</ul>')
     31 
     32     def test_string_escapes(self):
     33         for char in (u'\x00', u'\u2668', u'\xe4', u'\t', u'\r', u'\n'):
     34             tmpl = env.from_string('{{ %s }}' % jinja_string_repr(char))
     35 
     36     def test_bytefallback(self):
     37         from pprint import pformat
     38         tmpl = env.from_string(u"{{ 'foo'|pprint }}|{{ 'b\xe4r'|pprint }}")
     39 
     40     def test_operators(self):
     41         from jinja2.lexer import operators
     42         for test, expect in operators.iteritems():
     43             if test in '([{}])':
     44                 continue
     45             stream = env.lexer.tokenize('{{ %s }}' % test)
     46             stream.next()
     47 
     48     def test_normalizing(self):
     49         for seq in ('\r', '\r\n', '\n'):
     50             env = Environment(newline_sequence=seq)
     51             tmpl = env.from_string('1\n2\r\n3\n4\n')
     52             result = tmpl.render()
     53 
     54 
     55 class ParserTestCase(JinjaTestCase):
     56 
     57     def test_php_syntax(self):
     58         env = Environment('<?', '?>', '<?=', '?>', '<!--', '-->')
     59         tmpl = env.from_string("<!-- I'm a comment, I'm not interesting --><? for item in seq -?>\n    <?= item ?>\n<?- endfor ?>")
     60 
     61     def test_erb_syntax(self):
     62         env = Environment('<%', '%>', '<%=', '%>', '<%#', '%>')
     63         tmpl = env.from_string("<%# I'm a comment, I'm not interesting %><% for item in seq -%>\n    <%= item %>\n<%- endfor %>")
     64 
     65     def test_comment_syntax(self):
     66         env = Environment('<!--', '-->', '${', '}', '<!--#', '-->')
     67         tmpl = env.from_string("<!--# I'm a comment, I'm not interesting --><!-- for item in seq --->\n    ${item}\n<!--- endfor -->")
     68 
     69     def test_balancing(self):
     70         tmpl = env.from_string("{{{'foo':'bar'}.foo}}")
     71 
     72     def test_start_comment(self):
     73         tmpl = env.from_string('{# foo comment\nand bar comment #}\n{% macro blub() %}foo{% endmacro %}\n{{ blub() }}')
     74 
     75     def test_line_syntax(self):
     76         env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%')
     77         tmpl = env.from_string('<%# regular comment %>\n% for item in seq:\n    ${item}\n% endfor')
     78         env = Environment('<%', '%>', '${', '}', '<%#', '%>', '%', '##')
     79         tmpl = env.from_string('<%# regular comment %>\n% for item in seq:\n    ${item} ## the rest of the stuff\n% endfor')
     80 
     81     def test_line_syntax_priority(self):
     82         env = Environment('{%', '%}', '${', '}', '/*', '*/', '##', '#')
     83         tmpl = env.from_string("/* ignore me.\n   I'm a multiline comment */\n## for item in seq:\n* ${item}          # this is just extra stuff\n## endfor")
     84         env = Environment('{%', '%}', '${', '}', '/*', '*/', '#', '##')
     85         tmpl = env.from_string("/* ignore me.\n   I'm a multiline comment */\n# for item in seq:\n* ${item}          ## this is just extra stuff\n    ## extra stuff i just want to ignore\n# endfor")
     86 
     87     def test_error_messages(self):
     88 
     89         def assert_error(code, expected):
     90             try:
     91                 Template(code)
     92             except TemplateSyntaxError as e:
     93                 pass
     94 
     95         assert_error('{% for item in seq %}...{% endif %}', "Encountered unknown tag 'endif'. Jinja was looking for the following tags: 'endfor' or 'else'. The innermost block that needs to be closed is 'for'.")
     96         assert_error('{% if foo %}{% for item in seq %}...{% endfor %}{% endfor %}', "Encountered unknown tag 'endfor'. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.")
     97         assert_error('{% if foo %}', "Unexpected end of template. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.")
     98         assert_error('{% for item in seq %}', "Unexpected end of template. Jinja was looking for the following tags: 'endfor' or 'else'. The innermost block that needs to be closed is 'for'.")
     99         assert_error('{% block foo-bar-baz %}', 'Block names in Jinja have to be valid Python identifiers and may not contain hyphens, use an underscore instead.')
    100         assert_error('{% unknown_tag %}', "Encountered unknown tag 'unknown_tag'.")
    101 
    102 
    103 class SyntaxTestCase(JinjaTestCase):
    104 
    105     def test_call(self):
    106         env = Environment()
    107         env.globals['foo'] = lambda a, b, c, e, g: a + b + c + e + g
    108         tmpl = env.from_string("{{ foo('a', c='d', e='f', *['b'], **{'g': 'h'}) }}")
    109 
    110     def test_slicing(self):
    111         tmpl = env.from_string('{{ [1, 2, 3][:] }}|{{ [1, 2, 3][::-1] }}')
    112 
    113     def test_attr(self):
    114         tmpl = env.from_string("{{ foo.bar }}|{{ foo['bar'] }}")
    115 
    116     def test_subscript(self):
    117         tmpl = env.from_string('{{ foo[0] }}|{{ foo[-1] }}')
    118 
    119     def test_tuple(self):
    120         tmpl = env.from_string('{{ () }}|{{ (1,) }}|{{ (1, 2) }}')
    121 
    122     def test_math(self):
    123         tmpl = env.from_string('{{ (1 + 1 * 2) - 3 / 2 }}|{{ 2**3 }}')
    124 
    125     def test_div(self):
    126         tmpl = env.from_string('{{ 3 // 2 }}|{{ 3 / 2 }}|{{ 3 % 2 }}')
    127 
    128     def test_unary(self):
    129         tmpl = env.from_string('{{ +3 }}|{{ -3 }}')
    130 
    131     def test_concat(self):
    132         tmpl = env.from_string("{{ [1, 2] ~ 'foo' }}")
    133 
    134     def test_compare(self):
    135         tmpl = env.from_string('{{ 1 > 0 }}|{{ 1 >= 1 }}|{{ 2 < 3 }}|{{ 2 == 2 }}|{{ 1 <= 1 }}')
    136 
    137     def test_inop(self):
    138         tmpl = env.from_string('{{ 1 in [1, 2, 3] }}|{{ 1 not in [1, 2, 3] }}')
    139 
    140     def test_literals(self):
    141         tmpl = env.from_string('{{ [] }}|{{ {} }}|{{ () }}')
    142 
    143     def test_bool(self):
    144         tmpl = env.from_string('{{ true and false }}|{{ false or true }}|{{ not false }}')
    145 
    146     def test_grouping(self):
    147         tmpl = env.from_string('{{ (true and false) or (false and true) and not false }}')
    148 
    149     def test_django_attr(self):
    150         tmpl = env.from_string('{{ [1, 2, 3].0 }}|{{ [[1]].0.0 }}')
    151 
    152     def test_conditional_expression(self):
    153         tmpl = env.from_string('{{ 0 if true else 1 }}')
    154 
    155     def test_short_conditional_expression(self):
    156         tmpl = env.from_string('<{{ 1 if false }}>')
    157         tmpl = env.from_string('<{{ (1 if false).bar }}>')
    158         self.assert_raises(UndefinedError, tmpl.render)
    159 
    160     def test_filter_priority(self):
    161         tmpl = env.from_string('{{ "foo"|upper + "bar"|upper }}')
    162 
    163     def test_function_calls(self):
    164         tests = [(True, '*foo, bar'),
    165          (True, '*foo, *bar'),
    166          (True, '*foo, bar=42'),
    167          (True, '**foo, *bar'),
    168          (True, '**foo, bar'),
    169          (False, 'foo, bar'),
    170          (False, 'foo, bar=42'),
    171          (False, 'foo, bar=23, *args'),
    172          (False, 'a, b=c, *d, **e'),
    173          (False, '*foo, **bar')]
    174         for should_fail, sig in tests:
    175             if should_fail:
    176                 self.assert_raises(TemplateSyntaxError, env.from_string, '{{ foo(%s) }}' % sig)
    177             else:
    178                 env.from_string('foo(%s)' % sig)
    179 
    180     def test_tuple_expr(self):
    181         for tmpl in ['{{ () }}',
    182          '{{ (1, 2) }}',
    183          '{{ (1, 2,) }}',
    184          '{{ 1, }}',
    185          '{{ 1, 2 }}',
    186          '{% for foo, bar in seq %}...{% endfor %}',
    187          '{% for x in foo, bar %}...{% endfor %}',
    188          '{% for x in foo, %}...{% endfor %}']:
    189             pass
    190 
    191     def test_trailing_comma(self):
    192         tmpl = env.from_string('{{ (1, 2,) }}|{{ [1, 2,] }}|{{ {1: 2,} }}')
    193 
    194     def test_block_end_name(self):
    195         env.from_string('{% block foo %}...{% endblock foo %}')
    196         self.assert_raises(TemplateSyntaxError, env.from_string, '{% block x %}{% endblock y %}')
    197 
    198     def test_constant_casing(self):
    199         for const in (True, False, None):
    200             tmpl = env.from_string('{{ %s }}|{{ %s }}|{{ %s }}' % (str(const), str(const).lower(), str(const).upper()))
    201 
    202     def test_test_chaining(self):
    203         self.assert_raises(TemplateSyntaxError, env.from_string, '{{ foo is string is sequence }}')
    204 
    205     def test_string_concatenation(self):
    206         tmpl = env.from_string('{{ "foo" "bar" "baz" }}')
    207 
    208     def test_notin(self):
    209         bar = xrange(100)
    210         tmpl = env.from_string('{{ not 42 in bar }}')
    211 
    212     def test_implicit_subscribed_tuple(self):
    213 
    214         class Foo(object):
    215 
    216             def __getitem__(self, x):
    217                 return x
    218 
    219         t = env.from_string('{{ foo[1, 2] }}')
    220 
    221     def test_raw2(self):
    222         tmpl = env.from_string('{% raw %}{{ FOO }} and {% BAR %}{% endraw %}')
    223 
    224     def test_const(self):
    225         tmpl = env.from_string('{{ true }}|{{ false }}|{{ none }}|{{ none is defined }}|{{ missing is defined }}')
    226 
    227     def test_neg_filter_priority(self):
    228         node = env.parse('{{ -1|foo }}')
    229 
    230     def test_const_assign(self):
    231         constass1 = '{% set true = 42 %}'
    232         constass2 = '{% for none in seq %}{% endfor %}'
    233         for tmpl in (constass1, constass2):
    234             self.assert_raises(TemplateSyntaxError, env.from_string, tmpl)
    235 
    236     def test_localset(self):
    237         tmpl = env.from_string('{% set foo = 0 %}{% for item in [1, 2] %}{% set foo = 1 %}{% endfor %}{{ foo }}')
    238 
    239     def test_parse_unary(self):
    240         tmpl = env.from_string('{{ -foo["bar"] }}')
    241         tmpl = env.from_string('{{ -foo["bar"]|abs }}')
    242 
    243 
    244 def suite():
    245     suite = unittest.TestSuite()
    246     suite.addTest(unittest.makeSuite(LexerTestCase))
    247     suite.addTest(unittest.makeSuite(ParserTestCase))
    248     suite.addTest(unittest.makeSuite(SyntaxTestCase))
    249     return suite