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