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