1 module tests.it.runtime; 2 3 public import tests.it; 4 public import tests.utils; 5 import reggae.path: buildPath; 6 import reggae.reggae; 7 8 // calls reggae.run, which is basically main, but with a 9 // fake file 10 auto testRun(string[] args) { 11 import reggae.reggae: run; 12 13 auto output = FakeFile(); 14 run(output, args); 15 16 return output; 17 } 18 19 struct ReggaeSandbox { 20 21 alias sandbox this; 22 23 Sandbox sandbox; 24 static string currentTestPath; 25 26 static ReggaeSandbox opCall() { 27 ReggaeSandbox ret; 28 ret.sandbox = Sandbox(); 29 currentTestPath = ret.testPath; 30 return ret; 31 } 32 33 static ReggaeSandbox opCall(in string projectName) { 34 auto ret = ReggaeSandbox(); 35 ret.copyProject(projectName); 36 return ret; 37 } 38 39 ~this() @safe { 40 currentTestPath = null; 41 } 42 43 auto runReggae(string[] args...) const { 44 import std.algorithm: filter; 45 import std.array: array; 46 return runImpl(args.filter!(a => a !is null).array); 47 } 48 49 auto runReggae(string[] args, string project) const { 50 return runImpl(args, project); 51 } 52 53 void writeHelloWorldApp() const { 54 import std.stdio; 55 import std.file; 56 import std.array; 57 58 mkdir(buildPath(testPath, "src")); 59 sandbox.writeFile(buildPath("src/hello.d"), q{ 60 import std.stdio; 61 void main() { 62 writeln("Hello world!"); 63 } 64 }.split("\n").array); 65 } 66 67 auto shouldSucceed(in string arg, 68 in string file = __FILE__, 69 in size_t line = __LINE__ ) const { 70 import tests.utils; 71 return [buildPath(testPath, arg)].shouldExecuteOk(WorkDir(testPath), file, line); 72 } 73 74 auto shouldFail(in string arg, in string file = __FILE__, in size_t line = __LINE__) const { 75 import tests.utils; 76 return [buildPath(testPath, arg)].shouldFailToExecute(testPath, file, line); 77 } 78 79 void copyProject(in string projectName, in string testSubPath = ".") const { 80 const fromPath = buildPath(origPath, "tests/projects", projectName); 81 const toPath = buildPath(testPath, testSubPath); 82 copyProjectFiles(fromPath, toPath); 83 } 84 85 86 private: 87 88 auto runImpl(string[] args, string project = "") const { 89 90 import std.algorithm: canFind; 91 92 if(project == "") project = testPath; 93 94 string[] fromWhereArgs; 95 if(!args.canFind("-C")) fromWhereArgs = ["-C", testPath]; 96 97 return testRun(["reggae"] ~ fromWhereArgs ~ args ~ project); 98 } 99 } 100 101 102 void shouldContain(string[] haystack, in string needle, 103 string file = __FILE__, size_t line = __LINE__) { 104 import std.algorithm; 105 import std.array; 106 if(!haystack.canFind!(a => a.canFind(needle))) 107 throw new UnitTestException(["Could not find " ~ needle ~ " in:"] ~ haystack, file, line); 108 } 109 110 void shouldContain(in string haystack, in string needle, 111 in string file = __FILE__, in size_t line = __LINE__) { 112 import std.algorithm; 113 import std.array; 114 if(!haystack.canFind(needle)) 115 throw new UnitTestException(["Could not find " ~ needle ~ " in:"] ~ haystack, file, line); 116 } 117 118 119 void shouldNotContain(string[] haystack, in string needle, 120 string file = __FILE__, size_t line = __LINE__) { 121 import std.algorithm; 122 import std.array; 123 if(haystack.canFind!(a => a.canFind(needle))) 124 throw new UnitTestException(["Should not have found " ~ needle ~ " in:"] ~ haystack, file, line); 125 } 126 127 void shouldNotContain(in string haystack, in string needle, 128 in string file = __FILE__, in size_t line = __LINE__) { 129 import std.algorithm; 130 import std.array; 131 if(haystack.canFind(needle)) 132 throw new UnitTestException(["Should not have found " ~ needle ~ " in:"] ~ haystack, file, line); 133 }