Use the same rounding for width as for height in platform sections -- covers ticket...
[pyTivo.git] / Cheetah / Tests / SyntaxAndOutput.py
blob09abc4d817b378cade9c62ee22c99d3ccbedf3b4
1 #!/usr/bin/env python
2 # $Id: SyntaxAndOutput.py,v 1.105 2006/06/21 23:48:19 tavis_rudd Exp $
3 """Syntax and Output tests.
5 TODO
6 - #finally
7 - #filter
8 - #errorCatcher
9 - #echo
10 - #silent
12 Meta-Data
13 ================================================================================
14 Author: Tavis Rudd <tavis@damnsimple.com>
15 Version: $Revision: 1.105 $
16 Start Date: 2001/03/30
17 Last Revision Date: $Date: 2006/06/21 23:48:19 $
18 """
19 __author__ = "Tavis Rudd <tavis@damnsimple.com>"
20 __revision__ = "$Revision: 1.105 $"[11:-2]
23 ##################################################
24 ## DEPENDENCIES ##
26 import sys
27 import types
28 import re
29 from copy import deepcopy
30 import os
31 import os.path
32 import new
33 import warnings
35 from Cheetah.NameMapper import NotFound
36 from Cheetah.NameMapper import C_VERSION as NameMapper_C_VERSION
37 from Cheetah.Template import Template
38 from Cheetah.Parser import ParseError
39 from Cheetah.Compiler import Compiler, DEFAULT_COMPILER_SETTINGS
40 import unittest_local_copy as unittest
42 class Unspecified: pass
43 ##################################################
44 ## CONSTANTS & GLOBALS ##
46 majorVer, minorVer = sys.version_info[0], sys.version_info[1]
47 versionTuple = (majorVer, minorVer)
49 try:
50 True,False
51 except NameError:
52 True, False = (1==1),(1==0)
54 ##################################################
55 ## TEST DATA FOR USE IN THE TEMPLATES ##
57 def testdecorator(func):
58 return func
60 class DummyClass:
61 _called = False
62 def __str__(self):
63 return 'object'
65 def meth(self, arg="arff"):
66 return str(arg)
68 def meth1(self, arg="doo"):
69 return arg
71 def meth2(self, arg1="a1", arg2="a2"):
72 return str(arg1) + str(arg2)
74 def methWithPercentSignDefaultArg(self, arg1="110%"):
75 return str(arg1)
77 def callIt(self, arg=1234):
78 self._called = True
79 self._callArg = arg
82 def dummyFunc(arg="Scooby"):
83 return arg
85 defaultTestNameSpace = {
86 'aStr':'blarg',
87 'anInt':1,
88 'aFloat':1.5,
89 'aList': ['item0','item1','item2'],
90 'aDict': {'one':'item1',
91 'two':'item2',
92 'nestedDict':{1:'nestedItem1',
93 'two':'nestedItem2'
95 'nestedFunc':dummyFunc,
97 'aFunc': dummyFunc,
98 'anObj': DummyClass(),
99 'aMeth': DummyClass().meth1,
100 'aStrToBeIncluded': "$aStr $anInt",
101 'none' : None,
102 'emptyString':'',
103 'numOne':1,
104 'numTwo':2,
105 'zero':0,
106 'tenDigits': 1234567890,
107 'webSafeTest': 'abc <=> &',
108 'strip1': ' \t strippable whitespace \t\t \n',
109 'strip2': ' \t strippable whitespace \t\t ',
110 'strip3': ' \t strippable whitespace \t\t\n1 2 3\n',
112 'blockToBeParsed':"""$numOne $numTwo""",
113 'includeBlock2':"""$numOne $numTwo $aSetVar""",
115 'includeFileName':'parseTest.txt',
116 'listOfLambdas':[lambda x: x, lambda x: x, lambda x: x,],
117 'list': [
118 {'index': 0, 'numOne': 1, 'numTwo': 2},
119 {'index': 1, 'numOne': 1, 'numTwo': 2},
121 'nameList': [('john', 'doe'), ('jane', 'smith')],
122 'letterList': ['a', 'b', 'c'],
123 '_': lambda x: 'Translated: ' + x,
124 'unicodeData':u'aoeu12345\u1234',
128 ##################################################
129 ## TEST BASE CLASSES
131 class OutputTest(unittest.TestCase):
132 report = '''
133 Template output mismatch:
135 Input Template =
136 %(template)s%(end)s
138 Expected Output =
139 %(expected)s%(end)s
141 Actual Output =
142 %(actual)s%(end)s'''
144 convertEOLs = True
145 _EOLreplacement = None
146 _debugEOLReplacement = False
148 DEBUGLEV = 0
149 _searchList = [defaultTestNameSpace]
151 _useNewStyleCompilation = True
152 #_useNewStyleCompilation = False
154 _extraCompileKwArgs = None
156 def searchList(self):
157 return self._searchList
159 def verify(self, input, expectedOutput,
160 inputEncoding=None,
161 outputEncoding=None,
162 convertEOLs=Unspecified):
163 if self._EOLreplacement:
164 if convertEOLs is Unspecified:
165 convertEOLs = self.convertEOLs
166 if convertEOLs:
167 input = input.replace('\n', self._EOLreplacement)
168 expectedOutput = expectedOutput.replace('\n', self._EOLreplacement)
170 self._input = input
171 if self._useNewStyleCompilation:
172 extraKwArgs = self._extraCompileKwArgs or {}
174 templateClass = Template.compile(
175 source=input,
176 compilerSettings=self._getCompilerSettings(),
177 keepRefToGeneratedCode=True,
178 **extraKwArgs
180 moduleCode = templateClass._CHEETAH_generatedModuleCode
181 self.template = templateObj = templateClass(searchList=self.searchList())
182 else:
183 self.template = templateObj = Template(
184 input,
185 searchList=self.searchList(),
186 compilerSettings=self._getCompilerSettings(),
188 moduleCode = templateObj._CHEETAH_generatedModuleCode
189 if self.DEBUGLEV >= 1:
190 print moduleCode
191 try:
192 try:
193 output = templateObj.respond() # rather than __str__, because of unicode
194 if outputEncoding:
195 output = output.decode(outputEncoding)
196 assert output==expectedOutput, self._outputMismatchReport(output, expectedOutput)
197 except:
198 #print >>sys.stderr, moduleCode
199 raise
200 finally:
201 templateObj.shutdown()
203 def _getCompilerSettings(self):
204 return {}
206 def _outputMismatchReport(self, output, expectedOutput):
207 if self._debugEOLReplacement and self._EOLreplacement:
208 EOLrepl = self._EOLreplacement
209 marker = '*EOL*'
210 return self.report % {'template': self._input.replace(EOLrepl,marker),
211 'expected': expectedOutput.replace(EOLrepl,marker),
212 'actual': output.replace(EOLrepl,marker),
213 'end': '(end)'}
214 else:
215 return self.report % {'template': self._input,
216 'expected': expectedOutput,
217 'actual': output,
218 'end': '(end)'}
220 def genClassCode(self):
221 if hasattr(self, 'template'):
222 return self.template.generatedClassCode()
224 def genModuleCode(self):
225 if hasattr(self, 'template'):
226 return self.template.generatedModuleCode()
228 ##################################################
229 ## TEST CASE CLASSES
231 class EmptyTemplate(OutputTest):
232 convertEOLs = False
233 def test1(self):
234 """an empty string for the template"""
236 warnings.filterwarnings('error',
237 'You supplied an empty string for the source!',
238 UserWarning)
239 try:
240 self.verify("", "")
241 except UserWarning:
242 pass
243 else:
244 self.fail("Should warn about empty source strings.")
246 try:
247 self.verify("#implements foo", "")
248 except NotImplementedError:
249 pass
250 else:
251 self.fail("This should barf about respond() not being implemented.")
253 self.verify("#implements respond", "")
255 self.verify("#implements respond(foo=1234)", "")
258 class Backslashes(OutputTest):
259 convertEOLs = False
261 def setUp(self):
262 fp = open('backslashes.txt','w')
263 fp.write(r'\ #LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n')
264 fp.flush()
265 fp.close
267 def tearDown(self):
268 if os.path.exists('backslashes.txt'):
269 os.remove('backslashes.txt')
271 def test1(self):
272 """ a single \\ using rawstrings"""
273 self.verify(r"\ ",
274 r"\ ")
276 def test2(self):
277 """ a single \\ using rawstrings and lots of lines"""
278 self.verify(r"\ " + "\n\n\n\n\n\n\n\n\n",
279 r"\ " + "\n\n\n\n\n\n\n\n\n")
281 def test3(self):
282 """ a single \\ without using rawstrings"""
283 self.verify("\ \ ",
284 "\ \ ")
286 def test4(self):
287 """ single line from an apache conf file"""
288 self.verify(r'#LogFormat "%h %l %u %t \"%r\" %>s %b"',
289 r'#LogFormat "%h %l %u %t \"%r\" %>s %b"')
291 def test5(self):
292 """ single line from an apache conf file with many NEWLINES
294 The NEWLINES are used to make sure that MethodCompiler.commitStrConst()
295 is handling long and short strings in the same fashion. It uses
296 triple-quotes for strings with lots of \\n in them and repr(theStr) for
297 shorter strings with only a few newlines."""
299 self.verify(r'#LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n',
300 r'#LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n')
302 def test6(self):
303 """ test backslash handling in an included file"""
304 self.verify(r'#include "backslashes.txt"',
305 r'\ #LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n')
307 def test7(self):
308 """ a single \\ without using rawstrings plus many NEWLINES"""
309 self.verify("\ \ " + "\n\n\n\n\n\n\n\n\n",
310 "\ \ " + "\n\n\n\n\n\n\n\n\n")
312 def test8(self):
313 """ single line from an apache conf file with single quotes and many NEWLINES
316 self.verify(r"""#LogFormat '%h %l %u %t \"%r\" %>s %b'""" + '\n\n\n\n\n\n\n',
317 r"""#LogFormat '%h %l %u %t \"%r\" %>s %b'""" + '\n\n\n\n\n\n\n')
319 class NonTokens(OutputTest):
320 def test1(self):
321 """dollar signs not in Cheetah $vars"""
322 self.verify("$ $$ $5 $. $ test",
323 "$ $$ $5 $. $ test")
325 def test2(self):
326 """hash not in #directives"""
327 self.verify("# \# #5 ",
328 "# # #5 ")
330 def test3(self):
331 """escapted comments"""
332 self.verify(" \##escaped comment ",
333 " ##escaped comment ")
335 def test4(self):
336 """escapted multi-line comments"""
337 self.verify(" \#*escaped comment \n*# ",
338 " #*escaped comment \n*# ")
340 def test5(self):
341 """1 dollar sign"""
342 self.verify("$",
343 "$")
344 def _X_test6(self):
345 """1 dollar sign followed by hash"""
346 self.verify("\n$#\n",
347 "\n$#\n")
349 def test6(self):
350 """1 dollar sign followed by EOL Slurp Token"""
351 if DEFAULT_COMPILER_SETTINGS['EOLSlurpToken']:
352 self.verify("\n$%s\n"%DEFAULT_COMPILER_SETTINGS['EOLSlurpToken'],
353 "\n$")
354 else:
355 self.verify("\n$#\n",
356 "\n$#\n")
358 class Comments_SingleLine(OutputTest):
359 def test1(self):
360 """## followed by WS"""
361 self.verify("## ",
364 def test2(self):
365 """## followed by NEWLINE"""
366 self.verify("##\n",
369 def test3(self):
370 """## followed by text then NEWLINE"""
371 self.verify("## oeuao aoe uaoe \n",
373 def test4(self):
374 """## gobbles leading WS"""
375 self.verify(" ## oeuao aoe uaoe \n",
378 def test5(self):
379 """## followed by text then NEWLINE, + leading WS"""
380 self.verify(" ## oeuao aoe uaoe \n",
383 def test6(self):
384 """## followed by EOF"""
385 self.verify("##",
388 def test7(self):
389 """## followed by EOF with leading WS"""
390 self.verify(" ##",
393 def test8(self):
394 """## gobble line
395 with text on previous and following lines"""
396 self.verify("line1\n ## aoeu 1234 \nline2",
397 "line1\nline2")
399 def test9(self):
400 """## don't gobble line
401 with text on previous and following lines"""
402 self.verify("line1\n 12 ## aoeu 1234 \nline2",
403 "line1\n 12 \nline2")
405 def test10(self):
406 """## containing $placeholders
408 self.verify("##$a$b $c($d)",
411 def test11(self):
412 """## containing #for directive
414 self.verify("##for $i in range(15)",
418 class Comments_MultiLine_NoGobble(OutputTest):
420 Multiline comments used to not gobble whitespace. They do now, but this can
421 be turned off with a compilerSetting
424 def _getCompilerSettings(self):
425 return {'gobbleWhitespaceAroundMultiLineComments':False}
427 def test1(self):
428 """#* *# followed by WS
429 Shouldn't gobble WS
431 self.verify("#* blarg *# ",
432 " ")
434 def test2(self):
435 """#* *# preceded and followed by WS
436 Shouldn't gobble WS
438 self.verify(" #* blarg *# ",
439 " ")
441 def test3(self):
442 """#* *# followed by WS, with NEWLINE
443 Shouldn't gobble WS
445 self.verify("#* \nblarg\n *# ",
446 " ")
448 def test4(self):
449 """#* *# preceded and followed by WS, with NEWLINE
450 Shouldn't gobble WS
452 self.verify(" #* \nblarg\n *# ",
453 " ")
455 class Comments_MultiLine(OutputTest):
457 Note: Multiline comments don't gobble whitespace!
460 def test1(self):
461 """#* *# followed by WS
462 Should gobble WS
464 self.verify("#* blarg *# ",
467 def test2(self):
468 """#* *# preceded and followed by WS
469 Should gobble WS
471 self.verify(" #* blarg *# ",
474 def test3(self):
475 """#* *# followed by WS, with NEWLINE
476 Shouldn't gobble WS
478 self.verify("#* \nblarg\n *# ",
481 def test4(self):
482 """#* *# preceded and followed by WS, with NEWLINE
483 Shouldn't gobble WS
485 self.verify(" #* \nblarg\n *# ",
488 def test5(self):
489 """#* *# containing nothing
491 self.verify("#**#",
494 def test6(self):
495 """#* *# containing only NEWLINES
497 self.verify(" #*\n\n\n\n\n\n\n\n*# ",
500 def test7(self):
501 """#* *# containing $placeholders
503 self.verify("#* $var $var(1234*$c) *#",
506 def test8(self):
507 """#* *# containing #for directive
509 self.verify("#* #for $i in range(15) *#",
512 def test9(self):
513 """ text around #* *# containing #for directive
515 self.verify("foo\nfoo bar #* #for $i in range(15) *# foo\n",
516 "foo\nfoo bar foo\n")
518 def test9(self):
519 """ text around #* *# containing #for directive and trailing whitespace
520 which should be gobbled
522 self.verify("foo\nfoo bar #* #for $i in range(15) *# \ntest",
523 "foo\nfoo bar \ntest")
525 def test10(self):
526 """ text around #* *# containing #for directive and newlines: trailing whitespace
527 which should be gobbled.
529 self.verify("foo\nfoo bar #* \n\n#for $i in range(15) \n\n*# \ntest",
530 "foo\nfoo bar \ntest")
532 class Placeholders(OutputTest):
533 def test1(self):
534 """1 placeholder"""
535 self.verify("$aStr", "blarg")
537 def test2(self):
538 """2 placeholders"""
539 self.verify("$aStr $anInt", "blarg 1")
541 def test3(self):
542 """2 placeholders, back-to-back"""
543 self.verify("$aStr$anInt", "blarg1")
545 def test4(self):
546 """1 placeholder enclosed in ()"""
547 self.verify("$(aStr)", "blarg")
549 def test5(self):
550 """1 placeholder enclosed in {}"""
551 self.verify("${aStr}", "blarg")
553 def test6(self):
554 """1 placeholder enclosed in []"""
555 self.verify("$[aStr]", "blarg")
557 def test7(self):
558 """1 placeholder enclosed in () + WS
560 Test to make sure that $(<WS><identifier>.. matches
562 self.verify("$( aStr )", "blarg")
564 def test8(self):
565 """1 placeholder enclosed in {} + WS"""
566 self.verify("${ aStr }", "blarg")
568 def test9(self):
569 """1 placeholder enclosed in [] + WS"""
570 self.verify("$[ aStr ]", "blarg")
572 def test10(self):
573 """1 placeholder enclosed in () + WS + * cache
575 Test to make sure that $*(<WS><identifier>.. matches
577 self.verify("$*( aStr )", "blarg")
579 def test11(self):
580 """1 placeholder enclosed in {} + WS + *cache"""
581 self.verify("$*{ aStr }", "blarg")
583 def test12(self):
584 """1 placeholder enclosed in [] + WS + *cache"""
585 self.verify("$*[ aStr ]", "blarg")
587 def test13(self):
588 """1 placeholder enclosed in {} + WS + *<int>*cache"""
589 self.verify("$*5*{ aStr }", "blarg")
591 def test14(self):
592 """1 placeholder enclosed in [] + WS + *<int>*cache"""
593 self.verify("$*5*[ aStr ]", "blarg")
595 def test15(self):
596 """1 placeholder enclosed in {} + WS + *<float>*cache"""
597 self.verify("$*0.5d*{ aStr }", "blarg")
599 def test16(self):
600 """1 placeholder enclosed in [] + WS + *<float>*cache"""
601 self.verify("$*.5*[ aStr ]", "blarg")
603 def test17(self):
604 """1 placeholder + *<int>*cache"""
605 self.verify("$*5*aStr", "blarg")
607 def test18(self):
608 """1 placeholder *<float>*cache"""
609 self.verify("$*0.5h*aStr", "blarg")
611 def test19(self):
612 """1 placeholder surrounded by single quotes and multiple newlines"""
613 self.verify("""'\n\n\n\n'$aStr'\n\n\n\n'""",
614 """'\n\n\n\n'blarg'\n\n\n\n'""")
616 def test20(self):
617 """silent mode $!placeholders """
618 self.verify("$!aStr$!nonExistant$!*nonExistant$!{nonExistant}", "blarg")
620 try:
621 self.verify("$!aStr$nonExistant",
622 "blarg")
623 except NotFound:
624 pass
625 else:
626 self.fail('should raise NotFound exception')
628 def test21(self):
629 """Make sure that $*caching is actually working"""
630 namesStr = 'You Me Them Everyone'
631 names = namesStr.split()
633 tmpl = Template.compile('#for name in $names: $name ', baseclass=dict)
634 assert str(tmpl({'names':names})).strip()==namesStr
636 tmpl = tmpl.subclass('#for name in $names: $*name ')
637 assert str(tmpl({'names':names}))=='You '*len(names)
639 tmpl = tmpl.subclass('#for name in $names: $*1*name ')
640 assert str(tmpl({'names':names}))=='You '*len(names)
642 tmpl = tmpl.subclass('#for name in $names: $*1*(name) ')
643 assert str(tmpl({'names':names}))=='You '*len(names)
645 if versionTuple > (2,2):
646 tmpl = tmpl.subclass('#for name in $names: $*1*(name) ')
647 assert str(tmpl(names=names))=='You '*len(names)
649 class Placeholders_Vals(OutputTest):
650 convertEOLs = False
651 def test1(self):
652 """string"""
653 self.verify("$aStr", "blarg")
655 def test2(self):
656 """string - with whitespace"""
657 self.verify(" $aStr ", " blarg ")
659 def test3(self):
660 """empty string - with whitespace"""
661 self.verify("$emptyString", "")
663 def test4(self):
664 """int"""
665 self.verify("$anInt", "1")
667 def test5(self):
668 """float"""
669 self.verify("$aFloat", "1.5")
671 def test6(self):
672 """list"""
673 self.verify("$aList", "['item0', 'item1', 'item2']")
675 def test7(self):
676 """None
678 The default output filter is ReplaceNone.
680 self.verify("$none", "")
682 def test8(self):
683 """True, False
685 self.verify("$True $False", "%s %s"%(repr(True), repr(False)))
687 def test9(self):
688 """$_
690 self.verify("$_('foo')", "Translated: foo")
692 class PlaceholderStrings(OutputTest):
693 def test1(self):
694 """some c'text $placeholder text' strings"""
695 self.verify("$str(c'$aStr')", "blarg")
697 def test2(self):
698 """some c'text $placeholder text' strings"""
699 self.verify("$str(c'$aStr.upper')", "BLARG")
701 def test3(self):
702 """some c'text $placeholder text' strings"""
703 self.verify("$str(c'$(aStr.upper.replace(c\"A$str()\",\"\"))')", "BLRG")
705 def test4(self):
706 """some c'text $placeholder text' strings"""
707 self.verify("#echo $str(c'$(aStr.upper)')", "BLARG")
709 def test5(self):
710 """some c'text $placeholder text' strings"""
711 self.verify("#if 1 then $str(c'$(aStr.upper)') else 0", "BLARG")
713 def test6(self):
714 """some c'text $placeholder text' strings"""
715 self.verify("#if 1\n$str(c'$(aStr.upper)')#slurp\n#else\n0#end if", "BLARG")
717 def test7(self):
718 """some c'text $placeholder text' strings"""
719 self.verify("#def foo(arg=c'$(\"BLARG\")')\n"
720 "$arg#slurp\n"
721 "#end def\n"
722 "$foo()$foo(c'$anInt')#slurp",
724 "BLARG1")
728 class UnicodeStrings(OutputTest):
729 def test1(self):
730 """unicode data in placeholder
732 #self.verify(u"$unicodeData", defaultTestNameSpace['unicodeData'], outputEncoding='utf8')
733 self.verify(u"$unicodeData", defaultTestNameSpace['unicodeData'])
735 def test2(self):
736 """unicode data in body
738 self.verify(u"aoeu12345\u1234", u"aoeu12345\u1234")
739 #self.verify(u"#encoding utf8#aoeu12345\u1234", u"aoeu12345\u1234")
741 class EncodingDirective(OutputTest):
742 def test1(self):
743 """basic #encoding """
744 self.verify("#encoding utf-8\n1234",
745 "1234")
747 def test2(self):
748 """basic #encoding """
749 self.verify("#encoding ascii\n1234",
750 "1234")
752 def test3(self):
753 """basic #encoding """
754 self.verify("#encoding utf-8\n\xe1\x88\xb4",
755 u'\u1234', outputEncoding='utf8')
757 def test4(self):
758 """basic #encoding """
759 self.verify("#encoding ascii\n\xe1\x88\xb4",
760 "\xe1\x88\xb4")
762 def test5(self):
763 """basic #encoding """
764 self.verify("#encoding latin-1\nAndr\202",
765 u'Andr\202', outputEncoding='latin-1')
767 class Placeholders_Esc(OutputTest):
768 convertEOLs = False
769 def test1(self):
770 """1 escaped placeholder"""
771 self.verify("\$var",
772 "$var")
774 def test2(self):
775 """2 escaped placeholders"""
776 self.verify("\$var \$_",
777 "$var $_")
779 def test3(self):
780 """2 escaped placeholders - back to back"""
781 self.verify("\$var\$_",
782 "$var$_")
784 def test4(self):
785 """2 escaped placeholders - nested"""
786 self.verify("\$var(\$_)",
787 "$var($_)")
789 def test5(self):
790 """2 escaped placeholders - nested and enclosed"""
791 self.verify("\$(var(\$_)",
792 "$(var($_)")
795 class Placeholders_Calls(OutputTest):
796 def test1(self):
797 """func placeholder - no ()"""
798 self.verify("$aFunc",
799 "Scooby")
801 def test2(self):
802 """func placeholder - with ()"""
803 self.verify("$aFunc()",
804 "Scooby")
806 def test3(self):
807 r"""func placeholder - with (\n\n)"""
808 self.verify("$aFunc(\n\n)",
809 "Scooby", convertEOLs=False)
811 def test4(self):
812 r"""func placeholder - with (\n\n) and $() enclosure"""
813 self.verify("$(aFunc(\n\n))",
814 "Scooby", convertEOLs=False)
816 def test5(self):
817 r"""func placeholder - with (\n\n) and ${} enclosure"""
818 self.verify("${aFunc(\n\n)}",
819 "Scooby", convertEOLs=False)
821 def test6(self):
822 """func placeholder - with (int)"""
823 self.verify("$aFunc(1234)",
824 "1234")
826 def test7(self):
827 r"""func placeholder - with (\nint\n)"""
828 self.verify("$aFunc(\n1234\n)",
829 "1234", convertEOLs=False)
830 def test8(self):
831 """func placeholder - with (string)"""
832 self.verify("$aFunc('aoeu')",
833 "aoeu")
835 def test9(self):
836 """func placeholder - with ('''string''')"""
837 self.verify("$aFunc('''aoeu''')",
838 "aoeu")
839 def test10(self):
840 r"""func placeholder - with ('''\nstring\n''')"""
841 self.verify("$aFunc('''\naoeu\n''')",
842 "\naoeu\n")
844 def test11(self):
845 r"""func placeholder - with ('''\nstring'\n''')"""
846 self.verify("$aFunc('''\naoeu'\n''')",
847 "\naoeu'\n")
849 def test12(self):
850 r'''func placeholder - with ("""\nstring\n""")'''
851 self.verify('$aFunc("""\naoeu\n""")',
852 "\naoeu\n")
854 def test13(self):
855 """func placeholder - with (string*int)"""
856 self.verify("$aFunc('aoeu'*2)",
857 "aoeuaoeu")
859 def test14(self):
860 """func placeholder - with (int*int)"""
861 self.verify("$aFunc(2*2)",
862 "4")
864 def test15(self):
865 """func placeholder - with (int*float)"""
866 self.verify("$aFunc(2*2.0)",
867 "4.0")
869 def test16(self):
870 r"""func placeholder - with (int\n*\nfloat)"""
871 self.verify("$aFunc(2\n*\n2.0)",
872 "4.0", convertEOLs=False)
874 def test17(self):
875 """func placeholder - with ($arg=float)"""
876 self.verify("$aFunc($arg=4.0)",
877 "4.0")
879 def test18(self):
880 """func placeholder - with (arg=float)"""
881 self.verify("$aFunc(arg=4.0)",
882 "4.0")
884 def test19(self):
885 """deeply nested argstring, no enclosure"""
886 self.verify("$aFunc($arg=$aMeth($arg=$aFunc(1)))",
887 "1")
889 def test20(self):
890 """deeply nested argstring, no enclosure + with WS"""
891 self.verify("$aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) )",
892 "1")
893 def test21(self):
894 """deeply nested argstring, () enclosure + with WS"""
895 self.verify("$(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
896 "1")
898 def test22(self):
899 """deeply nested argstring, {} enclosure + with WS"""
900 self.verify("${aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) }",
901 "1")
903 def test23(self):
904 """deeply nested argstring, [] enclosure + with WS"""
905 self.verify("$[aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) ]",
906 "1")
908 def test24(self):
909 """deeply nested argstring, () enclosure + *cache"""
910 self.verify("$*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
911 "1")
912 def test25(self):
913 """deeply nested argstring, () enclosure + *15*cache"""
914 self.verify("$*15*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
915 "1")
917 def test26(self):
918 """a function call with the Python None kw."""
919 self.verify("$aFunc(None)",
922 class NameMapper(OutputTest):
923 def test1(self):
924 """autocalling"""
925 self.verify("$aFunc! $aFunc().",
926 "Scooby! Scooby.")
928 def test2(self):
929 """nested autocalling"""
930 self.verify("$aFunc($aFunc).",
931 "Scooby.")
933 def test3(self):
934 """list subscription"""
935 self.verify("$aList[0]",
936 "item0")
938 def test4(self):
939 """list slicing"""
940 self.verify("$aList[:2]",
941 "['item0', 'item1']")
943 def test5(self):
944 """list slicing and subcription combined"""
945 self.verify("$aList[:2][0]",
946 "item0")
948 def test6(self):
949 """dictionary access - NameMapper style"""
950 self.verify("$aDict.one",
951 "item1")
953 def test7(self):
954 """dictionary access - Python style"""
955 self.verify("$aDict['one']",
956 "item1")
958 def test8(self):
959 """dictionary access combined with autocalled string method"""
960 self.verify("$aDict.one.upper",
961 "ITEM1")
963 def test9(self):
964 """dictionary access combined with string method"""
965 self.verify("$aDict.one.upper()",
966 "ITEM1")
968 def test10(self):
969 """nested dictionary access - NameMapper style"""
970 self.verify("$aDict.nestedDict.two",
971 "nestedItem2")
973 def test11(self):
974 """nested dictionary access - Python style"""
975 self.verify("$aDict['nestedDict']['two']",
976 "nestedItem2")
978 def test12(self):
979 """nested dictionary access - alternating style"""
980 self.verify("$aDict['nestedDict'].two",
981 "nestedItem2")
983 def test13(self):
984 """nested dictionary access using method - alternating style"""
985 self.verify("$aDict.get('nestedDict').two",
986 "nestedItem2")
988 def test14(self):
989 """nested dictionary access - NameMapper style - followed by method"""
990 self.verify("$aDict.nestedDict.two.upper",
991 "NESTEDITEM2")
993 def test15(self):
994 """nested dictionary access - alternating style - followed by method"""
995 self.verify("$aDict['nestedDict'].two.upper",
996 "NESTEDITEM2")
998 def test16(self):
999 """nested dictionary access - NameMapper style - followed by method, then slice"""
1000 self.verify("$aDict.nestedDict.two.upper[:4]",
1001 "NEST")
1003 def test17(self):
1004 """nested dictionary access - Python style using a soft-coded key"""
1005 self.verify("$aDict[$anObj.meth('nestedDict')].two",
1006 "nestedItem2")
1008 def test18(self):
1009 """object method access"""
1010 self.verify("$anObj.meth1",
1011 "doo")
1013 def test19(self):
1014 """object method access, followed by complex slice"""
1015 self.verify("$anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ]",
1016 "do")
1018 def test20(self):
1019 """object method access, followed by a very complex slice
1020 If it can pass this one, it's safe to say it works!!"""
1021 self.verify("$( anObj.meth1[0:\n (\n(4/4*2)*2)/$anObj.meth1(2)\n ] )",
1022 "do")
1024 def test21(self):
1025 """object method access with % in the default arg for the meth.
1027 This tests a bug that Jeff Johnson found and submitted a patch to SF
1028 for."""
1030 self.verify("$anObj.methWithPercentSignDefaultArg",
1031 "110%")
1034 #class NameMapperDict(OutputTest):
1036 # _searchList = [{"update": "Yabba dabba doo!"}]
1038 # def test1(self):
1039 # if NameMapper_C_VERSION:
1040 # return # This feature is not in the C version yet.
1041 # self.verify("$update", "Yabba dabba doo!")
1044 class CacheDirective(OutputTest):
1046 def test1(self):
1047 r"""simple #cache """
1048 self.verify("#cache:$anInt",
1049 "1")
1051 def test2(self):
1052 r"""simple #cache + WS"""
1053 self.verify(" #cache \n$anInt#end cache",
1054 "1")
1056 def test3(self):
1057 r"""simple #cache ... #end cache"""
1058 self.verify("""#cache id='cache1', timer=150m
1059 $anInt
1060 #end cache
1061 $aStr""",
1062 "1\nblarg")
1064 def test4(self):
1065 r"""2 #cache ... #end cache blocks"""
1066 self.verify("""#slurp
1067 #def foo
1068 #cache ID='cache1', timer=150m
1069 $anInt
1070 #end cache
1071 #cache id='cache2', timer=15s
1072 #for $i in range(5)
1073 $i#slurp
1074 #end for
1075 #end cache
1076 $aStr#slurp
1077 #end def
1078 $foo$foo$foo$foo$foo""",
1079 "1\n01234blarg"*5)
1082 def test5(self):
1083 r"""nested #cache blocks"""
1084 self.verify("""#slurp
1085 #def foo
1086 #cache ID='cache1', timer=150m
1087 $anInt
1088 #cache id='cache2', timer=15s
1089 #for $i in range(5)
1090 $i#slurp
1091 #end for
1092 $*(6)#slurp
1093 #end cache
1094 #end cache
1095 $aStr#slurp
1096 #end def
1097 $foo$foo$foo$foo$foo""",
1098 "1\n012346blarg"*5)
1101 class CallDirective(OutputTest):
1103 def test1(self):
1104 r"""simple #call """
1105 self.verify("#call int\n$anInt#end call",
1106 "1")
1107 # single line version
1108 self.verify("#call int: $anInt",
1109 "1")
1110 self.verify("#call int: 10\n$aStr",
1111 "10\nblarg")
1113 def test2(self):
1114 r"""simple #call + WS"""
1115 self.verify("#call int\n$anInt #end call",
1116 "1")
1118 def test3(self):
1119 r"""a longer #call"""
1120 self.verify('''\
1121 #def meth(arg)
1122 $arg.upper()#slurp
1123 #end def
1124 #call $meth
1125 $(1234+1) foo#slurp
1126 #end call''',
1127 "1235 FOO")
1129 def test4(self):
1130 r"""#call with keyword #args"""
1131 self.verify('''\
1132 #def meth(arg1, arg2)
1133 $arg1.upper() - $arg2.lower()#slurp
1134 #end def
1135 #call self.meth
1136 #arg arg1
1137 $(1234+1) foo#slurp
1138 #arg arg2
1139 UPPER#slurp
1140 #end call''',
1141 "1235 FOO - upper")
1143 def test5(self):
1144 r"""#call with single-line keyword #args """
1145 self.verify('''\
1146 #def meth(arg1, arg2)
1147 $arg1.upper() - $arg2.lower()#slurp
1148 #end def
1149 #call self.meth
1150 #arg arg1:$(1234+1) foo#slurp
1151 #arg arg2:UPPER#slurp
1152 #end call''',
1153 "1235 FOO - upper")
1155 def test6(self):
1156 """#call with python kwargs and cheetah output for the 1s positional
1157 arg"""
1159 self.verify('''\
1160 #def meth(arg1, arg2)
1161 $arg1.upper() - $arg2.lower()#slurp
1162 #end def
1163 #call self.meth arg2="UPPER"
1164 $(1234+1) foo#slurp
1165 #end call''',
1166 "1235 FOO - upper")
1168 def test7(self):
1169 """#call with python kwargs and #args"""
1170 self.verify('''\
1171 #def meth(arg1, arg2, arg3)
1172 $arg1.upper() - $arg2.lower() - $arg3#slurp
1173 #end def
1174 #call self.meth arg2="UPPER", arg3=999
1175 #arg arg1:$(1234+1) foo#slurp
1176 #end call''',
1177 "1235 FOO - upper - 999")
1179 def test8(self):
1180 """#call with python kwargs and #args, and using a function to get the
1181 function that will be called"""
1182 self.verify('''\
1183 #def meth(arg1, arg2, arg3)
1184 $arg1.upper() - $arg2.lower() - $arg3#slurp
1185 #end def
1186 #call getattr(self, "meth") arg2="UPPER", arg3=999
1187 #arg arg1:$(1234+1) foo#slurp
1188 #end call''',
1189 "1235 FOO - upper - 999")
1191 def test9(self):
1192 """nested #call directives"""
1193 self.verify('''\
1194 #def meth(arg1)
1195 $arg1#slurp
1196 #end def
1197 #def meth2(x,y)
1198 $x$y#slurp
1199 #end def
1201 #call self.meth
1202 1#slurp
1203 #call self.meth
1204 2#slurp
1205 #call self.meth
1206 3#slurp
1207 #end call 3
1208 #set two = 2
1209 #call self.meth2 y=c"$(10/$two)"
1210 #arg x
1211 4#slurp
1212 #end call 4
1213 #end call 2
1214 #end call 1''',
1215 "12345")
1219 class I18nDirective(OutputTest):
1220 def test1(self):
1221 r"""simple #call """
1222 self.verify("#i18n \n$anInt#end i18n",
1223 "1")
1225 # single line version
1226 self.verify("#i18n: $anInt",
1227 "1")
1228 self.verify("#i18n: 10\n$aStr",
1229 "10\nblarg")
1232 class CaptureDirective(OutputTest):
1233 def test1(self):
1234 r"""simple #capture"""
1235 self.verify('''\
1236 #capture cap1
1237 $(1234+1) foo#slurp
1238 #end capture
1239 $cap1#slurp
1240 ''',
1241 "1235 foo")
1244 def test2(self):
1245 r"""slightly more complex #capture"""
1246 self.verify('''\
1247 #def meth(arg)
1248 $arg.upper()#slurp
1249 #end def
1250 #capture cap1
1251 $(1234+1) $anInt $meth("foo")#slurp
1252 #end capture
1253 $cap1#slurp
1254 ''',
1255 "1235 1 FOO")
1258 class SlurpDirective(OutputTest):
1259 def test1(self):
1260 r"""#slurp with 1 \n """
1261 self.verify("#slurp\n",
1264 def test2(self):
1265 r"""#slurp with 1 \n, leading whitespace
1266 Should gobble"""
1267 self.verify(" #slurp\n",
1270 def test3(self):
1271 r"""#slurp with 1 \n, leading content
1272 Shouldn't gobble"""
1273 self.verify(" 1234 #slurp\n",
1274 " 1234 ")
1276 def test4(self):
1277 r"""#slurp with WS then \n, leading content
1278 Shouldn't gobble"""
1279 self.verify(" 1234 #slurp \n",
1280 " 1234 ")
1282 def test5(self):
1283 r"""#slurp with garbage chars then \n, leading content
1284 Should eat the garbage"""
1285 self.verify(" 1234 #slurp garbage \n",
1286 " 1234 ")
1290 class EOLSlurpToken(OutputTest):
1291 _EOLSlurpToken = DEFAULT_COMPILER_SETTINGS['EOLSlurpToken']
1292 def test1(self):
1293 r"""#slurp with 1 \n """
1294 self.verify("%s\n"%self._EOLSlurpToken,
1297 def test2(self):
1298 r"""#slurp with 1 \n, leading whitespace
1299 Should gobble"""
1300 self.verify(" %s\n"%self._EOLSlurpToken,
1302 def test3(self):
1303 r"""#slurp with 1 \n, leading content
1304 Shouldn't gobble"""
1305 self.verify(" 1234 %s\n"%self._EOLSlurpToken,
1306 " 1234 ")
1308 def test4(self):
1309 r"""#slurp with WS then \n, leading content
1310 Shouldn't gobble"""
1311 self.verify(" 1234 %s \n"%self._EOLSlurpToken,
1312 " 1234 ")
1314 def test5(self):
1315 r"""#slurp with garbage chars then \n, leading content
1316 Should NOT eat the garbage"""
1317 self.verify(" 1234 %s garbage \n"%self._EOLSlurpToken,
1318 " 1234 %s garbage \n"%self._EOLSlurpToken)
1320 if not DEFAULT_COMPILER_SETTINGS['EOLSlurpToken']:
1321 del EOLSlurpToken
1323 class RawDirective(OutputTest):
1324 def test1(self):
1325 """#raw till EOF"""
1326 self.verify("#raw\n$aFunc().\n\n",
1327 "$aFunc().\n\n")
1329 def test2(self):
1330 """#raw till #end raw"""
1331 self.verify("#raw\n$aFunc().\n#end raw\n$anInt",
1332 "$aFunc().\n1")
1334 def test3(self):
1335 """#raw till #end raw gobble WS"""
1336 self.verify(" #raw \n$aFunc().\n #end raw \n$anInt",
1337 "$aFunc().\n1")
1339 def test4(self):
1340 """#raw till #end raw using explicit directive closure
1341 Shouldn't gobble"""
1342 self.verify(" #raw #\n$aFunc().\n #end raw #\n$anInt",
1343 " \n$aFunc().\n\n1")
1345 def test5(self):
1346 """single-line short form #raw: """
1347 self.verify("#raw: $aFunc().\n\n",
1348 "$aFunc().\n\n")
1350 self.verify("#raw: $aFunc().\n$anInt",
1351 "$aFunc().\n1")
1353 class BreakpointDirective(OutputTest):
1354 def test1(self):
1355 """#breakpoint part way through source code"""
1356 self.verify("$aFunc(2).\n#breakpoint\n$anInt",
1357 "2.\n")
1359 def test2(self):
1360 """#breakpoint at BOF"""
1361 self.verify("#breakpoint\n$anInt",
1364 def test3(self):
1365 """#breakpoint at EOF"""
1366 self.verify("$anInt\n#breakpoint",
1367 "1\n")
1370 class StopDirective(OutputTest):
1371 def test1(self):
1372 """#stop part way through source code"""
1373 self.verify("$aFunc(2).\n#stop\n$anInt",
1374 "2.\n")
1376 def test2(self):
1377 """#stop at BOF"""
1378 self.verify("#stop\n$anInt",
1381 def test3(self):
1382 """#stop at EOF"""
1383 self.verify("$anInt\n#stop",
1384 "1\n")
1386 def test4(self):
1387 """#stop in pos test block"""
1388 self.verify("""$anInt
1389 #if 1
1390 inside the if block
1391 #stop
1392 #end if
1393 blarg""",
1394 "1\ninside the if block\n")
1396 def test5(self):
1397 """#stop in neg test block"""
1398 self.verify("""$anInt
1399 #if 0
1400 inside the if block
1401 #stop
1402 #end if
1403 blarg""",
1404 "1\nblarg")
1407 class ReturnDirective(OutputTest):
1409 def test1(self):
1410 """#return'ing an int """
1411 self.verify("""1
1412 $str($test-6)
1414 #def test
1415 #if 1
1416 #return (3 *2) \
1417 + 2
1418 #else
1419 aoeuoaeu
1420 #end if
1421 #end def
1422 """,
1423 "1\n2\n3\n")
1425 def test2(self):
1426 """#return'ing an string """
1427 self.verify("""1
1428 $str($test[1])
1430 #def test
1431 #if 1
1432 #return '123'
1433 #else
1434 aoeuoaeu
1435 #end if
1436 #end def
1437 """,
1438 "1\n2\n3\n")
1440 def test3(self):
1441 """#return'ing an string AND streaming other output via the transaction"""
1442 self.verify("""1
1443 $str($test(trans=trans)[1])
1445 #def test
1447 #if 1
1448 #return '123'
1449 #else
1450 aoeuoaeu
1451 #end if
1452 #end def
1453 """,
1454 "1\n1.5\n2\n3\n")
1457 class YieldDirective(OutputTest):
1458 convertEOLs = False
1459 def test1(self):
1460 """simple #yield """
1462 src1 = """#for i in range(10)\n#yield i\n#end for"""
1463 src2 = """#for i in range(10)\n$i#slurp\n#yield\n#end for"""
1464 src3 = ("#def iterator\n"
1465 "#for i in range(10)\n#yield i\n#end for\n"
1466 "#end def\n"
1467 "#for i in $iterator\n$i#end for"
1471 for src in (src1,src2,src3):
1472 klass = Template.compile(src, keepRefToGeneratedCode=True)
1473 #print klass._CHEETAH_generatedModuleCode
1474 iter = klass().respond()
1475 output = [str(i) for i in iter]
1476 assert ''.join(output)=='0123456789'
1477 #print ''.join(output)
1479 # @@TR: need to expand this to cover error conditions etc.
1481 if versionTuple < (2,3):
1482 del YieldDirective
1484 class ForDirective(OutputTest):
1486 def test1(self):
1487 """#for loop with one local var"""
1488 self.verify("#for $i in range(5)\n$i\n#end for",
1489 "0\n1\n2\n3\n4\n")
1491 self.verify("#for $i in range(5):\n$i\n#end for",
1492 "0\n1\n2\n3\n4\n")
1494 self.verify("#for $i in range(5): ##comment\n$i\n#end for",
1495 "0\n1\n2\n3\n4\n")
1497 self.verify("#for $i in range(5) ##comment\n$i\n#end for",
1498 "0\n1\n2\n3\n4\n")
1501 def test2(self):
1502 """#for loop with WS in loop"""
1503 self.verify("#for $i in range(5)\n$i \n#end for",
1504 "0 \n1 \n2 \n3 \n4 \n")
1506 def test3(self):
1507 """#for loop gobble WS"""
1508 self.verify(" #for $i in range(5) \n$i \n #end for ",
1509 "0 \n1 \n2 \n3 \n4 \n")
1511 def test4(self):
1512 """#for loop over list"""
1513 self.verify("#for $i, $j in [(0,1),(2,3)]\n$i,$j\n#end for",
1514 "0,1\n2,3\n")
1516 def test5(self):
1517 """#for loop over list, with #slurp"""
1518 self.verify("#for $i, $j in [(0,1),(2,3)]\n$i,$j#slurp\n#end for",
1519 "0,12,3")
1521 def test6(self):
1522 """#for loop with explicit closures"""
1523 self.verify("#for $i in range(5)#$i#end for#",
1524 "01234")
1526 def test7(self):
1527 """#for loop with explicit closures and WS"""
1528 self.verify(" #for $i in range(5)#$i#end for# ",
1529 " 01234 ")
1531 def test8(self):
1532 """#for loop using another $var"""
1533 self.verify(" #for $i in range($aFunc(5))#$i#end for# ",
1534 " 01234 ")
1536 def test9(self):
1537 """test methods in for loops"""
1538 self.verify("#for $func in $listOfLambdas\n$func($anInt)\n#end for",
1539 "1\n1\n1\n")
1542 def test10(self):
1543 """#for loop over list, using methods of the items"""
1544 self.verify("#for i, j in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1545 "AA,BB\nCC,DD\n")
1546 self.verify("#for $i, $j in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1547 "AA,BB\nCC,DD\n")
1549 def test11(self):
1550 """#for loop over list, using ($i,$j) style target list"""
1551 self.verify("#for (i, j) in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1552 "AA,BB\nCC,DD\n")
1553 self.verify("#for ($i, $j) in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1554 "AA,BB\nCC,DD\n")
1556 def test12(self):
1557 """#for loop over list, using i, (j,k) style target list"""
1558 self.verify("#for i, (j, k) in enumerate([('aa','bb'),('cc','dd')])\n$j.upper,$k.upper\n#end for",
1559 "AA,BB\nCC,DD\n")
1560 self.verify("#for $i, ($j, $k) in enumerate([('aa','bb'),('cc','dd')])\n$j.upper,$k.upper\n#end for",
1561 "AA,BB\nCC,DD\n")
1563 def test13(self):
1564 """single line #for"""
1565 self.verify("#for $i in range($aFunc(5)): $i",
1566 "01234")
1568 def test14(self):
1569 """single line #for with 1 extra leading space"""
1570 self.verify("#for $i in range($aFunc(5)): $i",
1571 " 0 1 2 3 4")
1573 def test15(self):
1574 """2 times single line #for"""
1575 self.verify("#for $i in range($aFunc(5)): $i#slurp\n"*2,
1576 "01234"*2)
1578 def test16(self):
1579 """false single line #for """
1580 self.verify("#for $i in range(5): \n$i\n#end for",
1581 "0\n1\n2\n3\n4\n")
1583 if versionTuple < (2,3):
1584 del ForDirective.test12
1586 class RepeatDirective(OutputTest):
1588 def test1(self):
1589 """basic #repeat"""
1590 self.verify("#repeat 3\n1\n#end repeat",
1591 "1\n1\n1\n")
1592 self.verify("#repeat 3: \n1\n#end repeat",
1593 "1\n1\n1\n")
1595 self.verify("#repeat 3 ##comment\n1\n#end repeat",
1596 "1\n1\n1\n")
1598 self.verify("#repeat 3: ##comment\n1\n#end repeat",
1599 "1\n1\n1\n")
1601 def test2(self):
1602 """#repeat with numeric expression"""
1603 self.verify("#repeat 3*3/3\n1\n#end repeat",
1604 "1\n1\n1\n")
1606 def test3(self):
1607 """#repeat with placeholder"""
1608 self.verify("#repeat $numTwo\n1\n#end repeat",
1609 "1\n1\n")
1611 def test4(self):
1612 """#repeat with placeholder * num"""
1613 self.verify("#repeat $numTwo*1\n1\n#end repeat",
1614 "1\n1\n")
1616 def test5(self):
1617 """#repeat with placeholder and WS"""
1618 self.verify(" #repeat $numTwo \n1\n #end repeat ",
1619 "1\n1\n")
1621 def test6(self):
1622 """single-line #repeat"""
1623 self.verify("#repeat $numTwo: 1",
1624 "11")
1625 self.verify("#repeat $numTwo: 1\n"*2,
1626 "1\n1\n"*2)
1628 #false single-line
1629 self.verify("#repeat 3: \n1\n#end repeat",
1630 "1\n1\n1\n")
1633 class AttrDirective(OutputTest):
1635 def test1(self):
1636 """#attr with int"""
1637 self.verify("#attr $test = 1234\n$test",
1638 "1234")
1640 def test2(self):
1641 """#attr with string"""
1642 self.verify("#attr $test = 'blarg'\n$test",
1643 "blarg")
1645 def test3(self):
1646 """#attr with expression"""
1647 self.verify("#attr $test = 'blarg'.upper()*2\n$test",
1648 "BLARGBLARG")
1650 def test4(self):
1651 """#attr with string + WS
1652 Should gobble"""
1653 self.verify(" #attr $test = 'blarg' \n$test",
1654 "blarg")
1656 def test5(self):
1657 """#attr with string + WS + leading text
1658 Shouldn't gobble"""
1659 self.verify(" -- #attr $test = 'blarg' \n$test",
1660 " -- \nblarg")
1663 class DefDirective(OutputTest):
1665 def test1(self):
1666 """#def without argstring"""
1667 self.verify("#def testMeth\n1234\n#end def\n$testMeth",
1668 "1234\n")
1670 self.verify("#def testMeth ## comment\n1234\n#end def\n$testMeth",
1671 "1234\n")
1673 self.verify("#def testMeth: ## comment\n1234\n#end def\n$testMeth",
1674 "1234\n")
1676 def test2(self):
1677 """#def without argstring, gobble WS"""
1678 self.verify(" #def testMeth \n1234\n #end def \n$testMeth",
1679 "1234\n")
1681 def test3(self):
1682 """#def with argstring, gobble WS"""
1683 self.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth",
1684 "1234-999\n")
1686 def test4(self):
1687 """#def with argstring, gobble WS, string used in call"""
1688 self.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth('ABC')",
1689 "1234-ABC\n")
1691 def test5(self):
1692 """#def with argstring, gobble WS, list used in call"""
1693 self.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth([1,2,3])",
1694 "1234-[1, 2, 3]\n")
1696 def test6(self):
1697 """#def with 2 args, gobble WS, list used in call"""
1698 self.verify(" #def testMeth($a, $b='default') \n1234-$a$b\n #end def\n$testMeth([1,2,3])",
1699 "1234-[1, 2, 3]default\n")
1701 def test7(self):
1702 """#def with *args, gobble WS"""
1703 self.verify(" #def testMeth($*args) \n1234-$args\n #end def\n$testMeth",
1704 "1234-()\n")
1706 def test8(self):
1707 """#def with **KWs, gobble WS"""
1708 self.verify(" #def testMeth($**KWs) \n1234-$KWs\n #end def\n$testMeth",
1709 "1234-{}\n")
1711 def test9(self):
1712 """#def with *args + **KWs, gobble WS"""
1713 self.verify(" #def testMeth($*args, $**KWs) \n1234-$args-$KWs\n #end def\n$testMeth",
1714 "1234-()-{}\n")
1716 def test10(self):
1717 """#def with *args + **KWs, gobble WS"""
1718 self.verify(
1719 " #def testMeth($*args, $**KWs) \n1234-$args-$KWs.a\n #end def\n$testMeth(1,2, a=1)",
1720 "1234-(1, 2)-1\n")
1723 def test11(self):
1724 """single line #def with extra WS"""
1725 self.verify(
1726 "#def testMeth: aoeuaoeu\n- $testMeth -",
1727 "- aoeuaoeu -")
1729 def test12(self):
1730 """single line #def with extra WS and nested $placeholders"""
1731 self.verify(
1732 "#def testMeth: $anInt $aFunc(1234)\n- $testMeth -",
1733 "- 1 1234 -")
1735 def test13(self):
1736 """single line #def escaped $placeholders"""
1737 self.verify(
1738 "#def testMeth: \$aFunc(\$anInt)\n- $testMeth -",
1739 "- $aFunc($anInt) -")
1741 def test14(self):
1742 """single line #def 1 escaped $placeholders"""
1743 self.verify(
1744 "#def testMeth: \$aFunc($anInt)\n- $testMeth -",
1745 "- $aFunc(1) -")
1747 def test15(self):
1748 """single line #def 1 escaped $placeholders + more WS"""
1749 self.verify(
1750 "#def testMeth : \$aFunc($anInt)\n- $testMeth -",
1751 "- $aFunc(1) -")
1753 def test16(self):
1754 """multiline #def with $ on methodName"""
1755 self.verify("#def $testMeth\n1234\n#end def\n$testMeth",
1756 "1234\n")
1758 def test17(self):
1759 """single line #def with $ on methodName"""
1760 self.verify("#def $testMeth:1234\n$testMeth",
1761 "1234")
1763 def test18(self):
1764 """single line #def with an argument"""
1765 self.verify("#def $testMeth($arg=1234):$arg\n$testMeth",
1766 "1234")
1769 class DecoratorDirective(OutputTest):
1770 def test1(self):
1771 """single line #def with decorator"""
1772 self.verify("#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1773 +"#@testdecorator"
1774 +"\n#def $testMeth():1234\n$testMeth",
1776 "1234")
1778 self.verify("#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1779 +"#@testdecorator"
1780 +"\n#block $testMeth():1234",
1782 "1234")
1784 try:
1785 self.verify(
1786 "#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1787 +"#@testdecorator\n sdf"
1788 +"\n#def $testMeth():1234\n$testMeth",
1790 "1234")
1791 except ParseError:
1792 pass
1793 else:
1794 self.fail('should raise a ParseError')
1796 if versionTuple < (2,4):
1797 del DecoratorDirective
1799 class BlockDirective(OutputTest):
1801 def test1(self):
1802 """#block without argstring"""
1803 self.verify("#block testBlock\n1234\n#end block",
1804 "1234\n")
1806 self.verify("#block testBlock ##comment\n1234\n#end block",
1807 "1234\n")
1809 def test2(self):
1810 """#block without argstring, gobble WS"""
1811 self.verify(" #block testBlock \n1234\n #end block ",
1812 "1234\n")
1814 def test3(self):
1815 """#block with argstring, gobble WS
1817 Because blocks can be reused in multiple parts of the template arguments
1818 (!!with defaults!!) can be given."""
1820 self.verify(" #block testBlock($a=999) \n1234-$a\n #end block ",
1821 "1234-999\n")
1823 def test4(self):
1824 """#block with 2 args, gobble WS"""
1825 self.verify(" #block testBlock($a=999, $b=444) \n1234-$a$b\n #end block ",
1826 "1234-999444\n")
1829 def test5(self):
1830 """#block with 2 nested blocks
1832 Blocks can be nested to any depth and the name of the block is optional
1833 for the #end block part: #end block OR #end block [name] """
1835 self.verify("""#block testBlock
1836 this is a test block
1837 #block outerNest
1838 outer
1839 #block innerNest
1840 inner
1841 #end block innerNest
1842 #end block outerNest
1844 #end block testBlock
1845 """,
1846 "this is a test block\nouter\ninner\n---\n")
1849 def test6(self):
1850 """single line #block """
1851 self.verify(
1852 "#block testMeth: This is my block",
1853 "This is my block")
1855 def test7(self):
1856 """single line #block with WS"""
1857 self.verify(
1858 "#block testMeth: This is my block",
1859 "This is my block")
1861 def test8(self):
1862 """single line #block 1 escaped $placeholders"""
1863 self.verify(
1864 "#block testMeth: \$aFunc($anInt)",
1865 "$aFunc(1)")
1867 def test9(self):
1868 """single line #block 1 escaped $placeholders + WS"""
1869 self.verify(
1870 "#block testMeth: \$aFunc( $anInt )",
1871 "$aFunc( 1 )")
1873 def test10(self):
1874 """single line #block 1 escaped $placeholders + more WS"""
1875 self.verify(
1876 "#block testMeth : \$aFunc( $anInt )",
1877 "$aFunc( 1 )")
1879 def test11(self):
1880 """multiline #block $ on argstring"""
1881 self.verify("#block $testBlock\n1234\n#end block",
1882 "1234\n")
1884 def test12(self):
1885 """single line #block with $ on methodName """
1886 self.verify(
1887 "#block $testMeth: This is my block",
1888 "This is my block")
1890 def test13(self):
1891 """single line #block with an arg """
1892 self.verify(
1893 "#block $testMeth($arg='This is my block'): $arg",
1894 "This is my block")
1896 def test14(self):
1897 """single line #block with None for content"""
1898 self.verify(
1899 """#block $testMeth: $None\ntest $testMeth-""",
1900 "test -")
1902 def test15(self):
1903 """single line #block with nothing for content"""
1904 self.verify(
1905 """#block $testMeth: \nfoo\n#end block\ntest $testMeth-""",
1906 "foo\ntest foo\n-")
1908 class IncludeDirective(OutputTest):
1910 def setUp(self):
1911 fp = open('parseTest.txt','w')
1912 fp.write("$numOne $numTwo")
1913 fp.flush()
1914 fp.close
1916 def tearDown(self):
1917 if os.path.exists('parseTest.txt'):
1918 os.remove('parseTest.txt')
1920 def test1(self):
1921 """#include raw of source $emptyString"""
1922 self.verify("#include raw source=$emptyString",
1925 def test2(self):
1926 """#include raw of source $blockToBeParsed"""
1927 self.verify("#include raw source=$blockToBeParsed",
1928 "$numOne $numTwo")
1930 def test3(self):
1931 """#include raw of 'parseTest.txt'"""
1932 self.verify("#include raw 'parseTest.txt'",
1933 "$numOne $numTwo")
1935 def test4(self):
1936 """#include raw of $includeFileName"""
1937 self.verify("#include raw $includeFileName",
1938 "$numOne $numTwo")
1940 def test5(self):
1941 """#include raw of $includeFileName, with WS"""
1942 self.verify(" #include raw $includeFileName ",
1943 "$numOne $numTwo")
1945 def test6(self):
1946 """#include raw of source= , with WS"""
1947 self.verify(" #include raw source='This is my $Source '*2 ",
1948 "This is my $Source This is my $Source ")
1950 def test7(self):
1951 """#include of $blockToBeParsed"""
1952 self.verify("#include source=$blockToBeParsed",
1953 "1 2")
1955 def test8(self):
1956 """#include of $blockToBeParsed, with WS"""
1957 self.verify(" #include source=$blockToBeParsed ",
1958 "1 2")
1960 def test9(self):
1961 """#include of 'parseTest.txt', with WS"""
1962 self.verify(" #include source=$blockToBeParsed ",
1963 "1 2")
1965 def test10(self):
1966 """#include of "parseTest.txt", with WS"""
1967 self.verify(" #include source=$blockToBeParsed ",
1968 "1 2")
1970 def test11(self):
1971 """#include of 'parseTest.txt', with WS and surrounding text"""
1972 self.verify("aoeu\n #include source=$blockToBeParsed \naoeu",
1973 "aoeu\n1 2aoeu")
1975 def test12(self):
1976 """#include of 'parseTest.txt', with WS and explicit closure"""
1977 self.verify(" #include source=$blockToBeParsed# ",
1978 " 1 2 ")
1981 class SilentDirective(OutputTest):
1983 def test1(self):
1984 """simple #silent"""
1985 self.verify("#silent $aFunc",
1988 def test2(self):
1989 """simple #silent"""
1990 self.verify("#silent $anObj.callIt\n$anObj.callArg",
1991 "1234")
1993 self.verify("#silent $anObj.callIt ##comment\n$anObj.callArg",
1994 "1234")
1996 def test3(self):
1997 """simple #silent"""
1998 self.verify("#silent $anObj.callIt(99)\n$anObj.callArg",
1999 "99")
2001 class SetDirective(OutputTest):
2003 def test1(self):
2004 """simple #set"""
2005 self.verify("#set $testVar = 'blarg'\n$testVar",
2006 "blarg")
2007 self.verify("#set testVar = 'blarg'\n$testVar",
2008 "blarg")
2011 self.verify("#set testVar = 'blarg'##comment\n$testVar",
2012 "blarg")
2014 def test2(self):
2015 """simple #set with no WS between operands"""
2016 self.verify("#set $testVar='blarg'",
2018 def test3(self):
2019 """#set + use of var"""
2020 self.verify("#set $testVar = 'blarg'\n$testVar",
2021 "blarg")
2023 def test4(self):
2024 """#set + use in an #include"""
2025 self.verify("#set global $aSetVar = 1234\n#include source=$includeBlock2",
2026 "1 2 1234")
2028 def test5(self):
2029 """#set with a dictionary"""
2030 self.verify( """#set $testDict = {'one':'one1','two':'two2','three':'three3'}
2031 $testDict.one
2032 $testDict.two""",
2033 "one1\ntwo2")
2035 def test6(self):
2036 """#set with string, then used in #if block"""
2038 self.verify("""#set $test='a string'\n#if $test#blarg#end if""",
2039 "blarg")
2041 def test7(self):
2042 """simple #set, gobble WS"""
2043 self.verify(" #set $testVar = 'blarg' ",
2046 def test8(self):
2047 """simple #set, don't gobble WS"""
2048 self.verify(" #set $testVar = 'blarg'#---",
2049 " ---")
2051 def test9(self):
2052 """simple #set with a list"""
2053 self.verify(" #set $testVar = [1, 2, 3] \n$testVar",
2054 "[1, 2, 3]")
2056 def test10(self):
2057 """simple #set global with a list"""
2058 self.verify(" #set global $testVar = [1, 2, 3] \n$testVar",
2059 "[1, 2, 3]")
2061 def test11(self):
2062 """simple #set global with a list and *cache
2064 Caching only works with global #set vars. Local vars are not accesible
2065 to the cache namespace.
2068 self.verify(" #set global $testVar = [1, 2, 3] \n$*testVar",
2069 "[1, 2, 3]")
2071 def test12(self):
2072 """simple #set global with a list and *<int>*cache"""
2073 self.verify(" #set global $testVar = [1, 2, 3] \n$*5*testVar",
2074 "[1, 2, 3]")
2076 def test13(self):
2077 """simple #set with a list and *<float>*cache"""
2078 self.verify(" #set global $testVar = [1, 2, 3] \n$*.5*testVar",
2079 "[1, 2, 3]")
2081 def test14(self):
2082 """simple #set without NameMapper on"""
2083 self.verify("""#compiler useNameMapper = 0\n#set $testVar = 1 \n$testVar""",
2084 "1")
2086 def test15(self):
2087 """simple #set without $"""
2088 self.verify("""#set testVar = 1 \n$testVar""",
2089 "1")
2091 def test16(self):
2092 """simple #set global without $"""
2093 self.verify("""#set global testVar = 1 \n$testVar""",
2094 "1")
2096 def test17(self):
2097 """simple #set module without $"""
2098 self.verify("""#set module __foo__ = 'bar'\n$__foo__""",
2099 "bar")
2101 def test18(self):
2102 """#set with i,j=list style assignment"""
2103 self.verify("""#set i,j = [1,2]\n$i$j""",
2104 "12")
2105 self.verify("""#set $i,$j = [1,2]\n$i$j""",
2106 "12")
2108 def test19(self):
2109 """#set with (i,j)=list style assignment"""
2110 self.verify("""#set (i,j) = [1,2]\n$i$j""",
2111 "12")
2112 self.verify("""#set ($i,$j) = [1,2]\n$i$j""",
2113 "12")
2115 def test20(self):
2116 """#set with i, (j,k)=list style assignment"""
2117 self.verify("""#set i, (j,k) = [1,(2,3)]\n$i$j$k""",
2118 "123")
2119 self.verify("""#set $i, ($j,$k) = [1,(2,3)]\n$i$j$k""",
2120 "123")
2123 class IfDirective(OutputTest):
2125 def test1(self):
2126 """simple #if block"""
2127 self.verify("#if 1\n$aStr\n#end if\n",
2128 "blarg\n")
2130 self.verify("#if 1:\n$aStr\n#end if\n",
2131 "blarg\n")
2133 self.verify("#if 1: \n$aStr\n#end if\n",
2134 "blarg\n")
2136 self.verify("#if 1: ##comment \n$aStr\n#end if\n",
2137 "blarg\n")
2139 self.verify("#if 1 ##comment \n$aStr\n#end if\n",
2140 "blarg\n")
2142 self.verify("#if 1##for i in range(10)#$i#end for##end if",
2143 '0123456789')
2145 self.verify("#if 1: #for i in range(10)#$i#end for",
2146 '0123456789')
2148 self.verify("#if 1: #for i in range(10):$i",
2149 '0123456789')
2151 def test2(self):
2152 """simple #if block, with WS"""
2153 self.verify(" #if 1\n$aStr\n #end if \n",
2154 "blarg\n")
2155 def test3(self):
2156 """simple #if block, with WS and explicit closures"""
2157 self.verify(" #if 1#\n$aStr\n #end if #--\n",
2158 " \nblarg\n --\n")
2160 def test4(self):
2161 """#if block using $numOne"""
2162 self.verify("#if $numOne\n$aStr\n#end if\n",
2163 "blarg\n")
2165 def test5(self):
2166 """#if block using $zero"""
2167 self.verify("#if $zero\n$aStr\n#end if\n",
2169 def test6(self):
2170 """#if block using $emptyString"""
2171 self.verify("#if $emptyString\n$aStr\n#end if\n",
2173 def test7(self):
2174 """#if ... #else ... block using a $emptyString"""
2175 self.verify("#if $emptyString\n$anInt\n#else\n$anInt - $anInt\n#end if",
2176 "1 - 1\n")
2178 def test8(self):
2179 """#if ... #elif ... #else ... block using a $emptyString"""
2180 self.verify("#if $emptyString\n$c\n#elif $numOne\n$numOne\n#else\n$c - $c\n#end if",
2181 "1\n")
2183 def test9(self):
2184 """#if 'not' test, with #slurp"""
2185 self.verify("#if not $emptyString\n$aStr#slurp\n#end if\n",
2186 "blarg")
2188 def test10(self):
2189 """#if block using $*emptyString
2191 This should barf
2193 try:
2194 self.verify("#if $*emptyString\n$aStr\n#end if\n",
2196 except ParseError:
2197 pass
2198 else:
2199 self.fail('This should barf')
2201 def test11(self):
2202 """#if block using invalid top-level $(placeholder) syntax - should barf"""
2204 for badSyntax in ("#if $*5*emptyString\n$aStr\n#end if\n",
2205 "#if ${emptyString}\n$aStr\n#end if\n",
2206 "#if $(emptyString)\n$aStr\n#end if\n",
2207 "#if $[emptyString]\n$aStr\n#end if\n",
2208 "#if $!emptyString\n$aStr\n#end if\n",
2210 try:
2211 self.verify(badSyntax, "")
2212 except ParseError:
2213 pass
2214 else:
2215 self.fail('This should barf')
2217 def test12(self):
2218 """#if ... #else if ... #else ... block using a $emptyString
2219 Same as test 8 but using else if instead of elif"""
2220 self.verify("#if $emptyString\n$c\n#else if $numOne\n$numOne\n#else\n$c - $c\n#end if",
2221 "1\n")
2224 def test13(self):
2225 """#if# ... #else # ... block using a $emptyString with """
2226 self.verify("#if $emptyString# $anInt#else#$anInt - $anInt#end if",
2227 "1 - 1")
2229 def test14(self):
2230 """single-line #if: simple"""
2231 self.verify("#if $emptyString then 'true' else 'false'",
2232 "false")
2234 def test15(self):
2235 """single-line #if: more complex"""
2236 self.verify("#if $anInt then 'true' else 'false'",
2237 "true")
2239 def test16(self):
2240 """single-line #if: with the words 'else' and 'then' in the output """
2241 self.verify("#if ($anInt and not $emptyString==''' else ''') then $str('then') else 'else'",
2242 "then")
2244 def test17(self):
2245 """single-line #if: """
2246 self.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2247 "foo\nfoo")
2250 self.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2251 "foo\nfoo")
2253 def test18(self):
2254 """single-line #if: \n#else: """
2255 self.verify("#if 1: foo\n#elif 0: bar",
2256 "foo\n")
2258 self.verify("#if 1: foo\n#elif 0: bar\n#else: blarg\n",
2259 "foo\n")
2261 self.verify("#if 0: foo\n#elif 0: bar\n#else: blarg\n",
2262 "blarg\n")
2264 class UnlessDirective(OutputTest):
2266 def test1(self):
2267 """#unless 1"""
2268 self.verify("#unless 1\n 1234 \n#end unless",
2271 self.verify("#unless 1:\n 1234 \n#end unless",
2274 self.verify("#unless 1: ##comment\n 1234 \n#end unless",
2277 self.verify("#unless 1 ##comment\n 1234 \n#end unless",
2281 def test2(self):
2282 """#unless 0"""
2283 self.verify("#unless 0\n 1234 \n#end unless",
2284 " 1234 \n")
2286 def test3(self):
2287 """#unless $none"""
2288 self.verify("#unless $none\n 1234 \n#end unless",
2289 " 1234 \n")
2291 def test4(self):
2292 """#unless $numTwo"""
2293 self.verify("#unless $numTwo\n 1234 \n#end unless",
2296 def test5(self):
2297 """#unless $numTwo with WS"""
2298 self.verify(" #unless $numTwo \n 1234 \n #end unless ",
2301 def test6(self):
2302 """single-line #unless"""
2303 self.verify("#unless 1: 1234", "")
2304 self.verify("#unless 0: 1234", "1234")
2305 self.verify("#unless 0: 1234\n"*2, "1234\n"*2)
2307 class PSP(OutputTest):
2309 def test1(self):
2310 """simple <%= [int] %>"""
2311 self.verify("<%= 1234 %>", "1234")
2313 def test2(self):
2314 """simple <%= [string] %>"""
2315 self.verify("<%= 'blarg' %>", "blarg")
2317 def test3(self):
2318 """simple <%= None %>"""
2319 self.verify("<%= None %>", "")
2320 def test4(self):
2321 """simple <%= [string] %> + $anInt"""
2322 self.verify("<%= 'blarg' %>$anInt", "blarg1")
2324 def test5(self):
2325 """simple <%= [EXPR] %> + $anInt"""
2326 self.verify("<%= ('blarg'*2).upper() %>$anInt", "BLARGBLARG1")
2328 def test6(self):
2329 """for loop in <%%>"""
2330 self.verify("<% for i in range(5):%>1<%end%>", "11111")
2332 def test7(self):
2333 """for loop in <%%> and using <%=i%>"""
2334 self.verify("<% for i in range(5):%><%=i%><%end%>", "01234")
2336 def test8(self):
2337 """for loop in <% $%> and using <%=i%>"""
2338 self.verify("""<% for i in range(5):
2339 i=i*2$%><%=i%><%end%>""", "02468")
2341 def test9(self):
2342 """for loop in <% $%> and using <%=i%> plus extra text"""
2343 self.verify("""<% for i in range(5):
2344 i=i*2$%><%=i%>-<%end%>""", "0-2-4-6-8-")
2347 class WhileDirective(OutputTest):
2348 def test1(self):
2349 """simple #while with a counter"""
2350 self.verify("#set $i = 0\n#while $i < 5\n$i#slurp\n#set $i += 1\n#end while",
2351 "01234")
2353 class ContinueDirective(OutputTest):
2354 def test1(self):
2355 """#continue with a #while"""
2356 self.verify("""#set $i = 0
2357 #while $i < 5
2358 #if $i == 3
2359 #set $i += 1
2360 #continue
2361 #end if
2362 $i#slurp
2363 #set $i += 1
2364 #end while""",
2365 "0124")
2367 def test2(self):
2368 """#continue with a #for"""
2369 self.verify("""#for $i in range(5)
2370 #if $i == 3
2371 #continue
2372 #end if
2373 $i#slurp
2374 #end for""",
2375 "0124")
2377 class BreakDirective(OutputTest):
2378 def test1(self):
2379 """#break with a #while"""
2380 self.verify("""#set $i = 0
2381 #while $i < 5
2382 #if $i == 3
2383 #break
2384 #end if
2385 $i#slurp
2386 #set $i += 1
2387 #end while""",
2388 "012")
2390 def test2(self):
2391 """#break with a #for"""
2392 self.verify("""#for $i in range(5)
2393 #if $i == 3
2394 #break
2395 #end if
2396 $i#slurp
2397 #end for""",
2398 "012")
2401 class TryDirective(OutputTest):
2403 def test1(self):
2404 """simple #try
2406 self.verify("#try\n1234\n#except\nblarg\n#end try",
2407 "1234\n")
2409 def test2(self):
2410 """#try / #except with #raise
2412 self.verify("#try\n#raise ValueError\n#except\nblarg\n#end try",
2413 "blarg\n")
2415 def test3(self):
2416 """#try / #except with #raise + WS
2418 Should gobble
2420 self.verify(" #try \n #raise ValueError \n #except \nblarg\n #end try",
2421 "blarg\n")
2424 def test4(self):
2425 """#try / #except with #raise + WS and leading text
2427 Shouldn't gobble
2429 self.verify("--#try \n #raise ValueError \n #except \nblarg\n #end try#--",
2430 "--\nblarg\n --")
2432 def test5(self):
2433 """nested #try / #except with #raise
2435 self.verify(
2436 """#try
2437 #raise ValueError
2438 #except
2439 #try
2440 #raise ValueError
2441 #except
2442 blarg
2443 #end try
2444 #end try""",
2445 "blarg\n")
2447 class PassDirective(OutputTest):
2448 def test1(self):
2449 """#pass in a #try / #except block
2451 self.verify("#try\n#raise ValueError\n#except\n#pass\n#end try",
2454 def test2(self):
2455 """#pass in a #try / #except block + WS
2457 self.verify(" #try \n #raise ValueError \n #except \n #pass \n #end try",
2461 class AssertDirective(OutputTest):
2462 def test1(self):
2463 """simple #assert
2465 self.verify("#set $x = 1234\n#assert $x == 1234",
2468 def test2(self):
2469 """simple #assert that fails
2471 def test(self=self):
2472 self.verify("#set $x = 1234\n#assert $x == 999",
2473 ""),
2474 self.failUnlessRaises(AssertionError, test)
2476 def test3(self):
2477 """simple #assert with WS
2479 self.verify("#set $x = 1234\n #assert $x == 1234 ",
2483 class RaiseDirective(OutputTest):
2484 def test1(self):
2485 """simple #raise ValueError
2487 Should raise ValueError
2489 def test(self=self):
2490 self.verify("#raise ValueError",
2491 ""),
2492 self.failUnlessRaises(ValueError, test)
2494 def test2(self):
2495 """#raise ValueError in #if block
2497 Should raise ValueError
2499 def test(self=self):
2500 self.verify("#if 1\n#raise ValueError\n#end if\n",
2502 self.failUnlessRaises(ValueError, test)
2505 def test3(self):
2506 """#raise ValueError in #if block
2508 Shouldn't raise ValueError
2510 self.verify("#if 0\n#raise ValueError\n#else\nblarg#end if\n",
2511 "blarg\n")
2515 class ImportDirective(OutputTest):
2516 def test1(self):
2517 """#import math
2519 self.verify("#import math",
2522 def test2(self):
2523 """#import math + WS
2525 Should gobble
2527 self.verify(" #import math ",
2530 def test3(self):
2531 """#import math + WS + leading text
2533 Shouldn't gobble
2535 self.verify(" -- #import math ",
2536 " -- ")
2538 def test4(self):
2539 """#from math import syn
2541 self.verify("#from math import cos",
2544 def test5(self):
2545 """#from math import cos + WS
2546 Should gobble
2548 self.verify(" #from math import cos ",
2551 def test6(self):
2552 """#from math import cos + WS + leading text
2553 Shouldn't gobble
2555 self.verify(" -- #from math import cos ",
2556 " -- ")
2558 def test7(self):
2559 """#from math import cos -- use it
2561 self.verify("#from math import cos\n$cos(0)",
2562 "1.0")
2564 def test8(self):
2565 """#from math import cos,tan,sin -- and use them
2567 self.verify("#from math import cos, tan, sin\n$cos(0)-$tan(0)-$sin(0)",
2568 "1.0-0.0-0.0")
2570 def test9(self):
2571 """#import os.path -- use it
2574 self.verify("#import os.path\n$os.path.exists('.')",
2575 repr(True))
2577 def test10(self):
2578 """#import os.path -- use it with NameMapper turned off
2580 self.verify("""##
2581 #compiler-settings
2582 useNameMapper=False
2583 #end compiler-settings
2584 #import os.path
2585 $os.path.exists('.')""",
2586 repr(True))
2588 def test11(self):
2589 """#from math import *
2592 self.verify("#from math import *\n$pow(1,2) $log10(10)",
2593 "1.0 1.0")
2595 class CompilerDirective(OutputTest):
2596 def test1(self):
2597 """overriding the commentStartToken
2599 self.verify("""$anInt##comment
2600 #compiler commentStartToken = '//'
2601 $anInt//comment
2602 """,
2603 "1\n1\n")
2605 def test2(self):
2606 """overriding and resetting the commentStartToken
2608 self.verify("""$anInt##comment
2609 #compiler commentStartToken = '//'
2610 $anInt//comment
2611 #compiler reset
2612 $anInt//comment
2613 """,
2614 "1\n1\n1//comment\n")
2617 class CompilerSettingsDirective(OutputTest):
2619 def test1(self):
2620 """overriding the cheetahVarStartToken
2622 self.verify("""$anInt
2623 #compiler-settings
2624 cheetahVarStartToken = @
2625 #end compiler-settings
2626 @anInt
2627 #compiler-settings reset
2628 $anInt
2629 """,
2630 "1\n1\n1\n")
2632 def test2(self):
2633 """overriding the directiveStartToken
2635 self.verify("""#set $x = 1234
2637 #compiler-settings
2638 directiveStartToken = @
2639 #end compiler-settings
2640 @set $x = 1234
2642 """,
2643 "1234\n1234\n")
2645 def test3(self):
2646 """overriding the commentStartToken
2648 self.verify("""$anInt##comment
2649 #compiler-settings
2650 commentStartToken = //
2651 #end compiler-settings
2652 $anInt//comment
2653 """,
2654 "1\n1\n")
2656 if sys.platform.startswith('java'):
2657 del CompilerDirective
2658 del CompilerSettingsDirective
2660 class ExtendsDirective(OutputTest):
2662 def test1(self):
2663 """#extends Cheetah.Templates._SkeletonPage"""
2664 self.verify("""#from Cheetah.Templates._SkeletonPage import _SkeletonPage
2665 #extends _SkeletonPage
2666 #implements respond
2667 $spacer()
2668 """,
2669 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2672 self.verify("""#from Cheetah.Templates._SkeletonPage import _SkeletonPage
2673 #extends _SkeletonPage
2674 #implements respond(foo=1234)
2675 $spacer()$foo
2676 """,
2677 '<img src="spacer.gif" width="1" height="1" alt="" />1234\n')
2679 def test2(self):
2680 """#extends Cheetah.Templates.SkeletonPage without #import"""
2681 self.verify("""#extends Cheetah.Templates.SkeletonPage
2682 #implements respond
2683 $spacer()
2684 """,
2685 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2687 def test3(self):
2688 """#extends Cheetah.Templates.SkeletonPage.SkeletonPage without #import"""
2689 self.verify("""#extends Cheetah.Templates.SkeletonPage.SkeletonPage
2690 #implements respond
2691 $spacer()
2692 """,
2693 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2695 def test4(self):
2696 """#extends with globals and searchList test"""
2697 self.verify("""#extends Cheetah.Templates.SkeletonPage
2698 #set global g="Hello"
2699 #implements respond
2700 $g $numOne
2701 """,
2702 'Hello 1\n')
2704 class ImportantExampleCases(OutputTest):
2705 def test1(self):
2706 """how to make a comma-delimited list"""
2707 self.verify("""#set $sep = ''
2708 #for $letter in $letterList
2709 $sep$letter#slurp
2710 #set $sep = ', '
2711 #end for
2712 """,
2713 "a, b, c")
2715 class FilterDirective(OutputTest):
2716 convertEOLs=False
2718 def _getCompilerSettings(self):
2719 return {'useFilterArgsInPlaceholders':True}
2721 def test1(self):
2722 """#filter ReplaceNone
2724 self.verify("#filter ReplaceNone\n$none#end filter",
2727 self.verify("#filter ReplaceNone: $none",
2730 def test2(self):
2731 """#filter ReplaceNone with WS
2733 self.verify("#filter ReplaceNone \n$none#end filter",
2736 def test3(self):
2737 """#filter MaxLen -- maxlen of 5"""
2739 self.verify("#filter MaxLen \n${tenDigits, $maxlen=5}#end filter",
2740 "12345")
2742 def test4(self):
2743 """#filter MaxLen -- no maxlen
2745 self.verify("#filter MaxLen \n${tenDigits}#end filter",
2746 "1234567890")
2748 def test5(self):
2749 """#filter WebSafe -- basic usage
2751 self.verify("#filter WebSafe \n$webSafeTest#end filter",
2752 "abc &lt;=&gt; &amp;")
2754 def test6(self):
2755 """#filter WebSafe -- also space
2757 self.verify("#filter WebSafe \n${webSafeTest, $also=' '}#end filter",
2758 "abc&nbsp;&lt;=&gt;&nbsp;&amp;")
2760 def test7(self):
2761 """#filter WebSafe -- also space, without $ on the args
2763 self.verify("#filter WebSafe \n${webSafeTest, also=' '}#end filter",
2764 "abc&nbsp;&lt;=&gt;&nbsp;&amp;")
2766 def test8(self):
2767 """#filter Strip -- trailing newline
2769 self.verify("#filter Strip\n$strip1#end filter",
2770 "strippable whitespace\n")
2772 def test9(self):
2773 """#filter Strip -- no trailing newine
2775 self.verify("#filter Strip\n$strip2#end filter",
2776 "strippable whitespace")
2778 def test10(self):
2779 """#filter Strip -- multi-line
2781 self.verify("#filter Strip\n$strip3#end filter",
2782 "strippable whitespace\n1 2 3\n")
2784 def test11(self):
2785 """#filter StripSqueeze -- canonicalize all whitespace to ' '
2787 self.verify("#filter StripSqueeze\n$strip3#end filter",
2788 "strippable whitespace 1 2 3")
2791 class EchoDirective(OutputTest):
2792 def test1(self):
2793 """#echo 1234
2795 self.verify("#echo 1234",
2796 "1234")
2798 class SilentDirective(OutputTest):
2799 def test1(self):
2800 """#silent 1234
2802 self.verify("#silent 1234",
2805 class ErrorCatcherDirective(OutputTest):
2806 pass
2809 class VarExists(OutputTest): # Template.varExists()
2811 def test1(self):
2812 """$varExists('$anInt')
2814 self.verify("$varExists('$anInt')",
2815 repr(True))
2817 def test2(self):
2818 """$varExists('anInt')
2820 self.verify("$varExists('anInt')",
2821 repr(True))
2823 def test3(self):
2824 """$varExists('$anInt')
2826 self.verify("$varExists('$bogus')",
2827 repr(False))
2829 def test4(self):
2830 """$varExists('$anInt') combined with #if false
2832 self.verify("#if $varExists('$bogus')\n1234\n#else\n999\n#end if",
2833 "999\n")
2835 def test5(self):
2836 """$varExists('$anInt') combined with #if true
2838 self.verify("#if $varExists('$anInt')\n1234\n#else\n999#end if",
2839 "1234\n")
2841 class GetVar(OutputTest): # Template.getVar()
2842 def test1(self):
2843 """$getVar('$anInt')
2845 self.verify("$getVar('$anInt')",
2846 "1")
2848 def test2(self):
2849 """$getVar('anInt')
2851 self.verify("$getVar('anInt')",
2852 "1")
2854 def test3(self):
2855 """$self.getVar('anInt')
2857 self.verify("$self.getVar('anInt')",
2858 "1")
2860 def test4(self):
2861 """$getVar('bogus', 1234)
2863 self.verify("$getVar('bogus', 1234)",
2864 "1234")
2866 def test5(self):
2867 """$getVar('$bogus', 1234)
2869 self.verify("$getVar('$bogus', 1234)",
2870 "1234")
2873 class MiscComplexSyntax(OutputTest):
2874 def test1(self):
2875 """Complex use of {},[] and () in a #set expression
2876 ----
2877 #set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]
2880 self.verify("#set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]\n$c",
2881 "0")
2884 class CGI(OutputTest):
2885 """CGI scripts with(out) the CGI environment and with(out) GET variables.
2887 convertEOLs=False
2889 def _beginCGI(self):
2890 os.environ['REQUEST_METHOD'] = "GET"
2891 def _endCGI(self):
2892 try:
2893 del os.environ['REQUEST_METHOD']
2894 except KeyError:
2895 pass
2896 _guaranteeNoCGI = _endCGI
2899 def test1(self):
2900 """A regular template."""
2901 self._guaranteeNoCGI()
2902 source = "#extends Cheetah.Tools.CGITemplate\n" + \
2903 "#implements respond\n" + \
2904 "$cgiHeaders#slurp\n" + \
2905 "Hello, world!"
2906 self.verify(source, "Hello, world!")
2909 def test2(self):
2910 """A CGI script."""
2911 self._beginCGI()
2912 source = "#extends Cheetah.Tools.CGITemplate\n" + \
2913 "#implements respond\n" + \
2914 "$cgiHeaders#slurp\n" + \
2915 "Hello, world!"
2916 self.verify(source, "Content-type: text/html\n\nHello, world!")
2917 self._endCGI()
2920 def test3(self):
2921 """A (pseudo) Webware servlet.
2923 This uses the Python syntax escape to set
2924 self._CHEETAH__isControlledByWebKit.
2925 We could instead do '#silent self._CHEETAH__isControlledByWebKit = True',
2926 taking advantage of the fact that it will compile unchanged as long
2927 as there's no '$' in the statement. (It won't compile with an '$'
2928 because that would convert to a function call, and you can't assign
2929 to a function call.) Because this isn't really being called from
2930 Webware, we'd better not use any Webware services! Likewise, we'd
2931 better not call $cgiImport() because it would be misled.
2933 self._beginCGI()
2934 source = "#extends Cheetah.Tools.CGITemplate\n" + \
2935 "#implements respond\n" + \
2936 "<% self._CHEETAH__isControlledByWebKit = True %>#slurp\n" + \
2937 "$cgiHeaders#slurp\n" + \
2938 "Hello, world!"
2939 self.verify(source, "Hello, world!")
2940 self._endCGI()
2943 def test4(self):
2944 """A CGI script with a GET variable."""
2945 self._beginCGI()
2946 os.environ['QUERY_STRING'] = "cgiWhat=world"
2947 source = "#extends Cheetah.Tools.CGITemplate\n" + \
2948 "#implements respond\n" + \
2949 "$cgiHeaders#slurp\n" + \
2950 "#silent $webInput(['cgiWhat'])##slurp\n" + \
2951 "Hello, $cgiWhat!"
2952 self.verify(source,
2953 "Content-type: text/html\n\nHello, world!")
2954 del os.environ['QUERY_STRING']
2955 self._endCGI()
2959 class WhitespaceAfterDirectiveTokens(OutputTest):
2960 def _getCompilerSettings(self):
2961 return {'allowWhitespaceAfterDirectiveStartToken':True}
2963 def test1(self):
2964 self.verify("# for i in range(10): $i",
2965 "0123456789")
2966 self.verify("# for i in range(10)\n$i# end for",
2967 "0123456789")
2968 self.verify("# for i in range(10)#$i#end for",
2969 "0123456789")
2973 class DefmacroDirective(OutputTest):
2974 def _getCompilerSettings(self):
2975 def aMacro(src):
2976 return '$aStr'
2978 return {'macroDirectives':{'aMacro':aMacro
2981 def test1(self):
2982 self.verify("""\
2983 #defmacro inc: #set @src +=1
2984 #set i = 1
2985 #inc: $i
2986 $i""",
2987 "2")
2991 self.verify("""\
2992 #defmacro test
2993 #for i in range(10): @src
2994 #end defmacro
2995 #test: $i-foo#slurp
2996 #for i in range(3): $i""",
2997 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo012")
2999 self.verify("""\
3000 #defmacro test
3001 #for i in range(10): @src
3002 #end defmacro
3003 #test: $i-foo
3004 #for i in range(3): $i""",
3005 "0-foo\n1-foo\n2-foo\n3-foo\n4-foo\n5-foo\n6-foo\n7-foo\n8-foo\n9-foo\n012")
3008 self.verify("""\
3009 #defmacro test: #for i in range(10): @src
3010 #test: $i-foo#slurp
3011 -#for i in range(3): $i""",
3012 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3014 self.verify("""\
3015 #defmacro test##for i in range(10): @src#end defmacro##slurp
3016 #test: $i-foo#slurp
3017 -#for i in range(3): $i""",
3018 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3020 self.verify("""\
3021 #defmacro testFoo: nothing
3022 #defmacro test(foo=1234): #for i in range(10): @src
3023 #test foo=234: $i-foo#slurp
3024 -#for i in range(3): $i""",
3025 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3027 self.verify("""\
3028 #defmacro testFoo: nothing
3029 #defmacro test(foo=1234): #for i in range(10): @src@foo
3030 #test foo='-foo'#$i#end test#-#for i in range(3): $i""",
3031 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3033 self.verify("""\
3034 #defmacro testFoo: nothing
3035 #defmacro test(foo=1234): #for i in range(10): @src.strip()@foo
3036 #test foo='-foo': $i
3037 -#for i in range(3): $i""",
3038 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3040 def test2(self):
3041 self.verify("#aMacro: foo",
3042 "blarg")
3043 self.verify("#defmacro nested: @macros.aMacro(@src)\n#nested: foo",
3044 "blarg")
3047 class Indenter(OutputTest):
3048 convertEOLs=False
3050 source = """
3051 public class X
3053 #for $method in $methods
3054 $getMethod($method)
3056 #end for
3058 //end of class
3060 #def getMethod($method)
3061 #indent ++
3062 public $getType($method) ${method.Name}($getParams($method.Params));
3063 #indent --
3064 #end def
3066 #def getParams($params)
3067 #indent off
3069 #for $counter in $range($len($params))
3070 #if $counter == len($params) - 1
3071 $params[$counter]#slurp
3072 #else:
3073 $params[$counter],
3074 #end if
3075 #end for
3076 #indent on
3077 #end def
3079 #def getType($method)
3080 #indent push
3081 #indent=0
3082 #if $method.Type == "VT_VOID"
3083 void#slurp
3084 #elif $method.Type == "VT_INT"
3085 int#slurp
3086 #elif $method.Type == "VT_VARIANT"
3087 Object#slurp
3088 #end if
3089 #indent pop
3090 #end def
3093 control = """
3094 public class X
3096 public void Foo(
3097 _input,
3098 _output);
3101 public int Bar(
3102 _str1,
3103 str2,
3104 _str3);
3107 public Object Add(
3108 value1,
3109 value);
3113 //end of class
3118 def _getCompilerSettings(self):
3119 return {'useFilterArgsInPlaceholders':True}
3121 def searchList(self): # Inside Indenter class.
3122 class Method:
3123 def __init__(self, _name, _type, *_params):
3124 self.Name = _name
3125 self.Type = _type
3126 self.Params = _params
3127 methods = [Method("Foo", "VT_VOID", "_input", "_output"),
3128 Method("Bar", "VT_INT", "_str1", "str2", "_str3"),
3129 Method("Add", "VT_VARIANT", "value1", "value")]
3130 return [{"methods": methods}]
3132 def test1(self): # Inside Indenter class.
3133 self.verify(self.source, self.control)
3136 ##################################################
3137 ## CREATE CONVERTED EOL VERSIONS OF THE TEST CASES
3139 if OutputTest._useNewStyleCompilation and versionTuple >= (2,3):
3140 extraCompileKwArgsForDiffBaseclass = {'baseclass':dict}
3141 else:
3142 extraCompileKwArgsForDiffBaseclass = {'baseclass':object}
3145 for klass in [var for var in globals().values()
3146 if type(var) == types.ClassType and issubclass(var, unittest.TestCase)]:
3147 name = klass.__name__
3148 if hasattr(klass,'convertEOLs') and klass.convertEOLs:
3149 win32Src = r"class %(name)s_Win32EOL(%(name)s): _EOLreplacement = '\r\n'"%locals()
3150 macSrc = r"class %(name)s_MacEOL(%(name)s): _EOLreplacement = '\r'"%locals()
3151 #print win32Src
3152 #print macSrc
3153 exec win32Src+'\n'
3154 exec macSrc+'\n'
3156 if versionTuple >= (2,3):
3157 src = r"class %(name)s_DiffBaseClass(%(name)s): "%locals()
3158 src += " _extraCompileKwArgs = extraCompileKwArgsForDiffBaseclass"
3159 exec src+'\n'
3161 del name
3162 del klass
3164 ##################################################
3165 ## if run from the command line ##
3167 if __name__ == '__main__':
3168 unittest.main()
3170 # vim: shiftwidth=4 tabstop=4 expandtab