1 from clang.cindex import CompilationDatabase 2 from clang.cindex import CompilationDatabaseError 3 from clang.cindex import CompileCommands 4 from clang.cindex import CompileCommand 5 import os 6 import gc 7 8 kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') 9 10 def test_create_fail(): 11 """Check we fail loading a database with an assertion""" 12 path = os.path.dirname(__file__) 13 try: 14 cdb = CompilationDatabase.fromDirectory(path) 15 except CompilationDatabaseError as e: 16 assert e.cdb_error == CompilationDatabaseError.ERROR_CANNOTLOADDATABASE 17 else: 18 assert False 19 20 def test_create(): 21 """Check we can load a compilation database""" 22 cdb = CompilationDatabase.fromDirectory(kInputsDir) 23 24 def test_lookup_fail(): 25 """Check file lookup failure""" 26 cdb = CompilationDatabase.fromDirectory(kInputsDir) 27 assert cdb.getCompileCommands('file_do_not_exist.cpp') == None 28 29 def test_lookup_succeed(): 30 """Check we get some results if the file exists in the db""" 31 cdb = CompilationDatabase.fromDirectory(kInputsDir) 32 cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') 33 assert len(cmds) != 0 34 35 def test_1_compilecommand(): 36 """Check file with single compile command""" 37 cdb = CompilationDatabase.fromDirectory(kInputsDir) 38 cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') 39 assert len(cmds) == 1 40 assert cmds[0].directory == '/home/john.doe/MyProject' 41 expected = [ 'clang++', '-o', 'project.o', '-c', 42 '/home/john.doe/MyProject/project.cpp'] 43 for arg, exp in zip(cmds[0].arguments, expected): 44 assert arg == exp 45 46 def test_2_compilecommand(): 47 """Check file with 2 compile commands""" 48 cdb = CompilationDatabase.fromDirectory(kInputsDir) 49 cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp') 50 assert len(cmds) == 2 51 expected = [ 52 { 'wd': '/home/john.doe/MyProjectA', 53 'line': ['clang++', '-o', 'project2.o', '-c', 54 '/home/john.doe/MyProject/project2.cpp']}, 55 { 'wd': '/home/john.doe/MyProjectB', 56 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', 57 '/home/john.doe/MyProject/project2.cpp']} 58 ] 59 for i in range(len(cmds)): 60 assert cmds[i].directory == expected[i]['wd'] 61 for arg, exp in zip(cmds[i].arguments, expected[i]['line']): 62 assert arg == exp 63 64 def test_compilecommand_iterator_stops(): 65 """Check that iterator stops after the correct number of elements""" 66 cdb = CompilationDatabase.fromDirectory(kInputsDir) 67 count = 0 68 for cmd in cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp'): 69 count += 1 70 assert count <= 2 71 72 def test_compilationDB_references(): 73 """Ensure CompilationsCommands are independent of the database""" 74 cdb = CompilationDatabase.fromDirectory(kInputsDir) 75 cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') 76 del cdb 77 gc.collect() 78 workingdir = cmds[0].directory 79 80 def test_compilationCommands_references(): 81 """Ensure CompilationsCommand keeps a reference to CompilationCommands""" 82 cdb = CompilationDatabase.fromDirectory(kInputsDir) 83 cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') 84 del cdb 85 cmd0 = cmds[0] 86 del cmds 87 gc.collect() 88 workingdir = cmd0.directory 89 90