diff --git a/test/unit/unit.c b/test/unit/unit.c index 38326793d922caa9361adbd27500311a1362e672..d1784bb8eba7c80cfa08d14bc7926bade35cb42b 100644 --- a/test/unit/unit.c +++ b/test/unit/unit.c @@ -60,19 +60,24 @@ check_plan(void) return r; } -int -_ok(int condition, const char *fmt, ...) +void +_ok(int condition, const char *expr, const char *file, int line, + const char *fmt, ...) { va_list ap; _space(stdout); printf("%s %d - ", condition ? "ok" : "not ok", ++tests_done[level]); - if (!condition) - tests_failed[level]++; va_start(ap, fmt); vprintf(fmt, ap); printf("\n"); va_end(ap); - return condition; + if (!condition) { + tests_failed[level]++; + _space(stderr); + fprintf(stderr, "# Failed test `%s'\n", expr); + _space(stderr); + fprintf(stderr, "# in %s at line %d\n", file, line); + } } diff --git a/test/unit/unit.h b/test/unit/unit.h index 77d0847b56b9f6935c9d438096d3318c126223e6..bb0e53136db8a68fad16db2235710ce1c9984410 100644 --- a/test/unit/unit.h +++ b/test/unit/unit.h @@ -70,7 +70,9 @@ extern "C" { */ /* private function, use ok(...) instead */ -int _ok(int condition, const char *fmt, ...); +void +_ok(int condition, const char *expr, const char *file, int line, + const char *fmt, ...); /* private function, use note(...) or diag(...) instead */ void _space(FILE *stream); @@ -90,41 +92,31 @@ _plan(int count, bool tap); */ int check_plan(void); -#define ok(condition, fmt, args...) { \ - int res = _ok(condition, fmt, ##args); \ - if (!res) { \ - _space(stderr); \ - fprintf(stderr, "# Failed test '"); \ - fprintf(stderr, fmt, ##args); \ - fprintf(stderr, "'\n"); \ - _space(stderr); \ - fprintf(stderr, "# in %s at line %d\n", __FILE__, __LINE__); \ - } \ -} - -#define is(a, b, fmt, args...) { \ - int res = _ok((a) == (b), fmt, ##args); \ - if (!res) { \ - _space(stderr); \ - fprintf(stderr, "# Failed test '"); \ - fprintf(stderr, fmt, ##args); \ - fprintf(stderr, "'\n"); \ - _space(stderr); \ - fprintf(stderr, "# in %s at line %d\n", __FILE__, __LINE__); \ - } \ -} - -#define isnt(a, b, fmt, args...) { \ - int res = _ok((a) != (b), fmt, ##args); \ - if (!res) { \ - _space(stderr); \ - fprintf(stderr, "# Failed test '"); \ - fprintf(stderr, fmt, ##args); \ - fprintf(stderr, "'\n"); \ - _space(stderr); \ - fprintf(stderr, "# in %s at line %d\n", __FILE__, __LINE__); \ - } \ -} +/* + * The ok macro is defined so that it can be called without a message: + * + * ok(true); + * ok(true, "message"); + * ok(true, "message %d", i); + * + * It supports up to 7 format arguments. + */ +#define _select_10th(f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, ...) f10 +#define _ok0(cond, expr, ...) \ + _select_10th(, ##__VA_ARGS__, \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, __VA_ARGS__), \ + _ok(cond, expr, __FILE__, __LINE__, "line %d", __LINE__)) + +#define ok(cond, ...) _ok0(cond, #cond, ##__VA_ARGS__) +#define is(a, b, ...) _ok0((a) == (b), #a " == " #b, ##__VA_ARGS__) +#define isnt(a, b, ...) _ok0((a) != (b), #a " != " #b, ##__VA_ARGS__) #if UNIT_TAP_COMPATIBLE