1 module tests.cpprules;
2 
3 
4 import reggae;
5 import unit_threaded;
6 
7 
8 void testNoIncludePaths() {
9     const build = Build(objectFile(SourceFile("path/to/src/foo.cpp")));
10     const ninja = Ninja(build, "/tmp/myproject");
11     ninja.buildEntries.shouldEqual(
12         [NinjaEntry("build path/to/src/foo.o: _cppcompile /tmp/myproject/path/to/src/foo.cpp",
13                     ["DEPFILE = path/to/src/foo.o.dep"]),
14             ]);
15 }
16 
17 
18 void testIncludePaths() {
19     const build = Build(objectFile(SourceFile("path/to/src/foo.cpp"), Flags(""),
20                                    IncludePaths(["path/to/src", "other/path"])));
21     const ninja = Ninja(build, "/tmp/myproject");
22     ninja.buildEntries.shouldEqual(
23         [NinjaEntry("build path/to/src/foo.o: _cppcompile /tmp/myproject/path/to/src/foo.cpp",
24                     ["includes = -I/tmp/myproject/path/to/src -I/tmp/myproject/other/path",
25                      "DEPFILE = path/to/src/foo.o.dep"]),
26             ]);
27 }
28 
29 
30 void testFlagsCompileC() {
31     const build = Build(objectFile(SourceFile("path/to/src/foo.c"), Flags("-m64 -fPIC -O3")));
32     const ninja = Ninja(build, "/tmp/myproject");
33     ninja.buildEntries.shouldEqual(
34         [NinjaEntry("build path/to/src/foo.o: _ccompile /tmp/myproject/path/to/src/foo.c",
35                     ["flags = -m64 -fPIC -O3",
36                      "DEPFILE = path/to/src/foo.o.dep"]),
37             ]);
38 }
39 
40 void testFlagsCompileCpp() {
41     const build = Build(objectFile(SourceFile("path/to/src/foo.cpp"), Flags("-m64 -fPIC -O3")));
42     const ninja = Ninja(build, "/tmp/myproject");
43     ninja.buildEntries.shouldEqual(
44         [NinjaEntry("build path/to/src/foo.o: _cppcompile /tmp/myproject/path/to/src/foo.cpp",
45                     ["flags = -m64 -fPIC -O3",
46                      "DEPFILE = path/to/src/foo.o.dep"]),
47             ]);
48 }
49 
50 void testCppCompile() {
51     const mathsObj = objectFile(SourceFile("src/cpp/maths.cpp"),
52                                 Flags("-m64 -fPIC -O3"),
53                                 IncludePaths(["headers"]));
54 
55     mathsObj.shellCommand("/path/to").shouldEqual(
56         "g++ -m64 -fPIC -O3 -I/path/to/headers -MMD -MT src/cpp/maths.o -MF src/cpp/maths.o.dep "
57         "-o src/cpp/maths.o -c /path/to/src/cpp/maths.cpp");
58 }
59 
60 void testCCompile() {
61     const mathsObj = objectFile(SourceFile("src/c/maths.c"),
62                                 Flags("-m64 -fPIC -O3"),
63                                 IncludePaths(["headers"]));
64 
65     mathsObj.shellCommand("/path/to").shouldEqual(
66         "gcc -m64 -fPIC -O3 -I/path/to/headers -MMD -MT src/c/maths.o -MF src/c/maths.o.dep "
67         "-o src/c/maths.o -c /path/to/src/c/maths.c");
68 }
69 
70 
71 void testUnityNoFiles() {
72     string[] files;
73     immutable projectPath = "";
74     unityFileContents(projectPath, files).shouldThrow;
75 }
76 
77 
78 private void shouldEqualLines(string actual, string[] expected,
79                               in string file = __FILE__, in ulong line = __LINE__) {
80     import std.string;
81     actual.split("\n").shouldEqual(expected, file, line);
82 }
83 
84 void testUnityCppFiles() {
85     const files = ["src/foo.cpp", "src/bar.cpp"];
86     unityFileContents("/path/to/proj/", files).shouldEqualLines(
87         [`#include "/path/to/proj/src/foo.cpp"`,
88          `#include "/path/to/proj/src/bar.cpp"`]);
89 }
90 
91 
92 void testUnityCFiles() {
93     const files = ["src/foo.c", "src/bar.c"];
94     unityFileContents("/foo/bar/", files).shouldEqualLines(
95         [`#include "/foo/bar/src/foo.c"`,
96          `#include "/foo/bar/src/bar.c"`]);
97 }
98 
99 void testUnityMixedLanguages() {
100     const files = ["src/foo.cpp", "src/bar.c"];
101     unityFileContents("/project", files).shouldThrow;
102 }
103 
104 void testUnityDFiles() {
105     const files = ["src/foo.d", "src/bar.d"];
106     unityFileContents("/project", files).shouldThrow;
107 }
108 
109 
110 void testUnityTargetCpp() @safe {
111     const files = ["src/foo.cpp", "src/bar.cpp", "src/baz.cpp"];
112     Target[] dependencies() @safe pure nothrow {
113         return [Target("$builddir/mylib.a")];
114     }
115 
116     immutable projectPath = "/path/to/proj";
117     const target = unityTarget!(ExeName("leapp"),
118                                 projectPath,
119                                 files,
120                                 Flags("-g -O0"),
121                                 IncludePaths(["headers"]),
122                                 dependencies);
123     target.outputs.shouldEqual(["leapp"]);
124     target.shellCommand(projectPath).shouldEqual(
125         "g++ -g -O0 -I/path/to/proj/headers -MMD -MT leapp -MF leapp.dep -o leapp " ~
126         "objs/leapp.objs/unity.cpp mylib.a");
127     target.dependencies.shouldEqual([Target.phony("$builddir/objs/leapp.objs/unity.cpp",
128                                                   "",
129                                                   [],
130                                                   [Target("src/foo.cpp"),
131                                                    Target("src/bar.cpp"),
132                                                    Target("src/baz.cpp")]),
133                                      Target("$builddir/mylib.a")]);
134 }
135 
136 void testUnityTargetC() @safe {
137     const files = ["src/foo.c", "src/bar.c", "src/baz.c"];
138     Target[] dependencies() @safe pure nothrow {
139         return [Target("$builddir/mylib.a")];
140     }
141 
142     immutable projectPath = "/path/to/proj";
143     const target = unityTarget!(ExeName("leapp"),
144                                 projectPath,
145                                 files,
146                                 Flags("-g -O0"),
147                                 IncludePaths(["headers"]),
148                                 dependencies);
149     target.outputs.shouldEqual(["leapp"]);
150     target.shellCommand(projectPath).shouldEqual(
151         "gcc -g -O0 -I/path/to/proj/headers -MMD -MT leapp -MF leapp.dep -o leapp " ~
152         "objs/leapp.objs/unity.c mylib.a");
153     target.dependencies.shouldEqual([Target.phony("$builddir/objs/leapp.objs/unity.c",
154                                                   "",
155                                                   [],
156                                                   [Target("src/foo.c"),
157                                                    Target("src/bar.c"),
158                                                    Target("src/baz.c")]),
159                                      Target("$builddir/mylib.a")]);
160 }