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 }