def test_latin1_encoded_explicit_encoding(self): tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> \xf6 </div>""".encode('iso-8859-1'), encoding='iso-8859-1') self.assertEqual("""<div> \xf6 </div>""", str(tmpl.generate()))
def test_latin1_encoded_explicit_encoding(self): tmpl = MarkupTemplate(u"""<div xmlns:py="http://genshi.edgewall.org/"> \xf6 </div>""".encode('iso-8859-1'), encoding='iso-8859-1') self.assertEqual(u"""<div> \xf6 </div>""", unicode(tmpl.generate()))
def test_relative_include_without_loader_relative(self): file1 = open(os.path.join(self.dirname, 'tmpl1.html'), 'w') try: file1.write("""<div>Included</div>""") finally: file1.close() file2 = open(os.path.join(self.dirname, 'tmpl2.html'), 'w') try: file2.write("""<html xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="tmpl1.html" /> </html>""") finally: file2.close() tmpl = MarkupTemplate( """<html xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="tmpl1.html" /> </html>""", filename=os.path.join(self.dirname, 'tmpl2.html')) self.assertEqual( """<html> <div>Included</div> </html>""", tmpl.generate().render(encoding=None))
def test_relative_include_without_loader_relative(self): file1 = open(os.path.join(self.dirname, "tmpl1.html"), "w") try: file1.write("""<div>Included</div>""") finally: file1.close() file2 = open(os.path.join(self.dirname, "tmpl2.html"), "w") try: file2.write( """<html xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="tmpl1.html" /> </html>""" ) finally: file2.close() tmpl = MarkupTemplate( """<html xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="tmpl1.html" /> </html>""", filename=os.path.join(self.dirname, "tmpl2.html"), ) self.assertEqual( """<html> <div>Included</div> </html>""", tmpl.generate().render(encoding=None), )
def test_template_comment(self): tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> <!-- !foo --> <!--!bar--> </div>""") self.assertEqual("""<div> </div>""", str(tmpl.generate()))
def test_directive_element(self): tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> <py:if test="myvar">bar</py:if> </div>""") self.assertEqual("""<div> bar </div>""", str(tmpl.generate(myvar='"foo"')))
def test_match_tail_handling(self): # See <http://genshi.edgewall.org/ticket/399> xml = ("""<rhyme xmlns:py="http://genshi.edgewall.org/"> <py:match path="*[@type]"> ${select('.')} </py:match> <lines> <first type="one">fish</first> <second type="two">fish</second> <third type="red">fish</third> <fourth type="blue">fish</fourth> </lines> </rhyme>""") tmpl = MarkupTemplate(xml, filename='test.html') self.assertEqual( """<rhyme> <lines> <first type="one">fish</first> <second type="two">fish</second> <third type="red">fish</third> <fourth type="blue">fish</fourth> </lines> </rhyme>""", tmpl.generate().render(encoding=None))
def test_exec_import(self): tmpl = MarkupTemplate("""<?python from datetime import timedelta ?> <div xmlns:py="http://genshi.edgewall.org/"> ${timedelta(days=2)} </div>""") self.assertEqual("""<div> 2 days, 0:00:00 </div>""", str(tmpl.generate()))
def test_latin1_encoded_with_xmldecl(self): tmpl = MarkupTemplate("""<?xml version="1.0" encoding="iso-8859-1" ?> <div xmlns:py="http://genshi.edgewall.org/"> \xf6 </div>""".encode('iso-8859-1'), encoding='iso-8859-1') self.assertEqual("""<?xml version="1.0" encoding="iso-8859-1"?>\n<div> \xf6 </div>""", str(tmpl.generate()))
def test_lazy_string_with_genshi(self): # See https://github.com/TurboGears/tg2/pull/68 from genshi.template.markup import MarkupTemplate markup = """<b xmlns:py="http://genshi.edgewall.org/">${foo}</b>""" template = MarkupTemplate(markup) stream = template.generate(foo=LazyString(lambda: "bar")) output = str(stream) # Contains only ascii char, so it should cast fine on both py2 and py3 assert output == '<b>bar</b>', output
def test_latin1_encoded_with_xmldecl(self): tmpl = MarkupTemplate(u"""<?xml version="1.0" encoding="iso-8859-1" ?> <div xmlns:py="http://genshi.edgewall.org/"> \xf6 </div>""".encode('iso-8859-1'), encoding='iso-8859-1') self.assertEqual(u"""<?xml version="1.0" encoding="iso-8859-1"?>\n<div> \xf6 </div>""", unicode(tmpl.generate()))
def test_parse_with_same_namespace_nested(self): tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> <span xmlns:py="http://genshi.edgewall.org/"> </span> </div>""") self.assertEqual("""<div> <span> </span> </div>""", str(tmpl.generate()))
def render(self, namespace, **options): # import genshi only here because this package is optional from genshi.template.markup import MarkupTemplate template = MarkupTemplate(self.text) stream = template.generate(**namespace) # enforce conversion to unicode options['encoding'] = None rendered_template = stream.render(**options) return rendered_template
def test_attr_escape_quotes(self): """ Verify that outputting context data in attribtes escapes quotes. """ tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> <elem class="$myvar"/> </div>""") self.assertEqual("""<div> <elem class=""foo""/> </div>""", str(tmpl.generate(myvar='"foo"')))
def test_text_noescape_quotes(self): """ Verify that outputting context data in text nodes doesn't escape quotes. """ tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> $myvar </div>""") self.assertEqual("""<div> "foo" </div>""", str(tmpl.generate(myvar='"foo"')))
def test_markup_noescape(self): """ Verify that outputting context data that is a `Markup` instance is not escaped. """ tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> $myvar </div>""") self.assertEqual("""<div> <b>foo</b> </div>""", str(tmpl.generate(myvar=Markup('<b>foo</b>'))))
def __init__(self, source, basedir=None, filename=None, loader=None, encoding=None, lookup='strict', allow_exec=True, default_namespace=None): if default_namespace is None: default_namespace = self.DEFAULT_NAMESPACE self.default_namespace = default_namespace # FIXME: MarkupTemplate.__init__ does not expect the keyword argument # 'basedir' MarkupTemplate.__init__(self, source, #basedir=basedir, filename=filename, loader=loader, encoding=encoding, lookup=lookup, allow_exec=allow_exec)
def test_exec_def(self): tmpl = MarkupTemplate(""" <?python def foo(): return 42 ?> <div xmlns:py="http://genshi.edgewall.org/"> ${foo()} </div>""") self.assertEqual("""<div> 42 </div>""", str(tmpl.generate()))
def test_directive_single_line_with_translator(self): tmpl = MarkupTemplate("""<div xmlns:py="http://genshi.edgewall.org/"> <py:for each="i in range(2)"><py:for each="j in range(1)"> <span py:content="i + j"></span> </py:for></py:for> </div>""") translator = Translator(lambda s: s) tmpl.add_directives(Translator.NAMESPACE, translator) self.assertEqual( """<div> <span>0</span> <span>1</span> </div>""", str(tmpl.generate()))
def test_exec_in_match(self): xml = ("""<html xmlns:py="http://genshi.edgewall.org/"> <py:match path="body/p"> <?python title="wakka wakka wakka" ?> ${title} </py:match> <body><p>moot text</p></body> </html>""") tmpl = MarkupTemplate(xml, filename='test.html', allow_exec=True) self.assertEqual("""<html> <body> wakka wakka wakka </body> </html>""", tmpl.generate().render(encoding=None))
def test_relative_include_from_inmemory_template(self): file1 = open(os.path.join(self.dirname, 'tmpl1.html'), 'w') try: file1.write("""<div>Included</div>""") finally: file1.close() loader = TemplateLoader([self.dirname]) tmpl2 = MarkupTemplate("""<html xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="../tmpl1.html" /> </html>""", filename='subdir/tmpl2.html', loader=loader) self.assertEqual("""<html> <div>Included</div> </html>""", tmpl2.generate().render(encoding=None))
def test_with_in_match(self): xml = ("""<html xmlns:py="http://genshi.edgewall.org/"> <py:match path="body/p"> <h1>${select('text()')}</h1> ${select('.')} </py:match> <body><p py:with="foo='bar'">${foo}</p></body> </html>""") tmpl = MarkupTemplate(xml, filename='test.html') self.assertEqual("""<html> <body> <h1>bar</h1> <p>bar</p> </body> </html>""", tmpl.generate().render(encoding=None))
def test_namespace_on_removed_elem(self): """ Verify that a namespace declaration on an element that is removed from the generated stream does not get pushed up to the next non-stripped element (see ticket #107). """ tmpl = MarkupTemplate("""<?xml version="1.0"?> <Test xmlns:py="http://genshi.edgewall.org/"> <Size py:if="0" xmlns:t="test">Size</Size> <Item/> </Test>""") self.assertEqual("""<?xml version="1.0"?>\n<Test> <Item/> </Test>""", str(tmpl.generate()))
def test_relative_include_from_inmemory_template(self): file1 = open(os.path.join(self.dirname, 'tmpl1.html'), 'w') try: file1.write("""<div>Included</div>""") finally: file1.close() loader = TemplateLoader([self.dirname]) tmpl2 = MarkupTemplate("""<html xmlns:xi="http://www.w3.org/2001/XInclude"> <xi:include href="../tmpl1.html" /> </html>""", filename='subdir/tmpl2.html', loader=loader) self.assertEqual("""<html> <div>Included</div> </html>""", tmpl2.generate().render())
def test_bad_directive_error(self): xml = '<p xmlns:py="http://genshi.edgewall.org/" py:do="nothing" />' try: tmpl = MarkupTemplate(xml, filename='test.html') except BadDirectiveError as e: self.assertEqual('test.html', e.filename) self.assertEqual(1, e.lineno)
def test_pickle(self): stream = XML('<root>$var</root>') tmpl = MarkupTemplate(stream) buf = BytesIO() pickle.dump(tmpl, buf, 2) buf.seek(0) unpickled = pickle.load(buf) self.assertEqual('<root>42</root>', str(unpickled.generate(var=42)))
def _parse(self, source, encoding): if isinstance(source, str): source = source.decode(encoding) parser = Parser(source, self.filename, lookup=self.lookup, inline_directives=dict(self.directives), standalone_directives=self.standalone_directives) parser.parse() return MarkupTemplate._parse(self, parser.stream, encoding)
def test_directive_value_syntax_error(self): xml = """<p xmlns:py="http://genshi.edgewall.org/" py:if="bar'" />""" try: tmpl = MarkupTemplate(xml, filename='test.html').generate() self.fail('Expected TemplateSyntaxError') except TemplateSyntaxError as e: self.assertEqual('test.html', e.filename) self.assertEqual(1, e.lineno)
def test_genshi_template(): py.test.importorskip('genshi') from genshi.template.markup import MarkupTemplate # the following snippet is copied from # http://genshi.edgewall.org/wiki/ApiDocs/genshi.template.markup # and extended by an assignment at the beginning #<ul py:with="items=range(10)"> template_text = '''<div xmlns:py="http://genshi.edgewall.org/"> <ul> <li py:for="item in items">${item}</li> </ul> </div>''' genshi_template = GenshiTemplate(template_text) rendered_genshi_template = genshi_template.render({'items': range(10)}) assumed_stream = MarkupTemplate(template_text).generate(items=range(10)) assumed_result = assumed_stream.render() assert rendered_genshi_template == assumed_result
def test_directive_value_syntax_error(self): xml = """<p xmlns:py="http://genshi.edgewall.org/" py:if="bar'" />""" try: tmpl = MarkupTemplate(xml, filename='test.html') self.fail('Expected SyntaxError') except TemplateSyntaxError, e: self.assertEqual('test.html', e.filename) if sys.version_info[:2] >= (2, 4): self.assertEqual(1, e.lineno)
def test_match_without_select(self): # See <http://genshi.edgewall.org/ticket/243> xml = ("""<html xmlns:py="http://genshi.edgewall.org/"> <py:match path="body" buffer="false"> <body> This replaces the other text. </body> </py:match> <body> This gets replaced. </body> </html>""") tmpl = MarkupTemplate(xml, filename='test.html') self.assertEqual("""<html> <body> This replaces the other text. </body> </html>""", tmpl.generate().render(encoding=None))
def test_allow_exec_true(self): xml = ("""<?python title = "A Genshi Template" ?> <html xmlns:py="http://genshi.edgewall.org/"> <head> <title py:content="title">This is replaced.</title> </head> </html>""") tmpl = MarkupTemplate(xml, filename='test.html', allow_exec=True)
def test_exec_with_trailing_space(self): """ Verify that a code block processing instruction with trailing space does not cause a syntax error (see ticket #127). """ MarkupTemplate("""<foo> <?python bar = 42 ?> </foo>""")
def test_expression_syntax_error(self): xml = """<p> Foo <em>${bar"}</em> </p>""" try: tmpl = MarkupTemplate(xml, filename='test.html') self.fail('Expected TemplateSyntaxError') except TemplateSyntaxError as e: self.assertEqual('test.html', e.filename) self.assertEqual(2, e.lineno)
def test_nested_matches_without_buffering(self): xml = ("""<html xmlns:py="http://genshi.edgewall.org/"> <py:match path="body" once="true" buffer="false"> <body> ${select('*|text')} And some other stuff... </body> </py:match> <body> <span py:match="span">Foo</span> <span>Bar</span> </body> </html>""") tmpl = MarkupTemplate(xml, filename='test.html') self.assertEqual("""<html> <body> <span>Foo</span> And some other stuff... </body> </html>""", tmpl.generate().render(encoding=None))
def test_expression_syntax_error_multi_line(self): xml = """<p><em></em> ${bar"} </p>""" try: tmpl = MarkupTemplate(xml, filename='test.html') self.fail('Expected SyntaxError') except TemplateSyntaxError, e: self.assertEqual('test.html', e.filename) if sys.version_info[:2] >= (2, 4): self.assertEqual(3, e.lineno)
def test_allow_exec_false(self): xml = ("""<?python title = "A Genshi Template" ?> <html xmlns:py="http://genshi.edgewall.org/"> <head> <title py:content="title">This is replaced.</title> </head> </html>""") try: tmpl = MarkupTemplate(xml, filename='test.html', allow_exec=False) self.fail('Expected SyntaxError') except TemplateSyntaxError as e: pass
def test_match_tail_handling(self): # See <http://genshi.edgewall.org/ticket/399> xml = ("""<rhyme xmlns:py="http://genshi.edgewall.org/"> <py:match path="*[@type]"> ${select('.')} </py:match> <lines> <first type="one">fish</first> <second type="two">fish</second> <third type="red">fish</third> <fourth type="blue">fish</fourth> </lines> </rhyme>""") tmpl = MarkupTemplate(xml, filename='test.html') self.assertEqual("""<rhyme> <lines> <first type="one">fish</first> <second type="two">fish</second> <third type="red">fish</third> <fourth type="blue">fish</fourth> </lines> </rhyme>""", tmpl.generate().render(encoding=None))
def test_interpolate_list_result(self): tmpl = MarkupTemplate('<root>$foo</root>') self.assertEqual('<root>buzz</root>', str(tmpl.generate(foo=('buzz',))))
def test_interpolate_non_string_attrs(self): tmpl = MarkupTemplate('<root attr="${1}"/>') self.assertEqual('<root attr="1"/>', str(tmpl.generate()))
def test_empty_attr(self): tmpl = MarkupTemplate('<root attr=""/>') self.assertEqual('<root attr=""/>', str(tmpl.generate()))
def test_interpolate_multiline(self): tmpl = MarkupTemplate("""<root>${dict( bar = 'baz' )[foo]}</root>""") self.assertEqual('<root>baz</root>', str(tmpl.generate(foo='bar')))
def test_interpolate_leading_trailing_space(self): tmpl = MarkupTemplate('<root>${ foo }</root>') self.assertEqual('<root>bar</root>', str(tmpl.generate(foo='bar')))
def test_interpolate_mixed3(self): tmpl = MarkupTemplate('<root> ${var} $var</root>') self.assertEqual('<root> 42 42</root>', str(tmpl.generate(var=42)))
def test_empty_attr_interpolated(self): tmpl = MarkupTemplate('<root attr="$attr"/>') self.assertEqual('<root attr=""/>', str(tmpl.generate(attr='')))