Home | History | Annotate | Download | only in check_cfc
      1 #!/usr/bin/env python2.7
      2 
      3 """Test internal functions within check_cfc.py."""
      4 
      5 import check_cfc
      6 import os
      7 import platform
      8 import unittest
      9 
     10 
     11 class TestCheckCFC(unittest.TestCase):
     12 
     13     def test_flip_dash_g(self):
     14         self.assertIn('-g', check_cfc.flip_dash_g(['clang', '-c']))
     15         self.assertNotIn('-g', check_cfc.flip_dash_g(['clang', '-c', '-g']))
     16         self.assertNotIn(
     17             '-g', check_cfc.flip_dash_g(['clang', '-g', '-c', '-g']))
     18 
     19     def test_remove_dir_from_path(self):
     20         bin_path = r'/usr/bin'
     21         space_path = r'/home/user/space in path'
     22         superstring_path = r'/usr/bin/local'
     23 
     24         # Test removing last thing in path
     25         self.assertNotIn(
     26             bin_path, check_cfc.remove_dir_from_path(bin_path, bin_path))
     27 
     28         # Test removing one entry and leaving others
     29         # Also tests removing repeated path
     30         path_var = os.pathsep.join(
     31             [superstring_path, bin_path, space_path, bin_path])
     32         stripped_path_var = check_cfc.remove_dir_from_path(path_var, bin_path)
     33         self.assertIn(superstring_path, stripped_path_var)
     34         self.assertNotIn(bin_path, stripped_path_var.split(os.pathsep))
     35         self.assertIn(space_path, stripped_path_var)
     36 
     37         # Test removing non-canonical path
     38         self.assertNotIn(r'/usr//bin',
     39                          check_cfc.remove_dir_from_path(r'/usr//bin', bin_path))
     40 
     41         if platform == 'Windows':
     42             # Windows is case insensitive so should remove a different case
     43             # path
     44             self.assertNotIn(
     45                 bin_path, check_cfc.remove_dir_from_path(path_var, r'/USR/BIN'))
     46         else:
     47             # Case sensitive so will not remove different case path
     48             self.assertIn(
     49                 bin_path, check_cfc.remove_dir_from_path(path_var, r'/USR/BIN'))
     50 
     51     def test_is_output_specified(self):
     52         self.assertTrue(
     53             check_cfc.is_output_specified(['clang', '-o', 'test.o']))
     54         self.assertTrue(check_cfc.is_output_specified(['clang', '-otest.o']))
     55         self.assertFalse(
     56             check_cfc.is_output_specified(['clang', '-gline-tables-only']))
     57         # Not specified for implied output file name
     58         self.assertFalse(check_cfc.is_output_specified(['clang', 'test.c']))
     59 
     60     def test_get_output_file(self):
     61         self.assertEqual(
     62             check_cfc.get_output_file(['clang', '-o', 'test.o']), 'test.o')
     63         self.assertEqual(
     64             check_cfc.get_output_file(['clang', '-otest.o']), 'test.o')
     65         self.assertIsNone(
     66             check_cfc.get_output_file(['clang', '-gline-tables-only']))
     67         # Can't get output file if more than one input file
     68         self.assertIsNone(
     69             check_cfc.get_output_file(['clang', '-c', 'test.cpp', 'test2.cpp']))
     70         # No output file specified
     71         self.assertIsNone(check_cfc.get_output_file(['clang', '-c', 'test.c']))
     72 
     73     def test_derive_output_file(self):
     74         # Test getting implicit output file
     75         self.assertEqual(
     76             check_cfc.derive_output_file(['clang', '-c', 'test.c']), 'test.o')
     77         self.assertEqual(
     78             check_cfc.derive_output_file(['clang', '-c', 'test.cpp']), 'test.o')
     79         self.assertIsNone(check_cfc.derive_output_file(['clang', '--version']))
     80 
     81     def test_is_normal_compile(self):
     82         self.assertTrue(check_cfc.is_normal_compile(
     83             ['clang', '-c', 'test.cpp', '-o', 'test2.o']))
     84         self.assertTrue(
     85             check_cfc.is_normal_compile(['clang', '-c', 'test.cpp']))
     86         # Outputting bitcode is not a normal compile
     87         self.assertFalse(
     88             check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '-flto']))
     89         self.assertFalse(
     90             check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '-emit-llvm']))
     91         # Outputting preprocessed output or assembly is not a normal compile
     92         self.assertFalse(
     93             check_cfc.is_normal_compile(['clang', '-E', 'test.cpp', '-o', 'test.ii']))
     94         self.assertFalse(
     95             check_cfc.is_normal_compile(['clang', '-S', 'test.cpp', '-o', 'test.s']))
     96         # Input of preprocessed or assembly is not a "normal compile"
     97         self.assertFalse(
     98             check_cfc.is_normal_compile(['clang', '-c', 'test.s', '-o', 'test.o']))
     99         self.assertFalse(
    100             check_cfc.is_normal_compile(['clang', '-c', 'test.ii', '-o', 'test.o']))
    101         # Specifying --version and -c is not a normal compile
    102         self.assertFalse(
    103             check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '--version']))
    104         self.assertFalse(
    105             check_cfc.is_normal_compile(['clang', '-c', 'test.cpp', '--help']))
    106         # Outputting dependency files is not a normal compile
    107         self.assertFalse(
    108             check_cfc.is_normal_compile(['clang', '-c', '-M', 'test.cpp']))
    109         self.assertFalse(
    110             check_cfc.is_normal_compile(['clang', '-c', '-MM', 'test.cpp']))
    111         # Creating a dependency file as a side effect still outputs an object file
    112         self.assertTrue(
    113             check_cfc.is_normal_compile(['clang', '-c', '-MD', 'test.cpp']))
    114         self.assertTrue(
    115             check_cfc.is_normal_compile(['clang', '-c', '-MMD', 'test.cpp']))
    116 
    117     def test_replace_output_file(self):
    118         self.assertEqual(check_cfc.replace_output_file(
    119             ['clang', '-o', 'test.o'], 'testg.o'), ['clang', '-o', 'testg.o'])
    120         self.assertEqual(check_cfc.replace_output_file(
    121             ['clang', '-otest.o'], 'testg.o'), ['clang', '-otestg.o'])
    122         with self.assertRaises(Exception):
    123             check_cfc.replace_output_file(['clang'], 'testg.o')
    124 
    125     def test_add_output_file(self):
    126         self.assertEqual(check_cfc.add_output_file(
    127             ['clang'], 'testg.o'), ['clang', '-o', 'testg.o'])
    128 
    129     def test_set_output_file(self):
    130         # Test output not specified
    131         self.assertEqual(
    132             check_cfc.set_output_file(['clang'], 'test.o'), ['clang', '-o', 'test.o'])
    133         # Test output is specified
    134         self.assertEqual(check_cfc.set_output_file(
    135             ['clang', '-o', 'test.o'], 'testb.o'), ['clang', '-o', 'testb.o'])
    136 
    137     def test_get_input_file(self):
    138         # No input file
    139         self.assertIsNone(check_cfc.get_input_file(['clang']))
    140         # Input C file
    141         self.assertEqual(
    142             check_cfc.get_input_file(['clang', 'test.c']), 'test.c')
    143         # Input C++ file
    144         self.assertEqual(
    145             check_cfc.get_input_file(['clang', 'test.cpp']), 'test.cpp')
    146         # Multiple input files
    147         self.assertIsNone(
    148             check_cfc.get_input_file(['clang', 'test.c', 'test2.cpp']))
    149         self.assertIsNone(
    150             check_cfc.get_input_file(['clang', 'test.c', 'test2.c']))
    151         # Don't handle preprocessed files
    152         self.assertIsNone(check_cfc.get_input_file(['clang', 'test.i']))
    153         self.assertIsNone(check_cfc.get_input_file(['clang', 'test.ii']))
    154         # Test identifying input file with quotes
    155         self.assertEqual(
    156             check_cfc.get_input_file(['clang', '"test.c"']), '"test.c"')
    157         self.assertEqual(
    158             check_cfc.get_input_file(['clang', "'test.c'"]), "'test.c'")
    159         # Test multiple quotes
    160         self.assertEqual(
    161             check_cfc.get_input_file(['clang', "\"'test.c'\""]), "\"'test.c'\"")
    162 
    163     def test_set_input_file(self):
    164         self.assertEqual(check_cfc.set_input_file(
    165             ['clang', 'test.c'], 'test.s'), ['clang', 'test.s'])
    166 
    167 if __name__ == '__main__':
    168     unittest.main()
    169