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