root/livinglogic.python.xist/test/test_ul4.py @ 4524:00f8808b9221

Revision 4524:00f8808b9221, 65.2 KB (checked in by Walter Doerwald <walter@…>, 8 years ago)

Names for UL4 templates.

Line 
1#! /usr/bin/env/python
2# -*- coding: utf-8 -*-
3
4## Copyright 2009-2011 by LivingLogic AG, Bayreuth/Germany
5## Copyright 2009-2011 by Walter Dörwald
6##
7## All Rights Reserved
8##
9## See ll/__init__.py for the license
10
11
12from __future__ import division
13
14import sys, os, re, datetime, StringIO, json, contextlib, tempfile, collections, shutil, subprocess, pkg_resources
15
16import py.test
17
18from ll import ul4c, color, misc
19
20
21class PseudoDict(collections.Mapping):
22    def __init__(self, dict):
23        self.dict = dict
24
25    def __getitem__(self, key):
26        return self.dict[key]
27
28    def __iter__(self):
29        return iter(self.dict)
30
31    def __len__(self):
32        return len(self.dict)
33
34
35class PseudoList(collections.Sequence):
36    def __init__(self, list):
37        self.list = list
38
39    def __getitem__(self, index):
40        return self.list[index]
41
42    def __len__(self):
43        return len(self.list)
44
45
46class Render(object):
47    def __init__(self, __, **variables):
48        self.source = __
49        self.variables = variables
50        f = sys._getframe(1)
51        self.filename = f.f_code.co_filename
52        self.lineno = f.f_lineno
53
54    def __repr__(self):
55        return "{0.__class__.__name__}({0.source!r}, {0.variables!r})".format(self)
56
57
58class RenderPython(Render):
59    def renders(self):
60        template = ul4c.Template(self.source)
61        print "Testing Python template:".format(self.filename, self.lineno)
62        print template.pythonsource()
63        return template.renders(**self.variables)
64
65
66class RenderPythonDumpS(Render):
67    def renders(self):
68        template = ul4c.Template(self.source)
69        template = ul4c.Template.loads(template.dumps()) # Recreate the template from the binary dump
70        print "Testing Python template loaded from string ({}, line {}):".format(self.filename, self.lineno)
71        print template.pythonsource()
72        return template.renders(**self.variables)
73
74
75class RenderPythonDump(Render):
76    def renders(self):
77        template = ul4c.Template(self.source)
78        stream = StringIO.StringIO()
79        template.dump(stream)
80        stream.seek(0)
81        template = ul4c.Template.load(stream) # Recreate the template from the stream
82        print "Testing Python template loaded from stream ({}, line {}):".format(self.filename, self.lineno)
83        print template.pythonsource()
84        return template.renders(**self.variables)
85
86
87class RenderJS(Render):
88    def renders(self):
89        # Check the Javascript version (this requires an installed ``d8`` shell from V8 (http://code.google.com/p/v8/))
90        template = ul4c.Template(self.source)
91        js = template.jssource()
92        js = u"template = {};\ndata = {};\nprint(template.renders(data));\n".format(js, ul4c._json(self.variables))
93        print "Testing Javascript code compiled by Python ({}, line {}):".format(self.filename, self.lineno)
94        print js.encode("utf-8")
95        with tempfile.NamedTemporaryFile(mode="wb", suffix=".js") as f:
96            f.write(js.encode("utf-8"))
97            f.flush()
98            result = os.popen("d8 {} {}".format(pkg_resources.resource_filename("ll.xist", "data/"), f.name), "rb").read()
99        result = result.decode("utf-8")[:-1] # Drop the "\n"
100        # Check if we have an exception
101        if result.endswith("^"):
102            raise RuntimeError(result.splitlines()[0])
103        return result
104
105
106class RenderJava(Render):
107    maincodetemplate = u"""
108    public class UL4Test
109    {
110        @SuppressWarnings("unchecked")
111        public static void main(String[] args) throws java.io.IOException, java.io.UnsupportedEncodingException
112        {
113            %(source)s
114        }
115    }
116    """
117
118    def findexception(self, output):
119        lines = output.splitlines()
120        msg = None
121        for line in lines:
122            prefix1 = 'Exception in thread "main"'
123            prefix2 = "Caused by:"
124            if line.startswith(prefix1):
125                msg = line[len(prefix1):].strip()
126            elif line.startswith(prefix2):
127                msg = line[len(prefix2):].strip()
128            else:
129                continue
130            if msg == "Traceback (most recent call last):": # This is a Jython exception, the message is in the last line
131                msg = lines[-1]
132                break
133        if msg is not None:
134            print >>sys.stderr, output
135            raise RuntimeError(msg)
136
137    def formatsource(self, string):
138        """
139        Reindents the Java source.
140        """
141        indent = 0
142        newlines = []
143        for line in string.strip().splitlines(False):
144            line = line.strip()
145            if line == "}":
146                indent -= 1
147            if line:
148                newlines.append(indent*"\t" + line + "\n")
149            if line == "{":
150                indent += 1
151        return "".join(newlines)
152
153    def runsource(self, source):
154        """
155        Compile the Java source :var:`source`, run it and return the output
156        """
157        tempdir = tempfile.mkdtemp()
158        try:
159            source = self.maincodetemplate % dict(source=source)
160            source = self.formatsource(source)
161            print source.encode("utf-8")
162            with open(os.path.join(tempdir, "UL4Test.java"), "wb") as f:
163                f.write(source.encode("utf-8"))
164            os.system("cd {}; javac -encoding utf-8 UL4Test.java".format(tempdir))
165            pipe = subprocess.Popen("cd {}; java UL4Test".format(tempdir), stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
166            (stdout, stderr) = pipe.communicate()
167        finally:
168            shutil.rmtree(tempdir)
169        # Check if we have an exception
170        self.findexception(stdout)
171        self.findexception(stderr)
172        if stderr:
173            print >>sys.stderr, stderr
174        return stdout.decode("utf-8")
175
176
177class RenderJavaSourceCompiledByPython(RenderJava):
178    codetemplate = u"""
179    com.livinglogic.ul4.Template template = new com.livinglogic.ul4.JSPTemplate()
180    {
181        public String getName()
182        {
183            return "unnamed";
184        }
185        public void render(java.io.Writer out, java.util.Map<String, Object> variables) throws java.io.IOException
186        {
187            %(template)s
188        }
189    };
190    java.util.Map<String, Object> variables = %(variables)s;
191    String output = template.renders(variables);
192    // We can't use ``System.out.print`` here, because this gives us no control over the encoding
193    // Use ``System.out.write`` to make sure the output is in UTF-8
194    byte[] outputBytes = output.getBytes("utf-8");
195    System.out.write(outputBytes, 0, outputBytes.length);
196    """
197
198    def renders(self):
199        # Check the Java version
200        print "Testing Java code ({}, line {}):".format(self.filename, self.lineno)
201        template = ul4c.Template(self.source)
202        java = template.javasource(indent=4)
203        java = self.codetemplate % dict(variables=misc.javaexpr(self.variables), template=java)
204        return self.runsource(java)
205
206
207class RenderJavaLoadByJava(RenderJava):
208    codetemplate = u"""
209    com.livinglogic.ul4.InterpretedTemplate template = com.livinglogic.ul4.InterpretedTemplate.load(%(dump)s);
210    java.util.Map<String, Object> variables = %(variables)s;
211    String output = template.renders(variables);
212    // We can't use ``System.out.print`` here, because this gives us no control over the encoding
213    // Use ``System.out.write`` to make sure the output is in UTF-8
214    byte[] outputBytes = output.getBytes("utf-8");
215    System.out.write(outputBytes, 0, outputBytes.length);
216    """
217
218    def renders(self):
219        # Check the Java version
220        print "Testing Java InterpretedTemplate (interpreted mode, compiled by Python) ({}, line {}):".format(self.filename, self.lineno)
221        template = ul4c.Template(self.source)
222        dump = template.dumps()
223        java = self.codetemplate % dict(variables=misc.javaexpr(self.variables), dump=misc.javaexpr(dump))
224        return self.runsource(java)
225
226
227class RenderJavaSourceCompiledByJava(RenderJava):
228    codetemplate = u"""
229    com.livinglogic.ul4.InterpretedTemplate template = com.livinglogic.ul4.Compiler.compile(%(source)s);
230    System.err.println("Generate Java code:");
231    System.err.println(template.javaSource());
232    com.livinglogic.ul4.JSPTemplate compiledTemplate = template.compileToJava();
233    java.util.Map<String, Object> variables = %(variables)s;
234    String output = compiledTemplate.renders(variables);
235    // We can't use ``System.out.print`` here, because this gives us no control over the encoding
236    // Use ``System.out.write`` to make sure the output is in UTF-8
237    byte[] outputBytes = output.getBytes("utf-8");
238    System.out.write(outputBytes, 0, outputBytes.length);
239    """
240
241    def renders(self):
242        # Check the Java version
243        print "Testing Java InterpretedTemplate (compiled mode, compiled by Java) ({}, line {}):".format(self.filename, self.lineno)
244        java = self.codetemplate % dict(source=misc.javaexpr(self.source), variables=misc.javaexpr(self.variables))
245        return self.runsource(java)
246
247
248all_python_renderers = (RenderPython, RenderPythonDumpS, RenderPythonDump)
249# FIXME: The following really takes a long time to run:
250#all_renderers = (RenderPython, RenderPythonDumpS, RenderPythonDump, RenderJS, RenderJavaSourceCompiledByPython, RenderJavaLoadByJava, RenderJavaSourceCompiledByJava)
251all_renderers = all_python_renderers
252
253
254def eq(expected, render):
255    got = render.renders() # Put this on an extra line, so that py.test executes it only once
256    assert expected == got
257
258
259def evaleq(expected, render):
260    got = eval(render.renders())
261    assert expected == got
262
263
264def contains(expected, render):
265    got = render.renders()
266    assert got in expected
267
268
269def le(expected, render):
270    got = render.renders()
271    assert expected <= got
272
273
274def raises(msg, render):
275    # Check that executing ``render`` raises an exception that matches a regexp
276    try:
277        render.renders()
278    except Exception, exc:
279        assert re.search(msg, "{0.__class__.__module__}.{0.__class__.__name__}: {0}".format(exc)) is not None
280    else:
281        py.test.fail("failed to raise exception")
282
283
284@py.test.mark.ul4
285def test_text():
286    for r in all_renderers:
287        yield eq, u'gurk', r(u'gurk')
288        yield eq, u'g\xfcrk', r(u'g\xfcrk')
289
290
291@py.test.mark.ul4
292def test_none():
293    for r in all_renderers:
294        yield eq, '', r(u'<?print None?>')
295        yield eq, 'no', r(u'<?if None?>yes<?else?>no<?end if?>')
296
297
298@py.test.mark.ul4
299def test_false():
300    for r in all_renderers:
301        yield eq, 'False', r(u'<?print False?>')
302        yield eq, 'no', r(u'<?if False?>yes<?else?>no<?end if?>')
303
304
305@py.test.mark.ul4
306def test_true():
307    for r in all_renderers:
308        yield eq, 'True', r(u'<?print True?>')
309        yield eq, 'yes', r(u'<?if True?>yes<?else?>no<?end if?>')
310
311
312@py.test.mark.ul4
313def test_int():
314    for r in all_renderers:
315        yield eq, '0', r(u'<?print 0?>')
316        yield eq, '42', r(u'<?print 42?>')
317        yield eq, '-42', r(u'<?print -42?>')
318        yield eq, '255', r(u'<?print 0xff?>')
319        yield eq, '255', r(u'<?print 0Xff?>')
320        yield eq, '-255', r(u'<?print -0xff?>')
321        yield eq, '-255', r(u'<?print -0Xff?>')
322        yield eq, '63', r(u'<?print 0o77?>')
323        yield eq, '63', r(u'<?print 0O77?>')
324        yield eq, '-63', r(u'<?print -0o77?>')
325        yield eq, '-63', r(u'<?print -0O77?>')
326        yield eq, '7', r(u'<?print 0b111?>')
327        yield eq, '7', r(u'<?print 0B111?>')
328        yield eq, '-7', r(u'<?print -0b111?>')
329        yield eq, '-7', r(u'<?print -0B111?>')
330
331        yield eq, 'no', r(u'<?if 0?>yes<?else?>no<?end if?>')
332        yield eq, 'yes', r(u'<?if 1?>yes<?else?>no<?end if?>')
333        yield eq, 'yes', r(u'<?if -1?>yes<?else?>no<?end if?>')
334
335
336@py.test.mark.ul4
337def test_float():
338    for r in all_renderers:
339        # str() output might differ slightly between Python and JS, so eval the output again for tests
340        yield evaleq, 0.0, r(u'<?print 0.?>')
341        yield evaleq, 42.0, r(u'<?print 42.?>')
342        yield evaleq, -42.0, r(u'<?print -42.?>')
343        yield evaleq, -42.5, r(u'<?print -42.5?>')
344        yield evaleq, 1e42, r(u'<?print 1E42?>')
345        yield evaleq, 1e42, r(u'<?print 1e42?>')
346        yield evaleq, -1e42, r(u'<?print -1E42?>')
347        yield evaleq, -1e42, r(u'<?print -1e42?>')
348
349        yield eq, 'no', r(u'<?if 0.?>yes<?else?>no<?end if?>')
350        yield eq, 'yes', r(u'<?if 1.?>yes<?else?>no<?end if?>')
351        yield eq, 'yes', r(u'<?if -1.?>yes<?else?>no<?end if?>')
352
353
354@py.test.mark.ul4
355def test_string():
356    for r in all_renderers:
357        yield raises, "Unterminated string", r(u'<?print "?>')
358        yield eq, 'foo', r(u'<?print "foo"?>')
359        yield eq, '\n', r(u'<?print "\\n"?>')
360        yield eq, '\r', r(u'<?print "\\r"?>')
361        yield eq, '\t', r(u'<?print "\\t"?>')
362        yield eq, '\f', r(u'<?print "\\f"?>')
363        yield eq, '\b', r(u'<?print "\\b"?>')
364        yield eq, '\a', r(u'<?print "\\a"?>')
365        yield eq, '\x1b', r(u'<?print "\\e"?>')
366        yield eq, '\x00', r(u'<?print "\\x00"?>')
367        yield eq, '"', r(u'<?print "\\""?>')
368        yield eq, "'", r(u'<?print "\\\'"?>')
369        yield eq, u'\u20ac', r(u'<?print "\u20ac"?>')
370        yield eq, u'\xff', r(u'<?print "\\xff"?>')
371        yield eq, u'\u20ac', r(u'''<?print "\\u20ac"?>''')
372        yield eq, "a\nb", r(u'<?print "a\nb"?>')
373        for c in u"\x00\x80\u0100\u3042\n\r\t\f\b\a\e\"":
374            yield eq, c, r(u'<?print obj?>', obj=c) # This tests :func:`misc.javaexpr` for Java and :func:`ul4c._json` for JS
375
376        # Test literal control characters
377        yield eq, u'gu\n\r\trk', r(u"<?print 'gu\n\r\trk'?>")
378        yield eq, u'gu\n\r\t\\rk', r(ur"<?print 'gu\n\r\t\\rk'?>")
379
380        yield eq, 'no', r(u'<?if ""?>yes<?else?>no<?end if?>')
381        yield eq, 'yes', r(u'<?if "foo"?>yes<?else?>no<?end if?>')
382
383
384@py.test.mark.ul4
385def test_date():
386    for r in all_renderers:
387        yield eq, '2000-02-29', r(u'<?print @2000-02-29T.isoformat()?>')
388        yield eq, '2000-02-29T12:34:00', r(u'<?print @2000-02-29T12:34.isoformat()?>')
389        yield eq, '2000-02-29T12:34:56', r(u'<?print @2000-02-29T12:34:56.isoformat()?>')
390        yield eq, '2000-02-29T12:34:56.987000', r(u'<?print @2000-02-29T12:34:56.987000.isoformat()?>') # JS and Java only supports milliseconds
391        yield eq, 'yes', r(u'<?if @2000-02-29T12:34:56.987654?>yes<?else?>no<?end if?>')
392
393
394@py.test.mark.ul4
395def test_color():
396    for r in all_renderers:
397        yield eq, '255,255,255,255', r(u'<?code c = #fff?><?print c[0]?>,<?print c[1]?>,<?print c[2]?>,<?print c[3]?>')
398        yield eq, '255,255,255,255', r(u'<?code c = #ffffff?><?print c[0]?>,<?print c[1]?>,<?print c[2]?>,<?print c[3]?>')
399        yield eq, '18,52,86,255', r(u'<?code c = #123456?><?print c[0]?>,<?print c[1]?>,<?print c[2]?>,<?print c[3]?>')
400        yield eq, '17,34,51,68', r(u'<?code c = #1234?><?print c[0]?>,<?print c[1]?>,<?print c[2]?>,<?print c[3]?>')
401        yield eq, '18,52,86,120', r(u'<?code c = #12345678?><?print c[0]?>,<?print c[1]?>,<?print c[2]?>,<?print c[3]?>')
402        yield eq, 'yes', r(u'<?if #fff?>yes<?else?>no<?end if?>')
403
404
405@py.test.mark.ul4
406def test_list():
407    for r in all_renderers:
408        yield eq, '', r(u'<?for item in []?><?print item?>;<?end for?>')
409        yield eq, '1;', r(u'<?for item in [1]?><?print item?>;<?end for?>')
410        yield eq, '1;', r(u'<?for item in [1,]?><?print item?>;<?end for?>')
411        yield eq, '1;2;', r(u'<?for item in [1, 2]?><?print item?>;<?end for?>')
412        yield eq, '1;2;', r(u'<?for item in [1, 2,]?><?print item?>;<?end for?>')
413        yield eq, 'no', r(u'<?if []?>yes<?else?>no<?end if?>')
414        yield eq, 'yes', r(u'<?if [1]?>yes<?else?>no<?end if?>')
415
416
417@py.test.mark.ul4
418def test_dict():
419    for r in all_renderers:
420        yield eq, '', r(u'<?for (key, value) in {}.items()?><?print key?>:<?print value?>\n<?end for?>')
421        yield eq, '1:2\n', r(u'<?for (key, value) in {1:2}.items()?><?print key?>:<?print value?>\n<?end for?>')
422        yield eq, '1:2\n', r(u'<?for (key, value) in {1:2,}.items()?><?print key?>:<?print value?>\n<?end for?>')
423        # With duplicate keys, later ones simply overwrite earlier ones
424        yield eq, '1:3\n', r(u'<?for (key, value) in {1:2, 1: 3}.items()?><?print key?>:<?print value?>\n<?end for?>')
425        # Test **
426        yield eq, '1:2\n', r(u'<?for (key, value) in {**{1:2}}.items()?><?print key?>:<?print value?>\n<?end for?>')
427        yield eq, '1:4\n', r(u'<?for (key, value) in {1:1, **{1:2}, 1:3, **{1:4}}.items()?><?print key?>:<?print value?>\n<?end for?>')
428        yield eq, 'no', r(u'<?if {}?>yes<?else?>no<?end if?>')
429        yield eq, 'yes', r(u'<?if {1:2}?>yes<?else?>no<?end if?>')
430
431
432@py.test.mark.ul4
433def test_code_storevar():
434    for r in all_renderers:
435        yield eq, '42', r(u'<?code x = 42?><?print x?>')
436        yield eq, 'xyzzy', r(u'<?code x = "xyzzy"?><?print x?>')
437
438
439@py.test.mark.ul4
440def test_code_addvar():
441    for r in all_renderers:
442        for x in (17, 17., False, True):
443            for y in (23, 23., False, True):
444                yield evaleq, x + y, r(u'<?code x = {}?><?code x += {}?><?print x?>'.format(x, y))
445        yield eq, 'xyzzy', r(u'<?code x = "xyz"?><?code x += "zy"?><?print x?>')
446
447
448@py.test.mark.ul4
449def test_code_subvar():
450    for r in all_renderers:
451        for x in (17, 17., False, True):
452            for y in (23, 23., False, True):
453                yield evaleq, x - y, r(u'<?code x = {}?><?code x -= {}?><?print x?>'.format(x, y))
454
455
456@py.test.mark.ul4
457def test_code_mulvar():
458    for r in all_renderers:
459        for x in (17, 17., False, True):
460            for y in (23, 23., False, True):
461                yield evaleq, x * y, r(u'<?code x = {}?><?code x *= {}?><?print x?>'.format(x, y))
462        for x in (17, False, True):
463            y = "xyzzy"
464            yield eq, x * y, r(u'<?code x = {}?><?code x *= {!r}?><?print x?>'.format(x, y))
465        yield eq, 17*"xyzzy", r(u'<?code x = "xyzzy"?><?code x *= 17?><?print x?>')
466
467
468@py.test.mark.ul4
469def test_code_floordivvar():
470    for r in all_renderers:
471        for x in (5, -5, 5.0, -5.0, 4, -4, 4.0, -4.0, False, True):
472            for y in (2, -2, 2.0, -2.0, True):
473                yield evaleq, x // y, r(u'<?code x = {}?><?code x //= {}?><?print x?>'.format(x, y))
474
475
476@py.test.mark.ul4
477def test_code_truedivvar():
478    for r in all_renderers:
479        for x in (5, -5, 5.0, -5.0, 4, -4, 4.0, -4.0, False, True):
480            for y in (2, -2, 2.0, -2.0, True):
481                yield evaleq, x / y, r(u'<?code x = {}?><?code x /= {}?><?print x?>'.format(x, y))
482
483
484@py.test.mark.ul4
485def test_code_modvar():
486    for r in all_renderers:
487        for x in (1729, 1729.0, -1729, -1729.0, False, True):
488            for y in (23, 23., -23, -23.0, True):
489                yield evaleq, x % y, r(u'<?code x = {}?><?code x %= {}?><?print x?>'.format(x, y))
490
491
492@py.test.mark.ul4
493def test_code_delvar():
494    for r in all_renderers:
495        yield raises, "(KeyError|not found)", r(u'<?code x = 1729?><?code del x?><?print x?>')
496
497
498@py.test.mark.ul4
499def test_for_string():
500    for r in all_renderers:
501        yield eq, '', r(u'<?for c in data?>(<?print c?>)<?end for?>', data="")
502        yield eq, '(g)(u)(r)(k)', r(u'<?for c in data?>(<?print c?>)<?end for?>', data="gurk")
503
504
505@py.test.mark.ul4
506def test_for_list():
507    for r in all_renderers:
508        yield eq, '', r(u'<?for c in data?>(<?print c?>)<?end for?>', data="")
509        yield eq, '(g)(u)(r)(k)', r(u'<?for c in data?>(<?print c?>)<?end for?>', data=["g", "u", "r", "k"])
510
511
512@py.test.mark.ul4
513def test_for_dict():
514    for r in all_renderers:
515        yield eq, '', r(u'<?for c in data?>(<?print c?>)<?end for?>', data={})
516        yield eq, '(a)(b)(c)', r(u'<?for c in sorted(data)?>(<?print c?>)<?end for?>', data=dict(a=1, b=2, c=3))
517
518
519@py.test.mark.ul4
520def test_for_nested():
521    for r in all_renderers:
522        yield eq, '[(1)(2)][(3)(4)]', r(u'<?for list in data?>[<?for n in list?>(<?print n?>)<?end for?>]<?end for?>', data=[[1, 2], [3, 4]])
523
524
525@py.test.mark.ul4
526def test_for_unpacking():
527    data = [
528        ("spam", "eggs", 17),
529        ("gurk", "hurz", 23),
530        ("hinz", "kunz", 42)
531    ]
532
533    for r in all_renderers:
534        yield eq, '(spam)(gurk)(hinz)', r(u'<?for (a,) in data?>(<?print a?>)<?end for?>', data=data)
535        yield eq, '(spam,eggs)(gurk,hurz)(hinz,kunz)', r(u'<?for (a, b) in data?>(<?print a?>,<?print b?>)<?end for?>', data=data)
536        yield eq, '(spam,eggs,17)(gurk,hurz,23)(hinz,kunz,42)', r(u'<?for (a, b, c) in data?>(<?print a?>,<?print b?>,<?print c?>)<?end for?>', data=data)
537
538
539@py.test.mark.ul4
540def test_break():
541    for r in all_renderers:
542        yield eq, '1, 2, ', r(u'<?for i in [1,2,3]?><?print i?>, <?if i==2?><?break?><?end if?><?end for?>')
543
544
545@py.test.mark.ul4
546def test_break_nested():
547    for r in all_renderers:
548        yield eq, '1, 1, 2, 1, 2, 3, ', r(u'<?for i in [1,2,3,4]?><?for j in [1,2,3,4]?><?print j?>, <?if j>=i?><?break?><?end if?><?end for?><?if i>=3?><?break?><?end if?><?end for?>')
549
550
551@py.test.mark.ul4
552def test_continue():
553    for r in all_renderers:
554        yield eq, '1, 3, ', r(u'<?for i in [1,2,3]?><?if i==2?><?continue?><?end if?><?print i?>, <?end for?>')
555
556
557@py.test.mark.ul4
558def test_continue_nested():
559    for r in all_renderers:
560        yield eq, '1, 3, \n1, 3, \n', r(u'<?for i in [1,2,3]?><?if i==2?><?continue?><?end if?><?for j in [1,2,3]?><?if j==2?><?continue?><?end if?><?print j?>, <?end for?>\n<?end for?>')
561
562
563@py.test.mark.ul4
564def test_if():
565    for r in all_renderers:
566        yield eq, '42', r(u'<?if data?><?print data?><?end if?>', data=42)
567
568
569@py.test.mark.ul4
570def test_else():
571    for r in all_renderers:
572        yield eq, '42', r(u'<?if data?><?print data?><?else?>no<?end if?>', data=42)
573        yield eq, 'no', r(u'<?if data?><?print data?><?else?>no<?end if?>', data=0)
574
575
576@py.test.mark.ul4
577def test_block_errors():
578    yield raises, "in u?.<.for x in data.>..*block unclosed", RenderPython(u'<?for x in data?>')
579    yield raises, "endif doesn't match any if", RenderPython(u'<?for x in data?><?end if?>')
580    yield raises, "not in any block", RenderPython(u'<?end?>')
581    yield raises, "not in any block", RenderPython(u'<?end for?>')
582    yield raises, "not in any block", RenderPython(u'<?end if?>')
583    yield raises, "else doesn't match any if", RenderPython(u'<?else?>')
584    yield raises, "in u?.<.if data.>..*block unclosed", RenderPython(u'<?if data?>')
585    yield raises, "in u?.<.if data.>..*block unclosed", RenderPython(u'<?if data?><?else?>')
586    yield raises, "duplicate else", RenderPython(u'<?if data?><?else?><?else?>')
587    yield raises, "else already seen in elif", RenderPython(u'<?if data?><?else?><?elif data?>')
588    yield raises, "else already seen in elif", RenderPython(u'<?if data?><?elif data?><?elif data?><?else?><?elif data?>')
589
590
591@py.test.mark.ul4
592def test_empty():
593    yield raises, "expression required", RenderPython(u'<?print?>')
594    yield raises, "expression required", RenderPython(u'<?if?>')
595    yield raises, "expression required", RenderPython(u'<<?if x?><?elif?><?end if?>')
596    yield raises, "loop expression required", RenderPython(u'<?for?>')
597    yield raises, "statement required", RenderPython(u'<?code?>')
598    yield raises, "render statement required", RenderPython(u'<?render?>')
599
600
601@py.test.mark.ul4
602def test_add():
603    values = (17, 23, 1., -1.)
604    for r in all_renderers:
605        for x in values:
606            for y in values:
607                yield evaleq, x + y, r(u'<?print x + y?>', x=x, y=y) # Using ``evaleq`` avoids problem with the nonexistant int/float distinction in JS
608        yield eq, 'foobar', r(u'<?code x="foo"?><?code y="bar"?><?print x+y?>')
609        yield eq, '(f)(o)(o)(b)(a)(r)', r(u'<?for i in data.foo+data.bar?>(<?print i?>)<?end for?>', data=dict(foo="foo", bar="bar"))
610
611
612@py.test.mark.ul4
613def test_sub():
614    values = (17, 23, 1., -1.)
615    for r in all_renderers:
616        for x in values:
617            for y in values:
618                yield evaleq, x - y, r(u'<?print x - y?>', x=x, y=y)
619
620
621@py.test.mark.ul4
622def test_mul():
623    values = (17, 23, 1., -1.)
624    for r in all_renderers:
625        for x in values:
626            for y in values:
627                yield evaleq, x * y, r(u'<?print x * y?>', x=x, y=y)
628        yield eq, 17*"foo", r(u'<?print 17*"foo"?>')
629        yield eq, 17*"foo", r(u'<?code x=17?><?code y="foo"?><?print x*y?>')
630        yield eq, "foo"*17, r(u'<?code x="foo"?><?code y=17?><?print x*y?>')
631        yield eq, "foo"*17, r(u'<?print "foo"*17?>')
632        yield eq, "(foo)(bar)(foo)(bar)(foo)(bar)", r(u'<?for i in 3*data?>(<?print i?>)<?end for?>', data=["foo", "bar"])
633
634
635@py.test.mark.ul4
636def test_truediv():
637    for r in all_renderers:
638        yield eq, "0.5", r(u'<?print 1/2?>')
639        yield eq, "0.5", r(u'<?code x=1?><?code y=2?><?print x/y?>')
640
641
642@py.test.mark.ul4
643def test_floordiv():
644    for r in all_renderers:
645        yield eq, "0", r(u'<?print 1//2?>')
646        yield eq, "0", r(u'<?code x=1?><?code y=2?><?print x//y?>')
647
648
649@py.test.mark.ul4
650def test_mod():
651    values = (17, 23, 17., 23.)
652    for r in all_renderers:
653        for x in values:
654            for y in values:
655                yield evaleq, x % y, r(u'<?print {} % {}?>'.format(x, y))
656                yield evaleq, x % y, r(u'<?print x % y?>', x=x, y=y)
657
658
659@py.test.mark.ul4
660def test_eq():
661    values = (17, 23, 17., 23.)
662    for r in all_renderers:
663        for x in values:
664            for y in values:
665                yield eq, str(x == y), r(u'<?print {} == {}?>'.format(x, y))
666                yield eq, str(x == y), r(u'<?print x == y?>', x=x, y=y)
667
668
669@py.test.mark.ul4
670def test_ne():
671    values = (17, 23, 17., 23.)
672    for r in all_renderers:
673        for x in values:
674            for y in values:
675                yield eq, str(x != y), r(u'<?print {} != {}?>'.format(x, y))
676                yield eq, str(x != y), r(u'<?print x != y?>', x=x, y=y)
677
678
679@py.test.mark.ul4
680def test_lt():
681    values = (17, 23, 17., 23.)
682    for r in all_renderers:
683        for x in values:
684            for y in values:
685                yield eq, str(x < y), r(u'<?print {} < {}?>'.format(x, y))
686                yield eq, str(x < y), r(u'<?print x < y?>', x=x, y=y)
687
688
689@py.test.mark.ul4
690def test_le():
691    values = (17, 23, 17., 23.)
692    for r in all_renderers:
693        for x in values:
694            for y in values:
695                yield eq, str(x <= y), r(u'<?print {} <= {}?>'.format(x, y))
696                yield eq, str(x <= y), r(u'<?print x <= y?>', x=x, y=y)
697
698
699@py.test.mark.ul4
700def test_gt():
701    values = (17, 23, 17., 23.)
702    for r in all_renderers:
703        for x in values:
704            for y in values:
705                yield eq, str(x > y), r(u'<?print {} > {}?>'.format(x, y))
706                yield eq, str(x > y), r(u'<?print x > y?>', x=x, y=y)
707
708
709@py.test.mark.ul4
710def test_ge():
711    values = (17, 23, 17., 23.)
712    for r in all_renderers:
713        for x in values:
714            for y in values:
715                yield eq, str(x >= y), r(u'<?print {} >= {}?>'.format(x, y))
716                yield eq, str(x >= y), r(u'<?print x >= y?>', x=x, y=y)
717
718
719@py.test.mark.ul4
720def test_contains():
721    code = u'<?print x in y?>'
722
723    for r in all_renderers:
724        yield eq, "True", r(code, x=2, y=[1, 2, 3])
725        yield eq, "False", r(code, x=4, y=[1, 2, 3])
726        yield eq, "True", r(code, x="ur", y="gurk")
727        yield eq, "False", r(code, x="un", y="gurk")
728        yield eq, "True", r(code, x="a", y={"a": 1, "b": 2})
729        yield eq, "False", r(code, x="c", y={"a": 1, "b": 2})
730        yield eq, "True", r(code, x=0xff, y=color.Color(0x00, 0x80, 0xff, 0x42))
731        yield eq, "False", r(code, x=0x23, y=color.Color(0x00, 0x80, 0xff, 0x42))
732
733
734@py.test.mark.ul4
735def test_notcontains():
736    code = u'<?print x not in y?>'
737
738    for r in all_renderers:
739        yield eq, "False", r(code, x=2, y=[1, 2, 3])
740        yield eq, "True", r(code, x=4, y=[1, 2, 3])
741        yield eq, "False", r(code, x="ur", y="gurk")
742        yield eq, "True", r(code, x="un", y="gurk")
743        yield eq, "False", r(code, x="a", y={"a": 1, "b": 2})
744        yield eq, "True", r(code, x="c", y={"a": 1, "b": 2})
745        yield eq, "False", r(code, x=0xff, y=color.Color(0x00, 0x80, 0xff, 0x42))
746        yield eq, "True", r(code, x=0x23, y=color.Color(0x00, 0x80, 0xff, 0x42))
747
748
749@py.test.mark.ul4
750def test_and():
751    for r in all_renderers:
752        yield eq, "False", r(u'<?print x and y?>', x=False, y=False)
753        yield eq, "False", r(u'<?print x and y?>', x=False, y=True)
754        yield eq, "0", r(u'<?print x and y?>', x=0, y=True)
755
756
757@py.test.mark.ul4
758def test_or():
759    for r in all_renderers:
760        yield eq, "False", r(u'<?print x or y?>', x=False, y=False)
761        yield eq, "True", r(u'<?print x or y?>', x=False, y=True)
762        yield eq, "42", r(u'<?print x or y?>', x=42, y=True)
763
764
765@py.test.mark.ul4
766def test_not():
767    for r in all_renderers:
768        yield eq, "True", r(u'<?print not x?>', x=False)
769        yield eq, "False", r(u'<?print not x?>', x=42)
770
771
772@py.test.mark.ul4
773def test_getitem():
774    for r in all_renderers:
775        yield eq, "u", r(u"<?print 'gurk'[1]?>")
776        yield eq, "u", r(u"<?print x[1]?>", x="gurk")
777        yield eq, "u", r(u"<?print 'gurk'[-3]?>")
778        yield eq, "u", r(u"<?print x[-3]?>", x="gurk")
779        yield raises, "IndexError", r(u"<?print 'gurk'[4]?>")
780        yield raises, "index (4 )?out of range", r(u"<?print x[4]?>", x="gurk")
781        yield raises, "IndexError", r(u"<?print 'gurk'[-5]?>")
782        yield raises, "index (-5 )?out of range", r(u"<?print x[-5]?>", x="gurk")
783
784
785@py.test.mark.ul4
786def test_getslice12():
787    for r in all_renderers:
788        yield eq, "ur", r(u"<?print 'gurk'[1:3]?>")
789        yield eq, "ur", r(u"<?print x[1:3]?>", x="gurk")
790        yield eq, "ur", r(u"<?print 'gurk'[-3:-1]?>")
791        yield eq, "ur", r(u"<?print x[-3:-1]?>", x="gurk")
792        yield eq, "", r(u"<?print 'gurk'[4:10]?>")
793        yield eq, "", r(u"<?print x[4:10]?>", x="gurk")
794        yield eq, "", r(u"<?print 'gurk'[-10:-5]?>")
795        yield eq, "", r(u"<?print x[-10:-5]?>", x="gurk")
796
797
798@py.test.mark.ul4
799def test_getslice1():
800    for r in all_renderers:
801        yield eq, "urk", r(u"<?print 'gurk'[1:]?>")
802        yield eq, "urk", r(u"<?print x[1:]?>", x="gurk")
803        yield eq, "urk", r(u"<?print 'gurk'[-3:]?>")
804        yield eq, "urk", r(u"<?print x[-3:]?>", x="gurk")
805        yield eq, "", r(u"<?print 'gurk'[4:]?>")
806        yield eq, "", r(u"<?print x[4:]?>", x="gurk")
807        yield eq, "gurk", r(u"<?print 'gurk'[-10:]?>")
808        yield eq, "gurk", r(u"<?print x[-10:]?>", x="gurk")
809
810
811@py.test.mark.ul4
812def test_getslice2():
813    for r in all_renderers:
814        yield eq, "gur", r(u"<?print 'gurk'[:3]?>")
815        yield eq, "gur", r(u"<?print x[:3]?>", x="gurk")
816        yield eq, "gur", r(u"<?print 'gurk'[:-1]?>")
817        yield eq, "gur", r(u"<?print x[:-1]?>", x="gurk")
818        yield eq, "gurk", r(u"<?print 'gurk'[:10]?>")
819        yield eq, "gurk", r(u"<?print x[:10]?>", x="gurk")
820        yield eq, "", r(u"<?print 'gurk'[:-5]?>")
821        yield eq, "", r(u"<?print x[:-5]?>", x="gurk")
822
823
824@py.test.mark.ul4
825def test_nested():
826    sc = u"4"
827    sv = u"x"
828    n = 4
829    # when using 10 compiling the variable will run out of registers
830    # when using 8 Java will output "An irrecoverable stack overflow has occurred"
831    depth = 7
832    for i in xrange(depth):
833        sc = u"({})+({})".format(sc, sc)
834        sv = u"({})+({})".format(sv, sv)
835        n = n + n
836
837    for r in all_renderers:
838        yield eq, str(n), r(u'<?print {}?>'.format(sc))
839        yield eq, str(n), r(u'<?code x=4?><?print {}?>'.format(sv))
840
841
842@py.test.mark.ul4
843def test_precedence():
844    for r in all_renderers:
845        yield eq, "14", r(u'<?print 2+3*4?>')
846        yield eq, "20", r(u'<?print (2+3)*4?>')
847        yield eq, "10", r(u'<?print -2+-3*-4?>')
848        yield eq, "14", r(u'<?print --2+--3*--4?>')
849        yield eq, "14", r(u'<?print (-(-2))+(-((-3)*-(-4)))?>')
850        yield eq, "42", r(u'<?print 2*data.value?>', data=dict(value=21))
851        yield eq, "42", r(u'<?print data.value[0]?>', data=dict(value=[42]))
852        yield eq, "42", r(u'<?print data[0].value?>', data=[dict(value=42)])
853        yield eq, "42", r(u'<?print data[0][0][0]?>', data=[[[42]]])
854        yield eq, "42", r(u'<?print data.value.value[0]?>', data=dict(value=dict(value=[42])))
855        yield eq, "42", r(u'<?print data.value.value[0].value.value[0]?>', data=dict(value=dict(value=[dict(value=dict(value=[42]))])))
856
857
858@py.test.mark.ul4
859def test_bracket():
860    sc = u"4"
861    sv = u"x"
862    for i in xrange(10):
863        sc = u"({})".format(sc)
864        sv = u"({})".format(sv)
865
866    for r in all_renderers:
867        yield eq, "4", r(u'<?print {}?>'.format(sc))
868        yield eq, "4", r(u'<?code x=4?><?print {}?>'.format(sv))
869
870
871@py.test.mark.ul4
872def test_function_now():
873    now = unicode(datetime.datetime.now())
874
875    for r in all_renderers:
876        yield raises, "now.*unknown", r(u"<?print now(1)?>")
877        yield raises, "now.*unknown", r(u"<?print now(1, 2)?>")
878        yield le, now, r(u"<?print now()?>")
879
880
881@py.test.mark.ul4
882def test_function_utcnow():
883    utcnow = unicode(datetime.datetime.utcnow())
884
885    for r in all_renderers:
886        yield raises, "utcnow.*unknown", r(u"<?print utcnow(1)?>")
887        yield raises, "utcnow.*unknown", r(u"<?print utcnow(1, 2)?>")
888        utcnowfromtemplate = r(u"<?print utcnow()?>")
889        # JS and Java only have milliseconds precision, but this shouldn't lead to problems here, as rendering the template takes longer than a millisecond
890        yield le, utcnow, utcnowfromtemplate
891
892
893@py.test.mark.ul4
894def test_function_vars():
895    code = u"<?if var in vars()?>yes<?else?>no<?end if?>"
896
897    for r in all_renderers:
898        yield raises, "vars.*unknown", r("<?print vars(1)?>")
899        yield raises, "vars.*unknown", r("<?print vars(1, 2)?>")
900        yield eq, "yes", r(code, var="spam", spam="eggs")
901        yield eq, "no", r(code, var="nospam", spam="eggs")
902
903
904@py.test.mark.ul4
905def test_function_random():
906    for r in all_renderers:
907        yield raises, "random.*unknown", r("<?print random(1)?>")
908        yield raises, "random.*unknown", r("<?print random(1, 2)?>")
909        yield eq, "ok", r(u"<?code r = random()?><?if r>=0 and r<1?>ok<?else?>fail<?end if?>")
910
911
912@py.test.mark.ul4
913def test_function_randrange():
914    for r in all_renderers:
915        yield raises, "randrange.*unknown", r("<?print randrange()?>")
916        yield eq, "ok", r(u"<?code r = randrange(4)?><?if r>=0 and r<4?>ok<?else?>fail<?end if?>")
917        yield eq, "ok", r(u"<?code r = randrange(17, 23)?><?if r>=17 and r<23?>ok<?else?>fail<?end if?>")
918        yield eq, "ok", r(u"<?code r = randrange(17, 23, 2)?><?if r>=17 and r<23 and r%2?>ok<?else?>fail<?end if?>")
919
920
921@py.test.mark.ul4
922def test_function_randchoice():
923    for r in all_renderers:
924        yield raises, "randchoice.*unknown", r("<?print randchoice()?>")
925        yield eq, "ok", r(u"<?code r = randchoice('abc')?><?if r in 'abc'?>ok<?else?>fail<?end if?>")
926        yield eq, "ok", r(u"<?code s = [17, 23, 42]?><?code r = randchoice(s)?><?if r in s?>ok<?else?>fail<?end if?>")
927        yield eq, "ok", r(u"<?code s = #12345678?><?code sl = [0x12, 0x34, 0x56, 0x78]?><?code r = randchoice(s)?><?if r in sl?>ok<?else?>fail<?end if?>")
928
929
930@py.test.mark.ul4
931def test_function_xmlescape():
932    for r in all_renderers:
933        yield raises, "xmlescape.*unknown", r(u"<?print xmlescape()?>")
934        yield raises, "xmlescape.*unknown", r(u"<?print xmlescape(1, 2)?>")
935        yield eq, "&lt;&lt;&gt;&gt;&amp;&#39;&quot;gurk", r(u"<?print xmlescape(data)?>", data='<<>>&\'"gurk')
936
937
938@py.test.mark.ul4
939def test_function_csv():
940    for r in all_renderers:
941        yield raises, "csv.*unknown", r(u"<?print csv()?>")
942        yield raises, "csv.*unknown", r(u"<?print csv(1, 2)?>")
943        yield eq, "", r(u"<?print csv(data)?>", data=None)
944        yield eq, "False", r(u"<?print csv(data)?>", data=False)
945        yield eq, "True", r(u"<?print csv(data)?>", data=True)
946        yield eq, "42", r(u"<?print csv(data)?>", data=42)
947        # no check for float
948        yield eq, "abc", r(u"<?print csv(data)?>", data="abc")
949        yield eq, '"a,b,c"', r(u"<?print csv(data)?>", data="a,b,c")
950        yield eq, '"a""b""c"', r(u"<?print csv(data)?>", data='a"b"c')
951        yield eq, '"a\nb\nc"', r(u"<?print csv(data)?>", data="a\nb\nc")
952
953
954@py.test.mark.ul4
955def test_function_json():
956    for r in all_renderers:
957        yield raises, "json.*unknown", r(u"<?print json()?>")
958        yield raises, "json.*unknown", r(u"<?print json(1, 2)?>")
959        yield eq, "null", r(u"<?print json(data)?>", data=None)
960        yield eq, "false", r(u"<?print json(data)?>", data=False)
961        yield eq, "true", r(u"<?print json(data)?>", data=True)
962        yield eq, "42", r(u"<?print json(data)?>", data=42)
963        # no check for float
964        yield eq, '"abc"', r(u"<?print json(data)?>", data="abc")
965        yield eq, '[1, 2, 3]', r(u"<?print json(data)?>", data=[1, 2, 3])
966        yield eq, '[1, 2, 3]', r(u"<?print json(data)?>", data=PseudoList([1, 2, 3]))
967        yield eq, '{"one": 1}', r(u"<?print json(data)?>", data={"one": 1})
968        yield eq, '{"one": 1}', r(u"<?print json(data)?>", data=PseudoDict({"one": 1}))
969
970
971@py.test.mark.ul4
972def test_function_str():
973    code = u"<?print str(data)?>"
974    for r in all_renderers:
975        yield raises, "str.*unknown", r(u"<?print str()?>")
976        yield raises, "str.*unknown", r(u"<?print str(1, 2)?>")
977        yield eq, "", r(code, data=None)
978        yield eq, "True", r(code, data=True)
979        yield eq, "False", r(code, data=False)
980        yield eq, "42", r(code, data=42)
981        yield eq, "4.2", r(code, data=4.2)
982        yield eq, "foo", r(code, data="foo")
983        yield eq, "2011-02-09", r(code, data=datetime.date(2011, 2, 9))
984        yield eq, "2011-02-09 12:34:56", r(code, data=datetime.datetime(2011, 2, 9, 12, 34, 56))
985        yield eq, "2011-02-09 12:34:56.987000", r(code, data=datetime.datetime(2011, 2, 9, 12, 34, 56, 987000))
986
987
988@py.test.mark.ul4
989def test_function_int():
990    for r in all_renderers:
991        yield raises, "int.*unknown", RenderPython(u"<?print int()?>")
992        yield raises, "int.*unknown", RenderPython(u"<?print int(1, 2, 3)?>")
993        yield raises, "int\\(\\) argument must be a string or a number|int\\(null\\) not supported", RenderPython(u"<?print int(data)?>", data=None)
994        yield raises, "invalid literal for int|NumberFormatException", RenderPython(u"<?print int(data)?>", data="foo")
995        yield eq, "1", r(u"<?print int(data)?>", data=True)
996        yield eq, "0", r(u"<?print int(data)?>", data=False)
997        yield eq, "42", r(u"<?print int(data)?>", data=42)
998        yield eq, "4", r(u"<?print int(data)?>", data=4.2)
999        yield eq, "42", r(u"<?print int(data)?>", data="42")
1000        yield eq, "66", r(u"<?print int(data, 16)?>", data="42")
1001
1002
1003@py.test.mark.ul4
1004def test_function_float():
1005    code = u"<?print float(data)?>"
1006
1007    for r in all_renderers:
1008        yield raises, "float.*unknown", r(u"<?print float()?>")
1009        yield raises, "float.*unknown", r(u"<?print float(1, 2, 3)?>")
1010        yield raises, "float\\(\\) argument must be a string or a number|float\\(null\\) not supported", r(code, data=None)
1011        yield eq, "4.2", r(code, data=4.2)
1012        if r is not RenderJS:
1013            yield eq, "1.0", r(code, data=True)
1014            yield eq, "0.0", r(code, data=False)
1015            yield eq, "42.0", r(code, data=42)
1016            yield eq, "42.0", r(code, data="42")
1017        else:
1018            yield evaleq, 1.0, r(code, data=True)
1019            yield evaleq, 0.0, r(code, data=False)
1020            yield evaleq, 42.0, r(code, data=42)
1021            yield evaleq, 42.0, r(code, data="42")
1022
1023
1024@py.test.mark.ul4
1025def test_function_len():
1026    code = u"<?print len(data)?>"
1027    for r in all_renderers:
1028        yield raises, "len.*unknown", r(u"<?print len()?>")
1029        yield raises, "len.*unknown", r(u"<?print len(1, 2)?>")
1030        yield raises, "has no len\\(\\)|len\\(.*\\) not supported", r(code, data=None)
1031        yield raises, "has no len\\(\\)|len\\(.*\\) not supported", r(code, data=True)
1032        yield raises, "has no len\\(\\)|len\\(.*\\) not supported", r(code, data=False)
1033        yield raises, "has no len\\(\\)|len\\(.*\\) not supported", r(code, data=42)
1034        yield raises, "has no len\\(\\)|len\\(.*\\) not supported", r(code, data=4.2)
1035        yield eq, "42", r(code, data=42*"?")
1036        yield eq, "42", r(code, data=42*[None])
1037        yield eq, "42", r(code, data=dict.fromkeys(xrange(42)))
1038
1039
1040@py.test.mark.ul4
1041def test_function_enumerate():
1042    code = u"<?for (i, value) in enumerate(data)?><?print i?>:<?print value?>\n<?end for?>"
1043    for r in all_renderers:
1044        yield raises, "enumerate.*unknown", r(u"<?print enumerate()?>")
1045        yield raises, "enumerate.*unknown", r(u"<?print enumerate(1, 2)?>")
1046        yield raises, "is not iterable|iter\\(.*\\) not supported", r(code, data=None)
1047        yield raises, "is not iterable|iter\\(.*\\) not supported", r(code, data=True)
1048        yield raises, "is not iterable|iter\\(.*\\) not supported", r(code, data=False)
1049        yield raises, "is not iterable|iter\\(.*\\) not supported", r(code, data=42)
1050        yield raises, "is not iterable|iter\\(.*\\) not supported", r(code, data=4.2)
1051        yield eq, "0:f\n1:o\n2:o\n", r(code, data="foo")
1052        yield eq, "0:foo\n1:bar\n", r(code, data=["foo", "bar"])
1053        yield eq, "0:foo\n", r(code, data=dict(foo=True))
1054
1055
1056@py.test.mark.ul4
1057def test_function_isnone():
1058    code = u"<?print isnone(data)?>"
1059    for r in all_renderers:
1060        yield raises, "isnone.*unknown", r(u"<?print isnone()?>")
1061        yield raises, "isnone.*unknown", r(u"<?print isnone(1, 2)?>")
1062        yield eq, "True", r(code, data=None)
1063        yield eq, "False", r(code, data=True)
1064        yield eq, "False", r(code, data=False)
1065        yield eq, "False", r(code, data=42)
1066        yield eq, "False", r(code, data=4.2)
1067        yield eq, "False", r(code, data="foo")
1068        yield eq, "False", r(code, data=datetime.datetime.now())
1069        yield eq, "False", r(code, data=())
1070        yield eq, "False", r(code, data=[])
1071        yield eq, "False", r(code, data={})
1072        yield eq, "False", r(code, data=ul4c.Template(u""))
1073        yield eq, "False", r(code, data=color.red)
1074
1075
1076@py.test.mark.ul4
1077def test_function_isbool():
1078    code = u"<?print isbool(data)?>"
1079
1080    for r in all_renderers:
1081        yield raises, "isbool.*unknown", r(u"<?print isbool()?>")
1082        yield raises, "isbool.*unknown", r(u"<?print isbool(1, 2)?>")
1083        yield eq, "False", r(code, data=None)
1084        yield eq, "True", r(code, data=True)
1085        yield eq, "True", r(code, data=False)
1086        yield eq, "False", r(code, data=42)
1087        yield eq, "False", r(code, data=4.2)
1088        yield eq, "False", r(code, data="foo")
1089        yield eq, "False", r(code, data=datetime.datetime.now())
1090        yield eq, "False", r(code, data=())
1091        yield eq, "False", r(code, data=[])
1092        yield eq, "False", r(code, data={})
1093        yield eq, "False", r(code, data=ul4c.Template(u""))
1094        yield eq, "False", r(code, data=color.red)
1095
1096
1097@py.test.mark.ul4
1098def test_function_isint():
1099    code = u"<?print isint(data)?>"
1100
1101    for r in all_renderers:
1102        yield raises, "isint.*unknown", r(u"<?print isint()?>")
1103        yield raises, "isint.*unknown", r(u"<?print isint(1, 2)?>")
1104        yield eq, "False", r(code, data=None)
1105        yield eq, "False", r(code, data=True)
1106        yield eq, "False", r(code, data=False)
1107        yield eq, "True", r(code, data=42)
1108        yield eq, "False", r(code, data=4.2)
1109        yield eq, "False", r(code, data="foo")
1110        yield eq, "False", r(code, data=datetime.datetime.now())
1111        yield eq, "False", r(code, data=())
1112        yield eq, "False", r(code, data=[])
1113        yield eq, "False", r(code, data={})
1114        yield eq, "False", r(code, data=ul4c.Template(u""))
1115        yield eq, "False", r(code, data=color.red)
1116
1117
1118@py.test.mark.ul4
1119def test_function_isfloat():
1120    code = u"<?print isfloat(data)?>"
1121
1122    for r in all_renderers:
1123        yield raises, "isfloat.*unknown", r(u"<?print isfloat()?>")
1124        yield raises, "isfloat.*unknown", r(u"<?print isfloat(1, 2)?>")
1125        yield eq, "False", r(code, data=None)
1126        yield eq, "False", r(code, data=True)
1127        yield eq, "False", r(code, data=False)
1128        yield eq, "False", r(code, data=42)
1129        yield eq, "True", r(code, data=4.2)
1130        yield eq, "False", r(code, data="foo")
1131        yield eq, "False", r(code, data=datetime.datetime.now())
1132        yield eq, "False", r(code, data=())
1133        yield eq, "False", r(code, data=[])
1134        yield eq, "False", r(code, data={})
1135        yield eq, "False", r(code, data=ul4c.Template(u""))
1136        yield eq, "False", r(code, data=color.red)
1137
1138
1139@py.test.mark.ul4
1140def test_function_isstr():
1141    code = u"<?print isstr(data)?>"
1142
1143    for r in all_renderers:
1144        yield raises, "isstr.*unknown", r(u"<?print isstr()?>")
1145        yield raises, "isstr.*unknown", r(u"<?print isstr(1, 2)?>")
1146        yield eq, "False", r(code, data=None)
1147        yield eq, "False", r(code, data=True)
1148        yield eq, "False", r(code, data=False)
1149        yield eq, "False", r(code, data=42)
1150        yield eq, "False", r(code, data=4.2)
1151        yield eq, "True", r(code, data="foo")
1152        yield eq, "False", r(code, data=datetime.datetime.now())
1153        yield eq, "False", r(code, data=())
1154        yield eq, "False", r(code, data=[])
1155        yield eq, "False", r(code, data={})
1156        yield eq, "False", r(code, data=ul4c.Template(u""))
1157        yield eq, "False", r(code, data=color.red)
1158
1159
1160@py.test.mark.ul4
1161def test_function_isdate():
1162    code = u"<?print isdate(data)?>"
1163
1164    for r in all_renderers:
1165        yield raises, "isdate.*unknown", r(u"<?print isdate()?>")
1166        yield raises, "isdate.*unknown", r(u"<?print isdate(1, 2)?>")
1167        yield eq, "False", r(code, data=None)
1168        yield eq, "False", r(code, data=True)
1169        yield eq, "False", r(code, data=False)
1170        yield eq, "False", r(code, data=42)
1171        yield eq, "False", r(code, data=4.2)
1172        yield eq, "False", r(code, data="foo")
1173        yield eq, "True", r(code, data=datetime.datetime.now())
1174        yield eq, "False", r(code, data=())
1175        yield eq, "False", r(code, data=[])
1176        yield eq, "False", r(code, data={})
1177        yield eq, "False", r(code, data=ul4c.Template(u""))
1178        yield eq, "False", r(code, data=color.red)
1179
1180
1181@py.test.mark.ul4
1182def test_function_islist():
1183    code = u"<?print islist(data)?>"
1184
1185    for r in all_renderers:
1186        yield raises, "islist.*unknown", r(u"<?print islist()?>")
1187        yield raises, "islist.*unknown", r(u"<?print islist(1, 2)?>")
1188        yield eq, "False", r(code, data=None)
1189        yield eq, "False", r(code, data=True)
1190        yield eq, "False", r(code, data=False)
1191        yield eq, "False", r(code, data=42)
1192        yield eq, "False", r(code, data=4.2)
1193        yield eq, "False", r(code, data="foo")
1194        yield eq, "False", r(code, data=datetime.datetime.now())
1195        yield eq, "True", r(code, data=())
1196        yield eq, "True", r(code, data=[])
1197        yield eq, "True", r(code, data=PseudoList([]))
1198        yield eq, "False", r(code, data={})
1199        yield eq, "False", r(code, data=ul4c.Template(u""))
1200        yield eq, "False", r(code, data=color.red)
1201
1202
1203@py.test.mark.ul4
1204def test_function_isdict():
1205    code = u"<?print isdict(data)?>"
1206
1207    for r in all_renderers:
1208        yield raises, "isdict.*unknown", r(u"<?print isdict()?>")
1209        yield raises, "isdict.*unknown", r(u"<?print isdict(1, 2)?>")
1210        yield eq, "False", r(code, data=None)
1211        yield eq, "False", r(code, data=True)
1212        yield eq, "False", r(code, data=False)
1213        yield eq, "False", r(code, data=42)
1214        yield eq, "False", r(code, data=4.2)
1215        yield eq, "False", r(code, data="foo")
1216        yield eq, "False", r(code, data=datetime.datetime.now())
1217        yield eq, "False", r(code, data=())
1218        yield eq, "False", r(code, data=[])
1219        yield eq, "True", r(code, data={})
1220        yield eq, "True", r(code, data=PseudoDict({}))
1221        yield eq, "False", r(code, data=ul4c.Template(u""))
1222        yield eq, "False", r(code, data=color.red)
1223
1224
1225@py.test.mark.ul4
1226def test_function_istemplate():
1227    code = u"<?print istemplate(data)?>"
1228
1229    for r in all_renderers:
1230        yield raises, "istemplate.*unknown", r(u"<?print istemplate()?>")
1231        yield raises, "istemplate.*unknown", r(u"<?print istemplate(1, 2)?>")
1232        yield eq, "False", r(code, data=None)
1233        yield eq, "False", r(code, data=True)
1234        yield eq, "False", r(code, data=False)
1235        yield eq, "False", r(code, data=42)
1236        yield eq, "False", r(code, data=4.2)
1237        yield eq, "False", r(code, data="foo")
1238        yield eq, "False", r(code, data=datetime.datetime.now())
1239        yield eq, "False", r(code, data=())
1240        yield eq, "False", r(code, data=[])
1241        yield eq, "False", r(code, data={})
1242        yield eq, "True", r(code, data=ul4c.Template(u""))
1243        yield eq, "False", r(code, data=color.red)
1244
1245
1246@py.test.mark.ul4
1247def test_function_iscolor():
1248    code = u"<?print iscolor(data)?>"
1249
1250    for r in all_renderers:
1251        yield raises, "iscolor.*unknown", r(u"<?print iscolor()?>")
1252        yield raises, "iscolor.*unknown", r(u"<?print iscolor(1, 2)?>")
1253        yield eq, "False", r(code, data=None)
1254        yield eq, "False", r(code, data=True)
1255        yield eq, "False", r(code, data=False)
1256        yield eq, "False", r(code, data=42)
1257        yield eq, "False", r(code, data=4.2)
1258        yield eq, "False", r(code, data="foo")
1259        yield eq, "False", r(code, data=datetime.datetime.now())
1260        yield eq, "False", r(code, data=())
1261        yield eq, "False", r(code, data=[])
1262        yield eq, "False", r(code, data={})
1263        yield eq, "False", r(code, data=ul4c.Template(u""))
1264        yield eq, "True", r(code, data=color.red)
1265
1266
1267@py.test.mark.ul4
1268def test_function_get():
1269    for r in all_renderers:
1270        yield raises, "get.*unknown", r(u"<?print get()?>")
1271        yield eq, "", r(u"<?print get('x')?>")
1272        yield eq, "42", r(u"<?print get('x')?>", x=42)
1273        yield eq, "17", r(u"<?print get('x', 17)?>")
1274        yield eq, "42", r(u"<?print get('x', 17)?>", x=42)
1275
1276
1277@py.test.mark.ul4
1278def test_function_repr():
1279    code = u"<?print repr(data)?>"
1280
1281    for r in all_renderers:
1282        yield raises, "repr.*unknown", r(u"<?print repr()?>")
1283        yield raises, "repr.*unknown", r(u"<?print repr(1, 2)?>")
1284        yield eq, "None", r(code, data=None)
1285        yield eq, "True", r(code, data=True)
1286        yield eq, "False", r(code, data=False)
1287        yield eq, "42", r(code, data=42)
1288        yield evaleq, 42.5, r(code, data=42.5)
1289        yield contains, ('"foo"', "'foo'"), r(code, data="foo")
1290        yield evaleq, [1, 2, 3], r(code, data=[1, 2, 3])
1291        if r is not RenderJS:
1292            yield evaleq, [1, 2, 3], r(code, data=(1, 2, 3))
1293        yield evaleq, {"a": 1, "b": 2}, r(code, data={"a": 1, "b": 2})
1294        yield eq, "@2011-02-07T12:34:56.123000", r(code, data=datetime.datetime(2011, 2, 7, 12, 34, 56, 123000))
1295        yield eq, "@2011-02-07T12:34:56", r(code, data=datetime.datetime(2011, 2, 7, 12, 34, 56))
1296        yield eq, "@2011-02-07T", r(code, data=datetime.datetime(2011, 2, 7))
1297        yield eq, "@2011-02-07T", r(code, data=datetime.date(2011, 2, 7))
1298
1299
1300@py.test.mark.ul4
1301def test_method_format():
1302    t = datetime.datetime(2011, 2, 6, 12, 34, 56, 987000)
1303    code = u"<?print format(data, format)?>"
1304    for r in all_renderers:
1305        yield eq, "2011", r(code, format="%Y", data=t)
1306        yield eq, "02", r(code, format="%m", data=t)
1307        yield eq, "06", r(code, format="%d", data=t)
1308        yield eq, "12", r(code, format="%H", data=t)
1309        yield eq, "34", r(code, format="%M", data=t)
1310        yield eq, "56", r(code, format="%S", data=t)
1311        yield eq, "987000", r(code, format="%f", data=t)
1312        yield contains, ("Sun", "So"), r(code, format="%a", data=t)
1313        yield contains, ("Sunday", "Sonntag"), r(code, format="%A", data=t)
1314        yield eq, "Feb", r(code, format="%b", data=t)
1315        yield contains, ("February", "Februar"), r(code, format="%B", data=t)
1316        yield eq, "12", r(code, format="%I", data=t)
1317        yield eq, "037", r(code, format="%j", data=t)
1318        yield eq, "PM", r(code, format="%p", data=t)
1319        yield eq, "06", r(code, format="%U", data=t)
1320        yield eq, "0", r(code, format="%w", data=t)
1321        yield eq, "05", r(code, format="%W", data=t)
1322        yield eq, "11", r(code, format="%y", data=t)
1323        yield contains, ("Sun Feb  6 12:34:56 2011", "So Feb  6 12:34:56 2011"), r(code, format="%c", data=t)
1324        yield eq, "02/06/11", r(code, format="%x", data=t)
1325        yield eq, "12:34:56", r(code, format="%X", data=t)
1326        yield eq, "%", r(code, format="%%", data=t)
1327
1328
1329@py.test.mark.ul4
1330def test_function_chr():
1331    code = u"<?print chr(data)?>"
1332
1333    for r in all_renderers:
1334        yield raises, "chr.*unknown", r(u"<?print chr()?>")
1335        yield raises, "chr.*unknown", r(u"<?print chr(1, 2)?>")
1336        yield eq, "\x00", r(code, data=0)
1337        yield eq, "a", r(code, data=ord("a"))
1338        yield eq, u"\u20ac", r(code, data=0x20ac)
1339
1340
1341@py.test.mark.ul4
1342def test_function_ord():
1343    code = u"<?print ord(data)?>"
1344
1345    for r in all_renderers:
1346        yield raises, "ord.*unknown", r(u"<?print ord()?>")
1347        yield raises, "ord.*unknown", r(u"<?print ord(1, 2)?>")
1348        yield eq, "0", r(code, data="\x00")
1349        yield eq, str(ord("a")), r(code, data="a")
1350        yield eq, str(0x20ac), r(code, data=u"\u20ac")
1351
1352
1353@py.test.mark.ul4
1354def test_function_hex():
1355    code = u"<?print hex(data)?>"
1356
1357    for r in all_renderers:
1358        yield raises, "hex.*unknown", r(u"<?print hex()?>")
1359        yield raises, "hex.*unknown", r(u"<?print hex(1, 2)?>")
1360        yield eq, "0x0", r(code, data=0)
1361        yield eq, "0xff", r(code, data=0xff)
1362        yield eq, "0xffff", r(code, data=0xffff)
1363        yield eq, "-0xffff", r(code, data=-0xffff)
1364
1365
1366@py.test.mark.ul4
1367def test_function_oct():
1368    code = u"<?print oct(data)?>"
1369
1370    for r in all_renderers:
1371        yield raises, "oct.*unknown", r(u"<?print oct()?>")
1372        yield raises, "oct.*unknown", r(u"<?print oct(1, 2)?>")
1373        yield eq, "0o0", r(code, data=0)
1374        yield eq, "0o77", r(code, data=077)
1375        yield eq, "0o7777", r(code, data=07777)
1376        yield eq, "-0o7777", r(code, data=-07777)
1377
1378
1379@py.test.mark.ul4
1380def test_function_bin():
1381    code = u"<?print bin(data)?>"
1382
1383    for r in all_renderers:
1384        yield raises, "bin.*unknown", r(u"<?print bin()?>")
1385        yield raises, "bin.*unknown", r(u"<?print bin(1, 2)?>")
1386        yield eq, "0b0", r(code, data=0)
1387        yield eq, "0b11", r(code, data=3)
1388        yield eq, "-0b1111", r(code, data=-15)
1389
1390
1391@py.test.mark.ul4
1392def test_function_abs():
1393    code = u"<?print abs(data)?>"
1394
1395    for r in all_renderers:
1396        yield raises, "abs.*unknown", r(u"<?print abs()?>")
1397        yield raises, "abs.*unknown", r(u"<?print abs(1, 2)?>")
1398        yield eq, "0", r(code, data=0)
1399        yield eq, "42", r(code, data=42)
1400        yield eq, "42", r(code, data=-42)
1401
1402
1403@py.test.mark.ul4
1404def test_function_sorted():
1405    code = u"<?for i in sorted(data)?><?print i?><?end for?>"
1406
1407    for r in all_renderers:
1408        yield raises, "sorted.*unknown", r(u"<?print sorted()?>")
1409        yield raises, "sorted.*unknown", r(u"<?print sorted(1, 2)?>")
1410        yield eq, "gkru", r(code, data="gurk")
1411        yield eq, "24679", r(code, data="92746")
1412        yield eq, "012", r(code, data={0: "zero", 1: "one", 2: "two"})
1413
1414
1415@py.test.mark.ul4
1416def test_function_range():
1417    code1 = u"<?for i in range(data)?><?print i?><?end for?>"
1418    code2 = u"<?for i in range(data[0], data[1])?><?print i?><?end for?>"
1419    code3 = u"<?for i in range(data[0], data[1], data[2])?><?print i?><?end for?>"
1420
1421    for r in all_renderers:
1422        yield raises, "range.*unknown", r(u"<?print range()?>")
1423        yield eq, "", r(code1, data=-10)
1424        yield eq, "", r(code1, data=0)
1425        yield eq, "0", r(code1, data=1)
1426        yield eq, "01234", r(code1, data=5)
1427        yield eq, "", r(code2, data=[0, -10])
1428        yield eq, "", r(code2, data=[0, 0])
1429        yield eq, "01234", r(code2, data=[0, 5])
1430        yield eq, "-5-4-3-2-101234", r(code2, data=[-5, 5])
1431        yield eq, "", r(code3, data=[0, -10, 1])
1432        yield eq, "", r(code3, data=[0, 0, 1])
1433        yield eq, "02468", r(code3, data=[0, 10, 2])
1434        yield eq, "", r(code3, data=[0, 10, -2])
1435        yield eq, "108642", r(code3, data=[10, 0, -2])
1436        yield eq, "", r(code3, data=[10, 0, 2])
1437
1438
1439@py.test.mark.ul4
1440def test_function_zip():
1441    code2 = u"<?for (ix, iy) in zip(x, y)?><?print ix?>-<?print iy?>;<?end for?>"
1442    code3 = u"<?for (ix, iy, iz) in zip(x, y, z)?><?print ix?>-<?print iy?>+<?print iz?>;<?end for?>"
1443
1444    for r in all_renderers:
1445        yield raises, "zip.*unknown", r(u"<?print zip(1)?>")
1446        yield eq, "", r(code2, x=[], y=[])
1447        yield eq, "1-3;2-4;", r(code2, x=[1, 2], y=[3, 4])
1448        yield eq, "1-4;2-5;", r(code2, x=[1, 2, 3], y=[4, 5])
1449        yield eq, "", r(code3, x=[], y=[], z=[])
1450        yield eq, "1-3+5;2-4+6;", r(code3, x=[1, 2], y=[3, 4], z=[5, 6])
1451        yield eq, "1-4+6;", r(code3, x=[1, 2, 3], y=[4, 5], z=[6])
1452
1453
1454@py.test.mark.ul4
1455def test_function_type():
1456    code = u"<?print type(x)?>"
1457
1458    for r in all_renderers:
1459        yield raises, "type.*unknown", r(u"<?print type()?>")
1460        yield raises, "type.*unknown", r(u"<?print type(1, 2)?>")
1461        yield eq, "none", r(code, x=None)
1462        yield eq, "bool", r(code, x=False)
1463        yield eq, "bool", r(code, x=True)
1464        yield eq, "int", r(code, x=42)
1465        yield eq, "int", r(code, x=42L)
1466        yield eq, "float", r(code, x=4.2)
1467        yield eq, "str", r(code, x="foo")
1468        yield eq, "str", r(code, x=u"foo")
1469        yield eq, "date", r(code, x=datetime.datetime.now())
1470        yield eq, "date", r(code, x=datetime.date.today())
1471        yield eq, "list", r(code, x=(1, 2))
1472        yield eq, "list", r(code, x=[1, 2])
1473        yield eq, "list", r(code, x=PseudoList([1, 2]))
1474        yield eq, "dict", r(code, x={1: 2})
1475        yield eq, "dict", r(code, x=PseudoDict({1: 2}))
1476        yield eq, "template", r(code, x=ul4c.Template(""))
1477        yield eq, "color", r(code, x=color.red)
1478
1479
1480@py.test.mark.ul4
1481def test_function_reversed():
1482    code = u"<?for i in reversed(x)?>(<?print i?>)<?end for?>"
1483
1484    for r in all_renderers:
1485        yield raises, "reversed.*unknown", r(u"<?print reversed()?>")
1486        yield raises, "reversed.*unknown", r(u"<?print reversed(1, 2)?>")
1487        yield eq, "(3)(2)(1)", r(code, x="123")
1488        yield eq, "(3)(2)(1)", r(code, x=[1, 2, 3])
1489        yield eq, "(3)(2)(1)", r(code, x=(1, 2, 3))
1490
1491
1492@py.test.mark.ul4
1493def test_function_rgb():
1494    for r in all_renderers:
1495        yield eq, "#369", r("<?print repr(rgb(0.2, 0.4, 0.6))?>")
1496        yield eq, "#369c", r("<?print repr(rgb(0.2, 0.4, 0.6, 0.8))?>")
1497
1498
1499@py.test.mark.ul4
1500def test_function_hls():
1501    for r in all_renderers:
1502        yield eq, "#fff", r("<?print repr(hls(0, 1, 0))?>")
1503        yield eq, "#fff0", r("<?print repr(hls(0, 1, 0, 0))?>")
1504
1505
1506@py.test.mark.ul4
1507def test_function_hsv():
1508    for r in all_renderers:
1509        yield eq, "#fff", r("<?print repr(hsv(0, 0, 1))?>")
1510        yield eq, "#fff0", r("<?print repr(hsv(0, 0, 1, 0))?>")
1511
1512
1513@py.test.mark.ul4
1514def test_method_upper():
1515    for r in all_renderers:
1516        yield eq, "GURK", r(u"<?print 'gurk'.upper()?>")
1517
1518
1519@py.test.mark.ul4
1520def test_method_lower():
1521    for r in all_renderers:
1522        yield eq, "gurk", r(u"<?print 'GURK'.lower()?>")
1523
1524
1525@py.test.mark.ul4
1526def test_method_capitalize():
1527    for r in all_renderers:
1528        yield eq, "Gurk", r(u"<?print 'gURK'.capitalize()?>")
1529
1530
1531@py.test.mark.ul4
1532def test_method_startswith():
1533    for r in all_renderers:
1534        yield eq, "True", r(u"<?print 'gurkhurz'.startswith('gurk')?>")
1535        yield eq, "False", r(u"<?print 'gurkhurz'.startswith('hurz')?>")
1536
1537
1538@py.test.mark.ul4
1539def test_method_endswith():
1540    for r in all_renderers:
1541        yield eq, "True", r(u"<?print 'gurkhurz'.endswith('hurz')?>")
1542        yield eq, "False", r(u"<?print 'gurkhurz'.endswith('gurk')?>")
1543
1544
1545@py.test.mark.ul4
1546def test_method_strip():
1547    for r in all_renderers:
1548        yield eq, "gurk", r(r"<?print obj.strip()?>", obj=' \t\r\ngurk \t\r\n')
1549        yield eq, "gurk", r(r"<?print obj.strip('xyz')?>", obj='xyzzygurkxyzzy')
1550
1551
1552@py.test.mark.ul4
1553def test_method_lstrip():
1554    for r in all_renderers:
1555        yield eq, "gurk \t\r\n", r("<?print obj.lstrip()?>", obj=" \t\r\ngurk \t\r\n")
1556        yield eq, "gurkxyzzy", r("<?print obj.lstrip(arg)?>", obj="xyzzygurkxyzzy", arg="xyz")
1557
1558
1559@py.test.mark.ul4
1560def test_method_rstrip():
1561    for r in all_renderers:
1562        yield eq, " \t\r\ngurk", r("<?print obj.rstrip()?>", obj=" \t\r\ngurk \t\r\n")
1563        yield eq, "xyzzygurk", r("<?print obj.rstrip(arg)?>", obj="xyzzygurkxyzzy", arg="xyz")
1564
1565
1566@py.test.mark.ul4
1567def test_method_split():
1568    for r in all_renderers:
1569        yield eq, "(f)(o)(o)", r(u"<?for item in obj.split()?>(<?print item?>)<?end for?>", obj=" \t\r\nf \t\r\no \t\r\no \t\r\n")
1570        yield eq, "(f)(o \t\r\no \t\r\n)", r(u"<?for item in obj.split(None, 1)?>(<?print item?>)<?end for?>", obj=" \t\r\nf \t\r\no \t\r\no \t\r\n")
1571        yield eq, "()(f)(o)(o)()", r(u"<?for item in obj.split(arg)?>(<?print item?>)<?end for?>", obj="xxfxxoxxoxx", arg="xx")
1572        yield eq, "()(f)(oxxoxx)", r(u"<?for item in obj.split(arg, 2)?>(<?print item?>)<?end for?>", obj="xxfxxoxxoxx", arg="xx")
1573
1574
1575@py.test.mark.ul4
1576def test_method_rsplit():
1577    for r in all_renderers:
1578        yield eq, "(f)(o)(o)", r(u"<?for item in obj.rsplit()?>(<?print item?>)<?end for?>", obj=" \t\r\nf \t\r\no \t\r\no \t\r\n")
1579        yield eq, "( \t\r\nf \t\r\no)(o)", r(u"<?for item in obj.rsplit(None, 1)?>(<?print item?>)<?end for?>", obj=" \t\r\nf \t\r\no \t\r\no \t\r\n")
1580        yield eq, "()(f)(o)(o)()", r(u"<?for item in obj.rsplit(arg)?>(<?print item?>)<?end for?>", obj="xxfxxoxxoxx", arg="xx")
1581        yield eq, "(xxfxxo)(o)()", r(u"<?for item in obj.rsplit(arg, 2)?>(<?print item?>)<?end for?>", obj="xxfxxoxxoxx", arg="xx")
1582
1583
1584@py.test.mark.ul4
1585def test_method_replace():
1586    for r in all_renderers:
1587        yield eq, 'goork', r(ur"<?print 'gurk'.replace('u', 'oo')?>")
1588
1589
1590@py.test.mark.ul4
1591def test_method_render():
1592    for r in all_renderers:
1593        t = ul4c.Template(u'(<?print data?>)')
1594        yield eq, '(GURK)', r(u"<?print t.render(data='gurk').upper()?>", t=t)
1595        yield eq, '(GURK)', r(u"<?print t.render(**{'data': 'gurk'}).upper()?>", t=t)
1596
1597        t = ul4c.Template(u'(gurk)')
1598        yield eq, '(GURK)', r(u"<?print t.render().upper()?>", t=t)
1599
1600
1601@py.test.mark.ul4
1602def test_method_isoformat():
1603    t = datetime.datetime(2010, 02, 22, 12, 34, 56)
1604    for r in all_renderers:
1605        yield eq, 'Mon, 22 Feb 2010 12:34:56 GMT', r(ur"<?print data.mimeformat()?>", data=t)
1606
1607
1608@py.test.mark.ul4
1609def test_method_get():
1610    for r in all_renderers:
1611        yield eq, "42", r(u"<?print {}.get('foo', 42)?>")
1612        yield eq, "17", r(u"<?print {'foo': 17}.get('foo', 42)?>")
1613        yield eq, "", r(u"<?print {}.get('foo')?>")
1614        yield eq, "17", r(u"<?print {'foo': 17}.get('foo')?>")
1615
1616
1617@py.test.mark.ul4
1618def test_method_r_g_b_a():
1619    for r in all_renderers:
1620        yield eq, '0x11', r(u'<?code c = #123?><?print hex(c.r())?>')
1621        yield eq, '0x22', r(u'<?code c = #123?><?print hex(c.g())?>')
1622        yield eq, '0x33', r(u'<?code c = #123?><?print hex(c.b())?>')
1623        yield eq, '0xff', r(u'<?code c = #123?><?print hex(c.a())?>')
1624
1625
1626@py.test.mark.ul4
1627def test_method_hls():
1628    for r in all_renderers:
1629        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hls()[0])?>')
1630        yield eq, '1', r(u'<?code c = #fff?><?print int(c.hls()[1])?>')
1631        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hls()[2])?>')
1632
1633
1634@py.test.mark.ul4
1635def test_method_hlsa():
1636    for r in all_renderers:
1637        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hlsa()[0])?>')
1638        yield eq, '1', r(u'<?code c = #fff?><?print int(c.hlsa()[1])?>')
1639        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hlsa()[2])?>')
1640        yield eq, '1', r(u'<?code c = #fff?><?print int(c.hlsa()[3])?>')
1641
1642
1643@py.test.mark.ul4
1644def test_method_hsv():
1645    for r in all_renderers:
1646        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hsv()[0])?>')
1647        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hsv()[1])?>')
1648        yield eq, '1', r(u'<?code c = #fff?><?print int(c.hsv()[2])?>')
1649
1650
1651@py.test.mark.ul4
1652def test_method_hsva():
1653    for r in all_renderers:
1654        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hsva()[0])?>')
1655        yield eq, '0', r(u'<?code c = #fff?><?print int(c.hsva()[1])?>')
1656        yield eq, '1', r(u'<?code c = #fff?><?print int(c.hsva()[2])?>')
1657        yield eq, '1', r(u'<?code c = #fff?><?print int(c.hsva()[3])?>')
1658
1659
1660@py.test.mark.ul4
1661def test_method_lum():
1662    for r in all_renderers:
1663        yield eq, 'True', r(u'<?print #fff.lum() == 1?>')
1664
1665
1666@py.test.mark.ul4
1667def test_method_withlum():
1668    for r in all_renderers:
1669        yield eq, '#fff', r(u'<?print #000.withlum(1)?>')
1670
1671
1672@py.test.mark.ul4
1673def test_method_witha():
1674    for r in all_renderers:
1675        yield eq, '#0063a82a', r(u'<?print repr(#0063a8.witha(42))?>')
1676
1677
1678@py.test.mark.ul4
1679def test_method_join():
1680    for r in all_renderers:
1681        yield eq, '1,2,3,4', r(u'<?print ",".join("1234")?>')
1682        yield eq, '1,2,3,4', r(u'<?print ",".join([1, 2, 3, 4])?>')
1683
1684
1685@py.test.mark.ul4
1686def test_method_find():
1687    for r in all_renderers:
1688        yield eq, '-1', r(u'<?print s.find("ks")?>', s="gurkgurk")
1689        yield eq, '2', r(u'<?print s.find("rk")?>', s="gurkgurk")
1690        yield eq, '2', r(u'<?print s.find("rk", 2)?>', s="gurkgurk")
1691        yield eq, '2', r(u'<?print s.find("rk", 2, 4)?>', s="gurkgurk")
1692        yield eq, '6', r(u'<?print s.find("rk", 4, 8)?>', s="gurkgurk")
1693        yield eq, '-1', r(u'<?print s.find("rk", 2, 3)?>', s="gurkgurk")
1694        yield eq, '-1', r(u'<?print s.find("rk", 7)?>', s="gurkgurk")
1695
1696
1697@py.test.mark.ul4
1698def test_method_rfind():
1699    for r in all_renderers:
1700        yield eq, '-1', r(u'<?print s.rfind("ks")?>', s="gurkgurk")
1701        yield eq, '6', r(u'<?print s.rfind("rk")?>', s="gurkgurk")
1702        yield eq, '6', r(u'<?print s.rfind("rk", 2)?>', s="gurkgurk")
1703        yield eq, '2', r(u'<?print s.rfind("rk", 2, 4)?>', s="gurkgurk")
1704        yield eq, '6', r(u'<?print s.rfind("rk", 4, 8)?>', s="gurkgurk")
1705        yield eq, '-1', r(u'<?print s.rfind("rk", 2, 3)?>', s="gurkgurk")
1706        yield eq, '-1', r(u'<?print s.rfind("rk", 7)?>', s="gurkgurk")
1707
1708
1709@py.test.mark.ul4
1710def test_method_day():
1711    for r in all_renderers:
1712        yield eq, '12', r(u'<?print @2010-05-12T.day()?>')
1713        yield eq, '12', r(u'<?print d.day()?>', d=datetime.date(2010, 5, 12))
1714
1715
1716@py.test.mark.ul4
1717def test_method_month():
1718    for r in all_renderers:
1719        yield eq, '5', r(u'<?print @2010-05-12T.month()?>')
1720        yield eq, '5', r(u'<?print d.month()?>', d=datetime.date(2010, 5, 12))
1721
1722
1723@py.test.mark.ul4
1724def test_method_year():
1725    for r in all_renderers:
1726        yield eq, '5', r(u'<?print @2010-05-12T.month()?>')
1727        yield eq, '5', r(u'<?print d.month()?>', d=datetime.date(2010, 5, 12))
1728
1729
1730@py.test.mark.ul4
1731def test_method_hour():
1732    for r in all_renderers:
1733        yield eq, '16', r(u'<?print @2010-05-12T16:47:56.hour()?>')
1734        yield eq, '16', r(u'<?print d.hour()?>', d=datetime.datetime(2010, 5, 12, 16, 47, 56))
1735
1736
1737@py.test.mark.ul4
1738def test_method_minute():
1739    for r in all_renderers:
1740        yield eq, '47', r(u'<?print @2010-05-12T16:47:56.minute()?>')
1741        yield eq, '47', r(u'<?print d.minute()?>', d=datetime.datetime(2010, 5, 12, 16, 47, 56))
1742
1743
1744@py.test.mark.ul4
1745def test_method_second():
1746    for r in all_renderers:
1747        yield eq, '56', r(u'<?print @2010-05-12T16:47:56.second()?>')
1748        yield eq, '56', r(u'<?print d.second()?>', d=datetime.datetime(2010, 5, 12, 16, 47, 56))
1749
1750
1751@py.test.mark.ul4
1752def test_method_microsecond():
1753    for r in all_renderers:
1754        yield eq, '123000', r(u'<?print @2010-05-12T16:47:56.123000.microsecond()?>')
1755        yield eq, '123000', r(u'<?print d.microsecond()?>', d=datetime.datetime(2010, 5, 12, 16, 47, 56, 123000))
1756
1757
1758@py.test.mark.ul4
1759def test_method_weekday():
1760    for r in all_renderers:
1761        yield eq, '2', r(u'<?print @2010-05-12T.weekday()?>')
1762        yield eq, '2', r(u'<?print d.weekday()?>', d=datetime.date(2010, 5, 12))
1763
1764
1765@py.test.mark.ul4
1766def test_method_yearday():
1767    for r in all_renderers:
1768        yield eq, '1', r(u'<?print @2010-01-01T.yearday()?>')
1769        yield eq, '366', r(u'<?print @2008-12-31T.yearday()?>')
1770        yield eq, '365', r(u'<?print @2010-12-31T.yearday()?>')
1771        yield eq, '132', r(u'<?print @2010-05-12T.yearday()?>')
1772        yield eq, '132', r(u'<?print @2010-05-12T16:47:56.yearday()?>')
1773        yield eq, '132', r(u'<?print d.yearday()?>', d=datetime.date(2010, 5, 12))
1774        yield eq, '132', r(u'<?print d.yearday()?>', d=datetime.datetime(2010, 5, 12, 16, 47, 56))
1775
1776
1777@py.test.mark.ul4
1778def test_render():
1779    t = ul4c.Template(u'<?print prefix?><?print data?><?print suffix?>')
1780    for r in all_renderers:
1781        yield eq, '(f)(o)(o)', r(u'<?for c in data?><?render t(data=c, prefix="(", suffix=")")?><?end for?>', t=t, data='foo')
1782        yield eq, '(f)(o)(o)', r(u'<?for c in data?><?render t(data=c, **{"prefix": "(", "suffix": ")"})?><?end for?>', t=t, data='foo')
1783
1784
1785@py.test.mark.ul4
1786def test_render_var():
1787    t = ul4c.Template(u'<?code x += 1?><?print x?>')
1788    for r in all_renderers:
1789        yield eq, '42,43,42', r(u'<?print x?>,<?render t(x=x)?>,<?print x?>', t=t, x=42)
1790
1791
1792@py.test.mark.ul4
1793def test_def():
1794    for r in all_renderers:
1795        yield eq, 'foo', r(u'<?def lower?><?print x.lower()?><?end def?><?print lower.render(x="FOO")?>')
1796
1797
1798@py.test.mark.ul4
1799def test_parse():
1800    for r in all_renderers:
1801        yield eq, '42', r(u'<?print data.Noner?>', data=dict(Noner=42))
1802
1803
1804@py.test.mark.ul4
1805def test_nested_exceptions():
1806    tmpl1 = ul4c.Template(u"<?print 2*x?>")
1807    tmpl2 = ul4c.Template(u"<?render tmpl1(x=x)?>")
1808    tmpl3 = ul4c.Template(u"<?render tmpl2(tmpl1=tmpl1, x=x)?>")
1809
1810    for r in all_python_renderers:
1811        msg = "render tmpl3.*render tmpl2.*render tmpl1.*print 2.*TypeError.*unsupported operand type|.* \\* .* not supported"
1812        yield raises, msg, r(u"<?render tmpl3(tmpl1=tmpl1, tmpl2=tmpl2, x=x)?>", tmpl1=tmpl1, tmpl2=tmpl2, tmpl3=tmpl3, x=None)
1813
1814
1815@py.test.mark.ul4
1816def test_note():
1817    for r in all_renderers:
1818        yield eq, "foo", r(u"f<?note This is?>o<?note a comment?>o")
1819
1820
1821@py.test.mark.ul4
1822def test_templateattributes():
1823    s = "<?print x?>"
1824    t = ul4c.Template(s)
1825
1826    for r in all_python_renderers:
1827        yield eq, "<?", r(u"<?print template.startdelim?>", template=t)
1828        yield eq, "?>", r(u"<?print template.enddelim?>", template=t)
1829        yield eq, s, r(u"<?print template.source?>", template=t)
1830        yield eq, "2", r(u"<?print len(template.opcodes)?>", template=t)
1831        yield eq, "loadvar", r(u"<?print template.opcodes[0].code?>", template=t)
1832        yield eq, "0", r(u"<?print template.opcodes[0].r1?>", template=t)
1833        yield eq, "", r(u"<?print template.opcodes[0].r2?>", template=t)
1834        yield eq, "x", r(u"<?print template.opcodes[0].arg?>", template=t)
1835        yield eq, s, r(u"<?code loc = template.opcodes[0].location?><?print template.source[loc.starttag:loc.endtag]?>", template=t)
1836        yield eq, "x", r(u"<?code loc = template.opcodes[0].location?><?print template.source[loc.startcode:loc.endcode]?>", template=t)
1837
1838
1839def universaltemplate():
1840    return ul4c.Template("""
1841        text
1842        <?code x = 'gurk'?>
1843        <?code x = 42?>
1844        <?code x = 4.2?>
1845        <?code x = None?>
1846        <?code x = False?>
1847        <?code x = True?>
1848        <?code x = @2009-01-04T?>
1849        <?code x = #0063a8?>
1850        <?code x = [42]?>
1851        <?code x = {"fortytwo": 42}?>
1852        <?code x = {**{"fortytwo": 42}}?>
1853        <?code x = y?>
1854        <?code x += 42?>
1855        <?code x -= 42?>
1856        <?code x *= 42?>
1857        <?code x /= 42?>
1858        <?code x //= 42?>
1859        <?code x %= 42?>
1860        <?code del x?>
1861        <?print x.gurk?>
1862        <?print x["gurk"]?>
1863        <?print x[1:2]?>
1864        <?print x[1:]?>
1865        <?print x[:2]?>
1866        <?printx x?>
1867        <?for x in "12"?><?print x?><?break?><?continue?><?end for?>
1868        <?print not x?>
1869        <?print -x?>
1870        <?print x in y?>
1871        <?print x not in y?>
1872        <?print x==y?>
1873        <?print x!=y?>
1874        <?print x<y?>
1875        <?print x<=y?>
1876        <?print x>y?>
1877        <?print x>=y?>
1878        <?print x+y?>
1879        <?print x*y?>
1880        <?print x/y?>
1881        <?print x//y?>
1882        <?print x and y?>
1883        <?print x or y?>
1884        <?print x % y?>
1885        <?print now()?>
1886        <?print repr(1)?>
1887        <?print range(1, 2)?>
1888        <?print range(1, 2, 3)?>
1889        <?print rgb(1, 2, 3, 4)?>
1890        <?print x.r()?>
1891        <?print x.find(1)?>
1892        <?print x.find(1, 2)?>
1893        <?print x.find(1, 2, 3)?>
1894        <?if x?>gurk<?elif y?>hurz<?else?>hinz<?end if?>
1895        <?render x(a=1, b=2)?>
1896        <?def x?>foo<?end def?>
1897        <?render x()?>
1898    """)
1899
1900
1901@py.test.mark.ul4
1902def test_strtemplate():
1903    t = universaltemplate()
1904    str(t)
1905
1906
1907@py.test.mark.ul4
1908def test_pythonsource():
1909    t = universaltemplate()
1910    t.pythonsource()
1911
1912
1913@py.test.mark.ul4
1914def test_pythonfunction():
1915    t = universaltemplate()
1916    t.pythonfunction()
1917
1918
1919@py.test.mark.ul4
1920def test_jssource():
1921    t = universaltemplate()
1922    t.jssource()
1923
1924
1925@py.test.mark.ul4
1926def test_javasource():
1927    t = universaltemplate()
1928    t.javasource()
Note: See TracBrowser for help on using the browser.