dte test coverage


Directory: ./
File: test/dump.c
Date: 2025-07-03 15:44: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 {"paste", 0},
43 {"option", CHECK_PARSE},
44 {"search", ALLOW_EMPTY},
45 {"set", CHECK_NAME | CHECK_PARSE},
46 {"setenv", CHECK_NAME | CHECK_PARSE},
47 {"show", CHECK_NAME | CHECK_PARSE},
48 // {"tag", 0}, // Depends on filesystem state not controlled by the test runner
49 {"wsplit", 0},
50 };
51
52 1 static void test_dump_handlers(TestContext *ctx)
53 {
54 1 EditorState *e = ctx->userdata;
55 1 ASSERT_NONNULL(e);
56 1 ASSERT_NONNULL(e->window);
57 1 ASSERT_NONNULL(e->view);
58 1 ASSERT_NONNULL(e->buffer);
59 1 const CommandRunner runner = normal_mode_cmdrunner(e);
60 1 const CommandSet *cmds = runner.cmds;
61 1 ASSERT_NONNULL(cmds);
62 1 ASSERT_NONNULL(cmds->lookup);
63 1 clear_all_messages(e); // Clear messages for previous `tag` tests
64
65
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++) {
66 23 bool check_parse = (handlers[i].flags & CHECK_PARSE);
67 23 bool check_name = (handlers[i].flags & CHECK_NAME);
68 23 bool allow_empty_str = (handlers[i].flags & ALLOW_EMPTY);
69 23 EXPECT_TRUE(!check_name || check_parse);
70
71 23 const char *name = handlers[i].name;
72 23 DumpFunc dump = get_dump_function(name);
73 23 EXPECT_NONNULL(dump);
74
1/2
✗ Branch 0 (13→14) not taken.
✓ Branch 1 (13→15) taken 23 times.
23 if (!dump) {
75 3 continue;
76 }
77
78 23 String str = dump(e);
79
2/2
✓ Branch 0 (16→17) taken 3 times.
✓ Branch 1 (16→24) taken 20 times.
23 if (str.len == 0) {
80
1/2
✗ Branch 0 (17→18) not taken.
✓ Branch 1 (17→19) taken 3 times.
3 if (!allow_empty_str) {
81 TEST_FAIL("'show %s' handler returned an empty String", name);
82 } else {
83 3 test_pass(ctx);
84 }
85 3 EXPECT_EQ(str.alloc, 0);
86 3 EXPECT_NULL(str.buffer);
87 3 string_free(&str);
88 3 continue;
89 }
90
91
1/2
✗ Branch 0 (24→25) not taken.
✓ Branch 1 (24→27) taken 20 times.
20 if (allow_empty_str) {
92 TEST_FAIL (
93 "ALLOW_EMPTY flag set for '%s', but dump() produced: %s",
94 name, string_borrow_cstring(&str)
95 );
96 } else {
97 20 test_pass(ctx);
98 }
99
100 // The last line of generated text must end with a newline
101 // (see comment in get_delim_str())
102 20 ASSERT_EQ(str.buffer[str.len - 1], '\n');
103
104
2/2
✓ Branch 0 (55→30) taken 1098 times.
✓ Branch 1 (55→56) taken 20 times.
1118 for (size_t pos = 0, len = str.len; pos < len; ) {
105 1098 const char *line = buf_next_line(str.buffer, &pos, len);
106 1098 ASSERT_NONNULL(line);
107
4/4
✓ Branch 0 (32→33) taken 1076 times.
✓ Branch 1 (32→34) taken 22 times.
✓ Branch 2 (33→34) taken 395 times.
✓ Branch 3 (33→35) taken 681 times.
1098 if (line[0] == '\0' || line[0] == '#' || !check_parse) {
108 417 continue;
109 }
110
111 681 PointerArray arr = PTR_ARRAY_INIT;
112 681 CommandParseError parse_err = parse_commands(&runner, &arr, line);
113 681 EXPECT_EQ(parse_err, CMDERR_NONE);
114 681 EXPECT_TRUE(arr.count >= 2);
115
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) {
116 continue;
117 }
118
119
2/2
✓ Branch 0 (41→42) taken 547 times.
✓ Branch 1 (41→43) taken 134 times.
681 if (check_name) {
120 547 EXPECT_STREQ(arr.ptrs[0], name);
121 }
122
123 681 const Command *cmd = cmds->lookup(arr.ptrs[0]);
124 681 EXPECT_NONNULL(cmd);
125
1/2
✗ Branch 0 (45→46) not taken.
✓ Branch 1 (45→47) taken 681 times.
681 if (!cmd) {
126 continue;
127 }
128
129 681 CommandArgs a = cmdargs_new((char**)arr.ptrs + 1);
130 681 ArgParseError arg_err = do_parse_args(cmd, &a);
131 681 EXPECT_EQ(arg_err, ARGERR_NONE);
132
1/2
✗ Branch 0 (49→50) not taken.
✓ Branch 1 (49→51) taken 681 times.
681 if (arg_err != ARGERR_NONE) {
133 continue;
134 }
135 681 ptr_array_free(&arr);
136 }
137 20 string_free(&str);
138 }
139 1 }
140
141 static const TestEntry tests[] = {
142 TEST(test_dump_handlers),
143 };
144
145 const TestGroup dump_tests = TEST_GROUP(tests);
146