Home | History | Annotate | Download | only in test
      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_memoryerror(self):
    128         lines = linecache.getlines(FILENAME)
    129         self.assertTrue(lines)
    130         def raise_memoryerror(*args, **kwargs):
    131             raise MemoryError
    132         with support.swap_attr(linecache, 'updatecache', raise_memoryerror):
    133             lines2 = linecache.getlines(FILENAME)
    134         self.assertEqual(lines2, lines)
    135 
    136         linecache.clearcache()
    137         with support.swap_attr(linecache, 'updatecache', raise_memoryerror):
    138             lines3 = linecache.getlines(FILENAME)
    139         self.assertEqual(lines3, [])
    140         self.assertEqual(linecache.getlines(FILENAME), lines)
    141 
    142 
    143 def test_main():
    144     support.run_unittest(LineCacheTests)
    145 
    146 if __name__ == "__main__":
    147     test_main()
    148