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