1 module unit_threaded.ut.reflection; 2 3 import unit_threaded.runner.reflection; 4 import unit_threaded.ut.modules.module_with_tests; //defines tests and non-tests 5 import unit_threaded.asserts; 6 import std.algorithm; 7 import std.array; 8 9 //helper function for the unittest blocks below 10 private auto addModPrefix(string[] elements, 11 string module_ = "unit_threaded.ut.modules.module_with_tests") nothrow { 12 return elements.map!(a => module_ ~ "." ~ a).array; 13 } 14 15 16 17 unittest { 18 import std.algorithm: sorted = sort; 19 20 const expected = addModPrefix( 21 [ 22 "myUnitTest", 23 "StructWithUnitTests.InStruct", 24 "StructWithUnitTests.unittest_L58_C5", 25 "unittest_L36", 26 "unittest_L41", 27 ] 28 ).sorted.array; 29 const actual = moduleUnitTests!(unit_threaded.ut.modules.module_with_tests). 30 map!(a => a.name).array.sorted.array; 31 32 assertEqual(actual, expected); 33 } 34 35 36 @safe pure unittest { 37 import std.algorithm: sorted = sort; 38 import unit_threaded.ut.modules.issue225; 39 40 const actual = moduleUnitTests!(unit_threaded.ut.modules.issue225). 41 map!(a => a.name).array; 42 43 assertEqual(actual, ["unit_threaded.ut.modules.issue225.oops"]); 44 } 45 46 47 version(unittest) { 48 import unit_threaded.runner.testcase: TestCase; 49 private void assertFail(TestCase test, string file = __FILE__, size_t line = __LINE__) { 50 import core.exception; 51 import std.conv; 52 53 test.silence; 54 assert(test() != [], 55 file ~ ":" ~ line.to!string ~ " Expected test case " ~ test.getPath ~ 56 " to fail but it didn't"); 57 } 58 59 private void assertPass(TestCase test, string file = __FILE__, size_t line = __LINE__) { 60 import unit_threaded.should: fail; 61 if(test() != []) 62 fail("'" ~ test.getPath ~ "' was expected to pass but failed", file, line); 63 } 64 } 65 66 67 @("Tests can be selected by tags") unittest { 68 import unit_threaded.runner.factory; 69 import unit_threaded.runner.testcase; 70 import unit_threaded.ut.modules.tags; 71 72 const testData = allTestData!(unit_threaded.ut.modules.tags).array; 73 auto testsNoTags = createTestCases(testData); 74 assertEqual(testsNoTags.length, 3); 75 assertPass(testsNoTags.find!(a => a.getPath.canFind("unittest_L6")).front); 76 assertFail(testsNoTags.find!(a => a.getPath.canFind("unittest_L8")).front); 77 assertFail(testsNoTags.find!(a => a.getPath.canFind("unittest_L14")).front); 78 79 auto testsNinja = createTestCases(testData, ["@ninja"]); 80 assertEqual(testsNinja.length, 1); 81 assertPass(testsNinja[0]); 82 83 auto testsMake = createTestCases(testData, ["@make"]); 84 assertEqual(testsMake.length, 2); 85 assertPass(testsMake.find!(a => a.getPath.canFind("unittest_L6")).front); 86 assertFail(testsMake.find!(a => a.getPath.canFind("unittest_L14")).front); 87 88 auto testsNotNinja = createTestCases(testData, ["~@ninja"]); 89 assertEqual(testsNotNinja.length, 2); 90 assertFail(testsNotNinja.find!(a => a.getPath.canFind("unittest_L8")).front); 91 assertFail(testsNotNinja.find!(a => a.getPath.canFind("unittest_L14")).front); 92 93 assertEqual(createTestCases(testData, ["unit_threaded.ut.modules.tags.testMake", "@ninja"]).length, 0); 94 } 95 96 97 @("module setup and shutdown") 98 unittest { 99 import unit_threaded.runner.testcase; 100 import unit_threaded.runner.factory; 101 import unit_threaded.ut.modules.module_with_setup: gNumBefore, gNumAfter; 102 103 const testData = allTestData!"unit_threaded.ut.modules.module_with_setup".array; 104 auto tests = createTestCases(testData); 105 assertEqual(tests.length, 2); 106 107 assertPass(tests[0]); 108 assertEqual(gNumBefore, 1); 109 assertEqual(gNumAfter, 1); 110 111 assertFail(tests[1]); 112 assertEqual(gNumBefore, 2); 113 assertEqual(gNumAfter, 2); 114 } 115 116 @("issue 33") unittest { 117 import unit_threaded.runner.factory; 118 import unit_threaded.runner.testcase; 119 120 const testData = allTestData!"unit_threaded.ut.modules.issue33"; 121 assertEqual(testData.length, 1); 122 } 123 124 @("issue 43") unittest { 125 import unit_threaded.runner.factory; 126 import unit_threaded.asserts; 127 import unit_threaded.ut.modules.module_with_tests; 128 import std.algorithm: canFind; 129 import std.array: array; 130 131 const testData = allTestData!"unit_threaded.ut.modules.module_with_tests"; 132 assertEqual(testData.canFind!(a => a.getPath.canFind("InStruct" )), true); 133 auto inStructTest = testData 134 .find!(a => a.getPath.canFind("InStruct")) 135 .array 136 .createTestCases[0]; 137 assertFail(inStructTest); 138 } 139 140 141 @("@ShouldFail") unittest { 142 import unit_threaded.runner.factory; 143 import unit_threaded.asserts; 144 import unit_threaded.ut.modules.module_with_tests; 145 import std.algorithm: find, canFind; 146 import std.array: array; 147 148 const testData = allTestData!"unit_threaded.ut.modules.module_with_attrs"; 149 150 auto willFail = testData 151 .filter!(a => a.getPath.canFind("will fail")) 152 .array 153 .createTestCases[0]; 154 assertPass(willFail); 155 } 156 157 158 @("@ShouldFailWith") unittest { 159 import unit_threaded.runner.factory; 160 import unit_threaded.asserts; 161 import unit_threaded.ut.modules.module_with_attrs; 162 import std.algorithm: find, canFind; 163 import std.array: array; 164 165 const testData = allTestData!"unit_threaded.ut.modules.module_with_attrs"; 166 167 auto doesntFail = testData 168 .filter!(a => a.getPath.canFind("ShouldFailWith that fails due to not failing")) 169 .array 170 .createTestCases[0]; 171 assertFail(doesntFail); 172 173 auto wrongType = testData 174 .find!(a => a.getPath.canFind("ShouldFailWith that fails due to wrong type")) 175 .array 176 .createTestCases[0]; 177 assertFail(wrongType); 178 179 auto passes = testData 180 .find!(a => a.getPath.canFind("ShouldFailWith that passes")) 181 .array 182 .createTestCases[0]; 183 assertPass(passes); 184 } 185 186 @("structs are not classes") unittest { 187 import unit_threaded.should; 188 import unit_threaded.ut.modules.structs_are_not_classes; 189 const testData = allTestData!"unit_threaded.ut.modules.structs_are_not_classes"; 190 testData.shouldBeEmpty; 191 } 192 193 @("@Flaky") unittest { 194 import unit_threaded.runner.factory; 195 import unit_threaded.asserts; 196 import unit_threaded.ut.modules.module_with_attrs; 197 import std.algorithm: find, canFind; 198 import std.array: array; 199 200 const testData = allTestData!"unit_threaded.ut.modules.module_with_attrs"; 201 202 auto flakyPasses = testData 203 .filter!(a => a.getPath.canFind("flaky that passes eventually")) 204 .array 205 .createTestCases[0]; 206 assertPass(flakyPasses); 207 208 auto flakyFails = testData 209 .filter!(a => a.getPath.canFind("flaky that fails due to not enough retries")) 210 .array 211 .createTestCases[0]; 212 assertFail(flakyFails); 213 }