1 module tests.ut.backend.binary; 2 3 import reggae; 4 import unit_threaded; 5 import tests.utils; 6 7 void testTargetSelection() { 8 9 bool fooCalled; 10 bool barCalled; 11 void resetCalls() { fooCalled = false; barCalled = false;} 12 13 auto foo = Target("foo", (in string[] i, in string[] o) { fooCalled = true; }, Target("foo.d")); 14 auto bar = Target("bar", (in string[] i, in string[] o) { barCalled = true; }, Target("bar.d")); 15 auto binary = Binary(Build(foo, bar), getOptions(["reggae", "--export"])); 16 17 { 18 scope(exit) resetCalls; 19 binary.run(["prog", "--norerun"]); 20 fooCalled.shouldBeTrue; 21 barCalled.shouldBeTrue; 22 } 23 24 { 25 scope(exit) resetCalls; 26 binary.run(["prog", "--norerun", "foo", "bar"]); 27 fooCalled.shouldBeTrue; 28 barCalled.shouldBeTrue; 29 } 30 31 { 32 scope(exit) resetCalls; 33 binary.run(["prog", "--norerun", "foo"]); 34 fooCalled.shouldBeTrue; 35 barCalled.shouldBeFalse; 36 } 37 38 { 39 scope(exit) resetCalls; 40 binary.run(["prog", "--norerun", "bar"]); 41 fooCalled.shouldBeFalse; 42 barCalled.shouldBeTrue; 43 } 44 45 { 46 scope(exit) resetCalls; 47 binary.run(["prog", "--norerun", "nonexistent"]).shouldThrow; 48 fooCalled.shouldBeFalse; 49 barCalled.shouldBeFalse; 50 } 51 } 52 53 void testTopLevelTargets() { 54 auto foo = Target("foo", "", Target("foo.d")); 55 auto bar = Target("bar", "", Target("bar.d")); 56 auto binary = Binary(Build(foo, bar), Options()); 57 binary.topLevelTargets(["foo"]).shouldEqual([foo]); 58 binary.topLevelTargets(["bar"]).shouldEqual([bar]); 59 binary.topLevelTargets([]).shouldEqual([foo, bar]); 60 binary.topLevelTargets(["oops"]).shouldEqual([]); 61 } 62 63 64 private Build binaryBuild() { 65 mixin build!(Target("app", "dmd -of$out $in", [Target("foo.o"), Target("bar.o") ]), 66 optional(Target.phony(`opt`, `echo Optional!`))); 67 return buildFunc(); 68 } 69 70 @("Listing targets") unittest { 71 import std.stdio: stdout, File; 72 73 auto file = FakeFile(); 74 auto binary = Binary(binaryBuild, getOptions(["./reggae", "-b", "binary"]), file); 75 binary.run(["./build", "--norerun", "-l"]); 76 77 file.lines.shouldEqual( 78 ["List of available top-level targets:", 79 "- app", 80 "- opt (optional)"]); 81 } 82 83 84 @("Unknown target") unittest { 85 import std.stdio: stdout, File; 86 87 auto binary = Binary(binaryBuild, getOptions(["./reggae", "-b", "binary"])); 88 binary.run(["./build", "--norerun", "oops"]). 89 shouldThrowWithMessage("Unknown target(s) 'oops'"); 90 } 91 92 @("Unknown targets") unittest { 93 import std.stdio: stdout, File; 94 95 auto binary = Binary(binaryBuild, getOptions(["./reggae", "-b", "binary"])); 96 binary.run(["./build", "--norerun", "oops", "woopsie"]). 97 shouldThrowWithMessage("Unknown target(s) 'oops' 'woopsie'"); 98 } 99 100 101 @("Non-phony target with no dependencies gets built if output doesn't exist") 102 unittest { 103 bool ran; 104 auto build = Build(Target("foo.txt", 105 (in string[], in string[]) { ran = true; })); 106 auto binary = Binary(build, getOptions(["reggae", "-b", "binary"])); 107 binary.run(["./build", "--norerun"]); 108 ran.shouldBeTrue; 109 }