def test_tricky_expression(self): template = """ ${x and "|" or "hi"} """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n\n ', (1, 1)), Expression('x and "|" or "hi"', [], (3, 13)), Text('\n ', (3, 33)) ])) template = r""" ${hello + '''heres '{|}' text | | }''' | escape1} ${'Tricky string: ' + '\\\"\\\'|\\'} """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n\n ', (1, 1)), Expression("hello + '''heres '{|}' text | | }''' ", ['escape1'], (3, 13)), Text('\n ', (3, 62)), Expression(r"""'Tricky string: ' + '\\\"\\\'|\\'""", [], (4, 13)), Text('\n ', (4, 49)) ]))
def test_tricky_code(self): if compat.py3k: template = """<% print('hi %>') %>""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [Code("print('hi %>') \n", False, (1, 1))])) else: template = """<% print 'hi %>' %>""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [Code("print 'hi %>' \n", False, (1, 1))]))
def test_docs(self): template = \ """ <%doc> this is a comment </%doc> <%def name="foo()"> <%doc> this is the foo func </%doc> </%def> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n ', (1, 1)), Comment('''\n this is a comment\n ''', (2, 9)), Text('\n ', (4, 16)), DefTag('def', {'name': 'foo()'}, (5, 9), [ Text('\n ', (5, 28)), Comment( '''\n this is the foo func\n''' ''' ''', (6, 13)), Text('\n ', (8, 20)) ]), Text('\n ', (9, 16)) ]))
def test_crlf(self): template = util.read_file(self._file_path("crlf.html")) nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('<html>\r\n\r\n', (1, 1)), PageTag('page', {'args': "a=['foo',\n 'bar']"}, (3, 1), []), Text('\r\n\r\nlike the name says.\r\n\r\n', (4, 26)), ControlLine('for', 'for x in [1,2,3]:', False, (8, 1)), Text(' ', (9, 1)), Expression('x', [], (9, 9)), ControlLine('for', 'endfor', True, (10, 1)), Text('\r\n', (11, 1)), Expression( "trumpeter == 'Miles' and " "trumpeter or \\\n 'Dizzy'", [], (12, 1)), Text('\r\n\r\n', (13, 15)), DefTag('def', {'name': 'hi()'}, (15, 1), [Text('\r\n hi!\r\n', (15, 19))]), Text('\r\n\r\n</html>\r\n', (17, 8)) ])) assert flatten_result(Template(template).render()) \ == """<html> like the name says. 1 2 3 Dizzy </html>"""
def test_tricky_code_4(self): template = \ """<% foo = "\\"\\\\" %>""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [Code("""foo = "\\"\\\\" \n""", False, (1, 1))]))
def test_control_lines(self): template = \ """ text text la la % if foo(): mroe text la la blah blah % endif and osme more stuff % for l in range(1,5): tex tesl asdl l is ${l} kfmas d % endfor tetx text """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('''\ntext text la la\n''', (1, 1)), ControlLine('if', 'if foo():', False, (3, 1)), Text(' mroe text la la blah blah\n', (4, 1)), ControlLine('if', 'endif', True, (5, 1)), Text('''\n and osme more stuff\n''', (6, 1)), ControlLine('for', 'for l in range(1,5):', False, (8, 1)), Text(' tex tesl asdl l is ', (9, 1)), Expression('l', [], (9, 24)), Text(' kfmas d\n', (9, 28)), ControlLine('for', 'endfor', True, (10, 1)), Text(''' tetx text\n\n''', (11, 1)) ]))
def test_ternary_control(self): template = \ """ % if x: hi % elif y+7==10: there % elif lala: lala % else: hi % endif """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n', (1, 1)), ControlLine('if', 'if x:', False, (2, 1)), Text(' hi\n', (3, 1)), ControlLine('elif', 'elif y+7==10:', False, (4, 1)), Text(' there\n', (5, 1)), ControlLine('elif', 'elif lala:', False, (6, 1)), Text(' lala\n', (7, 1)), ControlLine('else', 'else:', False, (8, 1)), Text(' hi\n', (9, 1)), ControlLine('if', 'endif', True, (10, 1)) ]))
def test_tricky_code_3(self): template = \ """<% print('hi') # this is a comment # another comment x = 7 # someone's '''comment print(''' there ''') # someone else's comment %> '''and now some text '''""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Code( """ print('hi') # this is a comment # another comment x = 7 # someone's '''comment print(''' there ''') # someone else's comment """, False, (1, 1)), Text(" '''and now some text '''", (10, 3)) ]))
def test_expression(self): template = \ """ this is some ${text} and this is ${textwith | escapes, moreescapes} <%def name="hi()"> give me ${foo()} and ${bar()} </%def> ${hi()} """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n this is some ', (1, 1)), Expression('text', [], (2, 22)), Text(' and this is ', (2, 29)), Expression('textwith ', ['escapes', 'moreescapes'], (2, 42)), Text('\n ', (2, 76)), DefTag('def', {'name': 'hi()'}, (3, 9), [ Text('\n give me ', (3, 27)), Expression('foo()', [], (4, 21)), Text(' and ', (4, 29)), Expression('bar()', [], (4, 34)), Text('\n ', (4, 42)) ]), Text('\n ', (5, 16)), Expression('hi()', [], (6, 9)), Text('\n', (6, 16)) ]))
def test_ns_tag_open(self): template = \ """ <%self:go x="1" y="${process()}"> this is the body </%self:go> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text(''' ''', (1, 1)), CallNamespaceTag('self:go', { 'x': '1', 'y': '${process()}' }, (3, 13), [ Text(''' this is the body ''', (3, 46)) ]), Text('\n ', (5, 24)) ]))
def test_code(self): template = \ """text <% print "hi" for x in range(1,5): print x %> more text <%! import foo %> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('text\n ', (1, 1)), Code( '\nprint "hi"\nfor x in range(1,5):\n ' 'print x\n \n', False, (2, 5)), Text('\nmore text\n ', (6, 7)), Code('\nimport foo\n \n', True, (8, 5)), Text('\n', (10, 7)) ]))
def test_nesting(self): template = \ """ <%namespace name="ns"> <%def name="lala(hi, there)"> <%call expr="something()"/> </%def> </%namespace> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text(''' ''', (1, 1)), NamespaceTag('namespace', {'name': 'ns'}, (3, 9), [ Text('\n ', (3, 31)), DefTag('def', {'name': 'lala(hi, there)'}, (4, 13), [ Text('\n ', (4, 42)), CallTag('call', {'expr': 'something()'}, (5, 17), []), Text('\n ', (5, 44)) ]), Text('\n ', (6, 20)) ]), Text(''' ''', (7, 22)) ]))
def test_wrongcase_tag(self): template = \ """ <%DEF name="foo()"> </%def> """ self.assertRaises(errors.CompileException, Lexer(template).parse)
def test_def_syntax_2(self): template = \ """ <%def name="lala"> hi </%def> """ self.assertRaises(errors.CompileException, Lexer(template).parse)
def test_tricky_code_6(self): template = \ """before ${ (0x5302 | 0x0400) } after""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('before ', (1, 1)), Expression(" (0x5302 | 0x0400) ", [], (1, 8)), Text(' after', (1, 30)) ]))
def test_tricky_code_5(self): template = \ """before ${ {'key': 'value'} } after""" nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('before ', (1, 1)), Expression(" {'key': 'value'} ", [], (1, 8)), Text(' after', (1, 29)) ]))
def test_unmatched_control(self): template = """ % if foo: % for x in range(1,5): % endif """ assert_raises_message( errors.SyntaxException, "Keyword 'endif' doesn't match keyword 'for' at line: 5 char: 1", Lexer(template).parse)
def test_unmatched_control_2(self): template = """ % if foo: % for x in range(1,5): % endfor """ assert_raises_message( errors.SyntaxException, "Unterminated control keyword: 'if' at line: 3 char: 1", Lexer(template).parse)
def test_onlyclosed_tag(self): template = \ """ <%def name="foo()"> foo </%def> </%namespace> hi. """ self.assertRaises(errors.SyntaxException, Lexer(template).parse)
def test_unclosed_tag(self): template = """ <%def name="foo()"> other text """ try: nodes = Lexer(template).parse() assert False except errors.SyntaxException: eq_(str(compat.exception_as()), "Unclosed tag: <%def> at line: 5 char: 9")
def test_integration(self): template = \ """<%namespace name="foo" file="somefile.html"/> ## inherit from foobar.html <%inherit file="foobar.html"/> <%def name="header()"> <div>header</div> </%def> <%def name="footer()"> <div> footer</div> </%def> <table> % for j in data(): <tr> % for x in j: <td>Hello ${x| h}</td> % endfor </tr> % endfor </table> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ NamespaceTag('namespace', { 'file': 'somefile.html', 'name': 'foo' }, (1, 1), []), Text('\n', (1, 46)), Comment('inherit from foobar.html', (2, 1)), InheritTag('inherit', {'file': 'foobar.html'}, (3, 1), []), Text('''\n\n''', (3, 31)), DefTag('def', {'name': 'header()'}, (5, 1), [Text('''\n <div>header</div>\n''', (5, 23))]), Text('\n', (7, 8)), DefTag('def', {'name': 'footer()'}, (8, 1), [Text('''\n <div> footer</div>\n''', (8, 23))]), Text('''\n\n<table>\n''', (10, 8)), ControlLine('for', 'for j in data():', False, (13, 1)), Text(' <tr>\n', (14, 1)), ControlLine('for', 'for x in j:', False, (15, 1)), Text(' <td>Hello ', (16, 1)), Expression('x', ['h'], (16, 23)), Text('</td>\n', (16, 30)), ControlLine('for', 'endfor', True, (17, 1)), Text(' </tr>\n', (18, 1)), ControlLine('for', 'endfor', True, (19, 1)), Text('</table>\n', (20, 1)) ]))
def test_ns_tag_empty(self): template = \ """ <%form:option value=""></%form:option> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n ', (1, 1)), CallNamespaceTag('form:option', {'value': ''}, (2, 13), []), Text('\n ', (2, 51)) ]))
def test_unmatched_tag(self): template = \ """ <%namespace name="bar"> <%def name="foo()"> foo </%namespace> </%def> hi. """ self.assertRaises(errors.SyntaxException, Lexer(template).parse)
def test_text_tag(self): template = \ """ ## comment % if foo: hi % endif <%text> # more code % more code <%illegal compionent>/></> <%def name="laal()">def</%def> </%text> <%def name="foo()">this is foo</%def> % if bar: code % endif """ node = Lexer(template).parse() self._compare( node, TemplateNode({}, [ Text('\n', (1, 1)), Comment('comment', (2, 1)), ControlLine('if', 'if foo:', False, (3, 1)), Text(' hi\n', (4, 1)), ControlLine('if', 'endif', True, (5, 1)), Text(' ', (6, 1)), TextTag('text', {}, (6, 9), [ Text( '\n # more code\n\n ' ' % more code\n <%illegal compionent>/></>\n' ' <%def name="laal()">def</%def>\n\n\n ', (6, 16)) ]), Text('\n\n ', (14, 17)), DefTag('def', {'name': 'foo()'}, (16, 9), [Text('this is foo', (16, 28))]), Text('\n\n', (16, 46)), ControlLine('if', 'if bar:', False, (18, 1)), Text(' code\n', (19, 1)), ControlLine('if', 'endif', True, (20, 1)), Text(' ', (21, 1)) ]))
def test_control_lines_2(self): template = \ """% for file in requestattr['toc'].filenames: x % endfor """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ ControlLine('for', "for file in requestattr['toc'].filenames:", False, (1, 1)), Text(' x\n', (2, 1)), ControlLine('for', 'endfor', True, (3, 1)) ]))
def test_tricky_code_2(self): template = \ """<% # someone's comment %> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Code(""" # someone's comment """, False, (1, 1)), Text('\n ', (3, 3)) ]))
def test_whitespace_equals(self): template = \ """ <%def name = "adef()" > adef </%def> """ node = Lexer(template).parse() self._compare( node, TemplateNode({}, [ Text('\n ', (1, 1)), DefTag( 'def', {'name': 'adef()'}, (2, 13), [Text('''\n adef\n ''', (2, 36))]), Text('\n ', (4, 20)) ]))
def test_preprocess(self): def preproc(text): return re.sub(r'(?<=\n)\s*#[^#]', '##', text) template = \ """ hi # old style comment # another comment """ nodes = Lexer(template, preprocessor=preproc).parse() self._compare( nodes, TemplateNode({}, [ Text('''\n hi\n''', (1, 1)), Comment('old style comment', (3, 1)), Comment('another comment', (4, 1)) ]))
def test_code_and_tags(self): template = \ """ <%namespace name="foo"> <%def name="x()"> this is x </%def> <%def name="y()"> this is y </%def> </%namespace> <% result = [] data = get_data() for x in data: result.append(x+7) %> result: <%call expr="foo.x(result)"/> """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n', (1, 1)), NamespaceTag('namespace', {'name': 'foo'}, (2, 1), [ Text('\n ', (2, 24)), DefTag('def', {'name': 'x()'}, (3, 5), [Text('''\n this is x\n ''', (3, 22))]), Text('\n ', (5, 12)), DefTag('def', {'name': 'y()'}, (6, 5), [Text('''\n this is y\n ''', (6, 22))]), Text('\n', (8, 12)) ]), Text('''\n\n''', (9, 14)), Code( '''\nresult = []\ndata = get_data()\n''' '''for x in data:\n result.append(x+7)\n\n''', False, (11, 1)), Text('''\n\n result: ''', (16, 3)), CallTag('call', {'expr': 'foo.x(result)'}, (18, 13), []), Text('\n', (18, 42)) ]))
def test_comment_after_statement(self): template = \ """ % if x: #comment hi % else: #next hi % endif #end """ nodes = Lexer(template).parse() self._compare( nodes, TemplateNode({}, [ Text('\n', (1, 1)), ControlLine('if', 'if x: #comment', False, (2, 1)), Text(' hi\n', (3, 1)), ControlLine('else', 'else: #next', False, (4, 1)), Text(' hi\n', (5, 1)), ControlLine('if', 'endif #end', True, (6, 1)) ]))