diff --git a/dub.json b/dub.json index 3bf07c4..31ef8f9 100755 --- a/dub.json +++ b/dub.json @@ -38,6 +38,33 @@ "-op" ] }, + { + "name": "unittest-runner", + "targetType" : "executable", + "sourcePaths": ["source/","tests/"], + "mainSourceFile":"tests/runner.d", + "excludedSourceFiles":[ + "source\/win_dll.d", + "tests/tests.d" + ], + "dflags": [ + "-unittest" + ] + }, + { + "name": "unittest-runner-cov", + "targetType" : "executable", + "sourcePaths": ["source/","tests/"], + "mainSourceFile":"tests/runner.d", + "excludedSourceFiles":[ + "source\/win_dll.d", + "tests/tests.d" + ], + "dflags": [ + "-unittest", + "-cov" + ] + }, { "name" : "library-betterC", "targetType" : "library", @@ -84,12 +111,12 @@ "-lpthread" ] }, - { - "name": "unittest-runner", + "name": "unittest-runner-betterC", "targetType" : "executable", "dflags": [ - "-betterC" + "-betterC", + "-unittest" ], "sourcePaths": ["source/","tests/"], "mainSourceFile":"tests/runner.d", diff --git a/tests/basic.d b/tests/basic.d index 33006a7..f794475 100644 --- a/tests/basic.d +++ b/tests/basic.d @@ -48,6 +48,15 @@ struct CShort short value = 12; } +struct CUnregistered +{ + mixin ECS.Component; + + alias value this; + + short value = 12; +} + void beforeEveryTest() { gEM.initialize(1); @@ -72,6 +81,8 @@ unittest assert(tmpl_.info.components.length == 2); assert(tmpl_.getComponent!CInt); assert(tmpl_.getComponent!CFloat); + assert(!tmpl_.getComponent!CLong); + assert(!tmpl_.getComponent!CUnregistered); assert(*tmpl_.getComponent!CInt == 1); assert(*tmpl_.getComponent!CFloat == 2.0); diff --git a/tests/runner.d b/tests/runner.d index 105a7a2..d2f9210 100644 --- a/tests/runner.d +++ b/tests/runner.d @@ -15,6 +15,9 @@ enum string OUT_FILE = "test_report.xml"; static jmp_buf gEnvBuffer; static AssertInfo gAssertInfo; +version(betterC){} +else version = notBetterC; + struct AssertInfo { const(char)* msg; @@ -44,6 +47,7 @@ struct TestSuite string name; uint passed = 0; uint failed = 0; + uint skipped = 0; Vector!Test tests; } @@ -56,25 +60,6 @@ string copyString(const char* str) struct TestRunner(Args...) { - TestSuite[Args.length] suites; - uint passed = 0; - uint failed = 0; - - SimpleVector junit; - - void write(string txt) - { - junit.add(cast(ubyte[]) txt); - } - - void write(uint num) - { - ubyte[20] buffer; - int len; - len = sprintf(cast(char*)buffer.ptr, "%u", num); - junit.add(buffer[0..len]); - } - void generateJUnit() { write("\n\n"); @@ -93,6 +78,8 @@ struct TestRunner(Args...) write(suite.passed + suite.failed); write("\" failures=\""); write(suite.failed); + write("\" skipped=\""); + write(suite.skipped); write("\">\n"); foreach(ref Test test; suite.tests) @@ -124,21 +111,59 @@ struct TestRunner(Args...) write(""); } - void runTests() + void runTests(string[] include = null, string[] exclude = null) { foreach(i, module_; Args) { TestSuite* suite = &suites[i]; suite.name = module_.stringof; - static if(__traits(hasMember, module_, "beforeEveryTest"))module_.beforeEveryTest(); foreach (index, unittest_; __traits(getUnitTests, module_)) { enum attributes = __traits(getAttributes, unittest_); + static if (attributes.length != 0) + { + if(include.length > 0) + { + bool matched = false; + foreach(str; include) + { + if(match(str, attributes[0])) + { + matched = true; + break; + } + } + + foreach(str; exclude) + { + if(match(str, attributes[0])) + { + matched = false; + break; + } + } + + if(!matched) + { + suite.skipped++; + continue; + } + } + } + else if(include.length > 0) + { + suite.skipped++; + continue; + } + Test test; static if (attributes.length == 0)test.name = "None"; else test.name = attributes[0]; + + static if(__traits(hasMember, module_, "beforeEveryTest"))module_.beforeEveryTest(); + // Save calling environment for longjmp int jmp_ret = setjmp(gEnvBuffer); @@ -159,10 +184,11 @@ struct TestRunner(Args...) if(test.passed)suite.passed++; else suite.failed++; suite.tests ~= test; + static if(__traits(hasMember, module_, "afterEveryTest"))module_.afterEveryTest(); } passed += suite.passed; failed += suite.failed; - static if(__traits(hasMember, module_, "afterEveryTest"))module_.afterEveryTest(); + skipped += suite.skipped; } } @@ -178,7 +204,7 @@ struct TestRunner(Args...) { foreach(ref TestSuite suite; suites) { - printf("Suite: \"%s\" Passed: %u/%u\n", suite.name.ptr, suite.passed, suite.passed + suite.failed); + printf("Suite: \"%s\" Passed: %u/%u Skipped: %u\n", suite.name.ptr, suite.passed, suite.passed + suite.failed, suite.skipped); foreach(ref Test test;suite.tests) { if(!test.passed) @@ -187,24 +213,127 @@ struct TestRunner(Args...) } } } - printf("Passed: %u/%u tests.\n", passed, passed+failed); + printf("Passed %u/%u tests. Skipped: %u.\n", passed, passed+failed, skipped); + } + + bool match(string a, string b) + { + uint i = 0; + foreach(char c; b) + { + if(i > a.length)return false; + if(a[i] == c)i++; + else + { + if(a[i] == '*') + { + if(i+1 >= a.length)return true; + else if(a[i + 1] == c)i += 2; + } + else return false; + } + } + return i == a.length; + } + + void write(string txt) + { + junit.add(cast(ubyte[]) txt); + } + + void write(uint num) + { + ubyte[20] buffer; + int len; + len = sprintf(cast(char*)buffer.ptr, "%u", num); + junit.add(buffer[0..len]); + } + + TestSuite[Args.length] suites; + uint passed = 0; + uint failed = 0; + uint skipped = 0; + + SimpleVector junit; +} + +version(notBetterC) +{ + extern(C) int rt_init(); + extern(C) int rt_term(); + version(D_Coverage) extern (C) void dmd_coverDestPath(string path); +} + +void extractStrings(ref Vector!string container, string str) +{ + uint s = 0; + foreach(j, char c; str) + { + if(c == ',') + { + if(s < j) + { + container.add(str[s .. j]); + } + s = cast(uint)j+1; + } + } + if(s < str.length) + { + container.add(str[s .. $]); } } -int main() +extern(C) int main(int argc, char** args) { - import tests.vector; - import tests.id_manager; - import tests.basic; + Vector!string include; + Vector!string exclude; + + version(notBetterC) + { + rt_init(); + version(D_Coverage) dmd_coverDestPath("reports"); + } + + for(int i=1;i= argc)break; + i++; + arg = cast(string)args[i][0..strlen(args[i])]; + extractStrings(include, arg); + } + else if(arg =="-e") + { + if(i + 1 >= argc)break; + i++; + arg = cast(string)args[i][0..strlen(args[i])]; + extractStrings(exclude, arg); + } + else if(arg.length < 10)continue; + else if(arg[0..10] == "--include=") + { + extractStrings(include, arg[10..$]); + } + else if(arg[0..10] == "--exclude=") + { + extractStrings(exclude, arg[10..$]); + } + } TestRunner!(tests.runner, tests.id_manager, tests.vector, tests.basic) runner; - runner.runTests(); + runner.runTests(include[], exclude[]); runner.writeFile(); runner.writeOutput(); + + version(notBetterC)rt_term(); if(!runner.failed)return 0; else return 1; -} +} \ No newline at end of file diff --git a/tests/vector.d b/tests/vector.d index 9b76d0b..5b52b79 100644 --- a/tests/vector.d +++ b/tests/vector.d @@ -3,6 +3,7 @@ module tests.vector; import ecs.simple_vector; //import ecs.vector; +@("simple-vector") unittest { SimpleVector vector;