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 : enableStackTrace, 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...) if(Modules.length > 0) { 24 25 shared static this() { 26 import unit_threaded.testsuite : replaceModuleUnitTester; 27 28 replaceModuleUnitTester; 29 } 30 31 int main(string[] args) { 32 return runTests!Modules(args); 33 } 34 } 35 36 /** 37 * Runs all tests in passed-in modules. Modules can be symbols 38 * or strings. Arguments are taken from the command-line. 39 * -s Can be passed to run in single-threaded mode. The rest 40 * of argv is considered to be test names to be run. 41 * Params: 42 * args = Arguments passed to main. 43 * Returns: An integer suitable for the program's return code. 44 */ 45 int runTests(Modules...)(string[] args) if(Modules.length > 0) { 46 return runTests(args, allTestData!Modules); 47 } 48 49 /** 50 * Runs all tests in passed-in testData. Arguments are taken from the 51 * command-line. `-s` Can be passed to run in single-threaded mode. The 52 * rest of argv is considered to be test names to be run. 53 * Params: 54 * args = Arguments passed to main. 55 * testData = Data about the tests to run. 56 * Returns: An integer suitable for the program's return code. 57 */ 58 int runTests(string[] args, in TestData[] testData) { 59 const options = getOptions(args); 60 handleCmdLineOptions(options, testData); 61 if (options.exit) 62 return 0; 63 64 auto suite = TestSuite(options, testData); 65 return suite.run ? 0 : 1; 66 } 67 68 private void handleCmdLineOptions(in Options options, in TestData[] testData) { 69 if (options.list) { 70 import std.stdio; 71 72 writeln("Listing tests:"); 73 foreach (test; testData.map!(a => a.name)) { 74 writeln(test); 75 } 76 } 77 78 if (options.debugOutput) 79 enableDebugOutput(); 80 81 if (options.forceEscCodes) 82 forceEscCodes(); 83 84 if (options.stackTraces) 85 enableStackTrace(); 86 }