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