#include <u.h>
#include <libc.h>
#include <fcall.h>
#include <thread.h>
#include <9p.h>
#include "common.h"
#include "debug.h"
#include "unittest.h"
#define DEBUG_TESTCASE true
#define DEBUG_TESTSUITE true
#define DEBUG_TESTRESULT true
void abstracttest_init(AbstractTest *self, char *name)
{
assert_valid(self);
assert_valid(name);
self->name = estrdup_fs(name);
self->next = nil;
}
void abstracttest_run(AbstractTest *self, TestResult *result)
{
assert_valid(self);
assert_valid(result);
assert_valid(self->run);
self->run(self, result);
}
void abstracttest_free(AbstractTest *self)
{
if(self == nil)
{
return;
}
assert_valid(self->free);
abstracttest_free(self->next);
self->free(self);
free(self->name);
free(self);
}
void testresult_init(TestResult *self)
{
assert_valid(self);
self->totalsuccess = 0;
self->totalfailure = 0;
self->totalerror = 0;
}
static void testresult_add_failure(TestResult *self, AbstractTest *test)
{
assert_valid(self);
assert_valid(test);
++(self->totalfailure);
INFO(DEBUG_TESTRESULT, "testcase %s FAILED", test->name);
}
static void testresult_add_error(TestResult *self, AbstractTest *test)
{
assert_valid(self);
assert_valid(test);
++(self->totalerror);
INFO(DEBUG_TESTRESULT, "testcase %s generated ERROR", test->name);
}
static void testresult_add_success(TestResult *self, AbstractTest *test)
{
assert_valid(self);
assert_valid(test);
++(self->totalsuccess);
INFO(DEBUG_TESTRESULT, "testcase %s PASSED", test->name);
}
uint testresult_total_tests(TestResult *self)
{
assert_valid(self);
return self->totalfailure + self->totalsuccess + self->totalerror;
}
float testresult_success_rate(TestResult *self)
{
assert_valid(self);
return ((float) self->totalsuccess) / testresult_total_tests(self);
}
void testresult_report(TestResult *self)
{
assert_valid(self);
INFO(DEBUG_TESTRESULT,
"Total %d tests"
" success: %d, failure: %d, error: %d, success rate: %f",
testresult_total_tests(self),
self->totalsuccess, self->totalfailure, self->totalerror,
testresult_success_rate(self));
}
void testcase_run(AbstractTest *test, TestResult *result)
{
void *data;
TestCase *self = (TestCase *)test;
assert_valid(self);
assert_valid(result);
assert_valid(self->setup);
assert_valid(self->teardown);
INFO(DEBUG_TESTCASE, "testcase_run running %s", test->name);
data = self->setup();
if(!self->test(data))
{
testresult_add_failure(result, (AbstractTest *)self);
}
else
{
testresult_add_success(result, (AbstractTest *)self);
}
self->teardown(data);
}
void testcase_free(AbstractTest *test)
{
if(test == nil)
{
return;
}
NOISE(DEBUG_TESTCASE, "testcase_free freeing %s", test->name);
}
TestCase *testcase_new_fixure(char *name,
TestFixure *fixure, testcase_test test)
{
assert_valid(fixure);
return testcase_new(name, fixure->setup, fixure->teardown, test);
}
TestCase *testcase_new(char *name,
testcase_setup setup, testcase_teardown teardown, testcase_test test)
{
TestCase *result;
assert_valid(test);
result = (TestCase *)emalloc_fs(sizeof(*result));
abstracttest_init(result, name);
result->run = testcase_run;
result->free = testcase_free;
result->setup = setup;
result->teardown = teardown;
result->test = test;
return result;
}
void testsuite_run(AbstractTest *test, TestResult *result)
{
AbstractTest *current;
TestSuite *self = (TestSuite *)test;
assert_valid(self);
assert_valid(result);
INFO(DEBUG_TESTSUITE, "testsuite_run running %s", test->name);
current = self->head;
while(current != nil)
{
abstracttest_run(current, result);
current = current->next;
}
}
void testsuite_free(AbstractTest *test)
{
TestSuite *self = (TestSuite *)test;
if(self == nil)
{
return;
}
NOISE(DEBUG_TESTSUITE, "testsuite_free freeing %s", test->name);
abstracttest_free(self->head);
}
TestSuite *testsuite_new(char *name)
{
TestSuite *result;
assert_valid(name);
result = (TestSuite *)emalloc_fs(sizeof(*result));
abstracttest_init(result, name);
result->run = testsuite_run;
result->free = testsuite_free;
result->head = nil;
return result;
}
void testsuite_add(TestSuite *self, AbstractTest *test)
{
assert_valid(self);
assert_valid(test);
NOISE(DEBUG_TESTSUITE, "testsuite_add adding %s", test->name);
test->next = self->head;
self->head = test;
}
TestSuite *testsuite_make(char *name,
TestCaseNamePair *pairs, uint total, TestFixure *fixure)
{
int i;
TestSuite *result;
assert_valid(name);
assert_valid(pairs);
assert_valid(fixure);
result = testsuite_new(name);
for(i = 0; i < total; ++i)
{
testsuite_add(result,
(AbstractTest *)testcase_new_fixure(
pairs[i].name, fixure, pairs[i].test));
}
return result;
}
|