dte test coverage


Directory: ./
File: test/dump.c
Date: 2025-07-19 20:13:10
Exec Total Coverage
Lines: 54 57 94.7%
Functions: 1 1 100.0%
Branches: 19 26 73.1%

Line Branch Exec Source
1 #include "test.h"
2 #include "command/args.h"
3 #include "command/parse.h"
4 #include "editor.h"
5 #include "show.h"
6 #include "util/str-util.h"
7
8 typedef enum {
9 CHECK_NAME = 1u << 0, // Non-blank lines must begin with `name`
10 CHECK_PARSE = 1u << 1, // Non-blank lines must be parseable by parse_commands()
11 ALLOW_EMPTY = 1u << 2, // Dumped string may be empty
12 } DumpCheckFlags;
13
14 static const struct {
15 const char name[9];
16 uint8_t flags; // DumpCheckFlags
17 } handlers[] = {
18 {"alias", CHECK_NAME | CHECK_PARSE},
19 {"bind", CHECK_NAME | CHECK_PARSE},
20 {"buffer", 0},
21 {"builtin", 0}, // Same as `include`
22 {"color", CHECK_PARSE}, // Same as `hi`
23 {"command", ALLOW_EMPTY},
24 {"cursor", CHECK_NAME | CHECK_PARSE},
25 {"def-mode", CHECK_NAME | CHECK_PARSE},
26 {"env", 0}, // Similar to `setenv`
27 {"errorfmt", CHECK_NAME | CHECK_PARSE},
28 {"ft", CHECK_NAME | CHECK_PARSE},
29 {"hi", CHECK_NAME | CHECK_PARSE},
30 {"include", 0},
31 {"macro", 0},
32 {"msg", ALLOW_EMPTY},
33 {"open", 0},
34 {"paste", 0},
35 {"option", CHECK_PARSE},
36 {"search", ALLOW_EMPTY},
37 {"set", CHECK_NAME | CHECK_PARSE},
38 {"setenv", CHECK_NAME | CHECK_PARSE},
39 {"show", CHECK_NAME | CHECK_PARSE},
40 // {"tag", 0}, // Depends on filesystem state not controlled by the test runner
41 {"wsplit", 0},
42 };
43
44 1 static void test_dump_handlers(TestContext *ctx)
45 {
46 1 EditorState *e = ctx->userdata;
47 1 ASSERT_NONNULL(e);
48 1 ASSERT_NONNULL(e->window);
49 1 ASSERT_NONNULL(e->view);
50 1 ASSERT_NONNULL(e->buffer);
51 1 const CommandRunner runner = normal_mode_cmdrunner(e);
52 1 const CommandSet *cmds = runner.cmds;
53 1 ASSERT_NONNULL(cmds);
54 1 ASSERT_NONNULL(cmds->lookup);
55 1 clear_all_messages(e); // Clear messages for previous `tag` tests
56
57
2/2
✓ Branch 0 (60→10) taken 23 times.
✓ Branch 1 (60→61) taken 1 times.
24 for (size_t i = 0; i < ARRAYLEN(handlers); i++) {
58 23 bool check_parse = (handlers[i].flags & CHECK_PARSE);
59 23 bool check_name = (handlers[i].flags & CHECK_NAME);
60 23 bool allow_empty_str = (handlers[i].flags & ALLOW_EMPTY);
61 23 EXPECT_TRUE(!check_name || check_parse);
62
63 23 const char *name = handlers[i].name;
64 23 DumpFunc dump = get_dump_function(name);
65 23 EXPECT_NONNULL(dump);
66
1/2
✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→15) taken 23 times.
23 if (!dump) {
67 3 continue;
68 }
69
70 23 String str = dump(e);
71
2/2
✓ Branch 0 (16→17) taken 3 times.
✓ Branch 1 (16→24) taken 20 times.
23 if (str.len == 0) {
72
1/2
✗ Branch 0 (17→18) not taken.
✓ Branch 1 (17→19) taken 3 times.
3 if (!allow_empty_str) {
73 TEST_FAIL("'show %s' handler returned an empty String", name);
74 } else {
75 3 test_pass(ctx);
76 }
77 3 EXPECT_EQ(str.alloc, 0);
78 3 EXPECT_NULL(str.buffer);
79 3 string_free(&str);
80 3 continue;
81 }
82
83
1/2
✗ Branch 0 (24→25) not taken.
✓ Branch 1 (24→27) taken 20 times.
20 if (allow_empty_str) {
84 TEST_FAIL (
85 "ALLOW_EMPTY flag set for '%s', but dump() produced: %s",
86 name, string_borrow_cstring(&str)
87 );
88 } else {
89 20 test_pass(ctx);
90 }
91
92 // The last line of generated text must end with a newline
93 // (see comment in get_delim_str())
94 20 ASSERT_EQ(str.buffer[str.len - 1], '\n');
95
96
2/2
✓ Branch 0 (55→30) taken 1085 times.
✓ Branch 1 (55→56) taken 20 times.
1105 for (size_t pos = 0, len = str.len; pos < len; ) {
97 1085 const char *line = buf_next_line(str.buffer, &pos, len);
98 1085 ASSERT_NONNULL(line);
99
4/4
✓ Branch 0 (32→33) taken 1068 times.
✓ Branch 1 (32→34) taken 17 times.
✓ Branch 2 (33→34) taken 386 times.
✓ Branch 3 (33→35) taken 682 times.
1085 if (line[0] == '\0' || line[0] == '#' || !check_parse) {
100 403 continue;
101 }
102
103 682 PointerArray arr = PTR_ARRAY_INIT;
104 682 CommandParseError parse_err = parse_commands(&runner, &arr, line);
105 682 EXPECT_EQ(parse_err, CMDERR_NONE);
106 682 EXPECT_TRUE(arr.count >= 2);
107
2/4
✓ Branch 0 (38→39) taken 682 times.
✗ Branch 1 (38→40) not taken.
✗ Branch 2 (39→40) not taken.
✓ Branch 3 (39→41) taken 682 times.
682 if (parse_err != CMDERR_NONE || arr.count < 2) {
108 continue;
109 }
110
111
2/2
✓ Branch 0 (41→42) taken 548 times.
✓ Branch 1 (41→43) taken 134 times.
682 if (check_name) {
112 548 EXPECT_STREQ(arr.ptrs[0], name);
113 }
114
115 682 const Command *cmd = cmds->lookup(arr.ptrs[0]);
116 682 EXPECT_NONNULL(cmd);
117
1/2
✗ Branch 0 (45→46) not taken.
✓ Branch 1 (45→47) taken 682 times.
682 if (!cmd) {
118 continue;
119 }
120
121 682 CommandArgs a = cmdargs_new((char**)arr.ptrs + 1);
122 682 ArgParseError arg_err = do_parse_args(cmd, &a);
123 682 EXPECT_EQ(arg_err, ARGERR_NONE);
124
1/2
✗ Branch 0 (49→50) not taken.
✓ Branch 1 (49→51) taken 682 times.
682 if (arg_err != ARGERR_NONE) {
125 continue;
126 }
127 682 ptr_array_free(&arr);
128 }
129 20 string_free(&str);
130 }
131 1 }
132
133 static const TestEntry tests[] = {
134 TEST(test_dump_handlers),
135 };
136
137 const TestGroup dump_tests = TEST_GROUP(tests);
138