2 # $Id: SyntaxAndOutput.py,v 1.105 2006/06/21 23:48:19 tavis_rudd Exp $
3 """Syntax and Output tests.
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 $
19 __author__
= "Tavis Rudd <tavis@damnsimple.com>"
20 __revision__
= "$Revision: 1.105 $"[11:-2]
23 ##################################################
29 from copy
import deepcopy
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
)
52 True, False = (1==1),(1==0)
54 ##################################################
55 ## TEST DATA FOR USE IN THE TEMPLATES ##
57 def testdecorator(func
):
65 def meth(self
, arg
="arff"):
68 def meth1(self
, arg
="doo"):
71 def meth2(self
, arg1
="a1", arg2
="a2"):
72 return str(arg1
) + str(arg2
)
74 def methWithPercentSignDefaultArg(self
, arg1
="110%"):
77 def callIt(self
, arg
=1234):
82 def dummyFunc(arg
="Scooby"):
85 defaultTestNameSpace
= {
89 'aList': ['item0','item1','item2'],
90 'aDict': {'one':'item1',
92 'nestedDict':{1:'nestedItem1',
95 'nestedFunc':dummyFunc
,
98 'anObj': DummyClass(),
99 'aMeth': DummyClass().meth1
,
100 'aStrToBeIncluded': "$aStr $anInt",
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
,],
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 ##################################################
131 class OutputTest(unittest
.TestCase
):
133 Template output mismatch:
145 _EOLreplacement
= None
146 _debugEOLReplacement
= False
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
,
162 convertEOLs
=Unspecified
):
163 if self
._EOLreplacement
:
164 if convertEOLs
is Unspecified
:
165 convertEOLs
= self
.convertEOLs
167 input = input.replace('\n', self
._EOLreplacement
)
168 expectedOutput
= expectedOutput
.replace('\n', self
._EOLreplacement
)
171 if self
._useNewStyleCompilation
:
172 extraKwArgs
= self
._extraCompileKwArgs
or {}
174 templateClass
= Template
.compile(
176 compilerSettings
=self
._getCompilerSettings
(),
177 keepRefToGeneratedCode
=True,
180 moduleCode
= templateClass
._CHEETAH
_generatedModuleCode
181 self
.template
= templateObj
= templateClass(searchList
=self
.searchList())
183 self
.template
= templateObj
= Template(
185 searchList
=self
.searchList(),
186 compilerSettings
=self
._getCompilerSettings
(),
188 moduleCode
= templateObj
._CHEETAH
_generatedModuleCode
189 if self
.DEBUGLEV
>= 1:
193 output
= templateObj
.respond() # rather than __str__, because of unicode
195 output
= output
.decode(outputEncoding
)
196 assert output
==expectedOutput
, self
._outputMismatchReport
(output
, expectedOutput
)
198 #print >>sys.stderr, moduleCode
201 templateObj
.shutdown()
203 def _getCompilerSettings(self
):
206 def _outputMismatchReport(self
, output
, expectedOutput
):
207 if self
._debugEOLReplacement
and self
._EOLreplacement
:
208 EOLrepl
= self
._EOLreplacement
210 return self
.report
% {'template': self
._input
.replace(EOLrepl
,marker
),
211 'expected': expectedOutput
.replace(EOLrepl
,marker
),
212 'actual': output
.replace(EOLrepl
,marker
),
215 return self
.report
% {'template': self
._input
,
216 'expected': expectedOutput
,
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 ##################################################
231 class EmptyTemplate(OutputTest
):
234 """an empty string for the template"""
236 warnings
.filterwarnings('error',
237 'You supplied an empty string for the source!',
244 self
.fail("Should warn about empty source strings.")
247 self
.verify("#implements foo", "")
248 except NotImplementedError:
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
):
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')
268 if os
.path
.exists('backslashes.txt'):
269 os
.remove('backslashes.txt')
272 """ a single \\ using rawstrings"""
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")
282 """ a single \\ without using rawstrings"""
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"')
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')
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')
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")
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):
321 """dollar signs not in Cheetah $vars"""
322 self.verify("$ $$ $5 $. $ test",
326 """hash not in #directives"""
327 self.verify("# \# #5 ",
331 """escapted comments"""
332 self.verify(" \##escaped comment ",
333 " ##escaped comment ")
336 """escapted multi-line comments"""
337 self.verify(" \#*escaped comment \n*# ",
338 " #*escaped comment \n*# ")
345 """1 dollar sign followed by hash"""
346 self.verify("\n$#\n",
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
'],
355 self.verify("\n$#\n",
358 class Comments_SingleLine(OutputTest):
360 """## followed by WS"""
365 """## followed by NEWLINE"""
370 """## followed by text then NEWLINE"""
371 self.verify("## oeuao aoe uaoe \n",
374 """## gobbles leading WS"""
375 self.verify(" ## oeuao aoe uaoe \n",
379 """## followed by text then NEWLINE, + leading WS"""
380 self.verify(" ## oeuao aoe uaoe \n",
384 """## followed by EOF"""
389 """## followed by EOF with leading WS"""
395 with text on previous and following lines"""
396 self.verify("line1\n ## aoeu 1234 \nline2",
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")
406 """## containing $placeholders
408 self.verify("##$a$b $c($d)",
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}
428 """#* *# followed by WS
431 self.verify("#* blarg *# ",
435 """#* *# preceded and followed by WS
438 self.verify(" #* blarg *# ",
442 """#* *# followed by WS, with NEWLINE
445 self.verify("#* \nblarg\n *# ",
449 """#* *# preceded and followed by WS, with NEWLINE
452 self.verify(" #* \nblarg\n *# ",
455 class Comments_MultiLine(OutputTest):
457 Note
: Multiline comments don
't gobble whitespace!
461 """#* *# followed by WS
464 self.verify("#* blarg *# ",
468 """#* *# preceded and followed by WS
471 self.verify(" #* blarg *# ",
475 """#* *# followed by WS, with NEWLINE
478 self.verify("#* \nblarg\n *# ",
482 """#* *# preceded and followed by WS, with NEWLINE
485 self.verify(" #* \nblarg\n *# ",
489 """#* *# containing nothing
495 """#* *# containing only NEWLINES
497 self.verify(" #*\n\n\n\n\n\n\n\n*# ",
501 """#* *# containing $placeholders
503 self.verify("#* $var $var(1234*$c) *#",
507 """#* *# containing #for directive
509 self.verify("#* #for $i in range(15) *#",
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")
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")
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):
535 self.verify("$aStr", "blarg")
539 self.verify("$aStr $anInt", "blarg 1")
542 """2 placeholders, back-to-back"""
543 self.verify("$aStr$anInt", "blarg1")
546 """1 placeholder enclosed in ()"""
547 self.verify("$(aStr)", "blarg")
550 """1 placeholder enclosed in {}"""
551 self.verify("${aStr}", "blarg")
554 """1 placeholder enclosed in []"""
555 self.verify("$[aStr]", "blarg")
558 """1 placeholder enclosed in () + WS
560 Test to make sure that $(<WS><identifier>.. matches
562 self.verify("$( aStr )", "blarg")
565 """1 placeholder enclosed in {} + WS"""
566 self.verify("${ aStr }", "blarg")
569 """1 placeholder enclosed in [] + WS"""
570 self.verify("$[ aStr ]", "blarg")
573 """1 placeholder enclosed in () + WS + * cache
575 Test to make sure that $*(<WS><identifier>.. matches
577 self.verify("$*( aStr )", "blarg")
580 """1 placeholder enclosed in {} + WS + *cache"""
581 self.verify("$*{ aStr }", "blarg")
584 """1 placeholder enclosed in [] + WS + *cache"""
585 self.verify("$*[ aStr ]", "blarg")
588 """1 placeholder enclosed in {} + WS + *<int>*cache"""
589 self.verify("$*5*{ aStr }", "blarg")
592 """1 placeholder enclosed in [] + WS + *<int>*cache"""
593 self.verify("$*5*[ aStr ]", "blarg")
596 """1 placeholder enclosed in {} + WS + *<float>*cache"""
597 self.verify("$*0.5d*{ aStr }", "blarg")
600 """1 placeholder enclosed in [] + WS + *<float>*cache"""
601 self.verify("$*.5*[ aStr ]", "blarg")
604 """1 placeholder + *<int>*cache"""
605 self.verify("$*5*aStr", "blarg")
608 """1 placeholder *<float>*cache"""
609 self.verify("$*0.5h*aStr", "blarg")
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'""")
617 """silent mode $!placeholders """
618 self.verify("$!aStr$!nonExistant$!*nonExistant$!{nonExistant}", "blarg")
621 self.verify("$!aStr$nonExistant",
626 self.fail('should
raise NotFound exception
')
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
):
653 self
.verify("$aStr", "blarg")
656 """string - with whitespace"""
657 self
.verify(" $aStr ", " blarg ")
660 """empty string - with whitespace"""
661 self
.verify("$emptyString", "")
665 self
.verify("$anInt", "1")
669 self
.verify("$aFloat", "1.5")
673 self
.verify("$aList", "['item0', 'item1', 'item2']")
678 The default output filter is ReplaceNone.
680 self
.verify("$none", "")
685 self
.verify("$True $False", "%s %s"%(repr(True), repr(False)))
690 self
.verify("$_('foo')", "Translated: foo")
692 class PlaceholderStrings(OutputTest
):
694 """some c'text $placeholder text' strings"""
695 self
.verify("$str(c'$aStr')", "blarg")
698 """some c'text $placeholder text' strings"""
699 self
.verify("$str(c'$aStr.upper')", "BLARG")
702 """some c'text $placeholder text' strings"""
703 self
.verify("$str(c'$(aStr.upper.replace(c\"A$str()\",\"\"))')", "BLRG")
706 """some c'text $placeholder text' strings"""
707 self
.verify("#echo $str(c'$(aStr.upper)')", "BLARG")
710 """some c'text $placeholder text' strings"""
711 self
.verify("#if 1 then $str(c'$(aStr.upper)') else 0", "BLARG")
714 """some c'text $placeholder text' strings"""
715 self
.verify("#if 1\n$str(c'$(aStr.upper)')#slurp\n#else\n0#end if", "BLARG")
718 """some c'text $placeholder text' strings"""
719 self
.verify("#def foo(arg=c'$(\"BLARG\")')\n"
722 "$foo()$foo(c'$anInt')#slurp",
728 class UnicodeStrings(OutputTest
):
730 """unicode data in placeholder
732 #self.verify(u"$unicodeData", defaultTestNameSpace['unicodeData'], outputEncoding='utf8')
733 self
.verify(u
"$unicodeData", defaultTestNameSpace
['unicodeData'])
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
):
743 """basic #encoding """
744 self
.verify("#encoding utf-8\n1234",
748 """basic #encoding """
749 self
.verify("#encoding ascii\n1234",
753 """basic #encoding """
754 self
.verify("#encoding utf-8\n\xe1\x88\xb4",
755 u
'\u1234', outputEncoding
='utf8')
758 """basic #encoding """
759 self
.verify("#encoding ascii\n\xe1\x88\xb4",
763 """basic #encoding """
764 self
.verify("#encoding latin-1\nAndr\202",
765 u
'Andr\202', outputEncoding
='latin-1')
767 class Placeholders_Esc(OutputTest
):
770 """1 escaped placeholder"""
775 """2 escaped placeholders"""
776 self
.verify("\$var \$_",
780 """2 escaped placeholders - back to back"""
781 self
.verify("\$var\$_",
785 """2 escaped placeholders - nested"""
786 self
.verify("\$var(\$_)",
790 """2 escaped placeholders - nested and enclosed"""
791 self
.verify("\$(var(\$_)",
795 class Placeholders_Calls(OutputTest
):
797 """func placeholder - no ()"""
798 self
.verify("$aFunc",
802 """func placeholder - with ()"""
803 self
.verify("$aFunc()",
807 r
"""func placeholder - with (\n\n)"""
808 self
.verify("$aFunc(\n\n)",
809 "Scooby", convertEOLs
=False)
812 r
"""func placeholder - with (\n\n) and $() enclosure"""
813 self
.verify("$(aFunc(\n\n))",
814 "Scooby", convertEOLs
=False)
817 r
"""func placeholder - with (\n\n) and ${} enclosure"""
818 self
.verify("${aFunc(\n\n)}",
819 "Scooby", convertEOLs
=False)
822 """func placeholder - with (int)"""
823 self
.verify("$aFunc(1234)",
827 r
"""func placeholder - with (\nint\n)"""
828 self
.verify("$aFunc(\n1234\n)",
829 "1234", convertEOLs
=False)
831 """func placeholder - with (string)"""
832 self
.verify("$aFunc('aoeu')",
836 """func placeholder - with ('''string''')"""
837 self
.verify("$aFunc('''aoeu''')",
840 r
"""func placeholder - with ('''\nstring\n''')"""
841 self
.verify("$aFunc('''\naoeu\n''')",
845 r
"""func placeholder - with ('''\nstring'\n''')"""
846 self
.verify("$aFunc('''\naoeu'\n''')",
850 r
'''func placeholder - with ("""\nstring\n""")'''
851 self
.verify('$aFunc("""\naoeu\n""")',
855 """func placeholder - with (string*int)"""
856 self
.verify("$aFunc('aoeu'*2)",
860 """func placeholder - with (int*int)"""
861 self
.verify("$aFunc(2*2)",
865 """func placeholder - with (int*float)"""
866 self
.verify("$aFunc(2*2.0)",
870 r
"""func placeholder - with (int\n*\nfloat)"""
871 self
.verify("$aFunc(2\n*\n2.0)",
872 "4.0", convertEOLs
=False)
875 """func placeholder - with ($arg=float)"""
876 self
.verify("$aFunc($arg=4.0)",
880 """func placeholder - with (arg=float)"""
881 self
.verify("$aFunc(arg=4.0)",
885 """deeply nested argstring, no enclosure"""
886 self
.verify("$aFunc($arg=$aMeth($arg=$aFunc(1)))",
890 """deeply nested argstring, no enclosure + with WS"""
891 self
.verify("$aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) )",
894 """deeply nested argstring, () enclosure + with WS"""
895 self
.verify("$(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
899 """deeply nested argstring, {} enclosure + with WS"""
900 self
.verify("${aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) }",
904 """deeply nested argstring, [] enclosure + with WS"""
905 self
.verify("$[aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) ]",
909 """deeply nested argstring, () enclosure + *cache"""
910 self
.verify("$*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
913 """deeply nested argstring, () enclosure + *15*cache"""
914 self
.verify("$*15*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
918 """a function call with the Python None kw."""
919 self
.verify("$aFunc(None)",
922 class NameMapper(OutputTest
):
925 self
.verify("$aFunc! $aFunc().",
929 """nested autocalling"""
930 self
.verify("$aFunc($aFunc).",
934 """list subscription"""
935 self
.verify("$aList[0]",
940 self
.verify("$aList[:2]",
941 "['item0', 'item1']")
944 """list slicing and subcription combined"""
945 self
.verify("$aList[:2][0]",
949 """dictionary access - NameMapper style"""
950 self
.verify("$aDict.one",
954 """dictionary access - Python style"""
955 self
.verify("$aDict['one']",
959 """dictionary access combined with autocalled string method"""
960 self
.verify("$aDict.one.upper",
964 """dictionary access combined with string method"""
965 self
.verify("$aDict.one.upper()",
969 """nested dictionary access - NameMapper style"""
970 self
.verify("$aDict.nestedDict.two",
974 """nested dictionary access - Python style"""
975 self
.verify("$aDict['nestedDict']['two']",
979 """nested dictionary access - alternating style"""
980 self
.verify("$aDict['nestedDict'].two",
984 """nested dictionary access using method - alternating style"""
985 self
.verify("$aDict.get('nestedDict').two",
989 """nested dictionary access - NameMapper style - followed by method"""
990 self
.verify("$aDict.nestedDict.two.upper",
994 """nested dictionary access - alternating style - followed by method"""
995 self
.verify("$aDict['nestedDict'].two.upper",
999 """nested dictionary access - NameMapper style - followed by method, then slice"""
1000 self
.verify("$aDict.nestedDict.two.upper[:4]",
1004 """nested dictionary access - Python style using a soft-coded key"""
1005 self
.verify("$aDict[$anObj.meth('nestedDict')].two",
1009 """object method access"""
1010 self
.verify("$anObj.meth1",
1014 """object method access, followed by complex slice"""
1015 self
.verify("$anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ]",
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 ] )",
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
1030 self
.verify("$anObj.methWithPercentSignDefaultArg",
1034 #class NameMapperDict(OutputTest):
1036 # _searchList = [{"update": "Yabba dabba doo!"}]
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
):
1047 r
"""simple #cache """
1048 self
.verify("#cache:$anInt",
1052 r
"""simple #cache + WS"""
1053 self
.verify(" #cache \n$anInt#end cache",
1057 r
"""simple #cache ... #end cache"""
1058 self
.verify("""#cache id='cache1', timer=150m
1065 r
"""2 #cache ... #end cache blocks"""
1066 self
.verify("""#slurp
1068 #cache ID='cache1', timer=150m
1071 #cache id='cache2', timer=15s
1078 $foo$foo$foo$foo$foo""",
1083 r
"""nested #cache blocks"""
1084 self
.verify("""#slurp
1086 #cache ID='cache1', timer=150m
1088 #cache id='cache2', timer=15s
1097 $foo$foo$foo$foo$foo""",
1101 class CallDirective(OutputTest
):
1104 r
"""simple #call """
1105 self
.verify("#call int\n$anInt#end call",
1107 # single line version
1108 self
.verify("#call int: $anInt",
1110 self
.verify("#call int: 10\n$aStr",
1114 r
"""simple #call + WS"""
1115 self
.verify("#call int\n$anInt #end call",
1119 r
"""a longer #call"""
1130 r
"""#call with keyword #args"""
1132 #def meth(arg1, arg2)
1133 $arg1.upper() - $arg2.lower()#slurp
1144 r
"""#call with single-line keyword #args """
1146 #def meth(arg1, arg2)
1147 $arg1.upper() - $arg2.lower()#slurp
1150 #arg arg1:$(1234+1) foo#slurp
1151 #arg arg2:UPPER#slurp
1156 """#call with python kwargs and cheetah output for the 1s positional
1160 #def meth(arg1, arg2)
1161 $arg1.upper() - $arg2.lower()#slurp
1163 #call self.meth arg2="UPPER"
1169 """#call with python kwargs and #args"""
1171 #def meth(arg1, arg2, arg3)
1172 $arg1.upper() - $arg2.lower() - $arg3#slurp
1174 #call self.meth arg2="UPPER", arg3=999
1175 #arg arg1:$(1234+1) foo#slurp
1177 "1235 FOO - upper - 999")
1180 """#call with python kwargs and #args, and using a function to get the
1181 function that will be called"""
1183 #def meth(arg1, arg2, arg3)
1184 $arg1.upper() - $arg2.lower() - $arg3#slurp
1186 #call getattr(self, "meth") arg2="UPPER", arg3=999
1187 #arg arg1:$(1234+1) foo#slurp
1189 "1235 FOO - upper - 999")
1192 """nested #call directives"""
1209 #call self.meth2 y=c"$(10/$two)"
1219 class I18nDirective(OutputTest
):
1221 r
"""simple #call """
1222 self
.verify("#i18n \n$anInt#end i18n",
1225 # single line version
1226 self
.verify("#i18n: $anInt",
1228 self
.verify("#i18n: 10\n$aStr",
1232 class CaptureDirective(OutputTest
):
1234 r
"""simple #capture"""
1245 r
"""slightly more complex #capture"""
1251 $(1234+1) $anInt $meth("foo")#slurp
1258 class SlurpDirective(OutputTest
):
1260 r
"""#slurp with 1 \n """
1261 self
.verify("#slurp\n",
1265 r
"""#slurp with 1 \n, leading whitespace
1267 self
.verify(" #slurp\n",
1271 r
"""#slurp with 1 \n, leading content
1273 self
.verify(" 1234 #slurp\n",
1277 r
"""#slurp with WS then \n, leading content
1279 self
.verify(" 1234 #slurp \n",
1283 r
"""#slurp with garbage chars then \n, leading content
1284 Should eat the garbage"""
1285 self
.verify(" 1234 #slurp garbage \n",
1290 class EOLSlurpToken(OutputTest
):
1291 _EOLSlurpToken
= DEFAULT_COMPILER_SETTINGS
['EOLSlurpToken']
1293 r
"""#slurp with 1 \n """
1294 self
.verify("%s\n"%self
._EOLSlurpToken
,
1298 r
"""#slurp with 1 \n, leading whitespace
1300 self
.verify(" %s\n"%self
._EOLSlurpToken
,
1303 r
"""#slurp with 1 \n, leading content
1305 self
.verify(" 1234 %s\n"%self
._EOLSlurpToken
,
1309 r
"""#slurp with WS then \n, leading content
1311 self
.verify(" 1234 %s \n"%self
._EOLSlurpToken
,
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']:
1323 class RawDirective(OutputTest
):
1326 self
.verify("#raw\n$aFunc().\n\n",
1330 """#raw till #end raw"""
1331 self
.verify("#raw\n$aFunc().\n#end raw\n$anInt",
1335 """#raw till #end raw gobble WS"""
1336 self
.verify(" #raw \n$aFunc().\n #end raw \n$anInt",
1340 """#raw till #end raw using explicit directive closure
1342 self
.verify(" #raw #\n$aFunc().\n #end raw #\n$anInt",
1343 " \n$aFunc().\n\n1")
1346 """single-line short form #raw: """
1347 self
.verify("#raw: $aFunc().\n\n",
1350 self
.verify("#raw: $aFunc().\n$anInt",
1353 class BreakpointDirective(OutputTest
):
1355 """#breakpoint part way through source code"""
1356 self
.verify("$aFunc(2).\n#breakpoint\n$anInt",
1360 """#breakpoint at BOF"""
1361 self
.verify("#breakpoint\n$anInt",
1365 """#breakpoint at EOF"""
1366 self
.verify("$anInt\n#breakpoint",
1370 class StopDirective(OutputTest
):
1372 """#stop part way through source code"""
1373 self
.verify("$aFunc(2).\n#stop\n$anInt",
1378 self
.verify("#stop\n$anInt",
1383 self
.verify("$anInt\n#stop",
1387 """#stop in pos test block"""
1388 self
.verify("""$anInt
1394 "1\ninside the if block\n")
1397 """#stop in neg test block"""
1398 self
.verify("""$anInt
1407 class ReturnDirective(OutputTest
):
1410 """#return'ing an int """
1426 """#return'ing an string """
1441 """#return'ing an string AND streaming other output via the transaction"""
1443 $str($test(trans=trans)[1])
1457 class YieldDirective(OutputTest
):
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"
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):
1484 class ForDirective(OutputTest
):
1487 """#for loop with one local var"""
1488 self
.verify("#for $i in range(5)\n$i\n#end for",
1491 self
.verify("#for $i in range(5):\n$i\n#end for",
1494 self
.verify("#for $i in range(5): ##comment\n$i\n#end for",
1497 self
.verify("#for $i in range(5) ##comment\n$i\n#end for",
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")
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")
1512 """#for loop over list"""
1513 self
.verify("#for $i, $j in [(0,1),(2,3)]\n$i,$j\n#end for",
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",
1522 """#for loop with explicit closures"""
1523 self
.verify("#for $i in range(5)#$i#end for#",
1527 """#for loop with explicit closures and WS"""
1528 self
.verify(" #for $i in range(5)#$i#end for# ",
1532 """#for loop using another $var"""
1533 self
.verify(" #for $i in range($aFunc(5))#$i#end for# ",
1537 """test methods in for loops"""
1538 self
.verify("#for $func in $listOfLambdas\n$func($anInt)\n#end for",
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",
1546 self
.verify("#for $i, $j in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
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",
1553 self
.verify("#for ($i, $j) in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
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",
1560 self
.verify("#for $i, ($j, $k) in enumerate([('aa','bb'),('cc','dd')])\n$j.upper,$k.upper\n#end for",
1564 """single line #for"""
1565 self
.verify("#for $i in range($aFunc(5)): $i",
1569 """single line #for with 1 extra leading space"""
1570 self
.verify("#for $i in range($aFunc(5)): $i",
1574 """2 times single line #for"""
1575 self
.verify("#for $i in range($aFunc(5)): $i#slurp\n"*2,
1579 """false single line #for """
1580 self
.verify("#for $i in range(5): \n$i\n#end for",
1583 if versionTuple
< (2,3):
1584 del ForDirective
.test12
1586 class RepeatDirective(OutputTest
):
1590 self
.verify("#repeat 3\n1\n#end repeat",
1592 self
.verify("#repeat 3: \n1\n#end repeat",
1595 self
.verify("#repeat 3 ##comment\n1\n#end repeat",
1598 self
.verify("#repeat 3: ##comment\n1\n#end repeat",
1602 """#repeat with numeric expression"""
1603 self
.verify("#repeat 3*3/3\n1\n#end repeat",
1607 """#repeat with placeholder"""
1608 self
.verify("#repeat $numTwo\n1\n#end repeat",
1612 """#repeat with placeholder * num"""
1613 self
.verify("#repeat $numTwo*1\n1\n#end repeat",
1617 """#repeat with placeholder and WS"""
1618 self
.verify(" #repeat $numTwo \n1\n #end repeat ",
1622 """single-line #repeat"""
1623 self
.verify("#repeat $numTwo: 1",
1625 self
.verify("#repeat $numTwo: 1\n"*2,
1629 self
.verify("#repeat 3: \n1\n#end repeat",
1633 class AttrDirective(OutputTest
):
1636 """#attr with int"""
1637 self
.verify("#attr $test = 1234\n$test",
1641 """#attr with string"""
1642 self
.verify("#attr $test = 'blarg'\n$test",
1646 """#attr with expression"""
1647 self
.verify("#attr $test = 'blarg'.upper()*2\n$test",
1651 """#attr with string + WS
1653 self
.verify(" #attr $test = 'blarg' \n$test",
1657 """#attr with string + WS + leading text
1659 self
.verify(" -- #attr $test = 'blarg' \n$test",
1663 class DefDirective(OutputTest
):
1666 """#def without argstring"""
1667 self
.verify("#def testMeth\n1234\n#end def\n$testMeth",
1670 self
.verify("#def testMeth ## comment\n1234\n#end def\n$testMeth",
1673 self
.verify("#def testMeth: ## comment\n1234\n#end def\n$testMeth",
1677 """#def without argstring, gobble WS"""
1678 self
.verify(" #def testMeth \n1234\n #end def \n$testMeth",
1682 """#def with argstring, gobble WS"""
1683 self
.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth",
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')",
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])",
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")
1702 """#def with *args, gobble WS"""
1703 self
.verify(" #def testMeth($*args) \n1234-$args\n #end def\n$testMeth",
1707 """#def with **KWs, gobble WS"""
1708 self
.verify(" #def testMeth($**KWs) \n1234-$KWs\n #end def\n$testMeth",
1712 """#def with *args + **KWs, gobble WS"""
1713 self
.verify(" #def testMeth($*args, $**KWs) \n1234-$args-$KWs\n #end def\n$testMeth",
1717 """#def with *args + **KWs, gobble WS"""
1719 " #def testMeth($*args, $**KWs) \n1234-$args-$KWs.a\n #end def\n$testMeth(1,2, a=1)",
1724 """single line #def with extra WS"""
1726 "#def testMeth: aoeuaoeu\n- $testMeth -",
1730 """single line #def with extra WS and nested $placeholders"""
1732 "#def testMeth: $anInt $aFunc(1234)\n- $testMeth -",
1736 """single line #def escaped $placeholders"""
1738 "#def testMeth: \$aFunc(\$anInt)\n- $testMeth -",
1739 "- $aFunc($anInt) -")
1742 """single line #def 1 escaped $placeholders"""
1744 "#def testMeth: \$aFunc($anInt)\n- $testMeth -",
1748 """single line #def 1 escaped $placeholders + more WS"""
1750 "#def testMeth : \$aFunc($anInt)\n- $testMeth -",
1754 """multiline #def with $ on methodName"""
1755 self
.verify("#def $testMeth\n1234\n#end def\n$testMeth",
1759 """single line #def with $ on methodName"""
1760 self
.verify("#def $testMeth:1234\n$testMeth",
1764 """single line #def with an argument"""
1765 self
.verify("#def $testMeth($arg=1234):$arg\n$testMeth",
1769 class DecoratorDirective(OutputTest
):
1771 """single line #def with decorator"""
1772 self
.verify("#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1774 +"\n#def $testMeth():1234\n$testMeth",
1778 self
.verify("#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1780 +"\n#block $testMeth():1234",
1786 "#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1787 +"#@testdecorator\n sdf"
1788 +"\n#def $testMeth():1234\n$testMeth",
1794 self
.fail('should raise a ParseError')
1796 if versionTuple
< (2,4):
1797 del DecoratorDirective
1799 class BlockDirective(OutputTest
):
1802 """#block without argstring"""
1803 self
.verify("#block testBlock\n1234\n#end block",
1806 self
.verify("#block testBlock ##comment\n1234\n#end block",
1810 """#block without argstring, gobble WS"""
1811 self
.verify(" #block testBlock \n1234\n #end block ",
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 ",
1824 """#block with 2 args, gobble WS"""
1825 self
.verify(" #block testBlock($a=999, $b=444) \n1234-$a$b\n #end block ",
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
1841 #end block innerNest
1842 #end block outerNest
1844 #end block testBlock
1846 "this is a test block\nouter\ninner\n---\n")
1850 """single line #block """
1852 "#block testMeth: This is my block",
1856 """single line #block with WS"""
1858 "#block testMeth: This is my block",
1862 """single line #block 1 escaped $placeholders"""
1864 "#block testMeth: \$aFunc($anInt)",
1868 """single line #block 1 escaped $placeholders + WS"""
1870 "#block testMeth: \$aFunc( $anInt )",
1874 """single line #block 1 escaped $placeholders + more WS"""
1876 "#block testMeth : \$aFunc( $anInt )",
1880 """multiline #block $ on argstring"""
1881 self
.verify("#block $testBlock\n1234\n#end block",
1885 """single line #block with $ on methodName """
1887 "#block $testMeth: This is my block",
1891 """single line #block with an arg """
1893 "#block $testMeth($arg='This is my block'): $arg",
1897 """single line #block with None for content"""
1899 """#block $testMeth: $None\ntest $testMeth-""",
1903 """single line #block with nothing for content"""
1905 """#block $testMeth: \nfoo\n#end block\ntest $testMeth-""",
1908 class IncludeDirective(OutputTest
):
1911 fp
= open('parseTest.txt','w')
1912 fp
.write("$numOne $numTwo")
1917 if os
.path
.exists('parseTest.txt'):
1918 os
.remove('parseTest.txt')
1921 """#include raw of source $emptyString"""
1922 self
.verify("#include raw source=$emptyString",
1926 """#include raw of source $blockToBeParsed"""
1927 self
.verify("#include raw source=$blockToBeParsed",
1931 """#include raw of 'parseTest.txt'"""
1932 self
.verify("#include raw 'parseTest.txt'",
1936 """#include raw of $includeFileName"""
1937 self
.verify("#include raw $includeFileName",
1941 """#include raw of $includeFileName, with WS"""
1942 self
.verify(" #include raw $includeFileName ",
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 ")
1951 """#include of $blockToBeParsed"""
1952 self
.verify("#include source=$blockToBeParsed",
1956 """#include of $blockToBeParsed, with WS"""
1957 self
.verify(" #include source=$blockToBeParsed ",
1961 """#include of 'parseTest.txt', with WS"""
1962 self
.verify(" #include source=$blockToBeParsed ",
1966 """#include of "parseTest.txt", with WS"""
1967 self
.verify(" #include source=$blockToBeParsed ",
1971 """#include of 'parseTest.txt', with WS and surrounding text"""
1972 self
.verify("aoeu\n #include source=$blockToBeParsed \naoeu",
1976 """#include of 'parseTest.txt', with WS and explicit closure"""
1977 self
.verify(" #include source=$blockToBeParsed# ",
1981 class SilentDirective(OutputTest
):
1984 """simple #silent"""
1985 self
.verify("#silent $aFunc",
1989 """simple #silent"""
1990 self
.verify("#silent $anObj.callIt\n$anObj.callArg",
1993 self
.verify("#silent $anObj.callIt ##comment\n$anObj.callArg",
1997 """simple #silent"""
1998 self
.verify("#silent $anObj.callIt(99)\n$anObj.callArg",
2001 class SetDirective(OutputTest
):
2005 self
.verify("#set $testVar = 'blarg'\n$testVar",
2007 self
.verify("#set testVar = 'blarg'\n$testVar",
2011 self
.verify("#set testVar = 'blarg'##comment\n$testVar",
2015 """simple #set with no WS between operands"""
2016 self
.verify("#set $testVar='blarg'",
2019 """#set + use of var"""
2020 self
.verify("#set $testVar = 'blarg'\n$testVar",
2024 """#set + use in an #include"""
2025 self
.verify("#set global $aSetVar = 1234\n#include source=$includeBlock2",
2029 """#set with a dictionary"""
2030 self
.verify( """#set $testDict = {'one':'one1','two':'two2','three':'three3'}
2036 """#set with string, then used in #if block"""
2038 self
.verify("""#set $test='a string'\n#if $test#blarg#end if""",
2042 """simple #set, gobble WS"""
2043 self
.verify(" #set $testVar = 'blarg' ",
2047 """simple #set, don't gobble WS"""
2048 self
.verify(" #set $testVar = 'blarg'#---",
2052 """simple #set with a list"""
2053 self
.verify(" #set $testVar = [1, 2, 3] \n$testVar",
2057 """simple #set global with a list"""
2058 self
.verify(" #set global $testVar = [1, 2, 3] \n$testVar",
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",
2072 """simple #set global with a list and *<int>*cache"""
2073 self
.verify(" #set global $testVar = [1, 2, 3] \n$*5*testVar",
2077 """simple #set with a list and *<float>*cache"""
2078 self
.verify(" #set global $testVar = [1, 2, 3] \n$*.5*testVar",
2082 """simple #set without NameMapper on"""
2083 self
.verify("""#compiler useNameMapper = 0\n#set $testVar = 1 \n$testVar""",
2087 """simple #set without $"""
2088 self
.verify("""#set testVar = 1 \n$testVar""",
2092 """simple #set global without $"""
2093 self
.verify("""#set global testVar = 1 \n$testVar""",
2097 """simple #set module without $"""
2098 self
.verify("""#set module __foo__ = 'bar'\n$__foo__""",
2102 """#set with i,j=list style assignment"""
2103 self
.verify("""#set i,j = [1,2]\n$i$j""",
2105 self
.verify("""#set $i,$j = [1,2]\n$i$j""",
2109 """#set with (i,j)=list style assignment"""
2110 self
.verify("""#set (i,j) = [1,2]\n$i$j""",
2112 self
.verify("""#set ($i,$j) = [1,2]\n$i$j""",
2116 """#set with i, (j,k)=list style assignment"""
2117 self
.verify("""#set i, (j,k) = [1,(2,3)]\n$i$j$k""",
2119 self
.verify("""#set $i, ($j,$k) = [1,(2,3)]\n$i$j$k""",
2123 class IfDirective(OutputTest
):
2126 """simple #if block"""
2127 self
.verify("#if 1\n$aStr\n#end if\n",
2130 self
.verify("#if 1:\n$aStr\n#end if\n",
2133 self
.verify("#if 1: \n$aStr\n#end if\n",
2136 self
.verify("#if 1: ##comment \n$aStr\n#end if\n",
2139 self
.verify("#if 1 ##comment \n$aStr\n#end if\n",
2142 self
.verify("#if 1##for i in range(10)#$i#end for##end if",
2145 self
.verify("#if 1: #for i in range(10)#$i#end for",
2148 self
.verify("#if 1: #for i in range(10):$i",
2152 """simple #if block, with WS"""
2153 self
.verify(" #if 1\n$aStr\n #end if \n",
2156 """simple #if block, with WS and explicit closures"""
2157 self
.verify(" #if 1#\n$aStr\n #end if #--\n",
2161 """#if block using $numOne"""
2162 self
.verify("#if $numOne\n$aStr\n#end if\n",
2166 """#if block using $zero"""
2167 self
.verify("#if $zero\n$aStr\n#end if\n",
2170 """#if block using $emptyString"""
2171 self
.verify("#if $emptyString\n$aStr\n#end if\n",
2174 """#if ... #else ... block using a $emptyString"""
2175 self
.verify("#if $emptyString\n$anInt\n#else\n$anInt - $anInt\n#end if",
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",
2184 """#if 'not' test, with #slurp"""
2185 self
.verify("#if not $emptyString\n$aStr#slurp\n#end if\n",
2189 """#if block using $*emptyString
2194 self
.verify("#if $*emptyString\n$aStr\n#end if\n",
2199 self
.fail('This should barf')
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",
2211 self
.verify(badSyntax
, "")
2215 self
.fail('This should barf')
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",
2225 """#if# ... #else # ... block using a $emptyString with """
2226 self
.verify("#if $emptyString# $anInt#else#$anInt - $anInt#end if",
2230 """single-line #if: simple"""
2231 self
.verify("#if $emptyString then 'true' else 'false'",
2235 """single-line #if: more complex"""
2236 self
.verify("#if $anInt then 'true' else 'false'",
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'",
2245 """single-line #if: """
2246 self
.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2250 self
.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2254 """single-line #if: \n#else: """
2255 self
.verify("#if 1: foo\n#elif 0: bar",
2258 self
.verify("#if 1: foo\n#elif 0: bar\n#else: blarg\n",
2261 self
.verify("#if 0: foo\n#elif 0: bar\n#else: blarg\n",
2264 class UnlessDirective(OutputTest
):
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",
2283 self
.verify("#unless 0\n 1234 \n#end unless",
2288 self
.verify("#unless $none\n 1234 \n#end unless",
2292 """#unless $numTwo"""
2293 self
.verify("#unless $numTwo\n 1234 \n#end unless",
2297 """#unless $numTwo with WS"""
2298 self
.verify(" #unless $numTwo \n 1234 \n #end unless ",
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
):
2310 """simple <%= [int] %>"""
2311 self
.verify("<%= 1234 %>", "1234")
2314 """simple <%= [string] %>"""
2315 self
.verify("<%= 'blarg' %>", "blarg")
2318 """simple <%= None %>"""
2319 self
.verify("<%= None %>", "")
2321 """simple <%= [string] %> + $anInt"""
2322 self
.verify("<%= 'blarg' %>$anInt", "blarg1")
2325 """simple <%= [EXPR] %> + $anInt"""
2326 self
.verify("<%= ('blarg'*2).upper() %>$anInt", "BLARGBLARG1")
2329 """for loop in <%%>"""
2330 self
.verify("<% for i in range(5):%>1<%end%>", "11111")
2333 """for loop in <%%> and using <%=i%>"""
2334 self
.verify("<% for i in range(5):%><%=i%><%end%>", "01234")
2337 """for loop in <% $%> and using <%=i%>"""
2338 self
.verify("""<% for i in range(5):
2339 i=i*2$%><%=i%><%end%>""", "02468")
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
):
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",
2353 class ContinueDirective(OutputTest
):
2355 """#continue with a #while"""
2356 self
.verify("""#set $i = 0
2368 """#continue with a #for"""
2369 self
.verify("""#for $i in range(5)
2377 class BreakDirective(OutputTest
):
2379 """#break with a #while"""
2380 self
.verify("""#set $i = 0
2391 """#break with a #for"""
2392 self
.verify("""#for $i in range(5)
2401 class TryDirective(OutputTest
):
2406 self
.verify("#try\n1234\n#except\nblarg\n#end try",
2410 """#try / #except with #raise
2412 self
.verify("#try\n#raise ValueError\n#except\nblarg\n#end try",
2416 """#try / #except with #raise + WS
2420 self
.verify(" #try \n #raise ValueError \n #except \nblarg\n #end try",
2425 """#try / #except with #raise + WS and leading text
2429 self
.verify("--#try \n #raise ValueError \n #except \nblarg\n #end try#--",
2433 """nested #try / #except with #raise
2447 class PassDirective(OutputTest
):
2449 """#pass in a #try / #except block
2451 self
.verify("#try\n#raise ValueError\n#except\n#pass\n#end try",
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
):
2465 self
.verify("#set $x = 1234\n#assert $x == 1234",
2469 """simple #assert that fails
2471 def test(self
=self
):
2472 self
.verify("#set $x = 1234\n#assert $x == 999",
2474 self
.failUnlessRaises(AssertionError, test
)
2477 """simple #assert with WS
2479 self
.verify("#set $x = 1234\n #assert $x == 1234 ",
2483 class RaiseDirective(OutputTest
):
2485 """simple #raise ValueError
2487 Should raise ValueError
2489 def test(self
=self
):
2490 self
.verify("#raise ValueError",
2492 self
.failUnlessRaises(ValueError, test
)
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
)
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",
2515 class ImportDirective(OutputTest
):
2519 self
.verify("#import math",
2523 """#import math + WS
2527 self
.verify(" #import math ",
2531 """#import math + WS + leading text
2535 self
.verify(" -- #import math ",
2539 """#from math import syn
2541 self
.verify("#from math import cos",
2545 """#from math import cos + WS
2548 self
.verify(" #from math import cos ",
2552 """#from math import cos + WS + leading text
2555 self
.verify(" -- #from math import cos ",
2559 """#from math import cos -- use it
2561 self
.verify("#from math import cos\n$cos(0)",
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)",
2571 """#import os.path -- use it
2574 self
.verify("#import os.path\n$os.path.exists('.')",
2578 """#import os.path -- use it with NameMapper turned off
2583 #end compiler-settings
2585 $os.path.exists('.')""",
2589 """#from math import *
2592 self
.verify("#from math import *\n$pow(1,2) $log10(10)",
2595 class CompilerDirective(OutputTest
):
2597 """overriding the commentStartToken
2599 self
.verify("""$anInt##comment
2600 #compiler commentStartToken = '//'
2606 """overriding and resetting the commentStartToken
2608 self
.verify("""$anInt##comment
2609 #compiler commentStartToken = '//'
2614 "1\n1\n1//comment\n")
2617 class CompilerSettingsDirective(OutputTest
):
2620 """overriding the cheetahVarStartToken
2622 self
.verify("""$anInt
2624 cheetahVarStartToken = @
2625 #end compiler-settings
2627 #compiler-settings reset
2633 """overriding the directiveStartToken
2635 self
.verify("""#set $x = 1234
2638 directiveStartToken = @
2639 #end compiler-settings
2646 """overriding the commentStartToken
2648 self
.verify("""$anInt##comment
2650 commentStartToken = //
2651 #end compiler-settings
2656 if sys
.platform
.startswith('java'):
2657 del CompilerDirective
2658 del CompilerSettingsDirective
2660 class ExtendsDirective(OutputTest
):
2663 """#extends Cheetah.Templates._SkeletonPage"""
2664 self
.verify("""#from Cheetah.Templates._SkeletonPage import _SkeletonPage
2665 #extends _SkeletonPage
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)
2677 '<img src="spacer.gif" width="1" height="1" alt="" />1234\n')
2680 """#extends Cheetah.Templates.SkeletonPage without #import"""
2681 self
.verify("""#extends Cheetah.Templates.SkeletonPage
2685 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2688 """#extends Cheetah.Templates.SkeletonPage.SkeletonPage without #import"""
2689 self
.verify("""#extends Cheetah.Templates.SkeletonPage.SkeletonPage
2693 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2696 """#extends with globals and searchList test"""
2697 self
.verify("""#extends Cheetah.Templates.SkeletonPage
2698 #set global g="Hello"
2704 class ImportantExampleCases(OutputTest
):
2706 """how to make a comma-delimited list"""
2707 self
.verify("""#set $sep = ''
2708 #for $letter in $letterList
2715 class FilterDirective(OutputTest
):
2718 def _getCompilerSettings(self
):
2719 return {'useFilterArgsInPlaceholders':True}
2722 """#filter ReplaceNone
2724 self
.verify("#filter ReplaceNone\n$none#end filter",
2727 self
.verify("#filter ReplaceNone: $none",
2731 """#filter ReplaceNone with WS
2733 self
.verify("#filter ReplaceNone \n$none#end filter",
2737 """#filter MaxLen -- maxlen of 5"""
2739 self
.verify("#filter MaxLen \n${tenDigits, $maxlen=5}#end filter",
2743 """#filter MaxLen -- no maxlen
2745 self
.verify("#filter MaxLen \n${tenDigits}#end filter",
2749 """#filter WebSafe -- basic usage
2751 self
.verify("#filter WebSafe \n$webSafeTest#end filter",
2752 "abc <=> &")
2755 """#filter WebSafe -- also space
2757 self
.verify("#filter WebSafe \n${webSafeTest, $also=' '}#end filter",
2758 "abc <=> &")
2761 """#filter WebSafe -- also space, without $ on the args
2763 self
.verify("#filter WebSafe \n${webSafeTest, also=' '}#end filter",
2764 "abc <=> &")
2767 """#filter Strip -- trailing newline
2769 self
.verify("#filter Strip\n$strip1#end filter",
2770 "strippable whitespace\n")
2773 """#filter Strip -- no trailing newine
2775 self
.verify("#filter Strip\n$strip2#end filter",
2776 "strippable whitespace")
2779 """#filter Strip -- multi-line
2781 self
.verify("#filter Strip\n$strip3#end filter",
2782 "strippable whitespace\n1 2 3\n")
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
):
2795 self
.verify("#echo 1234",
2798 class SilentDirective(OutputTest
):
2802 self
.verify("#silent 1234",
2805 class ErrorCatcherDirective(OutputTest
):
2809 class VarExists(OutputTest
): # Template.varExists()
2812 """$varExists('$anInt')
2814 self
.verify("$varExists('$anInt')",
2818 """$varExists('anInt')
2820 self
.verify("$varExists('anInt')",
2824 """$varExists('$anInt')
2826 self
.verify("$varExists('$bogus')",
2830 """$varExists('$anInt') combined with #if false
2832 self
.verify("#if $varExists('$bogus')\n1234\n#else\n999\n#end if",
2836 """$varExists('$anInt') combined with #if true
2838 self
.verify("#if $varExists('$anInt')\n1234\n#else\n999#end if",
2841 class GetVar(OutputTest
): # Template.getVar()
2843 """$getVar('$anInt')
2845 self
.verify("$getVar('$anInt')",
2851 self
.verify("$getVar('anInt')",
2855 """$self.getVar('anInt')
2857 self
.verify("$self.getVar('anInt')",
2861 """$getVar('bogus', 1234)
2863 self
.verify("$getVar('bogus', 1234)",
2867 """$getVar('$bogus', 1234)
2869 self
.verify("$getVar('$bogus', 1234)",
2873 class MiscComplexSyntax(OutputTest
):
2875 """Complex use of {},[] and () in a #set expression
2877 #set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]
2880 self
.verify("#set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]\n$c",
2884 class CGI(OutputTest
):
2885 """CGI scripts with(out) the CGI environment and with(out) GET variables.
2889 def _beginCGI(self
):
2890 os
.environ
['REQUEST_METHOD'] = "GET"
2893 del os
.environ
['REQUEST_METHOD']
2896 _guaranteeNoCGI
= _endCGI
2900 """A regular template."""
2901 self
._guaranteeNoCGI
()
2902 source
= "#extends Cheetah.Tools.CGITemplate\n" + \
2903 "#implements respond\n" + \
2904 "$cgiHeaders#slurp\n" + \
2906 self
.verify(source
, "Hello, world!")
2912 source
= "#extends Cheetah.Tools.CGITemplate\n" + \
2913 "#implements respond\n" + \
2914 "$cgiHeaders#slurp\n" + \
2916 self
.verify(source
, "Content-type: text/html\n\nHello, world!")
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.
2934 source
= "#extends Cheetah.Tools.CGITemplate\n" + \
2935 "#implements respond\n" + \
2936 "<% self._CHEETAH__isControlledByWebKit = True %>#slurp\n" + \
2937 "$cgiHeaders#slurp\n" + \
2939 self
.verify(source
, "Hello, world!")
2944 """A CGI script with a GET variable."""
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" + \
2953 "Content-type: text/html\n\nHello, world!")
2954 del os
.environ
['QUERY_STRING']
2959 class WhitespaceAfterDirectiveTokens(OutputTest
):
2960 def _getCompilerSettings(self
):
2961 return {'allowWhitespaceAfterDirectiveStartToken':True}
2964 self
.verify("# for i in range(10): $i",
2966 self
.verify("# for i in range(10)\n$i# end for",
2968 self
.verify("# for i in range(10)#$i#end for",
2973 class DefmacroDirective(OutputTest
):
2974 def _getCompilerSettings(self
):
2978 return {'macroDirectives':{'aMacro':aMacro
2983 #defmacro inc: #set @src +=1
2993 #for i in range(10): @src
2996 #for i in range(3): $i""",
2997 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo012")
3001 #for i in range(10): @src
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")
3009 #defmacro test: #for i in range(10): @src
3011 -#for i in range(3): $i""",
3012 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3015 #defmacro test##for i in range(10): @src#end defmacro##slurp
3017 -#for i in range(3): $i""",
3018 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
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")
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")
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")
3041 self
.verify("#aMacro: foo",
3043 self
.verify("#defmacro nested: @macros.aMacro(@src)\n#nested: foo",
3047 class Indenter(OutputTest
):
3053 #for $method in $methods
3060 #def getMethod($method)
3062 public $getType($method) ${method.Name}($getParams($method.Params));
3066 #def getParams($params)
3069 #for $counter in $range($len($params))
3070 #if $counter == len($params) - 1
3071 $params[$counter]#slurp
3079 #def getType($method)
3082 #if $method.Type == "VT_VOID"
3084 #elif $method.Type == "VT_INT"
3086 #elif $method.Type == "VT_VARIANT"
3118 def _getCompilerSettings(self
):
3119 return {'useFilterArgsInPlaceholders':True}
3121 def searchList(self
): # Inside Indenter class.
3123 def __init__(self
, _name
, _type
, *_params
):
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}
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()
3156 if versionTuple
>= (2,3):
3157 src
= r
"class %(name)s_DiffBaseClass(%(name)s): "%locals()
3158 src
+= " _extraCompileKwArgs = extraCompileKwArgsForDiffBaseclass"
3164 ##################################################
3165 ## if run from the command line ##
3167 if __name__
== '__main__':
3170 # vim: shiftwidth=4 tabstop=4 expandtab