dte test coverage


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