#define test_assert(expression) if(!(expression)) return false #define test_assert_false(expression) test_assert(!(expression)) typedef struct TestResult { int totalsuccess; int totalfailure; int totalerror; } TestResult; void testresult_init(TestResult *self); void testresult_report(TestResult *self); typedef struct AbstractTest AbstractTest; struct AbstractTest { char *name; void (*run)(AbstractTest *test, TestResult *result); /** subclass only need to free its own private data, not even itself */ void (*free)(AbstractTest *test); AbstractTest *next; }; void abstracttest_run(AbstractTest *self, TestResult *result); void abstracttest_free(AbstractTest *self); typedef bool (*testcase_test)(void *data); typedef void *(*testcase_setup)(void); typedef void (*testcase_teardown)(void *data); typedef struct TestFixure { testcase_setup setup; testcase_teardown teardown; } TestFixure; typedef struct TestCase { AbstractTest; testcase_setup setup; testcase_teardown teardown; testcase_test test; } TestCase; TestCase *testcase_new_fixure(char *name, TestFixure *fixure, testcase_test test); TestCase *testcase_new(char *name, testcase_setup setup, testcase_teardown teardown, testcase_test test); typedef struct TestCaseNamePair { char *name; testcase_test test; } TestCaseNamePair; #define testcasenamepair_make(testcase) {"testcase", testcase} typedef struct TestSuite { AbstractTest; AbstractTest *head; } TestSuite; TestSuite *testsuite_new(char *name); void testsuite_add(TestSuite *self, AbstractTest *test); TestSuite *testsuite_make(char *name, TestCaseNamePair *pairs, uint total, TestFixure *fixure);