1#!/usr/bin/env python 2 3import sys 4import types 5import os 6import os.path 7 8import unittest 9from Cheetah.NameMapper import NotFound, valueForKey, \ 10 valueForName, valueFromSearchList, valueFromFrame, valueFromFrameOrSearchList 11 12 13class DummyClass(object): 14 classVar1 = 123 15 16 def __init__(self): 17 self.instanceVar1 = 123 18 19 def __str__(self): 20 return 'object' 21 22 def meth(self, arg="arff"): 23 return str(arg) 24 25 def meth1(self, arg="doo"): 26 return arg 27 28 def meth2(self, arg1="a1", arg2="a2"): 29 raise ValueError 30 31 def meth3(self): 32 """Tests a bug that Jeff Johnson reported on Oct 1, 2001""" 33 34 x = 'A string' 35 try: 36 for i in [1, 2, 3, 4]: 37 if x == 2: 38 pass 39 40 if x == 'xx': 41 pass 42 return x 43 except: 44 raise 45 46class DummyClassGetAttrRaises(object): 47 def __getattr__(self, name): 48 raise ValueError 49 50 51def dummyFunc(arg="Scooby"): 52 return arg 53 54def funcThatRaises(): 55 raise ValueError 56 57 58testNamespace = { 59 'aStr': 'blarg', 60 'anInt': 1, 61 'aFloat': 1.5, 62 'aDict': {'one': 'item1', 63 'two': 'item2', 64 'nestedDict': {'one': 'nestedItem1', 65 'two': 'nestedItem2', 66 'funcThatRaises': funcThatRaises, 67 'aClass': DummyClass, 68 }, 69 'nestedFunc': dummyFunc, 70 }, 71 'aClass': DummyClass, 72 'aFunc': dummyFunc, 73 'anObj': DummyClass(), 74 'anObjThatRaises': DummyClassGetAttrRaises(), 75 'aMeth': DummyClass().meth1, 76 'none': None, 77 'emptyString': '', 78 'funcThatRaises': funcThatRaises, 79 } 80 81autoCallResults = {'aFunc': 'Scooby', 82 'aMeth': 'doo', 83 } 84 85results = testNamespace.copy() 86results.update({'anObj.meth1': 'doo', 87 'aDict.one': 'item1', 88 'aDict.nestedDict': testNamespace['aDict']['nestedDict'], 89 'aDict.nestedDict.one': 'nestedItem1', 90 'aDict.nestedDict.aClass': DummyClass, 91 'aDict.nestedFunc': 'Scooby', 92 'aClass.classVar1': 123, 93 'anObj.instanceVar1': 123, 94 'anObj.meth3': 'A string', 95 }) 96 97for k in testNamespace.keys(): 98 # put them in the globals for the valueFromFrame tests 99 exec('%s = testNamespace[k]'%k) 100 101################################################## 102## TEST BASE CLASSES 103 104class NameMapperTest(unittest.TestCase): 105 failureException = NotFound 106 _testNamespace = testNamespace 107 _results = results 108 109 def namespace(self): 110 return self._testNamespace 111 112 def VFN(self, name, autocall=True): 113 return valueForName(self.namespace(), name, autocall) 114 115 def VFS(self, searchList, name, autocall=True): 116 return valueFromSearchList(searchList, name, autocall) 117 118 119 # alias to be overriden later 120 get = VFN 121 122 def check(self, name): 123 got = self.get(name) 124 if name in autoCallResults: 125 expected = autoCallResults[name] 126 else: 127 expected = self._results[name] 128 assert got == expected 129 130 131################################################## 132## TEST CASE CLASSES 133 134class VFN(NameMapperTest): 135 136 def test1(self): 137 """string in dict lookup""" 138 self.check('aStr') 139 140 def test2(self): 141 """string in dict lookup in a loop""" 142 for i in range(10): 143 self.check('aStr') 144 145 def test3(self): 146 """int in dict lookup""" 147 self.check('anInt') 148 149 def test4(self): 150 """int in dict lookup in a loop""" 151 for i in range(10): 152 self.check('anInt') 153 154 def test5(self): 155 """float in dict lookup""" 156 self.check('aFloat') 157 158 def test6(self): 159 """float in dict lookup in a loop""" 160 for i in range(10): 161 self.check('aFloat') 162 163 def test7(self): 164 """class in dict lookup""" 165 self.check('aClass') 166 167 def test8(self): 168 """class in dict lookup in a loop""" 169 for i in range(10): 170 self.check('aClass') 171 172 def test9(self): 173 """aFunc in dict lookup""" 174 self.check('aFunc') 175 176 def test10(self): 177 """aFunc in dict lookup in a loop""" 178 for i in range(10): 179 self.check('aFunc') 180 181 def test11(self): 182 """aMeth in dict lookup""" 183 self.check('aMeth') 184 185 def test12(self): 186 """aMeth in dict lookup in a loop""" 187 for i in range(10): 188 self.check('aMeth') 189 190 def test13(self): 191 """aMeth in dict lookup""" 192 self.check('aMeth') 193 194 def test14(self): 195 """aMeth in dict lookup in a loop""" 196 for i in range(10): 197 self.check('aMeth') 198 199 def test15(self): 200 """anObj in dict lookup""" 201 self.check('anObj') 202 203 def test16(self): 204 """anObj in dict lookup in a loop""" 205 for i in range(10): 206 self.check('anObj') 207 208 def test17(self): 209 """aDict in dict lookup""" 210 self.check('aDict') 211 212 def test18(self): 213 """aDict in dict lookup in a loop""" 214 for i in range(10): 215 self.check('aDict') 216 217 def test17(self): 218 """aDict in dict lookup""" 219 self.check('aDict') 220 221 def test18(self): 222 """aDict in dict lookup in a loop""" 223 for i in range(10): 224 self.check('aDict') 225 226 def test19(self): 227 """aClass.classVar1 in dict lookup""" 228 self.check('aClass.classVar1') 229 230 def test20(self): 231 """aClass.classVar1 in dict lookup in a loop""" 232 for i in range(10): 233 self.check('aClass.classVar1') 234 235 236 def test23(self): 237 """anObj.instanceVar1 in dict lookup""" 238 self.check('anObj.instanceVar1') 239 240 def test24(self): 241 """anObj.instanceVar1 in dict lookup in a loop""" 242 for i in range(10): 243 self.check('anObj.instanceVar1') 244 245 ## tests 22, 25, and 26 removed when the underscored lookup was removed 246 247 def test27(self): 248 """anObj.meth1 in dict lookup""" 249 self.check('anObj.meth1') 250 251 def test28(self): 252 """anObj.meth1 in dict lookup in a loop""" 253 for i in range(10): 254 self.check('anObj.meth1') 255 256 def test29(self): 257 """aDict.one in dict lookup""" 258 self.check('aDict.one') 259 260 def test30(self): 261 """aDict.one in dict lookup in a loop""" 262 for i in range(10): 263 self.check('aDict.one') 264 265 def test31(self): 266 """aDict.nestedDict in dict lookup""" 267 self.check('aDict.nestedDict') 268 269 def test32(self): 270 """aDict.nestedDict in dict lookup in a loop""" 271 for i in range(10): 272 self.check('aDict.nestedDict') 273 274 def test33(self): 275 """aDict.nestedDict.one in dict lookup""" 276 self.check('aDict.nestedDict.one') 277 278 def test34(self): 279 """aDict.nestedDict.one in dict lookup in a loop""" 280 for i in range(10): 281 self.check('aDict.nestedDict.one') 282 283 def test35(self): 284 """aDict.nestedFunc in dict lookup""" 285 self.check('aDict.nestedFunc') 286 287 def test36(self): 288 """aDict.nestedFunc in dict lookup in a loop""" 289 for i in range(10): 290 self.check('aDict.nestedFunc') 291 292 def test37(self): 293 """aDict.nestedFunc in dict lookup - without autocalling""" 294 assert self.get('aDict.nestedFunc', False) == dummyFunc 295 296 def test38(self): 297 """aDict.nestedFunc in dict lookup in a loop - without autocalling""" 298 for i in range(10): 299 assert self.get('aDict.nestedFunc', False) == dummyFunc 300 301 def test39(self): 302 """aMeth in dict lookup - without autocalling""" 303 assert self.get('aMeth', False) == self.namespace()['aMeth'] 304 305 def test40(self): 306 """aMeth in dict lookup in a loop - without autocalling""" 307 for i in range(10): 308 assert self.get('aMeth', False) == self.namespace()['aMeth'] 309 310 def test41(self): 311 """anObj.meth3 in dict lookup""" 312 self.check('anObj.meth3') 313 314 def test42(self): 315 """aMeth in dict lookup in a loop""" 316 for i in range(10): 317 self.check('anObj.meth3') 318 319 def test43(self): 320 """NotFound test""" 321 322 def test(self=self): 323 self.get('anObj.methX') 324 self.assertRaises(NotFound, test) 325 326 def test44(self): 327 """NotFound test in a loop""" 328 def test(self=self): 329 self.get('anObj.methX') 330 331 for i in range(10): 332 self.assertRaises(NotFound, test) 333 334 def test45(self): 335 """Other exception from meth test""" 336 337 def test(self=self): 338 self.get('anObj.meth2') 339 self.assertRaises(ValueError, test) 340 341 def test46(self): 342 """Other exception from meth test in a loop""" 343 def test(self=self): 344 self.get('anObj.meth2') 345 346 for i in range(10): 347 self.assertRaises(ValueError, test) 348 349 def test47(self): 350 """None in dict lookup""" 351 self.check('none') 352 353 def test48(self): 354 """None in dict lookup in a loop""" 355 for i in range(10): 356 self.check('none') 357 358 def test49(self): 359 """EmptyString in dict lookup""" 360 self.check('emptyString') 361 362 def test50(self): 363 """EmptyString in dict lookup in a loop""" 364 for i in range(10): 365 self.check('emptyString') 366 367 def test51(self): 368 """Other exception from func test""" 369 370 def test(self=self): 371 self.get('funcThatRaises') 372 self.assertRaises(ValueError, test) 373 374 def test52(self): 375 """Other exception from func test in a loop""" 376 def test(self=self): 377 self.get('funcThatRaises') 378 379 for i in range(10): 380 self.assertRaises(ValueError, test) 381 382 383 def test53(self): 384 """Other exception from func test""" 385 386 def test(self=self): 387 self.get('aDict.nestedDict.funcThatRaises') 388 self.assertRaises(ValueError, test) 389 390 def test54(self): 391 """Other exception from func test in a loop""" 392 def test(self=self): 393 self.get('aDict.nestedDict.funcThatRaises') 394 395 for i in range(10): 396 self.assertRaises(ValueError, test) 397 398 def test55(self): 399 """aDict.nestedDict.aClass in dict lookup""" 400 self.check('aDict.nestedDict.aClass') 401 402 def test56(self): 403 """aDict.nestedDict.aClass in dict lookup in a loop""" 404 for i in range(10): 405 self.check('aDict.nestedDict.aClass') 406 407 def test57(self): 408 """aDict.nestedDict.aClass in dict lookup - without autocalling""" 409 assert self.get('aDict.nestedDict.aClass', False) == DummyClass 410 411 def test58(self): 412 """aDict.nestedDict.aClass in dict lookup in a loop - without autocalling""" 413 for i in range(10): 414 assert self.get('aDict.nestedDict.aClass', False) == DummyClass 415 416 def test59(self): 417 """Other exception from func test -- but without autocalling shouldn't raise""" 418 419 self.get('aDict.nestedDict.funcThatRaises', False) 420 421 def test60(self): 422 """Other exception from func test in a loop -- but without autocalling shouldn't raise""" 423 424 for i in range(10): 425 self.get('aDict.nestedDict.funcThatRaises', False) 426 427 def test61(self): 428 """Accessing attribute where __getattr__ raises shouldn't segfault if something follows it""" 429 430 def test(self=self): 431 self.get('anObjThatRaises.willraise.anything') 432 self.assertRaises(ValueError, test) 433 434 435class VFS(VFN): 436 _searchListLength = 1 437 438 def searchList(self): 439 lng = self._searchListLength 440 if lng == 1: 441 return [self.namespace()] 442 elif lng == 2: 443 return [self.namespace(), {'dummy':1234}] 444 elif lng == 3: 445 # a tuple for kicks 446 return ({'dummy':1234}, self.namespace(), {'dummy':1234}) 447 elif lng == 4: 448 # a generator for more kicks 449 return self.searchListGenerator() 450 451 def searchListGenerator(self): 452 class Test: 453 pass 454 for i in [Test(), {'dummy':1234}, self.namespace(), {'dummy':1234}]: 455 yield i 456 457 def get(self, name, autocall=True): 458 return self.VFS(self.searchList(), name, autocall) 459 460class VFS_2namespaces(VFS): 461 _searchListLength = 2 462 463class VFS_3namespaces(VFS): 464 _searchListLength = 3 465 466class VFS_4namespaces(VFS): 467 _searchListLength = 4 468 469class VFF(VFN): 470 def get(self, name, autocall=True): 471 ns = self._testNamespace 472 aStr = ns['aStr'] 473 aFloat = ns['aFloat'] 474 none = 'some' 475 return valueFromFrame(name, autocall) 476 477 def setUp(self): 478 """Mod some of the data 479 """ 480 self._testNamespace = ns = self._testNamespace.copy() 481 self._results = res = self._results.copy() 482 ns['aStr'] = res['aStr'] = 'BLARG' 483 ns['aFloat'] = res['aFloat'] = 0.1234 484 res['none'] = 'some' 485 res['True'] = True 486 res['False'] = False 487 res['None'] = None 488 res['eval'] = eval 489 490 def test_VFF_1(self): 491 """Builtins""" 492 self.check('True') 493 self.check('None') 494 self.check('False') 495 assert self.get('eval', False)==eval 496 assert self.get('range', False)==range 497 498class VFFSL(VFS): 499 _searchListLength = 1 500 501 def setUp(self): 502 """Mod some of the data 503 """ 504 self._testNamespace = ns = self._testNamespace.copy() 505 self._results = res = self._results.copy() 506 ns['aStr'] = res['aStr'] = 'BLARG' 507 ns['aFloat'] = res['aFloat'] = 0.1234 508 res['none'] = 'some' 509 510 del ns['anInt'] # will be picked up by globals 511 512 def VFFSL(self, searchList, name, autocall=True): 513 anInt = 1 514 none = 'some' 515 return valueFromFrameOrSearchList(searchList, name, autocall) 516 517 def get(self, name, autocall=True): 518 return self.VFFSL(self.searchList(), name, autocall) 519 520class VFFSL_2(VFFSL): 521 _searchListLength = 2 522 523class VFFSL_3(VFFSL): 524 _searchListLength = 3 525 526class VFFSL_4(VFFSL): 527 _searchListLength = 4 528 529if sys.platform.startswith('java'): 530 del VFF, VFFSL, VFFSL_2, VFFSL_3, VFFSL_4 531 532 533class MapBuiltins(unittest.TestCase): 534 def test_int(self): 535 from Cheetah.Template import Template 536 t = Template(''' 537 #def intify(val) 538 #return $int(val) 539 #end def''', compilerSettings={'useStackFrames' : False}) 540 self.assertEquals(5, t.intify('5')) 541 542 543 544################################################## 545## if run from the command line ## 546 547if __name__ == '__main__': 548 unittest.main() 549