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