12#ifndef STB_TEST_DEFINITION
14#define STB_TEST_DEFINITION
21#define _STBTEST_ATTR_FORMAT(archetype, string_index, first_to_check) __attribute__((format(archetype, string_index, first_to_check)))
23#define _STBTEST_ATTR_FORMAT(archetype, string_index, first_to_check)
49#define test_fail(test, name, ...) _stbtest_test_case(__LINE__, __FILE_NAME__, (test), false, "(fail)", (name)__VA_OPT__(, ) __VA_ARGS__)
51#define test_case(test, expr, name, ...) _stbtest_test_case(__LINE__, __FILE_NAME__, (test), (expr), #expr, (name)__VA_OPT__(, ) __VA_ARGS__)
53#define test_case_wide(test, expr, name, ...) _stbtest_test_case(__LINE__, __FILE_NAME__, (test), (expr), NULL, (name)__VA_OPT__(, ) __VA_ARGS__)
55STB_TEST_DEFINITION bool _stbtest_test_case(
unsigned line,
char const *file,
struct test *
test,
bool ok,
char const *expr,
char const *fmt_name, ...)
56 _STBTEST_ATTR_FORMAT(printf, 6, 7);
72#ifdef STB_TEST_IMPLEMENTATION
79#define _stbtest_digit_count(n, base) ((n) == 0 ? 1 : (int)(log(n) / log(base)) + 1)
82 return (
struct test) {
88bool _stbtest_test_case(
unsigned line,
char const *file,
struct test *
test,
bool ok,
char const *expr,
char const *fmt_name, ...) {
91 va_start(ap, fmt_name);
92 size_t name_size = vsnprintf(NULL, 0, fmt_name, ap) + 1;
95 char *name = malloc(
sizeof *name * name_size);
98 va_start(ap, fmt_name);
99 vsnprintf(name, name_size, fmt_name, ap);
116 int i, nb_ko = 0, nb_ok = 0;
118 int col_len_file =
sizeof "file";
119 int col_len_expr =
sizeof "expr";
120 int col_len_name =
sizeof "info";
122 for (i = 0; i < arrlenu(
test->cases); ++i) {
124 c->ok ? ++nb_ok : ++nb_ko;
127 if ((len = strlen(c->file)) > col_len_file) col_len_file = len;
128 if ((len = strlen(c->expr)) > col_len_expr) col_len_expr = len;
129 if ((len = strlen(c->name)) > col_len_name) col_len_name = len;
134 fprintf(output,
"test %s: %d ko, %d ok, %d total: %s\n",
135 nb_ko == 0 ?
"\033[32;49msuccess\033[39;49m" :
"\033[31;49mfailure\033[39;49m",
143 int const col_len_num = _stbtest_digit_count(arrlenu(
test->cases), 10);
144 int const col_len_line = _stbtest_digit_count(arrlast(
test->cases).line, 10);
146 for (i = 0; i < col_len_num; ++i)
148 fprintf(output,
" | OK | %-*s | %*s | %-*s | %-*s |\n",
149 col_len_file,
"file",
151 col_len_expr,
"expr",
152 col_len_name,
"info");
154 for (i = 0; i < col_len_num; ++i)
156 fputs(
" | -- | ", output);
157 for (i = 0; i < col_len_file; ++i)
159 fputs(
" | ", output);
160 for (i = 0; i < col_len_line; ++i)
162 fputs(
" | ", output);
163 for (i = 0; i < col_len_expr; ++i)
165 fputs(
" | ", output);
166 for (i = 0; i < col_len_name; ++i)
168 fputs(
" |\n", output);
172 for (i = 0; i < arrlenu(
test->cases); ++i) {
174 char const *ok = c->ok ?
"\033[32;49mOK\033[39;49m" :
"\033[31;49mKO\033[39;49m";
176 fprintf(output,
"%*d | %s | %-*s | %*u | %-*s | %-*s |\n",
178 col_len_file, c->file,
179 col_len_line, c->line,
180 col_len_expr, c->expr,
181 col_len_name, c->name);
183 fprintf(output,
"%*d | %s | %-*s | %*u | %s\n",
185 col_len_file, c->file,
186 col_len_line, c->line,
192 for (i = 0; i < arrlenu(
test->cases); ++i)
193 free(
test->cases[i].name);
194 arrfree(
test->cases);
#define STB_TEST_DEFINITION
Defines modifier keywords for the definitions. Example value: static inline.
STB_TEST_DEFINITION bool STB_TEST_DEFINITION bool test_end(struct test *test, FILE *output)
Finish a test suite and prints the results to the provided output stream.
STB_TEST_DEFINITION struct test test_start(char const *name)
Start a new test suite with the given name.
Represents a test suite with a name and a collection of test cases.