1 module unit_threaded.testsuite;
2 
3 import unit_threaded.testcase;
4 import unit_threaded.io;
5 import unit_threaded.options;
6 import std.datetime;
7 import std.parallelism: taskPool;
8 import std.concurrency;
9 import std.stdio;
10 import std.conv;
11 import std.algorithm;
12 
13 
14 auto runTest(TestCase test) {
15     return test();
16 }
17 
18 /**
19  * Responsible for running tests
20  */
21 struct TestSuite {
22     this(TestCase[] tests) {
23         _tests = tests;
24     }
25 
26     /**
27      * Runs the tests with the given options.
28      * Returns: how long it took to run.
29      */
30     Duration run(in Options options) {
31         auto tests = getTests(options);
32         _stopWatch.start();
33 
34         if(options.multiThreaded) {
35             _failures = reduce!((a, b) => a ~ b)(_failures, taskPool.amap!runTest(tests));
36         } else {
37             foreach(test; tests) _failures ~= test();
38         }
39 
40         handleFailures();
41 
42         _stopWatch.stop();
43         return cast(Duration)_stopWatch.peek();
44     }
45 
46     @property ulong numTestsRun() const {
47         return _tests.map!(a => a.numTestsRun).reduce!((a, b) => a + b);
48     }
49 
50     @property ulong numFailures() const pure nothrow {
51         return _failures.length;
52     }
53 
54     @property bool passed() const pure nothrow {
55         return numFailures() == 0;
56     }
57 
58 private:
59 
60     TestCase[] _tests;
61     string[] _failures;
62     StopWatch _stopWatch;
63 
64     auto getTests(in Options options) {
65         auto tests = _tests;
66         if(options.random) {
67             import std.random;
68             auto generator = Random(options.seed);
69             tests.randomShuffle(generator);
70             utWriteln("Running tests in random order. To repeat this run, use --seed ", options.seed);
71         }
72         return tests;
73     }
74 
75     void handleFailures() {
76         if(_failures) utWriteln("");
77         foreach(failure; _failures) {
78             utWrite("Test ", failure, " ");
79             utWriteRed("failed");
80             utWriteln(".");
81         }
82         if(_failures) writeln("");
83     }
84 }