//--- // ft.test: Testing tools and status reports //--- #ifndef _FT_TEST_H_ #define _FT_TEST_H_ #include #include #include //--- // Test framework //--- /* ft_test: A series of assertions grouped together in a single function */ typedef struct ft_test { /* Test name */ char const *name; /* Test function */ void (*function)(struct ft_test *t); /* Optional visualization widget; called when the visualization is requested. The widget can be interactive, but it must not accept EXIT or MENU events. It is destroyed atfer use. */ jwidget *(*widget)(struct ft_test *test); /* Test log; this can be displayed by a scrolling widget */ char *log; uint16_t log_size; /* Number of passed, skipped and failed assertions in the test */ uint16_t passed; uint16_t skipped; uint16_t failed; /* Whether test was run */ bool run; } ft_test; /* ft_test_init(): Init counters and logs for a test */ void ft_test_init(ft_test *test); /* ft_test_run(): Reset and run a test */ void ft_test_run(ft_test *test); /* ft_assert(): Record an assertion in a test, return value */ int ft_assert(ft_test *test, int expression, char const *file, int line, char const *expression_str); #define ft_assert(test, expression) \ ft_assert(test, expression, __FILE__, __LINE__, #expression) /* ft_assert_eval(): Evaluate expression, log result and assert result */ #define ft_assert_eval(test, expression, expected, resultfmt) { \ if(ft_assert(test, (expression) == (expected))) \ ft_log(test, #expression " = " #expected "\n"); \ else \ ft_log(test, #expression " = " resultfmt " [wanted " #expected "]\n", \ (expression)); \ } /* ft_skip(): Skip some tests */ void ft_skip(ft_test *test, int amount); /* ft_log(): Write some data in a test's log */ __attribute__((format(printf, 2, 3))) void ft_log(ft_test *test, char const *format, ...); //--- // Test lists (to organize by header) //--- /* ft_list: A named list of tests with aggregating statistics */ typedef struct { /* List name (header name) */ char const *name; /* NULL-terminated list of children */ ft_test **children; /* Number of passed, skipped and failed assertions in the children */ uint16_t passed; uint16_t skipped; uint16_t failed; } ft_list; /* ft_list_init(): Init counters and logs for a NULL-terminated test list */ void ft_list_init(ft_list *list); /* ft_list_run(): Reset and run a list of tests (aggregates automatically) */ void ft_list_run(ft_list *list); /* ft_list_aggregate(): Update list results based on the children's results */ void ft_list_aggregate(ft_list *l); //--- // Utilities //--- /* Colors for each test category */ #define FT_TEST_EMPTY _(1, C_RGB(20,20,20)) #define FT_TEST_PASSED _(2, C_RGB(6,25,8)) #define FT_TEST_SKIPPED _(3, C_RGB(31,20,9)) #define FT_TEST_PENDING _(4, C_RGB(15,23,27)) #define FT_TEST_FAILED _(5, C_RGB(31,10,7)) /* ft_test_color(): Color for the summary of a test */ int ft_test_color(ft_test const *t); /* ft_list_color(): Color for the summary of a list of tests */ int ft_list_color(ft_list const *t); #endif /* _FT_TEST_H_ */