Initial Commit
[Projects.git] / pkgbuilds / pytivo / pkg / usr / share / pyTivo / Cheetah / Tests / SyntaxAndOutput.py
blob486cb822a66a381a48cc8b80b454eccd47dacfef
1 #!/usr/bin/env python
2 # -*- coding: latin-1 -*-
3 # $Id: SyntaxAndOutput.py,v 1.109 2007/04/04 00:28:21 tavis_rudd Exp $
4 """Syntax and Output tests.
6 TODO
7 - #finally
8 - #filter
9 - #errorCatcher
10 - #echo
11 - #silent
13 Meta-Data
14 ================================================================================
15 Author: Tavis Rudd <tavis@damnsimple.com>
16 Version: $Revision: 1.109 $
17 Start Date: 2001/03/30
18 Last Revision Date: $Date: 2007/04/04 00:28:21 $
19 """
20 __author__ = "Tavis Rudd <tavis@damnsimple.com>"
21 __revision__ = "$Revision: 1.109 $"[11:-2]
24 ##################################################
25 ## DEPENDENCIES ##
27 import sys
28 import types
29 import re
30 from copy import deepcopy
31 import os
32 import os.path
33 import new
34 import warnings
36 from Cheetah.NameMapper import NotFound
37 from Cheetah.NameMapper import C_VERSION as NameMapper_C_VERSION
38 from Cheetah.Template import Template
39 from Cheetah.Parser import ParseError
40 from Cheetah.Compiler import Compiler, DEFAULT_COMPILER_SETTINGS
41 import unittest_local_copy as unittest
43 class Unspecified: pass
44 ##################################################
45 ## CONSTANTS & GLOBALS ##
47 majorVer, minorVer = sys.version_info[0], sys.version_info[1]
48 versionTuple = (majorVer, minorVer)
50 try:
51 True,False
52 except NameError:
53 True, False = (1==1),(1==0)
55 ##################################################
56 ## TEST DATA FOR USE IN THE TEMPLATES ##
58 def testdecorator(func):
59 return func
61 class DummyClass:
62 _called = False
63 def __str__(self):
64 return 'object'
66 def meth(self, arg="arff"):
67 return str(arg)
69 def meth1(self, arg="doo"):
70 return arg
72 def meth2(self, arg1="a1", arg2="a2"):
73 return str(arg1) + str(arg2)
75 def methWithPercentSignDefaultArg(self, arg1="110%"):
76 return str(arg1)
78 def callIt(self, arg=1234):
79 self._called = True
80 self._callArg = arg
83 def dummyFunc(arg="Scooby"):
84 return arg
86 defaultTestNameSpace = {
87 'aStr':'blarg',
88 'anInt':1,
89 'aFloat':1.5,
90 'aList': ['item0','item1','item2'],
91 'aDict': {'one':'item1',
92 'two':'item2',
93 'nestedDict':{1:'nestedItem1',
94 'two':'nestedItem2'
96 'nestedFunc':dummyFunc,
98 'aFunc': dummyFunc,
99 'anObj': DummyClass(),
100 'aMeth': DummyClass().meth1,
101 'aStrToBeIncluded': "$aStr $anInt",
102 'none' : None,
103 'emptyString':'',
104 'numOne':1,
105 'numTwo':2,
106 'zero':0,
107 'tenDigits': 1234567890,
108 'webSafeTest': 'abc <=> &',
109 'strip1': ' \t strippable whitespace \t\t \n',
110 'strip2': ' \t strippable whitespace \t\t ',
111 'strip3': ' \t strippable whitespace \t\t\n1 2 3\n',
113 'blockToBeParsed':"""$numOne $numTwo""",
114 'includeBlock2':"""$numOne $numTwo $aSetVar""",
116 'includeFileName':'parseTest.txt',
117 'listOfLambdas':[lambda x: x, lambda x: x, lambda x: x,],
118 'list': [
119 {'index': 0, 'numOne': 1, 'numTwo': 2},
120 {'index': 1, 'numOne': 1, 'numTwo': 2},
122 'nameList': [('john', 'doe'), ('jane', 'smith')],
123 'letterList': ['a', 'b', 'c'],
124 '_': lambda x: 'Translated: ' + x,
125 'unicodeData':u'aoeu12345\u1234',
129 ##################################################
130 ## TEST BASE CLASSES
132 class OutputTest(unittest.TestCase):
133 report = '''
134 Template output mismatch:
136 Input Template =
137 %(template)s%(end)s
139 Expected Output =
140 %(expected)s%(end)s
142 Actual Output =
143 %(actual)s%(end)s'''
145 convertEOLs = True
146 _EOLreplacement = None
147 _debugEOLReplacement = False
149 DEBUGLEV = 0
150 _searchList = [defaultTestNameSpace]
152 _useNewStyleCompilation = True
153 #_useNewStyleCompilation = False
155 _extraCompileKwArgs = None
157 def searchList(self):
158 return self._searchList
160 def verify(self, input, expectedOutput,
161 inputEncoding=None,
162 outputEncoding=None,
163 convertEOLs=Unspecified):
164 if self._EOLreplacement:
165 if convertEOLs is Unspecified:
166 convertEOLs = self.convertEOLs
167 if convertEOLs:
168 input = input.replace('\n', self._EOLreplacement)
169 expectedOutput = expectedOutput.replace('\n', self._EOLreplacement)
171 self._input = input
172 if self._useNewStyleCompilation:
173 extraKwArgs = self._extraCompileKwArgs or {}
175 templateClass = Template.compile(
176 source=input,
177 compilerSettings=self._getCompilerSettings(),
178 keepRefToGeneratedCode=True,
179 **extraKwArgs
181 moduleCode = templateClass._CHEETAH_generatedModuleCode
182 self.template = templateObj = templateClass(searchList=self.searchList())
183 else:
184 self.template = templateObj = Template(
185 input,
186 searchList=self.searchList(),
187 compilerSettings=self._getCompilerSettings(),
189 moduleCode = templateObj._CHEETAH_generatedModuleCode
190 if self.DEBUGLEV >= 1:
191 print moduleCode
192 try:
193 try:
194 output = templateObj.respond() # rather than __str__, because of unicode
195 if outputEncoding:
196 output = output.decode(outputEncoding)
197 assert output==expectedOutput, self._outputMismatchReport(output, expectedOutput)
198 except:
199 #print >>sys.stderr, moduleCode
200 raise
201 finally:
202 templateObj.shutdown()
204 def _getCompilerSettings(self):
205 return {}
207 def _outputMismatchReport(self, output, expectedOutput):
208 if self._debugEOLReplacement and self._EOLreplacement:
209 EOLrepl = self._EOLreplacement
210 marker = '*EOL*'
211 return self.report % {'template': self._input.replace(EOLrepl,marker),
212 'expected': expectedOutput.replace(EOLrepl,marker),
213 'actual': output.replace(EOLrepl,marker),
214 'end': '(end)'}
215 else:
216 return self.report % {'template': self._input,
217 'expected': expectedOutput,
218 'actual': output,
219 'end': '(end)'}
221 def genClassCode(self):
222 if hasattr(self, 'template'):
223 return self.template.generatedClassCode()
225 def genModuleCode(self):
226 if hasattr(self, 'template'):
227 return self.template.generatedModuleCode()
229 ##################################################
230 ## TEST CASE CLASSES
232 class EmptyTemplate(OutputTest):
233 convertEOLs = False
234 def test1(self):
235 """an empty string for the template"""
237 warnings.filterwarnings('error',
238 'You supplied an empty string for the source!',
239 UserWarning)
240 try:
241 self.verify("", "")
242 except UserWarning:
243 pass
244 else:
245 self.fail("Should warn about empty source strings.")
247 try:
248 self.verify("#implements foo", "")
249 except NotImplementedError:
250 pass
251 else:
252 self.fail("This should barf about respond() not being implemented.")
254 self.verify("#implements respond", "")
256 self.verify("#implements respond(foo=1234)", "")
259 class Backslashes(OutputTest):
260 convertEOLs = False
262 def setUp(self):
263 fp = open('backslashes.txt','w')
264 fp.write(r'\ #LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n')
265 fp.flush()
266 fp.close
268 def tearDown(self):
269 if os.path.exists('backslashes.txt'):
270 os.remove('backslashes.txt')
272 def test1(self):
273 """ a single \\ using rawstrings"""
274 self.verify(r"\ ",
275 r"\ ")
277 def test2(self):
278 """ a single \\ using rawstrings and lots of lines"""
279 self.verify(r"\ " + "\n\n\n\n\n\n\n\n\n",
280 r"\ " + "\n\n\n\n\n\n\n\n\n")
282 def test3(self):
283 """ a single \\ without using rawstrings"""
284 self.verify("\ \ ",
285 "\ \ ")
287 def test4(self):
288 """ single line from an apache conf file"""
289 self.verify(r'#LogFormat "%h %l %u %t \"%r\" %>s %b"',
290 r'#LogFormat "%h %l %u %t \"%r\" %>s %b"')
292 def test5(self):
293 """ single line from an apache conf file with many NEWLINES
295 The NEWLINES are used to make sure that MethodCompiler.commitStrConst()
296 is handling long and short strings in the same fashion. It uses
297 triple-quotes for strings with lots of \\n in them and repr(theStr) for
298 shorter strings with only a few newlines."""
300 self.verify(r'#LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n',
301 r'#LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n')
303 def test6(self):
304 """ test backslash handling in an included file"""
305 self.verify(r'#include "backslashes.txt"',
306 r'\ #LogFormat "%h %l %u %t \"%r\" %>s %b"' + '\n\n\n\n\n\n\n')
308 def test7(self):
309 """ a single \\ without using rawstrings plus many NEWLINES"""
310 self.verify("\ \ " + "\n\n\n\n\n\n\n\n\n",
311 "\ \ " + "\n\n\n\n\n\n\n\n\n")
313 def test8(self):
314 """ single line from an apache conf file with single quotes and many NEWLINES
317 self.verify(r"""#LogFormat '%h %l %u %t \"%r\" %>s %b'""" + '\n\n\n\n\n\n\n',
318 r"""#LogFormat '%h %l %u %t \"%r\" %>s %b'""" + '\n\n\n\n\n\n\n')
320 class NonTokens(OutputTest):
321 def test1(self):
322 """dollar signs not in Cheetah $vars"""
323 self.verify("$ $$ $5 $. $ test",
324 "$ $$ $5 $. $ test")
326 def test2(self):
327 """hash not in #directives"""
328 self.verify("# \# #5 ",
329 "# # #5 ")
331 def test3(self):
332 """escapted comments"""
333 self.verify(" \##escaped comment ",
334 " ##escaped comment ")
336 def test4(self):
337 """escapted multi-line comments"""
338 self.verify(" \#*escaped comment \n*# ",
339 " #*escaped comment \n*# ")
341 def test5(self):
342 """1 dollar sign"""
343 self.verify("$",
344 "$")
345 def _X_test6(self):
346 """1 dollar sign followed by hash"""
347 self.verify("\n$#\n",
348 "\n$#\n")
350 def test6(self):
351 """1 dollar sign followed by EOL Slurp Token"""
352 if DEFAULT_COMPILER_SETTINGS['EOLSlurpToken']:
353 self.verify("\n$%s\n"%DEFAULT_COMPILER_SETTINGS['EOLSlurpToken'],
354 "\n$")
355 else:
356 self.verify("\n$#\n",
357 "\n$#\n")
359 class Comments_SingleLine(OutputTest):
360 def test1(self):
361 """## followed by WS"""
362 self.verify("## ",
365 def test2(self):
366 """## followed by NEWLINE"""
367 self.verify("##\n",
370 def test3(self):
371 """## followed by text then NEWLINE"""
372 self.verify("## oeuao aoe uaoe \n",
374 def test4(self):
375 """## gobbles leading WS"""
376 self.verify(" ## oeuao aoe uaoe \n",
379 def test5(self):
380 """## followed by text then NEWLINE, + leading WS"""
381 self.verify(" ## oeuao aoe uaoe \n",
384 def test6(self):
385 """## followed by EOF"""
386 self.verify("##",
389 def test7(self):
390 """## followed by EOF with leading WS"""
391 self.verify(" ##",
394 def test8(self):
395 """## gobble line
396 with text on previous and following lines"""
397 self.verify("line1\n ## aoeu 1234 \nline2",
398 "line1\nline2")
400 def test9(self):
401 """## don't gobble line
402 with text on previous and following lines"""
403 self.verify("line1\n 12 ## aoeu 1234 \nline2",
404 "line1\n 12 \nline2")
406 def test10(self):
407 """## containing $placeholders
409 self.verify("##$a$b $c($d)",
412 def test11(self):
413 """## containing #for directive
415 self.verify("##for $i in range(15)",
419 class Comments_MultiLine_NoGobble(OutputTest):
421 Multiline comments used to not gobble whitespace. They do now, but this can
422 be turned off with a compilerSetting
425 def _getCompilerSettings(self):
426 return {'gobbleWhitespaceAroundMultiLineComments':False}
428 def test1(self):
429 """#* *# followed by WS
430 Shouldn't gobble WS
432 self.verify("#* blarg *# ",
433 " ")
435 def test2(self):
436 """#* *# preceded and followed by WS
437 Shouldn't gobble WS
439 self.verify(" #* blarg *# ",
440 " ")
442 def test3(self):
443 """#* *# followed by WS, with NEWLINE
444 Shouldn't gobble WS
446 self.verify("#* \nblarg\n *# ",
447 " ")
449 def test4(self):
450 """#* *# preceded and followed by WS, with NEWLINE
451 Shouldn't gobble WS
453 self.verify(" #* \nblarg\n *# ",
454 " ")
456 class Comments_MultiLine(OutputTest):
458 Note: Multiline comments don't gobble whitespace!
461 def test1(self):
462 """#* *# followed by WS
463 Should gobble WS
465 self.verify("#* blarg *# ",
468 def test2(self):
469 """#* *# preceded and followed by WS
470 Should gobble WS
472 self.verify(" #* blarg *# ",
475 def test3(self):
476 """#* *# followed by WS, with NEWLINE
477 Shouldn't gobble WS
479 self.verify("#* \nblarg\n *# ",
482 def test4(self):
483 """#* *# preceded and followed by WS, with NEWLINE
484 Shouldn't gobble WS
486 self.verify(" #* \nblarg\n *# ",
489 def test5(self):
490 """#* *# containing nothing
492 self.verify("#**#",
495 def test6(self):
496 """#* *# containing only NEWLINES
498 self.verify(" #*\n\n\n\n\n\n\n\n*# ",
501 def test7(self):
502 """#* *# containing $placeholders
504 self.verify("#* $var $var(1234*$c) *#",
507 def test8(self):
508 """#* *# containing #for directive
510 self.verify("#* #for $i in range(15) *#",
513 def test9(self):
514 """ text around #* *# containing #for directive
516 self.verify("foo\nfoo bar #* #for $i in range(15) *# foo\n",
517 "foo\nfoo bar foo\n")
519 def test9(self):
520 """ text around #* *# containing #for directive and trailing whitespace
521 which should be gobbled
523 self.verify("foo\nfoo bar #* #for $i in range(15) *# \ntest",
524 "foo\nfoo bar \ntest")
526 def test10(self):
527 """ text around #* *# containing #for directive and newlines: trailing whitespace
528 which should be gobbled.
530 self.verify("foo\nfoo bar #* \n\n#for $i in range(15) \n\n*# \ntest",
531 "foo\nfoo bar \ntest")
533 class Placeholders(OutputTest):
534 def test1(self):
535 """1 placeholder"""
536 self.verify("$aStr", "blarg")
538 def test2(self):
539 """2 placeholders"""
540 self.verify("$aStr $anInt", "blarg 1")
542 def test3(self):
543 """2 placeholders, back-to-back"""
544 self.verify("$aStr$anInt", "blarg1")
546 def test4(self):
547 """1 placeholder enclosed in ()"""
548 self.verify("$(aStr)", "blarg")
550 def test5(self):
551 """1 placeholder enclosed in {}"""
552 self.verify("${aStr}", "blarg")
554 def test6(self):
555 """1 placeholder enclosed in []"""
556 self.verify("$[aStr]", "blarg")
558 def test7(self):
559 """1 placeholder enclosed in () + WS
561 Test to make sure that $(<WS><identifier>.. matches
563 self.verify("$( aStr )", "blarg")
565 def test8(self):
566 """1 placeholder enclosed in {} + WS"""
567 self.verify("${ aStr }", "blarg")
569 def test9(self):
570 """1 placeholder enclosed in [] + WS"""
571 self.verify("$[ aStr ]", "blarg")
573 def test10(self):
574 """1 placeholder enclosed in () + WS + * cache
576 Test to make sure that $*(<WS><identifier>.. matches
578 self.verify("$*( aStr )", "blarg")
580 def test11(self):
581 """1 placeholder enclosed in {} + WS + *cache"""
582 self.verify("$*{ aStr }", "blarg")
584 def test12(self):
585 """1 placeholder enclosed in [] + WS + *cache"""
586 self.verify("$*[ aStr ]", "blarg")
588 def test13(self):
589 """1 placeholder enclosed in {} + WS + *<int>*cache"""
590 self.verify("$*5*{ aStr }", "blarg")
592 def test14(self):
593 """1 placeholder enclosed in [] + WS + *<int>*cache"""
594 self.verify("$*5*[ aStr ]", "blarg")
596 def test15(self):
597 """1 placeholder enclosed in {} + WS + *<float>*cache"""
598 self.verify("$*0.5d*{ aStr }", "blarg")
600 def test16(self):
601 """1 placeholder enclosed in [] + WS + *<float>*cache"""
602 self.verify("$*.5*[ aStr ]", "blarg")
604 def test17(self):
605 """1 placeholder + *<int>*cache"""
606 self.verify("$*5*aStr", "blarg")
608 def test18(self):
609 """1 placeholder *<float>*cache"""
610 self.verify("$*0.5h*aStr", "blarg")
612 def test19(self):
613 """1 placeholder surrounded by single quotes and multiple newlines"""
614 self.verify("""'\n\n\n\n'$aStr'\n\n\n\n'""",
615 """'\n\n\n\n'blarg'\n\n\n\n'""")
617 def test20(self):
618 """silent mode $!placeholders """
619 self.verify("$!aStr$!nonExistant$!*nonExistant$!{nonExistant}", "blarg")
621 try:
622 self.verify("$!aStr$nonExistant",
623 "blarg")
624 except NotFound:
625 pass
626 else:
627 self.fail('should raise NotFound exception')
629 def test21(self):
630 """Make sure that $*caching is actually working"""
631 namesStr = 'You Me Them Everyone'
632 names = namesStr.split()
634 tmpl = Template.compile('#for name in $names: $name ', baseclass=dict)
635 assert str(tmpl({'names':names})).strip()==namesStr
637 tmpl = tmpl.subclass('#for name in $names: $*name ')
638 assert str(tmpl({'names':names}))=='You '*len(names)
640 tmpl = tmpl.subclass('#for name in $names: $*1*name ')
641 assert str(tmpl({'names':names}))=='You '*len(names)
643 tmpl = tmpl.subclass('#for name in $names: $*1*(name) ')
644 assert str(tmpl({'names':names}))=='You '*len(names)
646 if versionTuple > (2,2):
647 tmpl = tmpl.subclass('#for name in $names: $*1*(name) ')
648 assert str(tmpl(names=names))=='You '*len(names)
650 class Placeholders_Vals(OutputTest):
651 convertEOLs = False
652 def test1(self):
653 """string"""
654 self.verify("$aStr", "blarg")
656 def test2(self):
657 """string - with whitespace"""
658 self.verify(" $aStr ", " blarg ")
660 def test3(self):
661 """empty string - with whitespace"""
662 self.verify("$emptyString", "")
664 def test4(self):
665 """int"""
666 self.verify("$anInt", "1")
668 def test5(self):
669 """float"""
670 self.verify("$aFloat", "1.5")
672 def test6(self):
673 """list"""
674 self.verify("$aList", "['item0', 'item1', 'item2']")
676 def test7(self):
677 """None
679 The default output filter is ReplaceNone.
681 self.verify("$none", "")
683 def test8(self):
684 """True, False
686 self.verify("$True $False", "%s %s"%(repr(True), repr(False)))
688 def test9(self):
689 """$_
691 self.verify("$_('foo')", "Translated: foo")
693 class PlaceholderStrings(OutputTest):
694 def test1(self):
695 """some c'text $placeholder text' strings"""
696 self.verify("$str(c'$aStr')", "blarg")
698 def test2(self):
699 """some c'text $placeholder text' strings"""
700 self.verify("$str(c'$aStr.upper')", "BLARG")
702 def test3(self):
703 """some c'text $placeholder text' strings"""
704 self.verify("$str(c'$(aStr.upper.replace(c\"A$str()\",\"\"))')", "BLRG")
706 def test4(self):
707 """some c'text $placeholder text' strings"""
708 self.verify("#echo $str(c'$(aStr.upper)')", "BLARG")
710 def test5(self):
711 """some c'text $placeholder text' strings"""
712 self.verify("#if 1 then $str(c'$(aStr.upper)') else 0", "BLARG")
714 def test6(self):
715 """some c'text $placeholder text' strings"""
716 self.verify("#if 1\n$str(c'$(aStr.upper)')#slurp\n#else\n0#end if", "BLARG")
718 def test7(self):
719 """some c'text $placeholder text' strings"""
720 self.verify("#def foo(arg=c'$(\"BLARG\")')\n"
721 "$arg#slurp\n"
722 "#end def\n"
723 "$foo()$foo(c'$anInt')#slurp",
725 "BLARG1")
729 class UnicodeStrings(OutputTest):
730 def test1(self):
731 """unicode data in placeholder
733 #self.verify(u"$unicodeData", defaultTestNameSpace['unicodeData'], outputEncoding='utf8')
734 self.verify(u"$unicodeData", defaultTestNameSpace['unicodeData'])
736 def test2(self):
737 """unicode data in body
739 self.verify(u"aoeu12345\u1234", u"aoeu12345\u1234")
740 #self.verify(u"#encoding utf8#aoeu12345\u1234", u"aoeu12345\u1234")
742 class EncodingDirective(OutputTest):
743 def test1(self):
744 """basic #encoding """
745 self.verify("#encoding utf-8\n1234",
746 "1234")
748 def test2(self):
749 """basic #encoding """
750 self.verify("#encoding ascii\n1234",
751 "1234")
753 def test3(self):
754 """basic #encoding """
755 self.verify("#encoding utf-8\n\xe1\x88\xb4",
756 u'\u1234', outputEncoding='utf8')
758 def test4(self):
759 """basic #encoding """
760 self.verify("#encoding ascii\n\xe1\x88\xb4",
761 "\xe1\x88\xb4")
763 def test5(self):
764 """basic #encoding """
765 self.verify("#encoding latin-1\nAndr\202",
766 u'Andr\202', outputEncoding='latin-1')
768 class UnicodeDirective(OutputTest):
769 def test1(self):
770 """basic #unicode """
771 self.verify("#unicode utf-8\n1234",
772 u"1234")
774 self.verify("#unicode ascii\n1234",
775 u"1234")
777 self.verify("#unicode latin-1\n1234",
778 u"1234")
780 self.verify("#unicode latin-1\n1234ü",
781 u"1234ü")
782 self.verify("#unicode: latin-1\n1234ü",
783 u"1234ü")
784 self.verify("# unicode : latin-1\n1234ü",
785 u"1234ü")
787 self.verify(u"#unicode latin-1\n1234ü",
788 u"1234ü")
790 self.verify("#encoding latin-1\n1234ü",
791 "1234ü")
793 class Placeholders_Esc(OutputTest):
794 convertEOLs = False
795 def test1(self):
796 """1 escaped placeholder"""
797 self.verify("\$var",
798 "$var")
800 def test2(self):
801 """2 escaped placeholders"""
802 self.verify("\$var \$_",
803 "$var $_")
805 def test3(self):
806 """2 escaped placeholders - back to back"""
807 self.verify("\$var\$_",
808 "$var$_")
810 def test4(self):
811 """2 escaped placeholders - nested"""
812 self.verify("\$var(\$_)",
813 "$var($_)")
815 def test5(self):
816 """2 escaped placeholders - nested and enclosed"""
817 self.verify("\$(var(\$_)",
818 "$(var($_)")
821 class Placeholders_Calls(OutputTest):
822 def test1(self):
823 """func placeholder - no ()"""
824 self.verify("$aFunc",
825 "Scooby")
827 def test2(self):
828 """func placeholder - with ()"""
829 self.verify("$aFunc()",
830 "Scooby")
832 def test3(self):
833 r"""func placeholder - with (\n\n)"""
834 self.verify("$aFunc(\n\n)",
835 "Scooby", convertEOLs=False)
837 def test4(self):
838 r"""func placeholder - with (\n\n) and $() enclosure"""
839 self.verify("$(aFunc(\n\n))",
840 "Scooby", convertEOLs=False)
842 def test5(self):
843 r"""func placeholder - with (\n\n) and ${} enclosure"""
844 self.verify("${aFunc(\n\n)}",
845 "Scooby", convertEOLs=False)
847 def test6(self):
848 """func placeholder - with (int)"""
849 self.verify("$aFunc(1234)",
850 "1234")
852 def test7(self):
853 r"""func placeholder - with (\nint\n)"""
854 self.verify("$aFunc(\n1234\n)",
855 "1234", convertEOLs=False)
856 def test8(self):
857 """func placeholder - with (string)"""
858 self.verify("$aFunc('aoeu')",
859 "aoeu")
861 def test9(self):
862 """func placeholder - with ('''string''')"""
863 self.verify("$aFunc('''aoeu''')",
864 "aoeu")
865 def test10(self):
866 r"""func placeholder - with ('''\nstring\n''')"""
867 self.verify("$aFunc('''\naoeu\n''')",
868 "\naoeu\n")
870 def test11(self):
871 r"""func placeholder - with ('''\nstring'\n''')"""
872 self.verify("$aFunc('''\naoeu'\n''')",
873 "\naoeu'\n")
875 def test12(self):
876 r'''func placeholder - with ("""\nstring\n""")'''
877 self.verify('$aFunc("""\naoeu\n""")',
878 "\naoeu\n")
880 def test13(self):
881 """func placeholder - with (string*int)"""
882 self.verify("$aFunc('aoeu'*2)",
883 "aoeuaoeu")
885 def test14(self):
886 """func placeholder - with (int*int)"""
887 self.verify("$aFunc(2*2)",
888 "4")
890 def test15(self):
891 """func placeholder - with (int*float)"""
892 self.verify("$aFunc(2*2.0)",
893 "4.0")
895 def test16(self):
896 r"""func placeholder - with (int\n*\nfloat)"""
897 self.verify("$aFunc(2\n*\n2.0)",
898 "4.0", convertEOLs=False)
900 def test17(self):
901 """func placeholder - with ($arg=float)"""
902 self.verify("$aFunc($arg=4.0)",
903 "4.0")
905 def test18(self):
906 """func placeholder - with (arg=float)"""
907 self.verify("$aFunc(arg=4.0)",
908 "4.0")
910 def test19(self):
911 """deeply nested argstring, no enclosure"""
912 self.verify("$aFunc($arg=$aMeth($arg=$aFunc(1)))",
913 "1")
915 def test20(self):
916 """deeply nested argstring, no enclosure + with WS"""
917 self.verify("$aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) )",
918 "1")
919 def test21(self):
920 """deeply nested argstring, () enclosure + with WS"""
921 self.verify("$(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
922 "1")
924 def test22(self):
925 """deeply nested argstring, {} enclosure + with WS"""
926 self.verify("${aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) }",
927 "1")
929 def test23(self):
930 """deeply nested argstring, [] enclosure + with WS"""
931 self.verify("$[aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) ]",
932 "1")
934 def test24(self):
935 """deeply nested argstring, () enclosure + *cache"""
936 self.verify("$*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
937 "1")
938 def test25(self):
939 """deeply nested argstring, () enclosure + *15*cache"""
940 self.verify("$*15*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
941 "1")
943 def test26(self):
944 """a function call with the Python None kw."""
945 self.verify("$aFunc(None)",
948 class NameMapper(OutputTest):
949 def test1(self):
950 """autocalling"""
951 self.verify("$aFunc! $aFunc().",
952 "Scooby! Scooby.")
954 def test2(self):
955 """nested autocalling"""
956 self.verify("$aFunc($aFunc).",
957 "Scooby.")
959 def test3(self):
960 """list subscription"""
961 self.verify("$aList[0]",
962 "item0")
964 def test4(self):
965 """list slicing"""
966 self.verify("$aList[:2]",
967 "['item0', 'item1']")
969 def test5(self):
970 """list slicing and subcription combined"""
971 self.verify("$aList[:2][0]",
972 "item0")
974 def test6(self):
975 """dictionary access - NameMapper style"""
976 self.verify("$aDict.one",
977 "item1")
979 def test7(self):
980 """dictionary access - Python style"""
981 self.verify("$aDict['one']",
982 "item1")
984 def test8(self):
985 """dictionary access combined with autocalled string method"""
986 self.verify("$aDict.one.upper",
987 "ITEM1")
989 def test9(self):
990 """dictionary access combined with string method"""
991 self.verify("$aDict.one.upper()",
992 "ITEM1")
994 def test10(self):
995 """nested dictionary access - NameMapper style"""
996 self.verify("$aDict.nestedDict.two",
997 "nestedItem2")
999 def test11(self):
1000 """nested dictionary access - Python style"""
1001 self.verify("$aDict['nestedDict']['two']",
1002 "nestedItem2")
1004 def test12(self):
1005 """nested dictionary access - alternating style"""
1006 self.verify("$aDict['nestedDict'].two",
1007 "nestedItem2")
1009 def test13(self):
1010 """nested dictionary access using method - alternating style"""
1011 self.verify("$aDict.get('nestedDict').two",
1012 "nestedItem2")
1014 def test14(self):
1015 """nested dictionary access - NameMapper style - followed by method"""
1016 self.verify("$aDict.nestedDict.two.upper",
1017 "NESTEDITEM2")
1019 def test15(self):
1020 """nested dictionary access - alternating style - followed by method"""
1021 self.verify("$aDict['nestedDict'].two.upper",
1022 "NESTEDITEM2")
1024 def test16(self):
1025 """nested dictionary access - NameMapper style - followed by method, then slice"""
1026 self.verify("$aDict.nestedDict.two.upper[:4]",
1027 "NEST")
1029 def test17(self):
1030 """nested dictionary access - Python style using a soft-coded key"""
1031 self.verify("$aDict[$anObj.meth('nestedDict')].two",
1032 "nestedItem2")
1034 def test18(self):
1035 """object method access"""
1036 self.verify("$anObj.meth1",
1037 "doo")
1039 def test19(self):
1040 """object method access, followed by complex slice"""
1041 self.verify("$anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ]",
1042 "do")
1044 def test20(self):
1045 """object method access, followed by a very complex slice
1046 If it can pass this one, it's safe to say it works!!"""
1047 self.verify("$( anObj.meth1[0:\n (\n(4/4*2)*2)/$anObj.meth1(2)\n ] )",
1048 "do")
1050 def test21(self):
1051 """object method access with % in the default arg for the meth.
1053 This tests a bug that Jeff Johnson found and submitted a patch to SF
1054 for."""
1056 self.verify("$anObj.methWithPercentSignDefaultArg",
1057 "110%")
1060 #class NameMapperDict(OutputTest):
1062 # _searchList = [{"update": "Yabba dabba doo!"}]
1064 # def test1(self):
1065 # if NameMapper_C_VERSION:
1066 # return # This feature is not in the C version yet.
1067 # self.verify("$update", "Yabba dabba doo!")
1070 class CacheDirective(OutputTest):
1072 def test1(self):
1073 r"""simple #cache """
1074 self.verify("#cache:$anInt",
1075 "1")
1077 def test2(self):
1078 r"""simple #cache + WS"""
1079 self.verify(" #cache \n$anInt#end cache",
1080 "1")
1082 def test3(self):
1083 r"""simple #cache ... #end cache"""
1084 self.verify("""#cache id='cache1', timer=150m
1085 $anInt
1086 #end cache
1087 $aStr""",
1088 "1\nblarg")
1090 def test4(self):
1091 r"""2 #cache ... #end cache blocks"""
1092 self.verify("""#slurp
1093 #def foo
1094 #cache ID='cache1', timer=150m
1095 $anInt
1096 #end cache
1097 #cache id='cache2', timer=15s
1098 #for $i in range(5)
1099 $i#slurp
1100 #end for
1101 #end cache
1102 $aStr#slurp
1103 #end def
1104 $foo$foo$foo$foo$foo""",
1105 "1\n01234blarg"*5)
1108 def test5(self):
1109 r"""nested #cache blocks"""
1110 self.verify("""#slurp
1111 #def foo
1112 #cache ID='cache1', timer=150m
1113 $anInt
1114 #cache id='cache2', timer=15s
1115 #for $i in range(5)
1116 $i#slurp
1117 #end for
1118 $*(6)#slurp
1119 #end cache
1120 #end cache
1121 $aStr#slurp
1122 #end def
1123 $foo$foo$foo$foo$foo""",
1124 "1\n012346blarg"*5)
1126 def test6(self):
1127 r"""Make sure that partial directives don't match"""
1128 self.verify("#cache_foo",
1129 "#cache_foo")
1130 self.verify("#cached",
1131 "#cached")
1133 class CallDirective(OutputTest):
1135 def test1(self):
1136 r"""simple #call """
1137 self.verify("#call int\n$anInt#end call",
1138 "1")
1139 # single line version
1140 self.verify("#call int: $anInt",
1141 "1")
1142 self.verify("#call int: 10\n$aStr",
1143 "10\nblarg")
1145 def test2(self):
1146 r"""simple #call + WS"""
1147 self.verify("#call int\n$anInt #end call",
1148 "1")
1150 def test3(self):
1151 r"""a longer #call"""
1152 self.verify('''\
1153 #def meth(arg)
1154 $arg.upper()#slurp
1155 #end def
1156 #call $meth
1157 $(1234+1) foo#slurp
1158 #end call''',
1159 "1235 FOO")
1161 def test4(self):
1162 r"""#call with keyword #args"""
1163 self.verify('''\
1164 #def meth(arg1, arg2)
1165 $arg1.upper() - $arg2.lower()#slurp
1166 #end def
1167 #call self.meth
1168 #arg arg1
1169 $(1234+1) foo#slurp
1170 #arg arg2
1171 UPPER#slurp
1172 #end call''',
1173 "1235 FOO - upper")
1175 def test5(self):
1176 r"""#call with single-line keyword #args """
1177 self.verify('''\
1178 #def meth(arg1, arg2)
1179 $arg1.upper() - $arg2.lower()#slurp
1180 #end def
1181 #call self.meth
1182 #arg arg1:$(1234+1) foo#slurp
1183 #arg arg2:UPPER#slurp
1184 #end call''',
1185 "1235 FOO - upper")
1187 def test6(self):
1188 """#call with python kwargs and cheetah output for the 1s positional
1189 arg"""
1191 self.verify('''\
1192 #def meth(arg1, arg2)
1193 $arg1.upper() - $arg2.lower()#slurp
1194 #end def
1195 #call self.meth arg2="UPPER"
1196 $(1234+1) foo#slurp
1197 #end call''',
1198 "1235 FOO - upper")
1200 def test7(self):
1201 """#call with python kwargs and #args"""
1202 self.verify('''\
1203 #def meth(arg1, arg2, arg3)
1204 $arg1.upper() - $arg2.lower() - $arg3#slurp
1205 #end def
1206 #call self.meth arg2="UPPER", arg3=999
1207 #arg arg1:$(1234+1) foo#slurp
1208 #end call''',
1209 "1235 FOO - upper - 999")
1211 def test8(self):
1212 """#call with python kwargs and #args, and using a function to get the
1213 function that will be called"""
1214 self.verify('''\
1215 #def meth(arg1, arg2, arg3)
1216 $arg1.upper() - $arg2.lower() - $arg3#slurp
1217 #end def
1218 #call getattr(self, "meth") arg2="UPPER", arg3=999
1219 #arg arg1:$(1234+1) foo#slurp
1220 #end call''',
1221 "1235 FOO - upper - 999")
1223 def test9(self):
1224 """nested #call directives"""
1225 self.verify('''\
1226 #def meth(arg1)
1227 $arg1#slurp
1228 #end def
1229 #def meth2(x,y)
1230 $x$y#slurp
1231 #end def
1233 #call self.meth
1234 1#slurp
1235 #call self.meth
1236 2#slurp
1237 #call self.meth
1238 3#slurp
1239 #end call 3
1240 #set two = 2
1241 #call self.meth2 y=c"$(10/$two)"
1242 #arg x
1243 4#slurp
1244 #end call 4
1245 #end call 2
1246 #end call 1''',
1247 "12345")
1251 class I18nDirective(OutputTest):
1252 def test1(self):
1253 r"""simple #call """
1254 self.verify("#i18n \n$anInt#end i18n",
1255 "1")
1257 # single line version
1258 self.verify("#i18n: $anInt",
1259 "1")
1260 self.verify("#i18n: 10\n$aStr",
1261 "10\nblarg")
1264 class CaptureDirective(OutputTest):
1265 def test1(self):
1266 r"""simple #capture"""
1267 self.verify('''\
1268 #capture cap1
1269 $(1234+1) foo#slurp
1270 #end capture
1271 $cap1#slurp
1272 ''',
1273 "1235 foo")
1276 def test2(self):
1277 r"""slightly more complex #capture"""
1278 self.verify('''\
1279 #def meth(arg)
1280 $arg.upper()#slurp
1281 #end def
1282 #capture cap1
1283 $(1234+1) $anInt $meth("foo")#slurp
1284 #end capture
1285 $cap1#slurp
1286 ''',
1287 "1235 1 FOO")
1290 class SlurpDirective(OutputTest):
1291 def test1(self):
1292 r"""#slurp with 1 \n """
1293 self.verify("#slurp\n",
1296 def test2(self):
1297 r"""#slurp with 1 \n, leading whitespace
1298 Should gobble"""
1299 self.verify(" #slurp\n",
1302 def test3(self):
1303 r"""#slurp with 1 \n, leading content
1304 Shouldn't gobble"""
1305 self.verify(" 1234 #slurp\n",
1306 " 1234 ")
1308 def test4(self):
1309 r"""#slurp with WS then \n, leading content
1310 Shouldn't gobble"""
1311 self.verify(" 1234 #slurp \n",
1312 " 1234 ")
1314 def test5(self):
1315 r"""#slurp with garbage chars then \n, leading content
1316 Should eat the garbage"""
1317 self.verify(" 1234 #slurp garbage \n",
1318 " 1234 ")
1322 class EOLSlurpToken(OutputTest):
1323 _EOLSlurpToken = DEFAULT_COMPILER_SETTINGS['EOLSlurpToken']
1324 def test1(self):
1325 r"""#slurp with 1 \n """
1326 self.verify("%s\n"%self._EOLSlurpToken,
1329 def test2(self):
1330 r"""#slurp with 1 \n, leading whitespace
1331 Should gobble"""
1332 self.verify(" %s\n"%self._EOLSlurpToken,
1334 def test3(self):
1335 r"""#slurp with 1 \n, leading content
1336 Shouldn't gobble"""
1337 self.verify(" 1234 %s\n"%self._EOLSlurpToken,
1338 " 1234 ")
1340 def test4(self):
1341 r"""#slurp with WS then \n, leading content
1342 Shouldn't gobble"""
1343 self.verify(" 1234 %s \n"%self._EOLSlurpToken,
1344 " 1234 ")
1346 def test5(self):
1347 r"""#slurp with garbage chars then \n, leading content
1348 Should NOT eat the garbage"""
1349 self.verify(" 1234 %s garbage \n"%self._EOLSlurpToken,
1350 " 1234 %s garbage \n"%self._EOLSlurpToken)
1352 if not DEFAULT_COMPILER_SETTINGS['EOLSlurpToken']:
1353 del EOLSlurpToken
1355 class RawDirective(OutputTest):
1356 def test1(self):
1357 """#raw till EOF"""
1358 self.verify("#raw\n$aFunc().\n\n",
1359 "$aFunc().\n\n")
1361 def test2(self):
1362 """#raw till #end raw"""
1363 self.verify("#raw\n$aFunc().\n#end raw\n$anInt",
1364 "$aFunc().\n1")
1366 def test3(self):
1367 """#raw till #end raw gobble WS"""
1368 self.verify(" #raw \n$aFunc().\n #end raw \n$anInt",
1369 "$aFunc().\n1")
1371 def test4(self):
1372 """#raw till #end raw using explicit directive closure
1373 Shouldn't gobble"""
1374 self.verify(" #raw #\n$aFunc().\n #end raw #\n$anInt",
1375 " \n$aFunc().\n\n1")
1377 def test5(self):
1378 """single-line short form #raw: """
1379 self.verify("#raw: $aFunc().\n\n",
1380 "$aFunc().\n\n")
1382 self.verify("#raw: $aFunc().\n$anInt",
1383 "$aFunc().\n1")
1385 class BreakpointDirective(OutputTest):
1386 def test1(self):
1387 """#breakpoint part way through source code"""
1388 self.verify("$aFunc(2).\n#breakpoint\n$anInt",
1389 "2.\n")
1391 def test2(self):
1392 """#breakpoint at BOF"""
1393 self.verify("#breakpoint\n$anInt",
1396 def test3(self):
1397 """#breakpoint at EOF"""
1398 self.verify("$anInt\n#breakpoint",
1399 "1\n")
1402 class StopDirective(OutputTest):
1403 def test1(self):
1404 """#stop part way through source code"""
1405 self.verify("$aFunc(2).\n#stop\n$anInt",
1406 "2.\n")
1408 def test2(self):
1409 """#stop at BOF"""
1410 self.verify("#stop\n$anInt",
1413 def test3(self):
1414 """#stop at EOF"""
1415 self.verify("$anInt\n#stop",
1416 "1\n")
1418 def test4(self):
1419 """#stop in pos test block"""
1420 self.verify("""$anInt
1421 #if 1
1422 inside the if block
1423 #stop
1424 #end if
1425 blarg""",
1426 "1\ninside the if block\n")
1428 def test5(self):
1429 """#stop in neg test block"""
1430 self.verify("""$anInt
1431 #if 0
1432 inside the if block
1433 #stop
1434 #end if
1435 blarg""",
1436 "1\nblarg")
1439 class ReturnDirective(OutputTest):
1441 def test1(self):
1442 """#return'ing an int """
1443 self.verify("""1
1444 $str($test-6)
1446 #def test
1447 #if 1
1448 #return (3 *2) \
1449 + 2
1450 #else
1451 aoeuoaeu
1452 #end if
1453 #end def
1454 """,
1455 "1\n2\n3\n")
1457 def test2(self):
1458 """#return'ing an string """
1459 self.verify("""1
1460 $str($test[1])
1462 #def test
1463 #if 1
1464 #return '123'
1465 #else
1466 aoeuoaeu
1467 #end if
1468 #end def
1469 """,
1470 "1\n2\n3\n")
1472 def test3(self):
1473 """#return'ing an string AND streaming other output via the transaction"""
1474 self.verify("""1
1475 $str($test(trans=trans)[1])
1477 #def test
1479 #if 1
1480 #return '123'
1481 #else
1482 aoeuoaeu
1483 #end if
1484 #end def
1485 """,
1486 "1\n1.5\n2\n3\n")
1489 class YieldDirective(OutputTest):
1490 convertEOLs = False
1491 def test1(self):
1492 """simple #yield """
1494 src1 = """#for i in range(10)\n#yield i\n#end for"""
1495 src2 = """#for i in range(10)\n$i#slurp\n#yield\n#end for"""
1496 src3 = ("#def iterator\n"
1497 "#for i in range(10)\n#yield i\n#end for\n"
1498 "#end def\n"
1499 "#for i in $iterator\n$i#end for"
1503 for src in (src1,src2,src3):
1504 klass = Template.compile(src, keepRefToGeneratedCode=True)
1505 #print klass._CHEETAH_generatedModuleCode
1506 iter = klass().respond()
1507 output = [str(i) for i in iter]
1508 assert ''.join(output)=='0123456789'
1509 #print ''.join(output)
1511 # @@TR: need to expand this to cover error conditions etc.
1513 if versionTuple < (2,3):
1514 del YieldDirective
1516 class ForDirective(OutputTest):
1518 def test1(self):
1519 """#for loop with one local var"""
1520 self.verify("#for $i in range(5)\n$i\n#end for",
1521 "0\n1\n2\n3\n4\n")
1523 self.verify("#for $i in range(5):\n$i\n#end for",
1524 "0\n1\n2\n3\n4\n")
1526 self.verify("#for $i in range(5): ##comment\n$i\n#end for",
1527 "0\n1\n2\n3\n4\n")
1529 self.verify("#for $i in range(5) ##comment\n$i\n#end for",
1530 "0\n1\n2\n3\n4\n")
1533 def test2(self):
1534 """#for loop with WS in loop"""
1535 self.verify("#for $i in range(5)\n$i \n#end for",
1536 "0 \n1 \n2 \n3 \n4 \n")
1538 def test3(self):
1539 """#for loop gobble WS"""
1540 self.verify(" #for $i in range(5) \n$i \n #end for ",
1541 "0 \n1 \n2 \n3 \n4 \n")
1543 def test4(self):
1544 """#for loop over list"""
1545 self.verify("#for $i, $j in [(0,1),(2,3)]\n$i,$j\n#end for",
1546 "0,1\n2,3\n")
1548 def test5(self):
1549 """#for loop over list, with #slurp"""
1550 self.verify("#for $i, $j in [(0,1),(2,3)]\n$i,$j#slurp\n#end for",
1551 "0,12,3")
1553 def test6(self):
1554 """#for loop with explicit closures"""
1555 self.verify("#for $i in range(5)#$i#end for#",
1556 "01234")
1558 def test7(self):
1559 """#for loop with explicit closures and WS"""
1560 self.verify(" #for $i in range(5)#$i#end for# ",
1561 " 01234 ")
1563 def test8(self):
1564 """#for loop using another $var"""
1565 self.verify(" #for $i in range($aFunc(5))#$i#end for# ",
1566 " 01234 ")
1568 def test9(self):
1569 """test methods in for loops"""
1570 self.verify("#for $func in $listOfLambdas\n$func($anInt)\n#end for",
1571 "1\n1\n1\n")
1574 def test10(self):
1575 """#for loop over list, using methods of the items"""
1576 self.verify("#for i, j in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1577 "AA,BB\nCC,DD\n")
1578 self.verify("#for $i, $j in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1579 "AA,BB\nCC,DD\n")
1581 def test11(self):
1582 """#for loop over list, using ($i,$j) style target list"""
1583 self.verify("#for (i, j) in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1584 "AA,BB\nCC,DD\n")
1585 self.verify("#for ($i, $j) in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
1586 "AA,BB\nCC,DD\n")
1588 def test12(self):
1589 """#for loop over list, using i, (j,k) style target list"""
1590 self.verify("#for i, (j, k) in enumerate([('aa','bb'),('cc','dd')])\n$j.upper,$k.upper\n#end for",
1591 "AA,BB\nCC,DD\n")
1592 self.verify("#for $i, ($j, $k) in enumerate([('aa','bb'),('cc','dd')])\n$j.upper,$k.upper\n#end for",
1593 "AA,BB\nCC,DD\n")
1595 def test13(self):
1596 """single line #for"""
1597 self.verify("#for $i in range($aFunc(5)): $i",
1598 "01234")
1600 def test14(self):
1601 """single line #for with 1 extra leading space"""
1602 self.verify("#for $i in range($aFunc(5)): $i",
1603 " 0 1 2 3 4")
1605 def test15(self):
1606 """2 times single line #for"""
1607 self.verify("#for $i in range($aFunc(5)): $i#slurp\n"*2,
1608 "01234"*2)
1610 def test16(self):
1611 """false single line #for """
1612 self.verify("#for $i in range(5): \n$i\n#end for",
1613 "0\n1\n2\n3\n4\n")
1615 if versionTuple < (2,3):
1616 del ForDirective.test12
1618 class RepeatDirective(OutputTest):
1620 def test1(self):
1621 """basic #repeat"""
1622 self.verify("#repeat 3\n1\n#end repeat",
1623 "1\n1\n1\n")
1624 self.verify("#repeat 3: \n1\n#end repeat",
1625 "1\n1\n1\n")
1627 self.verify("#repeat 3 ##comment\n1\n#end repeat",
1628 "1\n1\n1\n")
1630 self.verify("#repeat 3: ##comment\n1\n#end repeat",
1631 "1\n1\n1\n")
1633 def test2(self):
1634 """#repeat with numeric expression"""
1635 self.verify("#repeat 3*3/3\n1\n#end repeat",
1636 "1\n1\n1\n")
1638 def test3(self):
1639 """#repeat with placeholder"""
1640 self.verify("#repeat $numTwo\n1\n#end repeat",
1641 "1\n1\n")
1643 def test4(self):
1644 """#repeat with placeholder * num"""
1645 self.verify("#repeat $numTwo*1\n1\n#end repeat",
1646 "1\n1\n")
1648 def test5(self):
1649 """#repeat with placeholder and WS"""
1650 self.verify(" #repeat $numTwo \n1\n #end repeat ",
1651 "1\n1\n")
1653 def test6(self):
1654 """single-line #repeat"""
1655 self.verify("#repeat $numTwo: 1",
1656 "11")
1657 self.verify("#repeat $numTwo: 1\n"*2,
1658 "1\n1\n"*2)
1660 #false single-line
1661 self.verify("#repeat 3: \n1\n#end repeat",
1662 "1\n1\n1\n")
1665 class AttrDirective(OutputTest):
1667 def test1(self):
1668 """#attr with int"""
1669 self.verify("#attr $test = 1234\n$test",
1670 "1234")
1672 def test2(self):
1673 """#attr with string"""
1674 self.verify("#attr $test = 'blarg'\n$test",
1675 "blarg")
1677 def test3(self):
1678 """#attr with expression"""
1679 self.verify("#attr $test = 'blarg'.upper()*2\n$test",
1680 "BLARGBLARG")
1682 def test4(self):
1683 """#attr with string + WS
1684 Should gobble"""
1685 self.verify(" #attr $test = 'blarg' \n$test",
1686 "blarg")
1688 def test5(self):
1689 """#attr with string + WS + leading text
1690 Shouldn't gobble"""
1691 self.verify(" -- #attr $test = 'blarg' \n$test",
1692 " -- \nblarg")
1695 class DefDirective(OutputTest):
1697 def test1(self):
1698 """#def without argstring"""
1699 self.verify("#def testMeth\n1234\n#end def\n$testMeth",
1700 "1234\n")
1702 self.verify("#def testMeth ## comment\n1234\n#end def\n$testMeth",
1703 "1234\n")
1705 self.verify("#def testMeth: ## comment\n1234\n#end def\n$testMeth",
1706 "1234\n")
1708 def test2(self):
1709 """#def without argstring, gobble WS"""
1710 self.verify(" #def testMeth \n1234\n #end def \n$testMeth",
1711 "1234\n")
1713 def test3(self):
1714 """#def with argstring, gobble WS"""
1715 self.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth",
1716 "1234-999\n")
1718 def test4(self):
1719 """#def with argstring, gobble WS, string used in call"""
1720 self.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth('ABC')",
1721 "1234-ABC\n")
1723 def test5(self):
1724 """#def with argstring, gobble WS, list used in call"""
1725 self.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth([1,2,3])",
1726 "1234-[1, 2, 3]\n")
1728 def test6(self):
1729 """#def with 2 args, gobble WS, list used in call"""
1730 self.verify(" #def testMeth($a, $b='default') \n1234-$a$b\n #end def\n$testMeth([1,2,3])",
1731 "1234-[1, 2, 3]default\n")
1733 def test7(self):
1734 """#def with *args, gobble WS"""
1735 self.verify(" #def testMeth($*args) \n1234-$args\n #end def\n$testMeth",
1736 "1234-()\n")
1738 def test8(self):
1739 """#def with **KWs, gobble WS"""
1740 self.verify(" #def testMeth($**KWs) \n1234-$KWs\n #end def\n$testMeth",
1741 "1234-{}\n")
1743 def test9(self):
1744 """#def with *args + **KWs, gobble WS"""
1745 self.verify(" #def testMeth($*args, $**KWs) \n1234-$args-$KWs\n #end def\n$testMeth",
1746 "1234-()-{}\n")
1748 def test10(self):
1749 """#def with *args + **KWs, gobble WS"""
1750 self.verify(
1751 " #def testMeth($*args, $**KWs) \n1234-$args-$KWs.a\n #end def\n$testMeth(1,2, a=1)",
1752 "1234-(1, 2)-1\n")
1755 def test11(self):
1756 """single line #def with extra WS"""
1757 self.verify(
1758 "#def testMeth: aoeuaoeu\n- $testMeth -",
1759 "- aoeuaoeu -")
1761 def test12(self):
1762 """single line #def with extra WS and nested $placeholders"""
1763 self.verify(
1764 "#def testMeth: $anInt $aFunc(1234)\n- $testMeth -",
1765 "- 1 1234 -")
1767 def test13(self):
1768 """single line #def escaped $placeholders"""
1769 self.verify(
1770 "#def testMeth: \$aFunc(\$anInt)\n- $testMeth -",
1771 "- $aFunc($anInt) -")
1773 def test14(self):
1774 """single line #def 1 escaped $placeholders"""
1775 self.verify(
1776 "#def testMeth: \$aFunc($anInt)\n- $testMeth -",
1777 "- $aFunc(1) -")
1779 def test15(self):
1780 """single line #def 1 escaped $placeholders + more WS"""
1781 self.verify(
1782 "#def testMeth : \$aFunc($anInt)\n- $testMeth -",
1783 "- $aFunc(1) -")
1785 def test16(self):
1786 """multiline #def with $ on methodName"""
1787 self.verify("#def $testMeth\n1234\n#end def\n$testMeth",
1788 "1234\n")
1790 def test17(self):
1791 """single line #def with $ on methodName"""
1792 self.verify("#def $testMeth:1234\n$testMeth",
1793 "1234")
1795 def test18(self):
1796 """single line #def with an argument"""
1797 self.verify("#def $testMeth($arg=1234):$arg\n$testMeth",
1798 "1234")
1801 class DecoratorDirective(OutputTest):
1802 def test1(self):
1803 """single line #def with decorator"""
1805 self.verify("#@ blah", "#@ blah")
1806 self.verify("#@23 blah", "#@23 blah")
1807 self.verify("#@@TR: comment", "#@@TR: comment")
1809 self.verify("#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1810 +"#@testdecorator"
1811 +"\n#def $testMeth():1234\n$testMeth",
1813 "1234")
1815 self.verify("#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1816 +"#@testdecorator"
1817 +"\n#block $testMeth():1234",
1819 "1234")
1821 try:
1822 self.verify(
1823 "#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1824 +"#@testdecorator\n sdf"
1825 +"\n#def $testMeth():1234\n$testMeth",
1827 "1234")
1828 except ParseError:
1829 pass
1830 else:
1831 self.fail('should raise a ParseError')
1833 if versionTuple < (2,4):
1834 del DecoratorDirective
1836 class BlockDirective(OutputTest):
1838 def test1(self):
1839 """#block without argstring"""
1840 self.verify("#block testBlock\n1234\n#end block",
1841 "1234\n")
1843 self.verify("#block testBlock ##comment\n1234\n#end block",
1844 "1234\n")
1846 def test2(self):
1847 """#block without argstring, gobble WS"""
1848 self.verify(" #block testBlock \n1234\n #end block ",
1849 "1234\n")
1851 def test3(self):
1852 """#block with argstring, gobble WS
1854 Because blocks can be reused in multiple parts of the template arguments
1855 (!!with defaults!!) can be given."""
1857 self.verify(" #block testBlock($a=999) \n1234-$a\n #end block ",
1858 "1234-999\n")
1860 def test4(self):
1861 """#block with 2 args, gobble WS"""
1862 self.verify(" #block testBlock($a=999, $b=444) \n1234-$a$b\n #end block ",
1863 "1234-999444\n")
1866 def test5(self):
1867 """#block with 2 nested blocks
1869 Blocks can be nested to any depth and the name of the block is optional
1870 for the #end block part: #end block OR #end block [name] """
1872 self.verify("""#block testBlock
1873 this is a test block
1874 #block outerNest
1875 outer
1876 #block innerNest
1877 inner
1878 #end block innerNest
1879 #end block outerNest
1881 #end block testBlock
1882 """,
1883 "this is a test block\nouter\ninner\n---\n")
1886 def test6(self):
1887 """single line #block """
1888 self.verify(
1889 "#block testMeth: This is my block",
1890 "This is my block")
1892 def test7(self):
1893 """single line #block with WS"""
1894 self.verify(
1895 "#block testMeth: This is my block",
1896 "This is my block")
1898 def test8(self):
1899 """single line #block 1 escaped $placeholders"""
1900 self.verify(
1901 "#block testMeth: \$aFunc($anInt)",
1902 "$aFunc(1)")
1904 def test9(self):
1905 """single line #block 1 escaped $placeholders + WS"""
1906 self.verify(
1907 "#block testMeth: \$aFunc( $anInt )",
1908 "$aFunc( 1 )")
1910 def test10(self):
1911 """single line #block 1 escaped $placeholders + more WS"""
1912 self.verify(
1913 "#block testMeth : \$aFunc( $anInt )",
1914 "$aFunc( 1 )")
1916 def test11(self):
1917 """multiline #block $ on argstring"""
1918 self.verify("#block $testBlock\n1234\n#end block",
1919 "1234\n")
1921 def test12(self):
1922 """single line #block with $ on methodName """
1923 self.verify(
1924 "#block $testMeth: This is my block",
1925 "This is my block")
1927 def test13(self):
1928 """single line #block with an arg """
1929 self.verify(
1930 "#block $testMeth($arg='This is my block'): $arg",
1931 "This is my block")
1933 def test14(self):
1934 """single line #block with None for content"""
1935 self.verify(
1936 """#block $testMeth: $None\ntest $testMeth-""",
1937 "test -")
1939 def test15(self):
1940 """single line #block with nothing for content"""
1941 self.verify(
1942 """#block $testMeth: \nfoo\n#end block\ntest $testMeth-""",
1943 "foo\ntest foo\n-")
1945 class IncludeDirective(OutputTest):
1947 def setUp(self):
1948 fp = open('parseTest.txt','w')
1949 fp.write("$numOne $numTwo")
1950 fp.flush()
1951 fp.close
1953 def tearDown(self):
1954 if os.path.exists('parseTest.txt'):
1955 os.remove('parseTest.txt')
1957 def test1(self):
1958 """#include raw of source $emptyString"""
1959 self.verify("#include raw source=$emptyString",
1962 def test2(self):
1963 """#include raw of source $blockToBeParsed"""
1964 self.verify("#include raw source=$blockToBeParsed",
1965 "$numOne $numTwo")
1967 def test3(self):
1968 """#include raw of 'parseTest.txt'"""
1969 self.verify("#include raw 'parseTest.txt'",
1970 "$numOne $numTwo")
1972 def test4(self):
1973 """#include raw of $includeFileName"""
1974 self.verify("#include raw $includeFileName",
1975 "$numOne $numTwo")
1977 def test5(self):
1978 """#include raw of $includeFileName, with WS"""
1979 self.verify(" #include raw $includeFileName ",
1980 "$numOne $numTwo")
1982 def test6(self):
1983 """#include raw of source= , with WS"""
1984 self.verify(" #include raw source='This is my $Source '*2 ",
1985 "This is my $Source This is my $Source ")
1987 def test7(self):
1988 """#include of $blockToBeParsed"""
1989 self.verify("#include source=$blockToBeParsed",
1990 "1 2")
1992 def test8(self):
1993 """#include of $blockToBeParsed, with WS"""
1994 self.verify(" #include source=$blockToBeParsed ",
1995 "1 2")
1997 def test9(self):
1998 """#include of 'parseTest.txt', with WS"""
1999 self.verify(" #include source=$blockToBeParsed ",
2000 "1 2")
2002 def test10(self):
2003 """#include of "parseTest.txt", with WS"""
2004 self.verify(" #include source=$blockToBeParsed ",
2005 "1 2")
2007 def test11(self):
2008 """#include of 'parseTest.txt', with WS and surrounding text"""
2009 self.verify("aoeu\n #include source=$blockToBeParsed \naoeu",
2010 "aoeu\n1 2aoeu")
2012 def test12(self):
2013 """#include of 'parseTest.txt', with WS and explicit closure"""
2014 self.verify(" #include source=$blockToBeParsed# ",
2015 " 1 2 ")
2018 class SilentDirective(OutputTest):
2020 def test1(self):
2021 """simple #silent"""
2022 self.verify("#silent $aFunc",
2025 def test2(self):
2026 """simple #silent"""
2027 self.verify("#silent $anObj.callIt\n$anObj.callArg",
2028 "1234")
2030 self.verify("#silent $anObj.callIt ##comment\n$anObj.callArg",
2031 "1234")
2033 def test3(self):
2034 """simple #silent"""
2035 self.verify("#silent $anObj.callIt(99)\n$anObj.callArg",
2036 "99")
2038 class SetDirective(OutputTest):
2040 def test1(self):
2041 """simple #set"""
2042 self.verify("#set $testVar = 'blarg'\n$testVar",
2043 "blarg")
2044 self.verify("#set testVar = 'blarg'\n$testVar",
2045 "blarg")
2048 self.verify("#set testVar = 'blarg'##comment\n$testVar",
2049 "blarg")
2051 def test2(self):
2052 """simple #set with no WS between operands"""
2053 self.verify("#set $testVar='blarg'",
2055 def test3(self):
2056 """#set + use of var"""
2057 self.verify("#set $testVar = 'blarg'\n$testVar",
2058 "blarg")
2060 def test4(self):
2061 """#set + use in an #include"""
2062 self.verify("#set global $aSetVar = 1234\n#include source=$includeBlock2",
2063 "1 2 1234")
2065 def test5(self):
2066 """#set with a dictionary"""
2067 self.verify( """#set $testDict = {'one':'one1','two':'two2','three':'three3'}
2068 $testDict.one
2069 $testDict.two""",
2070 "one1\ntwo2")
2072 def test6(self):
2073 """#set with string, then used in #if block"""
2075 self.verify("""#set $test='a string'\n#if $test#blarg#end if""",
2076 "blarg")
2078 def test7(self):
2079 """simple #set, gobble WS"""
2080 self.verify(" #set $testVar = 'blarg' ",
2083 def test8(self):
2084 """simple #set, don't gobble WS"""
2085 self.verify(" #set $testVar = 'blarg'#---",
2086 " ---")
2088 def test9(self):
2089 """simple #set with a list"""
2090 self.verify(" #set $testVar = [1, 2, 3] \n$testVar",
2091 "[1, 2, 3]")
2093 def test10(self):
2094 """simple #set global with a list"""
2095 self.verify(" #set global $testVar = [1, 2, 3] \n$testVar",
2096 "[1, 2, 3]")
2098 def test11(self):
2099 """simple #set global with a list and *cache
2101 Caching only works with global #set vars. Local vars are not accesible
2102 to the cache namespace.
2105 self.verify(" #set global $testVar = [1, 2, 3] \n$*testVar",
2106 "[1, 2, 3]")
2108 def test12(self):
2109 """simple #set global with a list and *<int>*cache"""
2110 self.verify(" #set global $testVar = [1, 2, 3] \n$*5*testVar",
2111 "[1, 2, 3]")
2113 def test13(self):
2114 """simple #set with a list and *<float>*cache"""
2115 self.verify(" #set global $testVar = [1, 2, 3] \n$*.5*testVar",
2116 "[1, 2, 3]")
2118 def test14(self):
2119 """simple #set without NameMapper on"""
2120 self.verify("""#compiler useNameMapper = 0\n#set $testVar = 1 \n$testVar""",
2121 "1")
2123 def test15(self):
2124 """simple #set without $"""
2125 self.verify("""#set testVar = 1 \n$testVar""",
2126 "1")
2128 def test16(self):
2129 """simple #set global without $"""
2130 self.verify("""#set global testVar = 1 \n$testVar""",
2131 "1")
2133 def test17(self):
2134 """simple #set module without $"""
2135 self.verify("""#set module __foo__ = 'bar'\n$__foo__""",
2136 "bar")
2138 def test18(self):
2139 """#set with i,j=list style assignment"""
2140 self.verify("""#set i,j = [1,2]\n$i$j""",
2141 "12")
2142 self.verify("""#set $i,$j = [1,2]\n$i$j""",
2143 "12")
2145 def test19(self):
2146 """#set with (i,j)=list style assignment"""
2147 self.verify("""#set (i,j) = [1,2]\n$i$j""",
2148 "12")
2149 self.verify("""#set ($i,$j) = [1,2]\n$i$j""",
2150 "12")
2152 def test20(self):
2153 """#set with i, (j,k)=list style assignment"""
2154 self.verify("""#set i, (j,k) = [1,(2,3)]\n$i$j$k""",
2155 "123")
2156 self.verify("""#set $i, ($j,$k) = [1,(2,3)]\n$i$j$k""",
2157 "123")
2160 class IfDirective(OutputTest):
2162 def test1(self):
2163 """simple #if block"""
2164 self.verify("#if 1\n$aStr\n#end if\n",
2165 "blarg\n")
2167 self.verify("#if 1:\n$aStr\n#end if\n",
2168 "blarg\n")
2170 self.verify("#if 1: \n$aStr\n#end if\n",
2171 "blarg\n")
2173 self.verify("#if 1: ##comment \n$aStr\n#end if\n",
2174 "blarg\n")
2176 self.verify("#if 1 ##comment \n$aStr\n#end if\n",
2177 "blarg\n")
2179 self.verify("#if 1##for i in range(10)#$i#end for##end if",
2180 '0123456789')
2182 self.verify("#if 1: #for i in range(10)#$i#end for",
2183 '0123456789')
2185 self.verify("#if 1: #for i in range(10):$i",
2186 '0123456789')
2188 def test2(self):
2189 """simple #if block, with WS"""
2190 self.verify(" #if 1\n$aStr\n #end if \n",
2191 "blarg\n")
2192 def test3(self):
2193 """simple #if block, with WS and explicit closures"""
2194 self.verify(" #if 1#\n$aStr\n #end if #--\n",
2195 " \nblarg\n --\n")
2197 def test4(self):
2198 """#if block using $numOne"""
2199 self.verify("#if $numOne\n$aStr\n#end if\n",
2200 "blarg\n")
2202 def test5(self):
2203 """#if block using $zero"""
2204 self.verify("#if $zero\n$aStr\n#end if\n",
2206 def test6(self):
2207 """#if block using $emptyString"""
2208 self.verify("#if $emptyString\n$aStr\n#end if\n",
2210 def test7(self):
2211 """#if ... #else ... block using a $emptyString"""
2212 self.verify("#if $emptyString\n$anInt\n#else\n$anInt - $anInt\n#end if",
2213 "1 - 1\n")
2215 def test8(self):
2216 """#if ... #elif ... #else ... block using a $emptyString"""
2217 self.verify("#if $emptyString\n$c\n#elif $numOne\n$numOne\n#else\n$c - $c\n#end if",
2218 "1\n")
2220 def test9(self):
2221 """#if 'not' test, with #slurp"""
2222 self.verify("#if not $emptyString\n$aStr#slurp\n#end if\n",
2223 "blarg")
2225 def test10(self):
2226 """#if block using $*emptyString
2228 This should barf
2230 try:
2231 self.verify("#if $*emptyString\n$aStr\n#end if\n",
2233 except ParseError:
2234 pass
2235 else:
2236 self.fail('This should barf')
2238 def test11(self):
2239 """#if block using invalid top-level $(placeholder) syntax - should barf"""
2241 for badSyntax in ("#if $*5*emptyString\n$aStr\n#end if\n",
2242 "#if ${emptyString}\n$aStr\n#end if\n",
2243 "#if $(emptyString)\n$aStr\n#end if\n",
2244 "#if $[emptyString]\n$aStr\n#end if\n",
2245 "#if $!emptyString\n$aStr\n#end if\n",
2247 try:
2248 self.verify(badSyntax, "")
2249 except ParseError:
2250 pass
2251 else:
2252 self.fail('This should barf')
2254 def test12(self):
2255 """#if ... #else if ... #else ... block using a $emptyString
2256 Same as test 8 but using else if instead of elif"""
2257 self.verify("#if $emptyString\n$c\n#else if $numOne\n$numOne\n#else\n$c - $c\n#end if",
2258 "1\n")
2261 def test13(self):
2262 """#if# ... #else # ... block using a $emptyString with """
2263 self.verify("#if $emptyString# $anInt#else#$anInt - $anInt#end if",
2264 "1 - 1")
2266 def test14(self):
2267 """single-line #if: simple"""
2268 self.verify("#if $emptyString then 'true' else 'false'",
2269 "false")
2271 def test15(self):
2272 """single-line #if: more complex"""
2273 self.verify("#if $anInt then 'true' else 'false'",
2274 "true")
2276 def test16(self):
2277 """single-line #if: with the words 'else' and 'then' in the output """
2278 self.verify("#if ($anInt and not $emptyString==''' else ''') then $str('then') else 'else'",
2279 "then")
2281 def test17(self):
2282 """single-line #if: """
2283 self.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2284 "foo\nfoo")
2287 self.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2288 "foo\nfoo")
2290 def test18(self):
2291 """single-line #if: \n#else: """
2292 self.verify("#if 1: foo\n#elif 0: bar",
2293 "foo\n")
2295 self.verify("#if 1: foo\n#elif 0: bar\n#else: blarg\n",
2296 "foo\n")
2298 self.verify("#if 0: foo\n#elif 0: bar\n#else: blarg\n",
2299 "blarg\n")
2301 class UnlessDirective(OutputTest):
2303 def test1(self):
2304 """#unless 1"""
2305 self.verify("#unless 1\n 1234 \n#end unless",
2308 self.verify("#unless 1:\n 1234 \n#end unless",
2311 self.verify("#unless 1: ##comment\n 1234 \n#end unless",
2314 self.verify("#unless 1 ##comment\n 1234 \n#end unless",
2318 def test2(self):
2319 """#unless 0"""
2320 self.verify("#unless 0\n 1234 \n#end unless",
2321 " 1234 \n")
2323 def test3(self):
2324 """#unless $none"""
2325 self.verify("#unless $none\n 1234 \n#end unless",
2326 " 1234 \n")
2328 def test4(self):
2329 """#unless $numTwo"""
2330 self.verify("#unless $numTwo\n 1234 \n#end unless",
2333 def test5(self):
2334 """#unless $numTwo with WS"""
2335 self.verify(" #unless $numTwo \n 1234 \n #end unless ",
2338 def test6(self):
2339 """single-line #unless"""
2340 self.verify("#unless 1: 1234", "")
2341 self.verify("#unless 0: 1234", "1234")
2342 self.verify("#unless 0: 1234\n"*2, "1234\n"*2)
2344 class PSP(OutputTest):
2346 def test1(self):
2347 """simple <%= [int] %>"""
2348 self.verify("<%= 1234 %>", "1234")
2350 def test2(self):
2351 """simple <%= [string] %>"""
2352 self.verify("<%= 'blarg' %>", "blarg")
2354 def test3(self):
2355 """simple <%= None %>"""
2356 self.verify("<%= None %>", "")
2357 def test4(self):
2358 """simple <%= [string] %> + $anInt"""
2359 self.verify("<%= 'blarg' %>$anInt", "blarg1")
2361 def test5(self):
2362 """simple <%= [EXPR] %> + $anInt"""
2363 self.verify("<%= ('blarg'*2).upper() %>$anInt", "BLARGBLARG1")
2365 def test6(self):
2366 """for loop in <%%>"""
2367 self.verify("<% for i in range(5):%>1<%end%>", "11111")
2369 def test7(self):
2370 """for loop in <%%> and using <%=i%>"""
2371 self.verify("<% for i in range(5):%><%=i%><%end%>", "01234")
2373 def test8(self):
2374 """for loop in <% $%> and using <%=i%>"""
2375 self.verify("""<% for i in range(5):
2376 i=i*2$%><%=i%><%end%>""", "02468")
2378 def test9(self):
2379 """for loop in <% $%> and using <%=i%> plus extra text"""
2380 self.verify("""<% for i in range(5):
2381 i=i*2$%><%=i%>-<%end%>""", "0-2-4-6-8-")
2384 class WhileDirective(OutputTest):
2385 def test1(self):
2386 """simple #while with a counter"""
2387 self.verify("#set $i = 0\n#while $i < 5\n$i#slurp\n#set $i += 1\n#end while",
2388 "01234")
2390 class ContinueDirective(OutputTest):
2391 def test1(self):
2392 """#continue with a #while"""
2393 self.verify("""#set $i = 0
2394 #while $i < 5
2395 #if $i == 3
2396 #set $i += 1
2397 #continue
2398 #end if
2399 $i#slurp
2400 #set $i += 1
2401 #end while""",
2402 "0124")
2404 def test2(self):
2405 """#continue with a #for"""
2406 self.verify("""#for $i in range(5)
2407 #if $i == 3
2408 #continue
2409 #end if
2410 $i#slurp
2411 #end for""",
2412 "0124")
2414 class BreakDirective(OutputTest):
2415 def test1(self):
2416 """#break with a #while"""
2417 self.verify("""#set $i = 0
2418 #while $i < 5
2419 #if $i == 3
2420 #break
2421 #end if
2422 $i#slurp
2423 #set $i += 1
2424 #end while""",
2425 "012")
2427 def test2(self):
2428 """#break with a #for"""
2429 self.verify("""#for $i in range(5)
2430 #if $i == 3
2431 #break
2432 #end if
2433 $i#slurp
2434 #end for""",
2435 "012")
2438 class TryDirective(OutputTest):
2440 def test1(self):
2441 """simple #try
2443 self.verify("#try\n1234\n#except\nblarg\n#end try",
2444 "1234\n")
2446 def test2(self):
2447 """#try / #except with #raise
2449 self.verify("#try\n#raise ValueError\n#except\nblarg\n#end try",
2450 "blarg\n")
2452 def test3(self):
2453 """#try / #except with #raise + WS
2455 Should gobble
2457 self.verify(" #try \n #raise ValueError \n #except \nblarg\n #end try",
2458 "blarg\n")
2461 def test4(self):
2462 """#try / #except with #raise + WS and leading text
2464 Shouldn't gobble
2466 self.verify("--#try \n #raise ValueError \n #except \nblarg\n #end try#--",
2467 "--\nblarg\n --")
2469 def test5(self):
2470 """nested #try / #except with #raise
2472 self.verify(
2473 """#try
2474 #raise ValueError
2475 #except
2476 #try
2477 #raise ValueError
2478 #except
2479 blarg
2480 #end try
2481 #end try""",
2482 "blarg\n")
2484 class PassDirective(OutputTest):
2485 def test1(self):
2486 """#pass in a #try / #except block
2488 self.verify("#try\n#raise ValueError\n#except\n#pass\n#end try",
2491 def test2(self):
2492 """#pass in a #try / #except block + WS
2494 self.verify(" #try \n #raise ValueError \n #except \n #pass \n #end try",
2498 class AssertDirective(OutputTest):
2499 def test1(self):
2500 """simple #assert
2502 self.verify("#set $x = 1234\n#assert $x == 1234",
2505 def test2(self):
2506 """simple #assert that fails
2508 def test(self=self):
2509 self.verify("#set $x = 1234\n#assert $x == 999",
2510 ""),
2511 self.failUnlessRaises(AssertionError, test)
2513 def test3(self):
2514 """simple #assert with WS
2516 self.verify("#set $x = 1234\n #assert $x == 1234 ",
2520 class RaiseDirective(OutputTest):
2521 def test1(self):
2522 """simple #raise ValueError
2524 Should raise ValueError
2526 def test(self=self):
2527 self.verify("#raise ValueError",
2528 ""),
2529 self.failUnlessRaises(ValueError, test)
2531 def test2(self):
2532 """#raise ValueError in #if block
2534 Should raise ValueError
2536 def test(self=self):
2537 self.verify("#if 1\n#raise ValueError\n#end if\n",
2539 self.failUnlessRaises(ValueError, test)
2542 def test3(self):
2543 """#raise ValueError in #if block
2545 Shouldn't raise ValueError
2547 self.verify("#if 0\n#raise ValueError\n#else\nblarg#end if\n",
2548 "blarg\n")
2552 class ImportDirective(OutputTest):
2553 def test1(self):
2554 """#import math
2556 self.verify("#import math",
2559 def test2(self):
2560 """#import math + WS
2562 Should gobble
2564 self.verify(" #import math ",
2567 def test3(self):
2568 """#import math + WS + leading text
2570 Shouldn't gobble
2572 self.verify(" -- #import math ",
2573 " -- ")
2575 def test4(self):
2576 """#from math import syn
2578 self.verify("#from math import cos",
2581 def test5(self):
2582 """#from math import cos + WS
2583 Should gobble
2585 self.verify(" #from math import cos ",
2588 def test6(self):
2589 """#from math import cos + WS + leading text
2590 Shouldn't gobble
2592 self.verify(" -- #from math import cos ",
2593 " -- ")
2595 def test7(self):
2596 """#from math import cos -- use it
2598 self.verify("#from math import cos\n$cos(0)",
2599 "1.0")
2601 def test8(self):
2602 """#from math import cos,tan,sin -- and use them
2604 self.verify("#from math import cos, tan, sin\n$cos(0)-$tan(0)-$sin(0)",
2605 "1.0-0.0-0.0")
2607 def test9(self):
2608 """#import os.path -- use it
2611 self.verify("#import os.path\n$os.path.exists('.')",
2612 repr(True))
2614 def test10(self):
2615 """#import os.path -- use it with NameMapper turned off
2617 self.verify("""##
2618 #compiler-settings
2619 useNameMapper=False
2620 #end compiler-settings
2621 #import os.path
2622 $os.path.exists('.')""",
2623 repr(True))
2625 def test11(self):
2626 """#from math import *
2629 self.verify("#from math import *\n$pow(1,2) $log10(10)",
2630 "1.0 1.0")
2632 class CompilerDirective(OutputTest):
2633 def test1(self):
2634 """overriding the commentStartToken
2636 self.verify("""$anInt##comment
2637 #compiler commentStartToken = '//'
2638 $anInt//comment
2639 """,
2640 "1\n1\n")
2642 def test2(self):
2643 """overriding and resetting the commentStartToken
2645 self.verify("""$anInt##comment
2646 #compiler commentStartToken = '//'
2647 $anInt//comment
2648 #compiler reset
2649 $anInt//comment
2650 """,
2651 "1\n1\n1//comment\n")
2654 class CompilerSettingsDirective(OutputTest):
2656 def test1(self):
2657 """overriding the cheetahVarStartToken
2659 self.verify("""$anInt
2660 #compiler-settings
2661 cheetahVarStartToken = @
2662 #end compiler-settings
2663 @anInt
2664 #compiler-settings reset
2665 $anInt
2666 """,
2667 "1\n1\n1\n")
2669 def test2(self):
2670 """overriding the directiveStartToken
2672 self.verify("""#set $x = 1234
2674 #compiler-settings
2675 directiveStartToken = @
2676 #end compiler-settings
2677 @set $x = 1234
2679 """,
2680 "1234\n1234\n")
2682 def test3(self):
2683 """overriding the commentStartToken
2685 self.verify("""$anInt##comment
2686 #compiler-settings
2687 commentStartToken = //
2688 #end compiler-settings
2689 $anInt//comment
2690 """,
2691 "1\n1\n")
2693 if sys.platform.startswith('java'):
2694 del CompilerDirective
2695 del CompilerSettingsDirective
2697 class ExtendsDirective(OutputTest):
2699 def test1(self):
2700 """#extends Cheetah.Templates._SkeletonPage"""
2701 self.verify("""#from Cheetah.Templates._SkeletonPage import _SkeletonPage
2702 #extends _SkeletonPage
2703 #implements respond
2704 $spacer()
2705 """,
2706 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2709 self.verify("""#from Cheetah.Templates._SkeletonPage import _SkeletonPage
2710 #extends _SkeletonPage
2711 #implements respond(foo=1234)
2712 $spacer()$foo
2713 """,
2714 '<img src="spacer.gif" width="1" height="1" alt="" />1234\n')
2716 def test2(self):
2717 """#extends Cheetah.Templates.SkeletonPage without #import"""
2718 self.verify("""#extends Cheetah.Templates.SkeletonPage
2719 #implements respond
2720 $spacer()
2721 """,
2722 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2724 def test3(self):
2725 """#extends Cheetah.Templates.SkeletonPage.SkeletonPage without #import"""
2726 self.verify("""#extends Cheetah.Templates.SkeletonPage.SkeletonPage
2727 #implements respond
2728 $spacer()
2729 """,
2730 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2732 def test4(self):
2733 """#extends with globals and searchList test"""
2734 self.verify("""#extends Cheetah.Templates.SkeletonPage
2735 #set global g="Hello"
2736 #implements respond
2737 $g $numOne
2738 """,
2739 'Hello 1\n')
2742 class SuperDirective(OutputTest):
2743 def test1(self):
2744 tmpl1 = Template.compile('''$foo $bar(99)
2745 #def foo: this is base foo
2746 #def bar(arg): super-$arg''')
2748 tmpl2 = tmpl1.subclass('''
2749 #implements dummy
2750 #def foo
2751 #super
2752 This is child foo
2753 #super(trans=trans)
2754 $bar(1234)
2755 #end def
2756 #def bar(arg): #super($arg)
2757 ''')
2758 expected = ('this is base foo '
2759 'This is child foo\nthis is base foo '
2760 'super-1234\n super-99')
2761 assert str(tmpl2()).strip()==expected
2764 class ImportantExampleCases(OutputTest):
2765 def test1(self):
2766 """how to make a comma-delimited list"""
2767 self.verify("""#set $sep = ''
2768 #for $letter in $letterList
2769 $sep$letter#slurp
2770 #set $sep = ', '
2771 #end for
2772 """,
2773 "a, b, c")
2775 class FilterDirective(OutputTest):
2776 convertEOLs=False
2778 def _getCompilerSettings(self):
2779 return {'useFilterArgsInPlaceholders':True}
2781 def test1(self):
2782 """#filter Filter
2784 self.verify("#filter Filter\n$none#end filter",
2787 self.verify("#filter Filter: $none",
2790 def test2(self):
2791 """#filter ReplaceNone with WS
2793 self.verify("#filter Filter \n$none#end filter",
2796 def test3(self):
2797 """#filter MaxLen -- maxlen of 5"""
2799 self.verify("#filter MaxLen \n${tenDigits, $maxlen=5}#end filter",
2800 "12345")
2802 def test4(self):
2803 """#filter MaxLen -- no maxlen
2805 self.verify("#filter MaxLen \n${tenDigits}#end filter",
2806 "1234567890")
2808 def test5(self):
2809 """#filter WebSafe -- basic usage
2811 self.verify("#filter WebSafe \n$webSafeTest#end filter",
2812 "abc &lt;=&gt; &amp;")
2814 def test6(self):
2815 """#filter WebSafe -- also space
2817 self.verify("#filter WebSafe \n${webSafeTest, $also=' '}#end filter",
2818 "abc&nbsp;&lt;=&gt;&nbsp;&amp;")
2820 def test7(self):
2821 """#filter WebSafe -- also space, without $ on the args
2823 self.verify("#filter WebSafe \n${webSafeTest, also=' '}#end filter",
2824 "abc&nbsp;&lt;=&gt;&nbsp;&amp;")
2826 def test8(self):
2827 """#filter Strip -- trailing newline
2829 self.verify("#filter Strip\n$strip1#end filter",
2830 "strippable whitespace\n")
2832 def test9(self):
2833 """#filter Strip -- no trailing newine
2835 self.verify("#filter Strip\n$strip2#end filter",
2836 "strippable whitespace")
2838 def test10(self):
2839 """#filter Strip -- multi-line
2841 self.verify("#filter Strip\n$strip3#end filter",
2842 "strippable whitespace\n1 2 3\n")
2844 def test11(self):
2845 """#filter StripSqueeze -- canonicalize all whitespace to ' '
2847 self.verify("#filter StripSqueeze\n$strip3#end filter",
2848 "strippable whitespace 1 2 3")
2851 class EchoDirective(OutputTest):
2852 def test1(self):
2853 """#echo 1234
2855 self.verify("#echo 1234",
2856 "1234")
2858 class SilentDirective(OutputTest):
2859 def test1(self):
2860 """#silent 1234
2862 self.verify("#silent 1234",
2865 class ErrorCatcherDirective(OutputTest):
2866 pass
2869 class VarExists(OutputTest): # Template.varExists()
2871 def test1(self):
2872 """$varExists('$anInt')
2874 self.verify("$varExists('$anInt')",
2875 repr(True))
2877 def test2(self):
2878 """$varExists('anInt')
2880 self.verify("$varExists('anInt')",
2881 repr(True))
2883 def test3(self):
2884 """$varExists('$anInt')
2886 self.verify("$varExists('$bogus')",
2887 repr(False))
2889 def test4(self):
2890 """$varExists('$anInt') combined with #if false
2892 self.verify("#if $varExists('$bogus')\n1234\n#else\n999\n#end if",
2893 "999\n")
2895 def test5(self):
2896 """$varExists('$anInt') combined with #if true
2898 self.verify("#if $varExists('$anInt')\n1234\n#else\n999#end if",
2899 "1234\n")
2901 class GetVar(OutputTest): # Template.getVar()
2902 def test1(self):
2903 """$getVar('$anInt')
2905 self.verify("$getVar('$anInt')",
2906 "1")
2908 def test2(self):
2909 """$getVar('anInt')
2911 self.verify("$getVar('anInt')",
2912 "1")
2914 def test3(self):
2915 """$self.getVar('anInt')
2917 self.verify("$self.getVar('anInt')",
2918 "1")
2920 def test4(self):
2921 """$getVar('bogus', 1234)
2923 self.verify("$getVar('bogus', 1234)",
2924 "1234")
2926 def test5(self):
2927 """$getVar('$bogus', 1234)
2929 self.verify("$getVar('$bogus', 1234)",
2930 "1234")
2933 class MiscComplexSyntax(OutputTest):
2934 def test1(self):
2935 """Complex use of {},[] and () in a #set expression
2936 ----
2937 #set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]
2940 self.verify("#set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]\n$c",
2941 "0")
2944 class CGI(OutputTest):
2945 """CGI scripts with(out) the CGI environment and with(out) GET variables.
2947 convertEOLs=False
2949 def _beginCGI(self):
2950 os.environ['REQUEST_METHOD'] = "GET"
2951 def _endCGI(self):
2952 try:
2953 del os.environ['REQUEST_METHOD']
2954 except KeyError:
2955 pass
2956 _guaranteeNoCGI = _endCGI
2959 def test1(self):
2960 """A regular template."""
2961 self._guaranteeNoCGI()
2962 source = "#extends Cheetah.Tools.CGITemplate\n" + \
2963 "#implements respond\n" + \
2964 "$cgiHeaders#slurp\n" + \
2965 "Hello, world!"
2966 self.verify(source, "Hello, world!")
2969 def test2(self):
2970 """A CGI script."""
2971 self._beginCGI()
2972 source = "#extends Cheetah.Tools.CGITemplate\n" + \
2973 "#implements respond\n" + \
2974 "$cgiHeaders#slurp\n" + \
2975 "Hello, world!"
2976 self.verify(source, "Content-type: text/html\n\nHello, world!")
2977 self._endCGI()
2980 def test3(self):
2981 """A (pseudo) Webware servlet.
2983 This uses the Python syntax escape to set
2984 self._CHEETAH__isControlledByWebKit.
2985 We could instead do '#silent self._CHEETAH__isControlledByWebKit = True',
2986 taking advantage of the fact that it will compile unchanged as long
2987 as there's no '$' in the statement. (It won't compile with an '$'
2988 because that would convert to a function call, and you can't assign
2989 to a function call.) Because this isn't really being called from
2990 Webware, we'd better not use any Webware services! Likewise, we'd
2991 better not call $cgiImport() because it would be misled.
2993 self._beginCGI()
2994 source = "#extends Cheetah.Tools.CGITemplate\n" + \
2995 "#implements respond\n" + \
2996 "<% self._CHEETAH__isControlledByWebKit = True %>#slurp\n" + \
2997 "$cgiHeaders#slurp\n" + \
2998 "Hello, world!"
2999 self.verify(source, "Hello, world!")
3000 self._endCGI()
3003 def test4(self):
3004 """A CGI script with a GET variable."""
3005 self._beginCGI()
3006 os.environ['QUERY_STRING'] = "cgiWhat=world"
3007 source = "#extends Cheetah.Tools.CGITemplate\n" + \
3008 "#implements respond\n" + \
3009 "$cgiHeaders#slurp\n" + \
3010 "#silent $webInput(['cgiWhat'])##slurp\n" + \
3011 "Hello, $cgiWhat!"
3012 self.verify(source,
3013 "Content-type: text/html\n\nHello, world!")
3014 del os.environ['QUERY_STRING']
3015 self._endCGI()
3019 class WhitespaceAfterDirectiveTokens(OutputTest):
3020 def _getCompilerSettings(self):
3021 return {'allowWhitespaceAfterDirectiveStartToken':True}
3023 def test1(self):
3024 self.verify("# for i in range(10): $i",
3025 "0123456789")
3026 self.verify("# for i in range(10)\n$i# end for",
3027 "0123456789")
3028 self.verify("# for i in range(10)#$i#end for",
3029 "0123456789")
3033 class DefmacroDirective(OutputTest):
3034 def _getCompilerSettings(self):
3035 def aMacro(src):
3036 return '$aStr'
3038 return {'macroDirectives':{'aMacro':aMacro
3041 def test1(self):
3042 self.verify("""\
3043 #defmacro inc: #set @src +=1
3044 #set i = 1
3045 #inc: $i
3046 $i""",
3047 "2")
3051 self.verify("""\
3052 #defmacro test
3053 #for i in range(10): @src
3054 #end defmacro
3055 #test: $i-foo#slurp
3056 #for i in range(3): $i""",
3057 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo012")
3059 self.verify("""\
3060 #defmacro test
3061 #for i in range(10): @src
3062 #end defmacro
3063 #test: $i-foo
3064 #for i in range(3): $i""",
3065 "0-foo\n1-foo\n2-foo\n3-foo\n4-foo\n5-foo\n6-foo\n7-foo\n8-foo\n9-foo\n012")
3068 self.verify("""\
3069 #defmacro test: #for i in range(10): @src
3070 #test: $i-foo#slurp
3071 -#for i in range(3): $i""",
3072 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3074 self.verify("""\
3075 #defmacro test##for i in range(10): @src#end defmacro##slurp
3076 #test: $i-foo#slurp
3077 -#for i in range(3): $i""",
3078 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3080 self.verify("""\
3081 #defmacro testFoo: nothing
3082 #defmacro test(foo=1234): #for i in range(10): @src
3083 #test foo=234: $i-foo#slurp
3084 -#for i in range(3): $i""",
3085 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3087 self.verify("""\
3088 #defmacro testFoo: nothing
3089 #defmacro test(foo=1234): #for i in range(10): @src@foo
3090 #test foo='-foo'#$i#end test#-#for i in range(3): $i""",
3091 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3093 self.verify("""\
3094 #defmacro testFoo: nothing
3095 #defmacro test(foo=1234): #for i in range(10): @src.strip()@foo
3096 #test foo='-foo': $i
3097 -#for i in range(3): $i""",
3098 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3100 def test2(self):
3101 self.verify("#aMacro: foo",
3102 "blarg")
3103 self.verify("#defmacro nested: @macros.aMacro(@src)\n#nested: foo",
3104 "blarg")
3107 class Indenter(OutputTest):
3108 convertEOLs=False
3110 source = """
3111 public class X
3113 #for $method in $methods
3114 $getMethod($method)
3116 #end for
3118 //end of class
3120 #def getMethod($method)
3121 #indent ++
3122 public $getType($method) ${method.Name}($getParams($method.Params));
3123 #indent --
3124 #end def
3126 #def getParams($params)
3127 #indent off
3129 #for $counter in $range($len($params))
3130 #if $counter == len($params) - 1
3131 $params[$counter]#slurp
3132 #else:
3133 $params[$counter],
3134 #end if
3135 #end for
3136 #indent on
3137 #end def
3139 #def getType($method)
3140 #indent push
3141 #indent=0
3142 #if $method.Type == "VT_VOID"
3143 void#slurp
3144 #elif $method.Type == "VT_INT"
3145 int#slurp
3146 #elif $method.Type == "VT_VARIANT"
3147 Object#slurp
3148 #end if
3149 #indent pop
3150 #end def
3153 control = """
3154 public class X
3156 public void Foo(
3157 _input,
3158 _output);
3161 public int Bar(
3162 _str1,
3163 str2,
3164 _str3);
3167 public Object Add(
3168 value1,
3169 value);
3173 //end of class
3178 def _getCompilerSettings(self):
3179 return {'useFilterArgsInPlaceholders':True}
3181 def searchList(self): # Inside Indenter class.
3182 class Method:
3183 def __init__(self, _name, _type, *_params):
3184 self.Name = _name
3185 self.Type = _type
3186 self.Params = _params
3187 methods = [Method("Foo", "VT_VOID", "_input", "_output"),
3188 Method("Bar", "VT_INT", "_str1", "str2", "_str3"),
3189 Method("Add", "VT_VARIANT", "value1", "value")]
3190 return [{"methods": methods}]
3192 def test1(self): # Inside Indenter class.
3193 self.verify(self.source, self.control)
3196 ##################################################
3197 ## CREATE CONVERTED EOL VERSIONS OF THE TEST CASES
3199 if OutputTest._useNewStyleCompilation and versionTuple >= (2,3):
3200 extraCompileKwArgsForDiffBaseclass = {'baseclass':dict}
3201 else:
3202 extraCompileKwArgsForDiffBaseclass = {'baseclass':object}
3205 for klass in [var for var in globals().values()
3206 if type(var) == types.ClassType and issubclass(var, unittest.TestCase)]:
3207 name = klass.__name__
3208 if hasattr(klass,'convertEOLs') and klass.convertEOLs:
3209 win32Src = r"class %(name)s_Win32EOL(%(name)s): _EOLreplacement = '\r\n'"%locals()
3210 macSrc = r"class %(name)s_MacEOL(%(name)s): _EOLreplacement = '\r'"%locals()
3211 #print win32Src
3212 #print macSrc
3213 exec win32Src+'\n'
3214 exec macSrc+'\n'
3216 if versionTuple >= (2,3):
3217 src = r"class %(name)s_DiffBaseClass(%(name)s): "%locals()
3218 src += " _extraCompileKwArgs = extraCompileKwArgsForDiffBaseclass"
3219 exec src+'\n'
3221 del name
3222 del klass
3224 ##################################################
3225 ## if run from the command line ##
3227 if __name__ == '__main__':
3228 unittest.main()
3230 # vim: shiftwidth=4 tabstop=4 expandtab