1 module toml_foolery_tests.run;
2 
3 import colorize;
4 import std.algorithm;
5 import std.array;
6 import std.conv;
7 import std.file;
8 import std.path;
9 import std.process;
10 import std.stdio;
11 import toml_foolery;
12 
13 
14 private string projectRoot;
15 
16 static this()
17 {
18     projectRoot = thisExePath.dirName;
19 }
20 
21 int main()
22 {
23     auto testFolders =
24         projectRoot
25         .buildPath("tests")
26         .dirEntries(SpanMode.shallow)
27         .filter!(e => e.isDir);
28 
29     bool anyFailed;
30 
31     foreach (DirEntry entry; testFolders)
32     {
33         string testSimpleName = entry.name.asRelativePath(projectRoot.buildPath("tests")).to!string;
34         string dScriptPath = entry.name.buildPath("mwe.d");
35         string testConfigPath = entry.name.buildPath("mwe.config.toml");
36         string testLabel = testSimpleName.color(fg.init, bg.init, mode.bold);
37 
38         write("▶".color(fg.blue) ~ " " ~ testLabel);
39         fflush(stdout.getFP());
40 
41         if (!exists(dScriptPath) || !isFile(dScriptPath))
42         {
43             write("\r");
44             writeln("⏭".color(fg.yellow) ~ " " ~ testLabel);
45             continue;
46         }
47 
48         struct TestConfig
49         {
50             string description;
51             string[] dubFlags;
52         }
53 
54         TestConfig config;
55 
56         if (exists(testConfigPath) && isFile(testConfigPath))
57         {
58             config = testConfigPath.readText.parseToml!TestConfig();
59         }
60 
61         string[] command = ["dub", "run", "--single", dScriptPath] ~ config.dubFlags;
62         ProcessPipes pipes = pipeProcess(
63             command,
64             Redirect.all,
65             null,
66             Config.none,
67             entry.name
68         );
69 
70         int status = wait(pipes.pid);
71 
72         if (status != 0)
73         {
74             anyFailed = true;
75             write("\r");
76             writeln("✗".color(fg.red) ~ " " ~ testLabel);
77 
78             if (config.description != "")
79             {
80                 writeln("  " ~ config.description);
81                 writeln();
82             }
83 
84             writeln("Test case failed with exit code " ~ status.to!string ~ "");
85 
86             writeln();
87             writeln("stderr:".color(mode.bold));
88             writeln();
89             writeln(readFileText(pipes.stderr));
90             writeln();
91 
92             writeln();
93             writeln("stdout:".color(mode.bold));
94             writeln();
95             writeln(readFileText(pipes.stdout));
96             writeln();
97 
98             continue;
99         }
100 
101         write("\r");
102         writeln("✓".color(fg.green) ~ " " ~ testLabel);
103     }
104 
105     return anyFailed ? 1 : 0;
106 }
107 
108 string readFileText(File file)
109 {
110     return file.byLine.joiner("\n").array.to!string;
111 }