1 module unit_threaded.testsuite; 2 3 import unit_threaded.testcase; 4 import unit_threaded.writer_thread; 5 import std.datetime; 6 import std.parallelism; 7 import std.concurrency; 8 import std.stdio; 9 import std.conv; 10 11 /** 12 * Responsible for running tests 13 */ 14 struct TestSuite { 15 this(TestCase[] tests) { 16 _tests = tests; 17 } 18 19 double run(in bool multiThreaded = true) { 20 _stopWatch.start(); 21 22 immutable redirectIo = multiThreaded; 23 24 if(multiThreaded) { 25 foreach(test; taskPool.parallel(_tests)) innerLoop(test); 26 } else { 27 foreach(test; _tests) innerLoop(test); 28 } 29 30 if(_failures) utWriteln(""); 31 foreach(failure; _failures) { 32 utWriteln("Test ", failure, " failed."); 33 } 34 if(_failures) writeln(""); 35 36 _stopWatch.stop(); 37 return _stopWatch.peek().seconds(); 38 } 39 40 @property ulong numTestsRun() const pure nothrow { 41 return _tests.length; 42 } 43 44 @property ulong numFailures() const pure nothrow { 45 return _failures.length; 46 } 47 48 @property bool passed() const pure nothrow { 49 return numFailures() == 0; 50 } 51 52 private: 53 TestCase[] _tests; 54 string[] _failures; 55 StopWatch _stopWatch; 56 57 void addFailure(in string testPath) nothrow { 58 _failures ~= testPath; 59 } 60 61 void innerLoop(TestCase test) { 62 utWriteln(test.getPath() ~ ":"); 63 immutable result = test(); 64 if(result.failed) { 65 addFailure(test.getPath()); 66 } 67 utWrite(result.output); 68 } 69 }