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.
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 $
20 __author__
= "Tavis Rudd <tavis@damnsimple.com>"
21 __revision__
= "$Revision: 1.109 $"[11:-2]
24 ##################################################
30 from copy
import deepcopy
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
)
53 True, False = (1==1),(1==0)
55 ##################################################
56 ## TEST DATA FOR USE IN THE TEMPLATES ##
58 def testdecorator(func
):
66 def meth(self
, arg
="arff"):
69 def meth1(self
, arg
="doo"):
72 def meth2(self
, arg1
="a1", arg2
="a2"):
73 return str(arg1
) + str(arg2
)
75 def methWithPercentSignDefaultArg(self
, arg1
="110%"):
78 def callIt(self
, arg
=1234):
83 def dummyFunc(arg
="Scooby"):
86 defaultTestNameSpace
= {
90 'aList': ['item0','item1','item2'],
91 'aDict': {'one':'item1',
93 'nestedDict':{1:'nestedItem1',
96 'nestedFunc':dummyFunc
,
99 'anObj': DummyClass(),
100 'aMeth': DummyClass().meth1
,
101 'aStrToBeIncluded': "$aStr $anInt",
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
,],
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 ##################################################
132 class OutputTest(unittest
.TestCase
):
134 Template output mismatch:
146 _EOLreplacement
= None
147 _debugEOLReplacement
= False
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
,
163 convertEOLs
=Unspecified
):
164 if self
._EOLreplacement
:
165 if convertEOLs
is Unspecified
:
166 convertEOLs
= self
.convertEOLs
168 input = input.replace('\n', self
._EOLreplacement
)
169 expectedOutput
= expectedOutput
.replace('\n', self
._EOLreplacement
)
172 if self
._useNewStyleCompilation
:
173 extraKwArgs
= self
._extraCompileKwArgs
or {}
175 templateClass
= Template
.compile(
177 compilerSettings
=self
._getCompilerSettings
(),
178 keepRefToGeneratedCode
=True,
181 moduleCode
= templateClass
._CHEETAH
_generatedModuleCode
182 self
.template
= templateObj
= templateClass(searchList
=self
.searchList())
184 self
.template
= templateObj
= Template(
186 searchList
=self
.searchList(),
187 compilerSettings
=self
._getCompilerSettings
(),
189 moduleCode
= templateObj
._CHEETAH
_generatedModuleCode
190 if self
.DEBUGLEV
>= 1:
194 output
= templateObj
.respond() # rather than __str__, because of unicode
196 output
= output
.decode(outputEncoding
)
197 assert output
==expectedOutput
, self
._outputMismatchReport
(output
, expectedOutput
)
199 #print >>sys.stderr, moduleCode
202 templateObj
.shutdown()
204 def _getCompilerSettings(self
):
207 def _outputMismatchReport(self
, output
, expectedOutput
):
208 if self
._debugEOLReplacement
and self
._EOLreplacement
:
209 EOLrepl
= self
._EOLreplacement
211 return self
.report
% {'template': self
._input
.replace(EOLrepl
,marker
),
212 'expected': expectedOutput
.replace(EOLrepl
,marker
),
213 'actual': output
.replace(EOLrepl
,marker
),
216 return self
.report
% {'template': self
._input
,
217 'expected': expectedOutput
,
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 ##################################################
232 class EmptyTemplate(OutputTest
):
235 """an empty string for the template"""
237 warnings
.filterwarnings('error',
238 'You supplied an empty string for the source!',
245 self
.fail("Should warn about empty source strings.")
248 self
.verify("#implements foo", "")
249 except NotImplementedError:
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
):
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')
269 if os
.path
.exists('backslashes.txt'):
270 os
.remove('backslashes.txt')
273 """ a single \\ using rawstrings"""
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")
283 """ a single \\ without using rawstrings"""
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"')
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')
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')
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")
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):
322 """dollar signs not in Cheetah $vars"""
323 self.verify("$ $$ $5 $. $ test",
327 """hash not in #directives"""
328 self.verify("# \# #5 ",
332 """escapted comments"""
333 self.verify(" \##escaped comment ",
334 " ##escaped comment ")
337 """escapted multi-line comments"""
338 self.verify(" \#*escaped comment \n*# ",
339 " #*escaped comment \n*# ")
346 """1 dollar sign followed by hash"""
347 self.verify("\n$#\n",
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
'],
356 self.verify("\n$#\n",
359 class Comments_SingleLine(OutputTest):
361 """## followed by WS"""
366 """## followed by NEWLINE"""
371 """## followed by text then NEWLINE"""
372 self.verify("## oeuao aoe uaoe \n",
375 """## gobbles leading WS"""
376 self.verify(" ## oeuao aoe uaoe \n",
380 """## followed by text then NEWLINE, + leading WS"""
381 self.verify(" ## oeuao aoe uaoe \n",
385 """## followed by EOF"""
390 """## followed by EOF with leading WS"""
396 with text on previous and following lines"""
397 self.verify("line1\n ## aoeu 1234 \nline2",
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")
407 """## containing $placeholders
409 self.verify("##$a$b $c($d)",
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}
429 """#* *# followed by WS
432 self.verify("#* blarg *# ",
436 """#* *# preceded and followed by WS
439 self.verify(" #* blarg *# ",
443 """#* *# followed by WS, with NEWLINE
446 self.verify("#* \nblarg\n *# ",
450 """#* *# preceded and followed by WS, with NEWLINE
453 self.verify(" #* \nblarg\n *# ",
456 class Comments_MultiLine(OutputTest):
458 Note
: Multiline comments don
't gobble whitespace!
462 """#* *# followed by WS
465 self.verify("#* blarg *# ",
469 """#* *# preceded and followed by WS
472 self.verify(" #* blarg *# ",
476 """#* *# followed by WS, with NEWLINE
479 self.verify("#* \nblarg\n *# ",
483 """#* *# preceded and followed by WS, with NEWLINE
486 self.verify(" #* \nblarg\n *# ",
490 """#* *# containing nothing
496 """#* *# containing only NEWLINES
498 self.verify(" #*\n\n\n\n\n\n\n\n*# ",
502 """#* *# containing $placeholders
504 self.verify("#* $var $var(1234*$c) *#",
508 """#* *# containing #for directive
510 self.verify("#* #for $i in range(15) *#",
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")
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")
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):
536 self.verify("$aStr", "blarg")
540 self.verify("$aStr $anInt", "blarg 1")
543 """2 placeholders, back-to-back"""
544 self.verify("$aStr$anInt", "blarg1")
547 """1 placeholder enclosed in ()"""
548 self.verify("$(aStr)", "blarg")
551 """1 placeholder enclosed in {}"""
552 self.verify("${aStr}", "blarg")
555 """1 placeholder enclosed in []"""
556 self.verify("$[aStr]", "blarg")
559 """1 placeholder enclosed in () + WS
561 Test to make sure that $(<WS><identifier>.. matches
563 self.verify("$( aStr )", "blarg")
566 """1 placeholder enclosed in {} + WS"""
567 self.verify("${ aStr }", "blarg")
570 """1 placeholder enclosed in [] + WS"""
571 self.verify("$[ aStr ]", "blarg")
574 """1 placeholder enclosed in () + WS + * cache
576 Test to make sure that $*(<WS><identifier>.. matches
578 self.verify("$*( aStr )", "blarg")
581 """1 placeholder enclosed in {} + WS + *cache"""
582 self.verify("$*{ aStr }", "blarg")
585 """1 placeholder enclosed in [] + WS + *cache"""
586 self.verify("$*[ aStr ]", "blarg")
589 """1 placeholder enclosed in {} + WS + *<int>*cache"""
590 self.verify("$*5*{ aStr }", "blarg")
593 """1 placeholder enclosed in [] + WS + *<int>*cache"""
594 self.verify("$*5*[ aStr ]", "blarg")
597 """1 placeholder enclosed in {} + WS + *<float>*cache"""
598 self.verify("$*0.5d*{ aStr }", "blarg")
601 """1 placeholder enclosed in [] + WS + *<float>*cache"""
602 self.verify("$*.5*[ aStr ]", "blarg")
605 """1 placeholder + *<int>*cache"""
606 self.verify("$*5*aStr", "blarg")
609 """1 placeholder *<float>*cache"""
610 self.verify("$*0.5h*aStr", "blarg")
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'""")
618 """silent mode $!placeholders """
619 self.verify("$!aStr$!nonExistant$!*nonExistant$!{nonExistant}", "blarg")
622 self.verify("$!aStr$nonExistant",
627 self.fail('should
raise NotFound exception
')
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
):
654 self
.verify("$aStr", "blarg")
657 """string - with whitespace"""
658 self
.verify(" $aStr ", " blarg ")
661 """empty string - with whitespace"""
662 self
.verify("$emptyString", "")
666 self
.verify("$anInt", "1")
670 self
.verify("$aFloat", "1.5")
674 self
.verify("$aList", "['item0', 'item1', 'item2']")
679 The default output filter is ReplaceNone.
681 self
.verify("$none", "")
686 self
.verify("$True $False", "%s %s"%(repr(True), repr(False)))
691 self
.verify("$_('foo')", "Translated: foo")
693 class PlaceholderStrings(OutputTest
):
695 """some c'text $placeholder text' strings"""
696 self
.verify("$str(c'$aStr')", "blarg")
699 """some c'text $placeholder text' strings"""
700 self
.verify("$str(c'$aStr.upper')", "BLARG")
703 """some c'text $placeholder text' strings"""
704 self
.verify("$str(c'$(aStr.upper.replace(c\"A$str()\",\"\"))')", "BLRG")
707 """some c'text $placeholder text' strings"""
708 self
.verify("#echo $str(c'$(aStr.upper)')", "BLARG")
711 """some c'text $placeholder text' strings"""
712 self
.verify("#if 1 then $str(c'$(aStr.upper)') else 0", "BLARG")
715 """some c'text $placeholder text' strings"""
716 self
.verify("#if 1\n$str(c'$(aStr.upper)')#slurp\n#else\n0#end if", "BLARG")
719 """some c'text $placeholder text' strings"""
720 self
.verify("#def foo(arg=c'$(\"BLARG\")')\n"
723 "$foo()$foo(c'$anInt')#slurp",
729 class UnicodeStrings(OutputTest
):
731 """unicode data in placeholder
733 #self.verify(u"$unicodeData", defaultTestNameSpace['unicodeData'], outputEncoding='utf8')
734 self
.verify(u
"$unicodeData", defaultTestNameSpace
['unicodeData'])
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
):
744 """basic #encoding """
745 self
.verify("#encoding utf-8\n1234",
749 """basic #encoding """
750 self
.verify("#encoding ascii\n1234",
754 """basic #encoding """
755 self
.verify("#encoding utf-8\n\xe1\x88\xb4",
756 u
'\u1234', outputEncoding
='utf8')
759 """basic #encoding """
760 self
.verify("#encoding ascii\n\xe1\x88\xb4",
764 """basic #encoding """
765 self
.verify("#encoding latin-1\nAndr\202",
766 u
'Andr\202', outputEncoding
='latin-1')
768 class UnicodeDirective(OutputTest
):
770 """basic #unicode """
771 self
.verify("#unicode utf-8\n1234",
774 self
.verify("#unicode ascii\n1234",
777 self
.verify("#unicode latin-1\n1234",
780 self
.verify("#unicode latin-1\n1234ü",
782 self
.verify("#unicode: latin-1\n1234ü",
784 self
.verify("# unicode : latin-1\n1234ü",
787 self
.verify(u
"#unicode latin-1\n1234ü",
790 self
.verify("#encoding latin-1\n1234ü",
793 class Placeholders_Esc(OutputTest
):
796 """1 escaped placeholder"""
801 """2 escaped placeholders"""
802 self
.verify("\$var \$_",
806 """2 escaped placeholders - back to back"""
807 self
.verify("\$var\$_",
811 """2 escaped placeholders - nested"""
812 self
.verify("\$var(\$_)",
816 """2 escaped placeholders - nested and enclosed"""
817 self
.verify("\$(var(\$_)",
821 class Placeholders_Calls(OutputTest
):
823 """func placeholder - no ()"""
824 self
.verify("$aFunc",
828 """func placeholder - with ()"""
829 self
.verify("$aFunc()",
833 r
"""func placeholder - with (\n\n)"""
834 self
.verify("$aFunc(\n\n)",
835 "Scooby", convertEOLs
=False)
838 r
"""func placeholder - with (\n\n) and $() enclosure"""
839 self
.verify("$(aFunc(\n\n))",
840 "Scooby", convertEOLs
=False)
843 r
"""func placeholder - with (\n\n) and ${} enclosure"""
844 self
.verify("${aFunc(\n\n)}",
845 "Scooby", convertEOLs
=False)
848 """func placeholder - with (int)"""
849 self
.verify("$aFunc(1234)",
853 r
"""func placeholder - with (\nint\n)"""
854 self
.verify("$aFunc(\n1234\n)",
855 "1234", convertEOLs
=False)
857 """func placeholder - with (string)"""
858 self
.verify("$aFunc('aoeu')",
862 """func placeholder - with ('''string''')"""
863 self
.verify("$aFunc('''aoeu''')",
866 r
"""func placeholder - with ('''\nstring\n''')"""
867 self
.verify("$aFunc('''\naoeu\n''')",
871 r
"""func placeholder - with ('''\nstring'\n''')"""
872 self
.verify("$aFunc('''\naoeu'\n''')",
876 r
'''func placeholder - with ("""\nstring\n""")'''
877 self
.verify('$aFunc("""\naoeu\n""")',
881 """func placeholder - with (string*int)"""
882 self
.verify("$aFunc('aoeu'*2)",
886 """func placeholder - with (int*int)"""
887 self
.verify("$aFunc(2*2)",
891 """func placeholder - with (int*float)"""
892 self
.verify("$aFunc(2*2.0)",
896 r
"""func placeholder - with (int\n*\nfloat)"""
897 self
.verify("$aFunc(2\n*\n2.0)",
898 "4.0", convertEOLs
=False)
901 """func placeholder - with ($arg=float)"""
902 self
.verify("$aFunc($arg=4.0)",
906 """func placeholder - with (arg=float)"""
907 self
.verify("$aFunc(arg=4.0)",
911 """deeply nested argstring, no enclosure"""
912 self
.verify("$aFunc($arg=$aMeth($arg=$aFunc(1)))",
916 """deeply nested argstring, no enclosure + with WS"""
917 self
.verify("$aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) )",
920 """deeply nested argstring, () enclosure + with WS"""
921 self
.verify("$(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
925 """deeply nested argstring, {} enclosure + with WS"""
926 self
.verify("${aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) }",
930 """deeply nested argstring, [] enclosure + with WS"""
931 self
.verify("$[aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) ]",
935 """deeply nested argstring, () enclosure + *cache"""
936 self
.verify("$*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
939 """deeply nested argstring, () enclosure + *15*cache"""
940 self
.verify("$*15*(aFunc( $arg = $aMeth( $arg = $aFunc( 1 ) ) ) )",
944 """a function call with the Python None kw."""
945 self
.verify("$aFunc(None)",
948 class NameMapper(OutputTest
):
951 self
.verify("$aFunc! $aFunc().",
955 """nested autocalling"""
956 self
.verify("$aFunc($aFunc).",
960 """list subscription"""
961 self
.verify("$aList[0]",
966 self
.verify("$aList[:2]",
967 "['item0', 'item1']")
970 """list slicing and subcription combined"""
971 self
.verify("$aList[:2][0]",
975 """dictionary access - NameMapper style"""
976 self
.verify("$aDict.one",
980 """dictionary access - Python style"""
981 self
.verify("$aDict['one']",
985 """dictionary access combined with autocalled string method"""
986 self
.verify("$aDict.one.upper",
990 """dictionary access combined with string method"""
991 self
.verify("$aDict.one.upper()",
995 """nested dictionary access - NameMapper style"""
996 self
.verify("$aDict.nestedDict.two",
1000 """nested dictionary access - Python style"""
1001 self
.verify("$aDict['nestedDict']['two']",
1005 """nested dictionary access - alternating style"""
1006 self
.verify("$aDict['nestedDict'].two",
1010 """nested dictionary access using method - alternating style"""
1011 self
.verify("$aDict.get('nestedDict').two",
1015 """nested dictionary access - NameMapper style - followed by method"""
1016 self
.verify("$aDict.nestedDict.two.upper",
1020 """nested dictionary access - alternating style - followed by method"""
1021 self
.verify("$aDict['nestedDict'].two.upper",
1025 """nested dictionary access - NameMapper style - followed by method, then slice"""
1026 self
.verify("$aDict.nestedDict.two.upper[:4]",
1030 """nested dictionary access - Python style using a soft-coded key"""
1031 self
.verify("$aDict[$anObj.meth('nestedDict')].two",
1035 """object method access"""
1036 self
.verify("$anObj.meth1",
1040 """object method access, followed by complex slice"""
1041 self
.verify("$anObj.meth1[0: ((4/4*2)*2)/$anObj.meth1(2) ]",
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 ] )",
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
1056 self
.verify("$anObj.methWithPercentSignDefaultArg",
1060 #class NameMapperDict(OutputTest):
1062 # _searchList = [{"update": "Yabba dabba doo!"}]
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
):
1073 r
"""simple #cache """
1074 self
.verify("#cache:$anInt",
1078 r
"""simple #cache + WS"""
1079 self
.verify(" #cache \n$anInt#end cache",
1083 r
"""simple #cache ... #end cache"""
1084 self
.verify("""#cache id='cache1', timer=150m
1091 r
"""2 #cache ... #end cache blocks"""
1092 self
.verify("""#slurp
1094 #cache ID='cache1', timer=150m
1097 #cache id='cache2', timer=15s
1104 $foo$foo$foo$foo$foo""",
1109 r
"""nested #cache blocks"""
1110 self
.verify("""#slurp
1112 #cache ID='cache1', timer=150m
1114 #cache id='cache2', timer=15s
1123 $foo$foo$foo$foo$foo""",
1127 r
"""Make sure that partial directives don't match"""
1128 self
.verify("#cache_foo",
1130 self
.verify("#cached",
1133 class CallDirective(OutputTest
):
1136 r
"""simple #call """
1137 self
.verify("#call int\n$anInt#end call",
1139 # single line version
1140 self
.verify("#call int: $anInt",
1142 self
.verify("#call int: 10\n$aStr",
1146 r
"""simple #call + WS"""
1147 self
.verify("#call int\n$anInt #end call",
1151 r
"""a longer #call"""
1162 r
"""#call with keyword #args"""
1164 #def meth(arg1, arg2)
1165 $arg1.upper() - $arg2.lower()#slurp
1176 r
"""#call with single-line keyword #args """
1178 #def meth(arg1, arg2)
1179 $arg1.upper() - $arg2.lower()#slurp
1182 #arg arg1:$(1234+1) foo#slurp
1183 #arg arg2:UPPER#slurp
1188 """#call with python kwargs and cheetah output for the 1s positional
1192 #def meth(arg1, arg2)
1193 $arg1.upper() - $arg2.lower()#slurp
1195 #call self.meth arg2="UPPER"
1201 """#call with python kwargs and #args"""
1203 #def meth(arg1, arg2, arg3)
1204 $arg1.upper() - $arg2.lower() - $arg3#slurp
1206 #call self.meth arg2="UPPER", arg3=999
1207 #arg arg1:$(1234+1) foo#slurp
1209 "1235 FOO - upper - 999")
1212 """#call with python kwargs and #args, and using a function to get the
1213 function that will be called"""
1215 #def meth(arg1, arg2, arg3)
1216 $arg1.upper() - $arg2.lower() - $arg3#slurp
1218 #call getattr(self, "meth") arg2="UPPER", arg3=999
1219 #arg arg1:$(1234+1) foo#slurp
1221 "1235 FOO - upper - 999")
1224 """nested #call directives"""
1241 #call self.meth2 y=c"$(10/$two)"
1251 class I18nDirective(OutputTest
):
1253 r
"""simple #call """
1254 self
.verify("#i18n \n$anInt#end i18n",
1257 # single line version
1258 self
.verify("#i18n: $anInt",
1260 self
.verify("#i18n: 10\n$aStr",
1264 class CaptureDirective(OutputTest
):
1266 r
"""simple #capture"""
1277 r
"""slightly more complex #capture"""
1283 $(1234+1) $anInt $meth("foo")#slurp
1290 class SlurpDirective(OutputTest
):
1292 r
"""#slurp with 1 \n """
1293 self
.verify("#slurp\n",
1297 r
"""#slurp with 1 \n, leading whitespace
1299 self
.verify(" #slurp\n",
1303 r
"""#slurp with 1 \n, leading content
1305 self
.verify(" 1234 #slurp\n",
1309 r
"""#slurp with WS then \n, leading content
1311 self
.verify(" 1234 #slurp \n",
1315 r
"""#slurp with garbage chars then \n, leading content
1316 Should eat the garbage"""
1317 self
.verify(" 1234 #slurp garbage \n",
1322 class EOLSlurpToken(OutputTest
):
1323 _EOLSlurpToken
= DEFAULT_COMPILER_SETTINGS
['EOLSlurpToken']
1325 r
"""#slurp with 1 \n """
1326 self
.verify("%s\n"%self
._EOLSlurpToken
,
1330 r
"""#slurp with 1 \n, leading whitespace
1332 self
.verify(" %s\n"%self
._EOLSlurpToken
,
1335 r
"""#slurp with 1 \n, leading content
1337 self
.verify(" 1234 %s\n"%self
._EOLSlurpToken
,
1341 r
"""#slurp with WS then \n, leading content
1343 self
.verify(" 1234 %s \n"%self
._EOLSlurpToken
,
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']:
1355 class RawDirective(OutputTest
):
1358 self
.verify("#raw\n$aFunc().\n\n",
1362 """#raw till #end raw"""
1363 self
.verify("#raw\n$aFunc().\n#end raw\n$anInt",
1367 """#raw till #end raw gobble WS"""
1368 self
.verify(" #raw \n$aFunc().\n #end raw \n$anInt",
1372 """#raw till #end raw using explicit directive closure
1374 self
.verify(" #raw #\n$aFunc().\n #end raw #\n$anInt",
1375 " \n$aFunc().\n\n1")
1378 """single-line short form #raw: """
1379 self
.verify("#raw: $aFunc().\n\n",
1382 self
.verify("#raw: $aFunc().\n$anInt",
1385 class BreakpointDirective(OutputTest
):
1387 """#breakpoint part way through source code"""
1388 self
.verify("$aFunc(2).\n#breakpoint\n$anInt",
1392 """#breakpoint at BOF"""
1393 self
.verify("#breakpoint\n$anInt",
1397 """#breakpoint at EOF"""
1398 self
.verify("$anInt\n#breakpoint",
1402 class StopDirective(OutputTest
):
1404 """#stop part way through source code"""
1405 self
.verify("$aFunc(2).\n#stop\n$anInt",
1410 self
.verify("#stop\n$anInt",
1415 self
.verify("$anInt\n#stop",
1419 """#stop in pos test block"""
1420 self
.verify("""$anInt
1426 "1\ninside the if block\n")
1429 """#stop in neg test block"""
1430 self
.verify("""$anInt
1439 class ReturnDirective(OutputTest
):
1442 """#return'ing an int """
1458 """#return'ing an string """
1473 """#return'ing an string AND streaming other output via the transaction"""
1475 $str($test(trans=trans)[1])
1489 class YieldDirective(OutputTest
):
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"
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):
1516 class ForDirective(OutputTest
):
1519 """#for loop with one local var"""
1520 self
.verify("#for $i in range(5)\n$i\n#end for",
1523 self
.verify("#for $i in range(5):\n$i\n#end for",
1526 self
.verify("#for $i in range(5): ##comment\n$i\n#end for",
1529 self
.verify("#for $i in range(5) ##comment\n$i\n#end for",
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")
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")
1544 """#for loop over list"""
1545 self
.verify("#for $i, $j in [(0,1),(2,3)]\n$i,$j\n#end for",
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",
1554 """#for loop with explicit closures"""
1555 self
.verify("#for $i in range(5)#$i#end for#",
1559 """#for loop with explicit closures and WS"""
1560 self
.verify(" #for $i in range(5)#$i#end for# ",
1564 """#for loop using another $var"""
1565 self
.verify(" #for $i in range($aFunc(5))#$i#end for# ",
1569 """test methods in for loops"""
1570 self
.verify("#for $func in $listOfLambdas\n$func($anInt)\n#end for",
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",
1578 self
.verify("#for $i, $j in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
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",
1585 self
.verify("#for ($i, $j) in [('aa','bb'),('cc','dd')]\n$i.upper,$j.upper\n#end for",
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",
1592 self
.verify("#for $i, ($j, $k) in enumerate([('aa','bb'),('cc','dd')])\n$j.upper,$k.upper\n#end for",
1596 """single line #for"""
1597 self
.verify("#for $i in range($aFunc(5)): $i",
1601 """single line #for with 1 extra leading space"""
1602 self
.verify("#for $i in range($aFunc(5)): $i",
1606 """2 times single line #for"""
1607 self
.verify("#for $i in range($aFunc(5)): $i#slurp\n"*2,
1611 """false single line #for """
1612 self
.verify("#for $i in range(5): \n$i\n#end for",
1615 if versionTuple
< (2,3):
1616 del ForDirective
.test12
1618 class RepeatDirective(OutputTest
):
1622 self
.verify("#repeat 3\n1\n#end repeat",
1624 self
.verify("#repeat 3: \n1\n#end repeat",
1627 self
.verify("#repeat 3 ##comment\n1\n#end repeat",
1630 self
.verify("#repeat 3: ##comment\n1\n#end repeat",
1634 """#repeat with numeric expression"""
1635 self
.verify("#repeat 3*3/3\n1\n#end repeat",
1639 """#repeat with placeholder"""
1640 self
.verify("#repeat $numTwo\n1\n#end repeat",
1644 """#repeat with placeholder * num"""
1645 self
.verify("#repeat $numTwo*1\n1\n#end repeat",
1649 """#repeat with placeholder and WS"""
1650 self
.verify(" #repeat $numTwo \n1\n #end repeat ",
1654 """single-line #repeat"""
1655 self
.verify("#repeat $numTwo: 1",
1657 self
.verify("#repeat $numTwo: 1\n"*2,
1661 self
.verify("#repeat 3: \n1\n#end repeat",
1665 class AttrDirective(OutputTest
):
1668 """#attr with int"""
1669 self
.verify("#attr $test = 1234\n$test",
1673 """#attr with string"""
1674 self
.verify("#attr $test = 'blarg'\n$test",
1678 """#attr with expression"""
1679 self
.verify("#attr $test = 'blarg'.upper()*2\n$test",
1683 """#attr with string + WS
1685 self
.verify(" #attr $test = 'blarg' \n$test",
1689 """#attr with string + WS + leading text
1691 self
.verify(" -- #attr $test = 'blarg' \n$test",
1695 class DefDirective(OutputTest
):
1698 """#def without argstring"""
1699 self
.verify("#def testMeth\n1234\n#end def\n$testMeth",
1702 self
.verify("#def testMeth ## comment\n1234\n#end def\n$testMeth",
1705 self
.verify("#def testMeth: ## comment\n1234\n#end def\n$testMeth",
1709 """#def without argstring, gobble WS"""
1710 self
.verify(" #def testMeth \n1234\n #end def \n$testMeth",
1714 """#def with argstring, gobble WS"""
1715 self
.verify(" #def testMeth($a=999) \n1234-$a\n #end def\n$testMeth",
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')",
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])",
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")
1734 """#def with *args, gobble WS"""
1735 self
.verify(" #def testMeth($*args) \n1234-$args\n #end def\n$testMeth",
1739 """#def with **KWs, gobble WS"""
1740 self
.verify(" #def testMeth($**KWs) \n1234-$KWs\n #end def\n$testMeth",
1744 """#def with *args + **KWs, gobble WS"""
1745 self
.verify(" #def testMeth($*args, $**KWs) \n1234-$args-$KWs\n #end def\n$testMeth",
1749 """#def with *args + **KWs, gobble WS"""
1751 " #def testMeth($*args, $**KWs) \n1234-$args-$KWs.a\n #end def\n$testMeth(1,2, a=1)",
1756 """single line #def with extra WS"""
1758 "#def testMeth: aoeuaoeu\n- $testMeth -",
1762 """single line #def with extra WS and nested $placeholders"""
1764 "#def testMeth: $anInt $aFunc(1234)\n- $testMeth -",
1768 """single line #def escaped $placeholders"""
1770 "#def testMeth: \$aFunc(\$anInt)\n- $testMeth -",
1771 "- $aFunc($anInt) -")
1774 """single line #def 1 escaped $placeholders"""
1776 "#def testMeth: \$aFunc($anInt)\n- $testMeth -",
1780 """single line #def 1 escaped $placeholders + more WS"""
1782 "#def testMeth : \$aFunc($anInt)\n- $testMeth -",
1786 """multiline #def with $ on methodName"""
1787 self
.verify("#def $testMeth\n1234\n#end def\n$testMeth",
1791 """single line #def with $ on methodName"""
1792 self
.verify("#def $testMeth:1234\n$testMeth",
1796 """single line #def with an argument"""
1797 self
.verify("#def $testMeth($arg=1234):$arg\n$testMeth",
1801 class DecoratorDirective(OutputTest
):
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"
1811 +"\n#def $testMeth():1234\n$testMeth",
1815 self
.verify("#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1817 +"\n#block $testMeth():1234",
1823 "#from Cheetah.Tests.SyntaxAndOutput import testdecorator\n"
1824 +"#@testdecorator\n sdf"
1825 +"\n#def $testMeth():1234\n$testMeth",
1831 self
.fail('should raise a ParseError')
1833 if versionTuple
< (2,4):
1834 del DecoratorDirective
1836 class BlockDirective(OutputTest
):
1839 """#block without argstring"""
1840 self
.verify("#block testBlock\n1234\n#end block",
1843 self
.verify("#block testBlock ##comment\n1234\n#end block",
1847 """#block without argstring, gobble WS"""
1848 self
.verify(" #block testBlock \n1234\n #end block ",
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 ",
1861 """#block with 2 args, gobble WS"""
1862 self
.verify(" #block testBlock($a=999, $b=444) \n1234-$a$b\n #end block ",
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
1878 #end block innerNest
1879 #end block outerNest
1881 #end block testBlock
1883 "this is a test block\nouter\ninner\n---\n")
1887 """single line #block """
1889 "#block testMeth: This is my block",
1893 """single line #block with WS"""
1895 "#block testMeth: This is my block",
1899 """single line #block 1 escaped $placeholders"""
1901 "#block testMeth: \$aFunc($anInt)",
1905 """single line #block 1 escaped $placeholders + WS"""
1907 "#block testMeth: \$aFunc( $anInt )",
1911 """single line #block 1 escaped $placeholders + more WS"""
1913 "#block testMeth : \$aFunc( $anInt )",
1917 """multiline #block $ on argstring"""
1918 self
.verify("#block $testBlock\n1234\n#end block",
1922 """single line #block with $ on methodName """
1924 "#block $testMeth: This is my block",
1928 """single line #block with an arg """
1930 "#block $testMeth($arg='This is my block'): $arg",
1934 """single line #block with None for content"""
1936 """#block $testMeth: $None\ntest $testMeth-""",
1940 """single line #block with nothing for content"""
1942 """#block $testMeth: \nfoo\n#end block\ntest $testMeth-""",
1945 class IncludeDirective(OutputTest
):
1948 fp
= open('parseTest.txt','w')
1949 fp
.write("$numOne $numTwo")
1954 if os
.path
.exists('parseTest.txt'):
1955 os
.remove('parseTest.txt')
1958 """#include raw of source $emptyString"""
1959 self
.verify("#include raw source=$emptyString",
1963 """#include raw of source $blockToBeParsed"""
1964 self
.verify("#include raw source=$blockToBeParsed",
1968 """#include raw of 'parseTest.txt'"""
1969 self
.verify("#include raw 'parseTest.txt'",
1973 """#include raw of $includeFileName"""
1974 self
.verify("#include raw $includeFileName",
1978 """#include raw of $includeFileName, with WS"""
1979 self
.verify(" #include raw $includeFileName ",
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 ")
1988 """#include of $blockToBeParsed"""
1989 self
.verify("#include source=$blockToBeParsed",
1993 """#include of $blockToBeParsed, with WS"""
1994 self
.verify(" #include source=$blockToBeParsed ",
1998 """#include of 'parseTest.txt', with WS"""
1999 self
.verify(" #include source=$blockToBeParsed ",
2003 """#include of "parseTest.txt", with WS"""
2004 self
.verify(" #include source=$blockToBeParsed ",
2008 """#include of 'parseTest.txt', with WS and surrounding text"""
2009 self
.verify("aoeu\n #include source=$blockToBeParsed \naoeu",
2013 """#include of 'parseTest.txt', with WS and explicit closure"""
2014 self
.verify(" #include source=$blockToBeParsed# ",
2018 class SilentDirective(OutputTest
):
2021 """simple #silent"""
2022 self
.verify("#silent $aFunc",
2026 """simple #silent"""
2027 self
.verify("#silent $anObj.callIt\n$anObj.callArg",
2030 self
.verify("#silent $anObj.callIt ##comment\n$anObj.callArg",
2034 """simple #silent"""
2035 self
.verify("#silent $anObj.callIt(99)\n$anObj.callArg",
2038 class SetDirective(OutputTest
):
2042 self
.verify("#set $testVar = 'blarg'\n$testVar",
2044 self
.verify("#set testVar = 'blarg'\n$testVar",
2048 self
.verify("#set testVar = 'blarg'##comment\n$testVar",
2052 """simple #set with no WS between operands"""
2053 self
.verify("#set $testVar='blarg'",
2056 """#set + use of var"""
2057 self
.verify("#set $testVar = 'blarg'\n$testVar",
2061 """#set + use in an #include"""
2062 self
.verify("#set global $aSetVar = 1234\n#include source=$includeBlock2",
2066 """#set with a dictionary"""
2067 self
.verify( """#set $testDict = {'one':'one1','two':'two2','three':'three3'}
2073 """#set with string, then used in #if block"""
2075 self
.verify("""#set $test='a string'\n#if $test#blarg#end if""",
2079 """simple #set, gobble WS"""
2080 self
.verify(" #set $testVar = 'blarg' ",
2084 """simple #set, don't gobble WS"""
2085 self
.verify(" #set $testVar = 'blarg'#---",
2089 """simple #set with a list"""
2090 self
.verify(" #set $testVar = [1, 2, 3] \n$testVar",
2094 """simple #set global with a list"""
2095 self
.verify(" #set global $testVar = [1, 2, 3] \n$testVar",
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",
2109 """simple #set global with a list and *<int>*cache"""
2110 self
.verify(" #set global $testVar = [1, 2, 3] \n$*5*testVar",
2114 """simple #set with a list and *<float>*cache"""
2115 self
.verify(" #set global $testVar = [1, 2, 3] \n$*.5*testVar",
2119 """simple #set without NameMapper on"""
2120 self
.verify("""#compiler useNameMapper = 0\n#set $testVar = 1 \n$testVar""",
2124 """simple #set without $"""
2125 self
.verify("""#set testVar = 1 \n$testVar""",
2129 """simple #set global without $"""
2130 self
.verify("""#set global testVar = 1 \n$testVar""",
2134 """simple #set module without $"""
2135 self
.verify("""#set module __foo__ = 'bar'\n$__foo__""",
2139 """#set with i,j=list style assignment"""
2140 self
.verify("""#set i,j = [1,2]\n$i$j""",
2142 self
.verify("""#set $i,$j = [1,2]\n$i$j""",
2146 """#set with (i,j)=list style assignment"""
2147 self
.verify("""#set (i,j) = [1,2]\n$i$j""",
2149 self
.verify("""#set ($i,$j) = [1,2]\n$i$j""",
2153 """#set with i, (j,k)=list style assignment"""
2154 self
.verify("""#set i, (j,k) = [1,(2,3)]\n$i$j$k""",
2156 self
.verify("""#set $i, ($j,$k) = [1,(2,3)]\n$i$j$k""",
2160 class IfDirective(OutputTest
):
2163 """simple #if block"""
2164 self
.verify("#if 1\n$aStr\n#end if\n",
2167 self
.verify("#if 1:\n$aStr\n#end if\n",
2170 self
.verify("#if 1: \n$aStr\n#end if\n",
2173 self
.verify("#if 1: ##comment \n$aStr\n#end if\n",
2176 self
.verify("#if 1 ##comment \n$aStr\n#end if\n",
2179 self
.verify("#if 1##for i in range(10)#$i#end for##end if",
2182 self
.verify("#if 1: #for i in range(10)#$i#end for",
2185 self
.verify("#if 1: #for i in range(10):$i",
2189 """simple #if block, with WS"""
2190 self
.verify(" #if 1\n$aStr\n #end if \n",
2193 """simple #if block, with WS and explicit closures"""
2194 self
.verify(" #if 1#\n$aStr\n #end if #--\n",
2198 """#if block using $numOne"""
2199 self
.verify("#if $numOne\n$aStr\n#end if\n",
2203 """#if block using $zero"""
2204 self
.verify("#if $zero\n$aStr\n#end if\n",
2207 """#if block using $emptyString"""
2208 self
.verify("#if $emptyString\n$aStr\n#end if\n",
2211 """#if ... #else ... block using a $emptyString"""
2212 self
.verify("#if $emptyString\n$anInt\n#else\n$anInt - $anInt\n#end if",
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",
2221 """#if 'not' test, with #slurp"""
2222 self
.verify("#if not $emptyString\n$aStr#slurp\n#end if\n",
2226 """#if block using $*emptyString
2231 self
.verify("#if $*emptyString\n$aStr\n#end if\n",
2236 self
.fail('This should barf')
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",
2248 self
.verify(badSyntax
, "")
2252 self
.fail('This should barf')
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",
2262 """#if# ... #else # ... block using a $emptyString with """
2263 self
.verify("#if $emptyString# $anInt#else#$anInt - $anInt#end if",
2267 """single-line #if: simple"""
2268 self
.verify("#if $emptyString then 'true' else 'false'",
2272 """single-line #if: more complex"""
2273 self
.verify("#if $anInt then 'true' else 'false'",
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'",
2282 """single-line #if: """
2283 self
.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2287 self
.verify("#if 1: foo\n#if 0: bar\n#if 1: foo",
2291 """single-line #if: \n#else: """
2292 self
.verify("#if 1: foo\n#elif 0: bar",
2295 self
.verify("#if 1: foo\n#elif 0: bar\n#else: blarg\n",
2298 self
.verify("#if 0: foo\n#elif 0: bar\n#else: blarg\n",
2301 class UnlessDirective(OutputTest
):
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",
2320 self
.verify("#unless 0\n 1234 \n#end unless",
2325 self
.verify("#unless $none\n 1234 \n#end unless",
2329 """#unless $numTwo"""
2330 self
.verify("#unless $numTwo\n 1234 \n#end unless",
2334 """#unless $numTwo with WS"""
2335 self
.verify(" #unless $numTwo \n 1234 \n #end unless ",
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
):
2347 """simple <%= [int] %>"""
2348 self
.verify("<%= 1234 %>", "1234")
2351 """simple <%= [string] %>"""
2352 self
.verify("<%= 'blarg' %>", "blarg")
2355 """simple <%= None %>"""
2356 self
.verify("<%= None %>", "")
2358 """simple <%= [string] %> + $anInt"""
2359 self
.verify("<%= 'blarg' %>$anInt", "blarg1")
2362 """simple <%= [EXPR] %> + $anInt"""
2363 self
.verify("<%= ('blarg'*2).upper() %>$anInt", "BLARGBLARG1")
2366 """for loop in <%%>"""
2367 self
.verify("<% for i in range(5):%>1<%end%>", "11111")
2370 """for loop in <%%> and using <%=i%>"""
2371 self
.verify("<% for i in range(5):%><%=i%><%end%>", "01234")
2374 """for loop in <% $%> and using <%=i%>"""
2375 self
.verify("""<% for i in range(5):
2376 i=i*2$%><%=i%><%end%>""", "02468")
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
):
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",
2390 class ContinueDirective(OutputTest
):
2392 """#continue with a #while"""
2393 self
.verify("""#set $i = 0
2405 """#continue with a #for"""
2406 self
.verify("""#for $i in range(5)
2414 class BreakDirective(OutputTest
):
2416 """#break with a #while"""
2417 self
.verify("""#set $i = 0
2428 """#break with a #for"""
2429 self
.verify("""#for $i in range(5)
2438 class TryDirective(OutputTest
):
2443 self
.verify("#try\n1234\n#except\nblarg\n#end try",
2447 """#try / #except with #raise
2449 self
.verify("#try\n#raise ValueError\n#except\nblarg\n#end try",
2453 """#try / #except with #raise + WS
2457 self
.verify(" #try \n #raise ValueError \n #except \nblarg\n #end try",
2462 """#try / #except with #raise + WS and leading text
2466 self
.verify("--#try \n #raise ValueError \n #except \nblarg\n #end try#--",
2470 """nested #try / #except with #raise
2484 class PassDirective(OutputTest
):
2486 """#pass in a #try / #except block
2488 self
.verify("#try\n#raise ValueError\n#except\n#pass\n#end try",
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
):
2502 self
.verify("#set $x = 1234\n#assert $x == 1234",
2506 """simple #assert that fails
2508 def test(self
=self
):
2509 self
.verify("#set $x = 1234\n#assert $x == 999",
2511 self
.failUnlessRaises(AssertionError, test
)
2514 """simple #assert with WS
2516 self
.verify("#set $x = 1234\n #assert $x == 1234 ",
2520 class RaiseDirective(OutputTest
):
2522 """simple #raise ValueError
2524 Should raise ValueError
2526 def test(self
=self
):
2527 self
.verify("#raise ValueError",
2529 self
.failUnlessRaises(ValueError, test
)
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
)
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",
2552 class ImportDirective(OutputTest
):
2556 self
.verify("#import math",
2560 """#import math + WS
2564 self
.verify(" #import math ",
2568 """#import math + WS + leading text
2572 self
.verify(" -- #import math ",
2576 """#from math import syn
2578 self
.verify("#from math import cos",
2582 """#from math import cos + WS
2585 self
.verify(" #from math import cos ",
2589 """#from math import cos + WS + leading text
2592 self
.verify(" -- #from math import cos ",
2596 """#from math import cos -- use it
2598 self
.verify("#from math import cos\n$cos(0)",
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)",
2608 """#import os.path -- use it
2611 self
.verify("#import os.path\n$os.path.exists('.')",
2615 """#import os.path -- use it with NameMapper turned off
2620 #end compiler-settings
2622 $os.path.exists('.')""",
2626 """#from math import *
2629 self
.verify("#from math import *\n$pow(1,2) $log10(10)",
2632 class CompilerDirective(OutputTest
):
2634 """overriding the commentStartToken
2636 self
.verify("""$anInt##comment
2637 #compiler commentStartToken = '//'
2643 """overriding and resetting the commentStartToken
2645 self
.verify("""$anInt##comment
2646 #compiler commentStartToken = '//'
2651 "1\n1\n1//comment\n")
2654 class CompilerSettingsDirective(OutputTest
):
2657 """overriding the cheetahVarStartToken
2659 self
.verify("""$anInt
2661 cheetahVarStartToken = @
2662 #end compiler-settings
2664 #compiler-settings reset
2670 """overriding the directiveStartToken
2672 self
.verify("""#set $x = 1234
2675 directiveStartToken = @
2676 #end compiler-settings
2683 """overriding the commentStartToken
2685 self
.verify("""$anInt##comment
2687 commentStartToken = //
2688 #end compiler-settings
2693 if sys
.platform
.startswith('java'):
2694 del CompilerDirective
2695 del CompilerSettingsDirective
2697 class ExtendsDirective(OutputTest
):
2700 """#extends Cheetah.Templates._SkeletonPage"""
2701 self
.verify("""#from Cheetah.Templates._SkeletonPage import _SkeletonPage
2702 #extends _SkeletonPage
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)
2714 '<img src="spacer.gif" width="1" height="1" alt="" />1234\n')
2717 """#extends Cheetah.Templates.SkeletonPage without #import"""
2718 self
.verify("""#extends Cheetah.Templates.SkeletonPage
2722 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2725 """#extends Cheetah.Templates.SkeletonPage.SkeletonPage without #import"""
2726 self
.verify("""#extends Cheetah.Templates.SkeletonPage.SkeletonPage
2730 '<img src="spacer.gif" width="1" height="1" alt="" />\n')
2733 """#extends with globals and searchList test"""
2734 self
.verify("""#extends Cheetah.Templates.SkeletonPage
2735 #set global g="Hello"
2742 class SuperDirective(OutputTest
):
2744 tmpl1
= Template
.compile('''$foo $bar(99)
2745 #def foo: this is base foo
2746 #def bar(arg): super-$arg''')
2748 tmpl2
= tmpl1
.subclass('''
2756 #def bar(arg): #super($arg)
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
):
2766 """how to make a comma-delimited list"""
2767 self
.verify("""#set $sep = ''
2768 #for $letter in $letterList
2775 class FilterDirective(OutputTest
):
2778 def _getCompilerSettings(self
):
2779 return {'useFilterArgsInPlaceholders':True}
2784 self
.verify("#filter Filter\n$none#end filter",
2787 self
.verify("#filter Filter: $none",
2791 """#filter ReplaceNone with WS
2793 self
.verify("#filter Filter \n$none#end filter",
2797 """#filter MaxLen -- maxlen of 5"""
2799 self
.verify("#filter MaxLen \n${tenDigits, $maxlen=5}#end filter",
2803 """#filter MaxLen -- no maxlen
2805 self
.verify("#filter MaxLen \n${tenDigits}#end filter",
2809 """#filter WebSafe -- basic usage
2811 self
.verify("#filter WebSafe \n$webSafeTest#end filter",
2812 "abc <=> &")
2815 """#filter WebSafe -- also space
2817 self
.verify("#filter WebSafe \n${webSafeTest, $also=' '}#end filter",
2818 "abc <=> &")
2821 """#filter WebSafe -- also space, without $ on the args
2823 self
.verify("#filter WebSafe \n${webSafeTest, also=' '}#end filter",
2824 "abc <=> &")
2827 """#filter Strip -- trailing newline
2829 self
.verify("#filter Strip\n$strip1#end filter",
2830 "strippable whitespace\n")
2833 """#filter Strip -- no trailing newine
2835 self
.verify("#filter Strip\n$strip2#end filter",
2836 "strippable whitespace")
2839 """#filter Strip -- multi-line
2841 self
.verify("#filter Strip\n$strip3#end filter",
2842 "strippable whitespace\n1 2 3\n")
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
):
2855 self
.verify("#echo 1234",
2858 class SilentDirective(OutputTest
):
2862 self
.verify("#silent 1234",
2865 class ErrorCatcherDirective(OutputTest
):
2869 class VarExists(OutputTest
): # Template.varExists()
2872 """$varExists('$anInt')
2874 self
.verify("$varExists('$anInt')",
2878 """$varExists('anInt')
2880 self
.verify("$varExists('anInt')",
2884 """$varExists('$anInt')
2886 self
.verify("$varExists('$bogus')",
2890 """$varExists('$anInt') combined with #if false
2892 self
.verify("#if $varExists('$bogus')\n1234\n#else\n999\n#end if",
2896 """$varExists('$anInt') combined with #if true
2898 self
.verify("#if $varExists('$anInt')\n1234\n#else\n999#end if",
2901 class GetVar(OutputTest
): # Template.getVar()
2903 """$getVar('$anInt')
2905 self
.verify("$getVar('$anInt')",
2911 self
.verify("$getVar('anInt')",
2915 """$self.getVar('anInt')
2917 self
.verify("$self.getVar('anInt')",
2921 """$getVar('bogus', 1234)
2923 self
.verify("$getVar('bogus', 1234)",
2927 """$getVar('$bogus', 1234)
2929 self
.verify("$getVar('$bogus', 1234)",
2933 class MiscComplexSyntax(OutputTest
):
2935 """Complex use of {},[] and () in a #set expression
2937 #set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]
2940 self
.verify("#set $c = {'A':0}[{}.get('a', {'a' : 'A'}['a'])]\n$c",
2944 class CGI(OutputTest
):
2945 """CGI scripts with(out) the CGI environment and with(out) GET variables.
2949 def _beginCGI(self
):
2950 os
.environ
['REQUEST_METHOD'] = "GET"
2953 del os
.environ
['REQUEST_METHOD']
2956 _guaranteeNoCGI
= _endCGI
2960 """A regular template."""
2961 self
._guaranteeNoCGI
()
2962 source
= "#extends Cheetah.Tools.CGITemplate\n" + \
2963 "#implements respond\n" + \
2964 "$cgiHeaders#slurp\n" + \
2966 self
.verify(source
, "Hello, world!")
2972 source
= "#extends Cheetah.Tools.CGITemplate\n" + \
2973 "#implements respond\n" + \
2974 "$cgiHeaders#slurp\n" + \
2976 self
.verify(source
, "Content-type: text/html\n\nHello, world!")
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.
2994 source
= "#extends Cheetah.Tools.CGITemplate\n" + \
2995 "#implements respond\n" + \
2996 "<% self._CHEETAH__isControlledByWebKit = True %>#slurp\n" + \
2997 "$cgiHeaders#slurp\n" + \
2999 self
.verify(source
, "Hello, world!")
3004 """A CGI script with a GET variable."""
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" + \
3013 "Content-type: text/html\n\nHello, world!")
3014 del os
.environ
['QUERY_STRING']
3019 class WhitespaceAfterDirectiveTokens(OutputTest
):
3020 def _getCompilerSettings(self
):
3021 return {'allowWhitespaceAfterDirectiveStartToken':True}
3024 self
.verify("# for i in range(10): $i",
3026 self
.verify("# for i in range(10)\n$i# end for",
3028 self
.verify("# for i in range(10)#$i#end for",
3033 class DefmacroDirective(OutputTest
):
3034 def _getCompilerSettings(self
):
3038 return {'macroDirectives':{'aMacro':aMacro
3043 #defmacro inc: #set @src +=1
3053 #for i in range(10): @src
3056 #for i in range(3): $i""",
3057 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo012")
3061 #for i in range(10): @src
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")
3069 #defmacro test: #for i in range(10): @src
3071 -#for i in range(3): $i""",
3072 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
3075 #defmacro test##for i in range(10): @src#end defmacro##slurp
3077 -#for i in range(3): $i""",
3078 "0-foo1-foo2-foo3-foo4-foo5-foo6-foo7-foo8-foo9-foo-012")
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")
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")
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")
3101 self
.verify("#aMacro: foo",
3103 self
.verify("#defmacro nested: @macros.aMacro(@src)\n#nested: foo",
3107 class Indenter(OutputTest
):
3113 #for $method in $methods
3120 #def getMethod($method)
3122 public $getType($method) ${method.Name}($getParams($method.Params));
3126 #def getParams($params)
3129 #for $counter in $range($len($params))
3130 #if $counter == len($params) - 1
3131 $params[$counter]#slurp
3139 #def getType($method)
3142 #if $method.Type == "VT_VOID"
3144 #elif $method.Type == "VT_INT"
3146 #elif $method.Type == "VT_VARIANT"
3178 def _getCompilerSettings(self
):
3179 return {'useFilterArgsInPlaceholders':True}
3181 def searchList(self
): # Inside Indenter class.
3183 def __init__(self
, _name
, _type
, *_params
):
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}
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()
3216 if versionTuple
>= (2,3):
3217 src
= r
"class %(name)s_DiffBaseClass(%(name)s): "%locals()
3218 src
+= " _extraCompileKwArgs = extraCompileKwArgsForDiffBaseclass"
3224 ##################################################
3225 ## if run from the command line ##
3227 if __name__
== '__main__':
3230 # vim: shiftwidth=4 tabstop=4 expandtab