1 module unit_threaded.testcase;
2 
3 import unit_threaded.check;
4 import unit_threaded.io;
5 
6 import std.exception;
7 import std.string;
8 import std.conv;
9 
10 struct TestResult {
11     immutable bool failed;
12     immutable string output;
13 }
14 
15 /**
16  * Class from which other test cases derive
17  */
18 class TestCase {
19     string getPath() const pure nothrow {
20         return this.classinfo.name;
21     }
22 
23     final auto opCall() {
24         print(getPath() ~ ":\n");
25         check(setup());
26         check(test());
27         check(shutdown());
28         if(_failed) print("\n\n");
29         return TestResult(_failed, _output);
30     }
31 
32     void setup() { } ///override to run before test()
33     void shutdown() { } ///override to run after test()
34     abstract void test();
35 
36 private:
37     bool _failed;
38     string _output;
39 
40     bool check(T = Exception, E)(lazy E expression) {
41         setStatus(collectExceptionMsg!T(expression));
42         return !_failed;
43     }
44 
45     void setStatus(in string msg) {
46         if(msg) {
47             _failed = true;
48             print(chomp(msg));
49         }
50     }
51 
52     void print(in string msg) {
53         addToOutput(_output, msg);
54     }
55 }