1 """ Tests for the linecache module """ 2 3 import linecache 4 import unittest 5 import os.path 6 from test import test_support as support 7 8 9 FILENAME = linecache.__file__ 10 INVALID_NAME = '!@$)(!@#_1' 11 EMPTY = '' 12 TESTS = 'inspect_fodder inspect_fodder2 mapping_tests' 13 TESTS = TESTS.split() 14 TEST_PATH = os.path.dirname(support.__file__) 15 MODULES = "linecache abc".split() 16 MODULE_PATH = os.path.dirname(FILENAME) 17 18 SOURCE_1 = ''' 19 " Docstring " 20 21 def function(): 22 return result 23 24 ''' 25 26 SOURCE_2 = ''' 27 def f(): 28 return 1 + 1 29 30 a = f() 31 32 ''' 33 34 SOURCE_3 = ''' 35 def f(): 36 return 3''' # No ending newline 37 38 39 class LineCacheTests(unittest.TestCase): 40 41 def test_getline(self): 42 getline = linecache.getline 43 44 # Bad values for line number should return an empty string 45 self.assertEqual(getline(FILENAME, 2**15), EMPTY) 46 self.assertEqual(getline(FILENAME, -1), EMPTY) 47 48 # Float values currently raise TypeError, should it? 49 self.assertRaises(TypeError, getline, FILENAME, 1.1) 50 51 # Bad filenames should return an empty string 52 self.assertEqual(getline(EMPTY, 1), EMPTY) 53 self.assertEqual(getline(INVALID_NAME, 1), EMPTY) 54 55 # Check whether lines correspond to those from file iteration 56 for entry in TESTS: 57 filename = os.path.join(TEST_PATH, entry) + '.py' 58 for index, line in enumerate(open(filename)): 59 self.assertEqual(line, getline(filename, index + 1)) 60 61 # Check module loading 62 for entry in MODULES: 63 filename = os.path.join(MODULE_PATH, entry) + '.py' 64 for index, line in enumerate(open(filename)): 65 self.assertEqual(line, getline(filename, index + 1)) 66 67 # Check that bogus data isn't returned (issue #1309567) 68 empty = linecache.getlines('a/b/c/__init__.py') 69 self.assertEqual(empty, []) 70 71 def test_no_ending_newline(self): 72 self.addCleanup(support.unlink, support.TESTFN) 73 with open(support.TESTFN, "w") as fp: 74 fp.write(SOURCE_3) 75 lines = linecache.getlines(support.TESTFN) 76 self.assertEqual(lines, ["\n", "def f():\n", " return 3\n"]) 77 78 def test_clearcache(self): 79 cached = [] 80 for entry in TESTS: 81 filename = os.path.join(TEST_PATH, entry) + '.py' 82 cached.append(filename) 83 linecache.getline(filename, 1) 84 85 # Are all files cached? 86 cached_empty = [fn for fn in cached if fn not in linecache.cache] 87 self.assertEqual(cached_empty, []) 88 89 # Can we clear the cache? 90 linecache.clearcache() 91 cached_empty = [fn for fn in cached if fn in linecache.cache] 92 self.assertEqual(cached_empty, []) 93 94 def test_checkcache(self): 95 getline = linecache.getline 96 # Create a source file and cache its contents 97 source_name = support.TESTFN + '.py' 98 self.addCleanup(support.unlink, source_name) 99 with open(source_name, 'w') as source: 100 source.write(SOURCE_1) 101 getline(source_name, 1) 102 103 # Keep a copy of the old contents 104 source_list = [] 105 with open(source_name) as source: 106 for index, line in enumerate(source): 107 self.assertEqual(line, getline(source_name, index + 1)) 108 source_list.append(line) 109 110 with open(source_name, 'w') as source: 111 source.write(SOURCE_2) 112 113 # Try to update a bogus cache entry 114 linecache.checkcache('dummy') 115 116 # Check that the cache matches the old contents 117 for index, line in enumerate(source_list): 118 self.assertEqual(line, getline(source_name, index + 1)) 119 120 # Update the cache and check whether it matches the new source file 121 linecache.checkcache(source_name) 122 with open(source_name) as source: 123 for index, line in enumerate(source): 124 self.assertEqual(line, getline(source_name, index + 1)) 125 source_list.append(line) 126 127 def test_main(): 128 support.run_unittest(LineCacheTests) 129 130 if __name__ == "__main__": 131 test_main() 132