diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 0000000..7c85138 --- /dev/null +++ b/include/assert.h @@ -0,0 +1,62 @@ +#ifndef CRITERION_ASSERT_H_ +# define CRITERION_ASSERT_H_ + +# include +# include +# include "criterion.h" + +enum criterion_assert_kind { + NORMAL, + FATAL +}; + +struct criterion_assert_stat { + enum criterion_assert_kind kind; + const char *condition; + const char *message; + bool passed; + unsigned line; + + struct criterion_assert_stat *next; +}; + +struct criterion_test_stats { + struct criterion_test *test; + struct criterion_assert_stat *asserts; + unsigned failed; + unsigned passed; +}; + +extern struct criterion_test_stats g_current_test_stats; + +# define assertImpl(Kind, Condition, ...) \ + do { \ + int passed = !!(Condition); \ + struct criterion_assert_stat *stat = \ + malloc(sizeof (struct criterion_assert_stat)); \ + *stat = (struct criterion_assert_stat) { \ + .kind = Kind, \ + .condition = #Condition, \ + .message = "" __VA_ARGS__, \ + .passed = passed, \ + .line = __LINE__, \ + .next = g_current_test_stats.asserts, \ + }; \ + g_current_test_stats.asserts = stat; \ + if (passed) \ + ++g_current_test_stats.passed; \ + else \ + ++g_current_test_stats.failed; \ + if (!passed && Kind == FATAL) \ + return; \ + } while (0) + +# define expect(Condition, ...) assertImpl(NORMAL, Condition, __VA_ARGS__) +# define assert(Condition, ...) assertImpl(FATAL, Condition, __VA_ARGS__) + +# define assertArrayEquals(A, B, Size, ...) \ + assertImpl(NORMAL, !memcmp((A), (B), Size), __VA_ARGS__) +# define expectArrayEquals(A, B, Size, ...) \ + assertImpl(FATAL, !memcmp((A), (B), Size), __VA_ARGS__) + +#endif /* !CRITERION_ASSERT_H_ */ diff --git a/include/criterion.h b/include/criterion.h index c0a0d03..0379e57 100644 --- a/include/criterion.h +++ b/include/criterion.h @@ -24,8 +24,10 @@ #ifndef CRITERION_H_ # define CRITERION_H_ -#include -#include "common.h" +# include +# include +# include "common.h" +# include "assert.h" struct criterion_test_extra_data { size_t sentinel_; diff --git a/samples/simple.c b/samples/simple.c index 8df8fd8..19d4336 100644 --- a/samples/simple.c +++ b/samples/simple.c @@ -2,12 +2,15 @@ #include #include "criterion.h" #include "report.h" - -Test(misc, simple) { -} +#include "assert.h" Test(misc, failing) { - exit(1); + assert(1); + assert(0); +} + +Test(misc, simple) { + expect(1); } ReportHook(PRE_INIT) { diff --git a/src/report.c b/src/report.c index 48ea375..c647c74 100644 --- a/src/report.c +++ b/src/report.c @@ -28,7 +28,11 @@ ReportHook(PRE_INIT) { } ReportHook(POST_TEST) { + struct criterion_test_stats *stats = data; + int success = stats->failed == 0; + + printf("%s\n", success ? "SUCCESS" : "FAILURE"); } ReportHook(PRE_TEST) {} diff --git a/src/runner.c b/src/runner.c index 617b3b0..04ab118 100644 --- a/src/runner.c +++ b/src/runner.c @@ -27,6 +27,7 @@ #include #include "runner.h" #include "report.h" +#include "assert.h" static struct criterion_test * const g_section_start = &__start_criterion_tests; static struct criterion_test * const g_section_end = &__stop_criterion_tests; @@ -38,14 +39,19 @@ static void map_tests(void (*fun)(struct criterion_test *)) { } __attribute__ ((always_inline)) -static inline void nothing(void) {} +static inline void nothing() {} + +struct criterion_test_stats g_current_test_stats; static void run_test_nofork(struct criterion_test *test) { report(PRE_INIT, test); (test->data->init ?: nothing)(); report(PRE_TEST, test); + + g_current_test_stats = (struct criterion_test_stats) { .test = test }; (test->test ?: nothing)(); - report(POST_TEST, test); + + report(POST_TEST, &g_current_test_stats); (test->data->fini ?: nothing)(); report(POST_FINI, test); }