1 /**
2 Copyright: Copyright (c) 2017, Joakim Brännström. All rights reserved.
3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0)
4 Author: Joakim Brännström (joakim.brannstrom@gmx.com)
5 */
6 module dextool_test.compilation_database_integration;
7 
8 import std.typecons : No;
9 
10 import dextool_test.utility;
11 
12 // dfmt off
13 
14 @(testId ~ "Should load compiler settings from compilation database")
15 unittest {
16     mixin(envSetup(globalTestdir));
17     makeDextool(testEnv)
18         .addInputArg(testData ~ "compile_db/single_file_main.c")
19         .addArg(["--compile-db", (testData ~ "compile_db/single_file_db.json").toString])
20         .addArg("--file-restrict=.*/single_file.h")
21         .run;
22     dextool_test.makeCompile(testEnv, "g++")
23         .outputToDefaultBinary
24         .addInclude(testData ~ "compile_db/dir1")
25         .addDefine("DEXTOOL_TEST")
26         .addArg(testData ~ "compile_db/single_file_main.cpp")
27         .run;
28     makeCommand(testEnv, defaultBinary).run;
29 }
30 
31 @(testId ~ "Should fail with an error message when file not found in the compilation database")
32 unittest {
33     mixin(envSetup(globalTestdir));
34     auto r = makeDextool(testEnv)
35         .throwOnExitStatus(false)
36         .addInputArg(testData ~ "compile_db/file_not_found.c")
37         .addArg(["--compile-db", (testData ~ "compile_db/single_file_db.json").toString])
38         .run;
39 
40     r.success.shouldBeFalse;
41     r.stderr.sliceContains("error: Unable to find any compiler flags for").shouldBeTrue;
42 }
43 
44 @(testId ~ "shall derive the flags for parsing single_file.h via the #include in single_file_main.c in the compilation database")
45 @(Values(["compile_db/dir1/single_file.h", "use_file"], ["compile_db/single_file.h", "fallback"]))
46 unittest {
47     mixin(envSetup(globalTestdir, No.setupEnv));
48     testEnv.outputSuffix(getValue!(string[])[1]);
49     testEnv.setupEnv;
50 
51     auto r = makeDextool(testEnv)
52         .addArg(["--compile-db", (testData ~ "compile_db/single_file_db.json").toString])
53         .addInputArg(testData ~ getValue!(string[])[0])
54         .run;
55 
56     r.stderr.sliceContains("error: Unable to find any compiler flags for").shouldBeFalse;
57     // the file returned shall be the full path for the one searching for
58     r.stderr.sliceContains("because it has an '#include' for '" ~ (testData ~ "compile_db/dir1/single_file.h").toString).shouldBeTrue;
59 }
60 
61 @(testId ~ "Should load compiler settings from the second compilation database")
62 unittest {
63     mixin(envSetup(globalTestdir));
64     TestParams p;
65     p.root = Path("testdata/compile_db").absolutePath;
66     p.input_ext = p.root ~ Path("file2.h");
67     p.out_hdr = testEnv.outdir ~ "test_double.hpp";
68 
69     // find compilation flags by looking up how single_file_main.c was compiled
70     p.dexParams = ["ctestdouble", "--debug", "--compile-db=" ~ (p.root ~ "db1.json")
71         .toString, "--compile-db=" ~ (p.root ~ "db2.json").toString];
72 
73     p.skipCompile = Yes.skipCompile;
74     runTestFile(p, testEnv);
75 }
76 
77 @(testId ~ "Should use the exact supplied --in=... as key when looking in compile db")
78 unittest {
79     mixin(envSetup(globalTestdir));
80     TestParams p;
81     p.root = Path("testdata/compile_db").absolutePath;
82     p.input_ext = p.root ~ Path("file2.h");
83     p.out_hdr = testEnv.outdir ~ "test_double.hpp";
84 
85     p.dexParams = ["ctestdouble", "--debug",
86         "--compile-db=" ~ (p.root ~ "db2.json").toString, "--in=file2.h"];
87 
88     p.skipCompile = Yes.skipCompile;
89     p.skipCompare = Yes.skipCompare;
90     runTestFile(p, testEnv);
91 }