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 }