1 /** 2 * This module implements functions to run the unittests with 3 * command-line options. 4 */ 5 6 module unit_threaded.runner; 7 8 import unit_threaded.testsuite; 9 import unit_threaded.options; 10 import unit_threaded.io : enableDebugOutput, forceEscCodes; 11 import unit_threaded.testcase : TestData; 12 import unit_threaded.reflection : allTestData; 13 14 import std.conv : text; 15 import std.algorithm : map, filter, count; 16 17 /** 18 * Runs all tests in passed-in modules. Modules can be symbols or 19 * strings. Generates a main function and substitutes the default D 20 * runtime unittest runner. This mixin should be used instead of 21 * $(D runTests) if Phobos is linked as a shared library. 22 */ 23 mixin template runTestsMixin(Modules...) 24 { 25 26 shared static this() 27 { 28 import unit_threaded.testsuite : replaceModuleUnitTester; 29 30 replaceModuleUnitTester; 31 } 32 33 int main(string[] args) 34 { 35 return runTests!Modules(args); 36 } 37 } 38 39 /** 40 * Runs all tests in passed-in modules. Modules can be symbols 41 * or strings. Arguments are taken from the command-line. 42 * -s Can be passed to run in single-threaded mode. The rest 43 * of argv is considered to be test names to be run. 44 * Params: 45 * args = Arguments passed to main. 46 * Returns: An integer suitable for the program's return code. 47 */ 48 int runTests(Modules...)(string[] args) 49 { 50 return runTests(args, allTestData!Modules); 51 } 52 53 /** 54 * Runs all tests in passed-in testData. Arguments are taken from the 55 * command-line. `-s` Can be passed to run in single-threaded mode. The 56 * rest of argv is considered to be test names to be run. 57 * Params: 58 * args = Arguments passed to main. 59 * testData = Data about the tests to run. 60 * Returns: An integer suitable for the program's return code. 61 */ 62 int runTests(string[] args, in TestData[] testData) 63 { 64 const options = getOptions(args); 65 handleCmdLineOptions(options, testData); 66 if (options.exit) 67 return 0; 68 69 auto suite = TestSuite(options, testData); 70 return suite.run ? 0 : 1; 71 } 72 73 private void handleCmdLineOptions(in Options options, in TestData[] testData) 74 { 75 if (options.list) 76 { 77 import std.stdio; 78 79 writeln("Listing tests:"); 80 foreach (test; testData.map!(a => a.name)) 81 { 82 writeln(test); 83 } 84 } 85 86 if (options.debugOutput) 87 enableDebugOutput(); 88 if (options.forceEscCodes) 89 forceEscCodes(); 90 }