unit-tests: show location of checks outside of tests

Checks outside of tests are caught at runtime and reported like this: Assertion failed: (ctx.running), function test_assert, file test-lib.c, line 267. The assert() call aborts the unit test and doesn't reveal the location or even the type of the offending check, as test_assert() is called by all of them. Handle it like the opposite case, a test without any checks: Don't abort, but report the location of the actual check, along with a message explaining the situation. The output for example above becomes: # BUG: check outside of test at t/helper/test-example-tap.c:75 ... and the unit test program continues and indicates the error in its exit code at the end. Signed-off-by: René Scharfe <l.s.r@web.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

René Scharfe committed Jul 30, 2024 at 16:07 UTC 1f452d6c6835e41d25e163616d8ee75aa91b5b17
3 files changed +11 -3
t/helper/test-example-tap.c
+2
@@ -72,6 +72,8 @@ static void t_empty(void)
72
73 int cmd__example_tap(int argc, const char **argv)
74 {
75 + check(1);
76 +
77 test_res = TEST(check_res = check_int(1, ==, 1), "passing test");
78 TEST(t_res(1), "passing test and assertion return 1");
79 test_res = TEST(check_res = check_int(1, ==, 2), "failing test");
t/t0080-unit-test-output.sh
+3 -2
@@ -7,9 +7,10 @@ TEST_PASSES_SANITIZE_LEAK=true
7
8 test_expect_success 'TAP output from unit tests' - <<\EOT
9 cat >expect <<-EOF &&
10 + # BUG: check outside of test at t/helper/test-example-tap.c:75
11 ok 1 - passing test
12 ok 2 - passing test and assertion return 1
12 - # check "1 == 2" failed at t/helper/test-example-tap.c:77
13 + # check "1 == 2" failed at t/helper/test-example-tap.c:79
14 # left: 1
15 # right: 2
16 not ok 3 - failing test
@@ -46,7 +47,7 @@ test_expect_success 'TAP output from unit tests' - <<\EOT
47 # left: '\\\\'
48 # right: '\\''
49 not ok 17 - messages from failing string and char comparison
49 - # BUG: test has no checks at t/helper/test-example-tap.c:92
50 + # BUG: test has no checks at t/helper/test-example-tap.c:94
51 not ok 18 - test with no checks
52 ok 19 - test with no checks returns 0
53 1..19
t/unit-tests/test-lib.c
+6 -1
@@ -264,7 +264,12 @@ static void test_todo(void)
264
265 int test_assert(const char *location, const char *check, int ok)
266 {
267 - assert(ctx.running);
267 + if (!ctx.running) {
268 + test_msg("BUG: check outside of test at %s",
269 + make_relative(location));
270 + ctx.failed = 1;
271 + return 0;
272 + }
273
274 if (ctx.result == RESULT_SKIP) {
275 test_msg("skipping check '%s' at %s", check,