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