Unitests update
-unittest runner works for non betterC build -working unittest coverage generation -unittest runner support for named tests. Simple regex is supported (* as any substring) and two list of expressions are used, one for include regex and one for exclude regex
This commit is contained in:
parent
998240f7be
commit
2aef76d75a
4 changed files with 201 additions and 33 deletions
33
dub.json
33
dub.json
|
|
@ -38,6 +38,33 @@
|
||||||
"-op"
|
"-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",
|
"name" : "library-betterC",
|
||||||
"targetType" : "library",
|
"targetType" : "library",
|
||||||
|
|
@ -84,12 +111,12 @@
|
||||||
"-lpthread"
|
"-lpthread"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
"name": "unittest-runner",
|
"name": "unittest-runner-betterC",
|
||||||
"targetType" : "executable",
|
"targetType" : "executable",
|
||||||
"dflags": [
|
"dflags": [
|
||||||
"-betterC"
|
"-betterC",
|
||||||
|
"-unittest"
|
||||||
],
|
],
|
||||||
"sourcePaths": ["source/","tests/"],
|
"sourcePaths": ["source/","tests/"],
|
||||||
"mainSourceFile":"tests/runner.d",
|
"mainSourceFile":"tests/runner.d",
|
||||||
|
|
|
||||||
|
|
@ -48,6 +48,15 @@ struct CShort
|
||||||
short value = 12;
|
short value = 12;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CUnregistered
|
||||||
|
{
|
||||||
|
mixin ECS.Component;
|
||||||
|
|
||||||
|
alias value this;
|
||||||
|
|
||||||
|
short value = 12;
|
||||||
|
}
|
||||||
|
|
||||||
void beforeEveryTest()
|
void beforeEveryTest()
|
||||||
{
|
{
|
||||||
gEM.initialize(1);
|
gEM.initialize(1);
|
||||||
|
|
@ -72,6 +81,8 @@ unittest
|
||||||
assert(tmpl_.info.components.length == 2);
|
assert(tmpl_.info.components.length == 2);
|
||||||
assert(tmpl_.getComponent!CInt);
|
assert(tmpl_.getComponent!CInt);
|
||||||
assert(tmpl_.getComponent!CFloat);
|
assert(tmpl_.getComponent!CFloat);
|
||||||
|
assert(!tmpl_.getComponent!CLong);
|
||||||
|
assert(!tmpl_.getComponent!CUnregistered);
|
||||||
assert(*tmpl_.getComponent!CInt == 1);
|
assert(*tmpl_.getComponent!CInt == 1);
|
||||||
assert(*tmpl_.getComponent!CFloat == 2.0);
|
assert(*tmpl_.getComponent!CFloat == 2.0);
|
||||||
|
|
||||||
|
|
|
||||||
189
tests/runner.d
189
tests/runner.d
|
|
@ -15,6 +15,9 @@ enum string OUT_FILE = "test_report.xml";
|
||||||
static jmp_buf gEnvBuffer;
|
static jmp_buf gEnvBuffer;
|
||||||
static AssertInfo gAssertInfo;
|
static AssertInfo gAssertInfo;
|
||||||
|
|
||||||
|
version(betterC){}
|
||||||
|
else version = notBetterC;
|
||||||
|
|
||||||
struct AssertInfo
|
struct AssertInfo
|
||||||
{
|
{
|
||||||
const(char)* msg;
|
const(char)* msg;
|
||||||
|
|
@ -44,6 +47,7 @@ struct TestSuite
|
||||||
string name;
|
string name;
|
||||||
uint passed = 0;
|
uint passed = 0;
|
||||||
uint failed = 0;
|
uint failed = 0;
|
||||||
|
uint skipped = 0;
|
||||||
Vector!Test tests;
|
Vector!Test tests;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -56,25 +60,6 @@ string copyString(const char* str)
|
||||||
|
|
||||||
struct TestRunner(Args...)
|
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()
|
void generateJUnit()
|
||||||
{
|
{
|
||||||
write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
|
write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n");
|
||||||
|
|
@ -93,6 +78,8 @@ struct TestRunner(Args...)
|
||||||
write(suite.passed + suite.failed);
|
write(suite.passed + suite.failed);
|
||||||
write("\" failures=\"");
|
write("\" failures=\"");
|
||||||
write(suite.failed);
|
write(suite.failed);
|
||||||
|
write("\" skipped=\"");
|
||||||
|
write(suite.skipped);
|
||||||
write("\">\n");
|
write("\">\n");
|
||||||
|
|
||||||
foreach(ref Test test; suite.tests)
|
foreach(ref Test test; suite.tests)
|
||||||
|
|
@ -124,21 +111,59 @@ struct TestRunner(Args...)
|
||||||
write("</testsuites>");
|
write("</testsuites>");
|
||||||
}
|
}
|
||||||
|
|
||||||
void runTests()
|
void runTests(string[] include = null, string[] exclude = null)
|
||||||
{
|
{
|
||||||
foreach(i, module_; Args)
|
foreach(i, module_; Args)
|
||||||
{
|
{
|
||||||
TestSuite* suite = &suites[i];
|
TestSuite* suite = &suites[i];
|
||||||
suite.name = module_.stringof;
|
suite.name = module_.stringof;
|
||||||
static if(__traits(hasMember, module_, "beforeEveryTest"))module_.beforeEveryTest();
|
|
||||||
foreach (index, unittest_; __traits(getUnitTests, module_))
|
foreach (index, unittest_; __traits(getUnitTests, module_))
|
||||||
{
|
{
|
||||||
enum attributes = __traits(getAttributes, unittest_);
|
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;
|
Test test;
|
||||||
|
|
||||||
static if (attributes.length == 0)test.name = "None";
|
static if (attributes.length == 0)test.name = "None";
|
||||||
else test.name = attributes[0];
|
else test.name = attributes[0];
|
||||||
|
|
||||||
|
|
||||||
|
static if(__traits(hasMember, module_, "beforeEveryTest"))module_.beforeEveryTest();
|
||||||
|
|
||||||
// Save calling environment for longjmp
|
// Save calling environment for longjmp
|
||||||
int jmp_ret = setjmp(gEnvBuffer);
|
int jmp_ret = setjmp(gEnvBuffer);
|
||||||
|
|
||||||
|
|
@ -159,10 +184,11 @@ struct TestRunner(Args...)
|
||||||
if(test.passed)suite.passed++;
|
if(test.passed)suite.passed++;
|
||||||
else suite.failed++;
|
else suite.failed++;
|
||||||
suite.tests ~= test;
|
suite.tests ~= test;
|
||||||
|
static if(__traits(hasMember, module_, "afterEveryTest"))module_.afterEveryTest();
|
||||||
}
|
}
|
||||||
passed += suite.passed;
|
passed += suite.passed;
|
||||||
failed += suite.failed;
|
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)
|
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)
|
foreach(ref Test test;suite.tests)
|
||||||
{
|
{
|
||||||
if(!test.passed)
|
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;
|
Vector!string include;
|
||||||
import tests.id_manager;
|
Vector!string exclude;
|
||||||
import tests.basic;
|
|
||||||
|
version(notBetterC)
|
||||||
|
{
|
||||||
|
rt_init();
|
||||||
|
version(D_Coverage) dmd_coverDestPath("reports");
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int i=1;i<argc;i++)
|
||||||
|
{
|
||||||
|
string arg = cast(string)args[i][0..strlen(args[i])];
|
||||||
|
if(arg.length < 2)continue;
|
||||||
|
else if(arg == "-i")
|
||||||
|
{
|
||||||
|
if(i + 1 >= 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;
|
TestRunner!(tests.runner, tests.id_manager, tests.vector, tests.basic) runner;
|
||||||
|
|
||||||
runner.runTests();
|
runner.runTests(include[], exclude[]);
|
||||||
|
|
||||||
runner.writeFile();
|
runner.writeFile();
|
||||||
|
|
||||||
runner.writeOutput();
|
runner.writeOutput();
|
||||||
|
|
||||||
|
version(notBetterC)rt_term();
|
||||||
|
|
||||||
if(!runner.failed)return 0;
|
if(!runner.failed)return 0;
|
||||||
else return 1;
|
else return 1;
|
||||||
}
|
}
|
||||||
|
|
@ -3,6 +3,7 @@ module tests.vector;
|
||||||
import ecs.simple_vector;
|
import ecs.simple_vector;
|
||||||
//import ecs.vector;
|
//import ecs.vector;
|
||||||
|
|
||||||
|
@("simple-vector")
|
||||||
unittest
|
unittest
|
||||||
{
|
{
|
||||||
SimpleVector vector;
|
SimpleVector vector;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue