test-lib: print escape sequence names

When printing expected/actual characters in failed checks, use their names (\a, \b, \n, ...) instead of their octal representation, making it easier to read. Add tests to test-example-tap.c Update t0080-unit-test-output.sh to match the desired output Teach 'print_one_char()' the equivalent name Signed-off-by: Pablo Sabater <pabloosabaterr@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Pablo Sabater committed Mar 11, 2026 at 04:14 UTC e30e9442fd9b90d96dde2fad4a6b26d7a03dee5e
3 files changed +53 -22
t/helper/test-example-tap.c
+4
@@ -63,6 +63,8 @@ static void t_messages(void)
63 check_str("NULL", NULL);
64 check_char('a', ==, '\n');
65 check_char('\\', ==, '\'');
66 + check_char('\a', ==, '\v');
67 + check_char('\x00', ==, '\x01');
68 }
69
70 static void t_empty(void)
@@ -123,6 +125,8 @@ int cmd__example_tap(int argc UNUSED, const char **argv UNUSED)
125 check_str("NULL", NULL);
126 check_char('a', ==, '\n');
127 check_char('\\', ==, '\'');
128 + check_char('\a', ==, '\v');
129 + check_char('\x00', ==, '\x01');
130 }
131 if_test ("if_test test with no checks")
132 ; /* nothing */
t/t0080-unit-test-output.sh
+32 -20
@@ -6,10 +6,10 @@ test_description='Test the output of the unit test framework'
6
7 test_expect_success 'TAP output from unit tests' - <<\EOT
8 cat >expect <<-EOF &&
9 - # BUG: check outside of test at t/helper/test-example-tap.c:75
9 + # BUG: check outside of test at t/helper/test-example-tap.c:77
10 ok 1 - passing test
11 ok 2 - passing test and assertion return 1
12 - # check "1 == 2" failed at t/helper/test-example-tap.c:79
12 + # check "1 == 2" failed at t/helper/test-example-tap.c:81
13 # left: 1
14 # right: 2
15 not ok 3 - failing test
@@ -34,53 +34,65 @@ test_expect_success 'TAP output from unit tests' - <<\EOT
34 not ok 15 - failing check after TEST_TODO()
35 ok 16 - failing check after TEST_TODO() returns 0
36 # check "!strcmp("\thello\\\\", "there\"\n")" failed at t/helper/test-example-tap.c:62
37 - # left: "\011hello\\\\"
38 - # right: "there\"\012"
37 + # left: "\thello\\\\"
38 + # right: "there\"\n"
39 # check "!strcmp("NULL", NULL)" failed at t/helper/test-example-tap.c:63
40 # left: "NULL"
41 # right: NULL
42 # check "'a' == '\n'" failed at t/helper/test-example-tap.c:64
43 # left: 'a'
44 - # right: '\012'
44 + # right: '\n'
45 # check "'\\\\' == '\\''" failed at t/helper/test-example-tap.c:65
46 # left: '\\\\'
47 # right: '\\''
48 + # check "'\a' == '\v'" failed at t/helper/test-example-tap.c:66
49 + # left: '\a'
50 + # right: '\v'
51 + # check "'\x00' == '\x01'" failed at t/helper/test-example-tap.c:67
52 + # left: '\000'
53 + # right: '\001'
54 not ok 17 - messages from failing string and char comparison
49 - # BUG: test has no checks at t/helper/test-example-tap.c:94
55 + # BUG: test has no checks at t/helper/test-example-tap.c:96
56 not ok 18 - test with no checks
57 ok 19 - test with no checks returns 0
58 ok 20 - if_test passing test
53 - # check "1 == 2" failed at t/helper/test-example-tap.c:100
59 + # check "1 == 2" failed at t/helper/test-example-tap.c:102
60 # left: 1
61 # right: 2
62 not ok 21 - if_test failing test
63 not ok 22 - if_test passing TEST_TODO() # TODO
58 - # todo check 'check(1)' succeeded at t/helper/test-example-tap.c:104
64 + # todo check 'check(1)' succeeded at t/helper/test-example-tap.c:106
65 not ok 23 - if_test failing TEST_TODO()
60 - # check "0" failed at t/helper/test-example-tap.c:106
66 + # check "0" failed at t/helper/test-example-tap.c:108
67 # skipping test - missing prerequisite
62 - # skipping check '1' at t/helper/test-example-tap.c:108
68 + # skipping check '1' at t/helper/test-example-tap.c:110
69 ok 24 - if_test test_skip() # SKIP
70 # skipping test - missing prerequisite
71 ok 25 - if_test test_skip() inside TEST_TODO() # SKIP
66 - # check "0" failed at t/helper/test-example-tap.c:113
72 + # check "0" failed at t/helper/test-example-tap.c:115
73 not ok 26 - if_test TEST_TODO() after failing check
68 - # check "0" failed at t/helper/test-example-tap.c:119
74 + # check "0" failed at t/helper/test-example-tap.c:121
75 not ok 27 - if_test failing check after TEST_TODO()
70 - # check "!strcmp("\thello\\\\", "there\"\n")" failed at t/helper/test-example-tap.c:122
71 - # left: "\011hello\\\\"
72 - # right: "there\"\012"
73 - # check "!strcmp("NULL", NULL)" failed at t/helper/test-example-tap.c:123
76 + # check "!strcmp("\thello\\\\", "there\"\n")" failed at t/helper/test-example-tap.c:124
77 + # left: "\thello\\\\"
78 + # right: "there\"\n"
79 + # check "!strcmp("NULL", NULL)" failed at t/helper/test-example-tap.c:125
80 # left: "NULL"
81 # right: NULL
76 - # check "'a' == '\n'" failed at t/helper/test-example-tap.c:124
82 + # check "'a' == '\n'" failed at t/helper/test-example-tap.c:126
83 # left: 'a'
78 - # right: '\012'
79 - # check "'\\\\' == '\\''" failed at t/helper/test-example-tap.c:125
84 + # right: '\n'
85 + # check "'\\\\' == '\\''" failed at t/helper/test-example-tap.c:127
86 # left: '\\\\'
87 # right: '\\''
88 + # check "'\a' == '\v'" failed at t/helper/test-example-tap.c:128
89 + # left: '\a'
90 + # right: '\v'
91 + # check "'\x00' == '\x01'" failed at t/helper/test-example-tap.c:129
92 + # left: '\000'
93 + # right: '\001'
94 not ok 28 - if_test messages from failing string and char comparison
83 - # BUG: test has no checks at t/helper/test-example-tap.c:127
95 + # BUG: test has no checks at t/helper/test-example-tap.c:131
96 not ok 29 - if_test test with no checks
97 1..29
98 EOF
t/unit-tests/test-lib.c
+17 -2
@@ -396,8 +396,23 @@ int check_uint_loc(const char *loc, const char *check, int ok,
396 static void print_one_char(char ch, char quote)
397 {
398 if ((unsigned char)ch < 0x20u || ch == 0x7f) {
399 - /* TODO: improve handling of \a, \b, \f ... */
400 - printf("\\%03o", (unsigned char)ch);
399 + char esc;
400 + switch (ch) {
401 + case '\a': esc = 'a'; break;
402 + case '\b': esc = 'b'; break;
403 + case '\t': esc = 't'; break;
404 + case '\n': esc = 'n'; break;
405 + case '\v': esc = 'v'; break;
406 + case '\f': esc = 'f'; break;
407 + case '\r': esc = 'r'; break;
408 + default: esc = 0; break;
409 + }
410 + if (esc) {
411 + putc('\\', stdout);
412 + putc(esc, stdout);
413 + } else {
414 + printf("\\%03o", (unsigned char)ch);
415 + }
416 } else {
417 if (ch == '\\' || ch == quote)
418 putc('\\', stdout);