dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 100.0% 135 / 0 / 135
Functions: 100.0% 5 / 0 / 5
Branches: -% 0 / 0 / 0

test/editorconfig.c
Line Branch Exec Source
1 #include <stdlib.h>
2 #include "test.h"
3 #include "editorconfig/editorconfig.h"
4 #include "editorconfig/ini.h"
5 #include "editorconfig/match.h"
6 #include "options.h"
7 #include "util/bit.h"
8 #include "util/path.h"
9
10 1 static void test_ini_parse(TestContext *ctx)
11 {
12 1 static const StringView input = STRING_VIEW (
13 " \t key = val \n"
14 "\n"
15 " \t [section 1] \n"
16 "xyz = 123\n"
17 "\tfoo bar = this;is#not#a;comment\n"
18 "[section 2]\n"
19 " x=0\n"
20 "[]\n"
21 " \t # comm=ent\n"
22 "; comm=ent\n"
23 "k\n"
24 "z=."
25 );
26
27 1 IniParser ini = {.input = input};
28 1 EXPECT_TRUE(ini_parse(&ini));
29 1 EXPECT_EQ(ini.pos, 17);
30 1 EXPECT_EQ(ini.name_count, 1);
31 1 EXPECT_STRVIEW_EQ_CSTRING(ini.section, "");
32 1 EXPECT_STRVIEW_EQ_CSTRING(ini.name, "key");
33 1 EXPECT_STRVIEW_EQ_CSTRING(ini.value, "val");
34
35 1 EXPECT_TRUE(ini_parse(&ini));
36 1 EXPECT_EQ(ini.pos, 45);
37 1 EXPECT_EQ(ini.name_count, 1);
38 1 EXPECT_STRVIEW_EQ_CSTRING(ini.section, "section 1");
39 1 EXPECT_STRVIEW_EQ_CSTRING(ini.name, "xyz");
40 1 EXPECT_STRVIEW_EQ_CSTRING(ini.value, "123");
41
42 1 EXPECT_TRUE(ini_parse(&ini));
43 1 EXPECT_EQ(ini.pos, 78);
44 1 EXPECT_EQ(ini.name_count, 2);
45 1 EXPECT_STRVIEW_EQ_CSTRING(ini.section, "section 1");
46 1 EXPECT_STRVIEW_EQ_CSTRING(ini.name, "foo bar");
47 1 EXPECT_STRVIEW_EQ_CSTRING(ini.value, "this;is#not#a;comment");
48
49 1 EXPECT_TRUE(ini_parse(&ini));
50 1 EXPECT_EQ(ini.pos, 95);
51 1 EXPECT_EQ(ini.name_count, 1);
52 1 EXPECT_STRVIEW_EQ_CSTRING(ini.section, "section 2");
53 1 EXPECT_STRVIEW_EQ_CSTRING(ini.name, "x");
54 1 EXPECT_STRVIEW_EQ_CSTRING(ini.value, "0");
55
56 1 EXPECT_TRUE(ini_parse(&ini));
57 1 EXPECT_EQ(ini.pos, 128);
58 1 EXPECT_EQ(ini.name_count, 1);
59 1 EXPECT_STRVIEW_EQ_CSTRING(ini.section, "");
60 1 EXPECT_STRVIEW_EQ_CSTRING(ini.name, "z");
61 1 EXPECT_STRVIEW_EQ_CSTRING(ini.value, ".");
62
63 1 EXPECT_FALSE(ini_parse(&ini));
64 1 }
65
66 1 static void test_ec_pattern_to_regex(TestContext *ctx)
67 {
68 1 const StringView dir = strview("/dir");
69
70 1 String str = ec_pattern_to_regex(strview("\\[ab]"), dir);
71 1 EXPECT_STRING_EQ_CSTRING(&str, "^/dir/(.*/)?\\[ab]$");
72 1 string_free(&str);
73
74 1 str = ec_pattern_to_regex(strview("**.c"), dir);
75 1 EXPECT_STRING_EQ_CSTRING(&str, "^/dir/(.*/)?.*\\.c$");
76 1 string_free(&str);
77
78 1 str = ec_pattern_to_regex(strview("\\*\\*.c"), dir);
79 1 EXPECT_STRING_EQ_CSTRING(&str, "^/dir/(.*/)?\\*\\*\\.c$");
80 1 string_free(&str);
81
82 1 str = ec_pattern_to_regex(strview("/xyz/\\[test-dir]/\\**.conf"), dir);
83 1 EXPECT_STRING_EQ_CSTRING(&str, "^/dir/xyz/\\[test-dir]/\\*[^/]*\\.conf$");
84 1 string_free(&str);
85 1 }
86
87 1 static void test_ec_pattern_match(TestContext *ctx)
88 {
89 1 const StringView dir = strview("/dir");
90
91 1 EXPECT_TRUE(ec_pattern_match(strview("*"), dir, "/dir/file.c"));
92 1 EXPECT_FALSE(ec_pattern_match(strview("*"), dir, "/other-dir/file.c"));
93 1 EXPECT_TRUE(ec_pattern_match(strview("*.{c,h}"), dir, "/dir/file.c"));
94 1 EXPECT_TRUE(ec_pattern_match(strview("*.{foo}"), dir, "/dir/file.foo"));
95
96 1 EXPECT_TRUE(ec_pattern_match(strview("*.{foo{bar,baz}}"), dir, "/dir/file.foobaz"));
97 1 EXPECT_FALSE(ec_pattern_match(strview("*.{foo{bar,baz}}"), dir, "/dir/file.foo"));
98
99 1 EXPECT_TRUE(ec_pattern_match(strview("a/**/b/c/*.[ch]"), dir, "/dir/a/zzz/yyy/foo/b/c/file.h"));
100 1 EXPECT_FALSE(ec_pattern_match(strview("a/*/b/c/*.[ch]"), dir, "/dir/a/zzz/yyy/foo/b/c/file.h"));
101
102 1 EXPECT_TRUE(ec_pattern_match(strview("}*.{x,y}"), dir, "/dir/}foo.y"));
103 1 EXPECT_FALSE(ec_pattern_match(strview("}*.{x,y}"), dir, "/dir/foo.y"));
104 1 EXPECT_TRUE(ec_pattern_match(strview("{}*.{x,y}"), dir, "/dir/foo.y"));
105
106 1 EXPECT_TRUE(ec_pattern_match(strview("*.[xyz]"), dir, "/dir/foo.z"));
107 1 EXPECT_FALSE(ec_pattern_match(strview("*.[xyz"), dir, "/dir/foo.z"));
108 1 EXPECT_TRUE(ec_pattern_match(strview("*.[xyz"), dir, "/dir/foo.[xyz"));
109
110 1 EXPECT_TRUE(ec_pattern_match(strview("*.[!xyz]"), dir, "/dir/foo.a"));
111 1 EXPECT_FALSE(ec_pattern_match(strview("*.[!xyz]"), dir, "/dir/foo.z"));
112
113 1 EXPECT_TRUE(ec_pattern_match(strview("*.["), dir, "/dir/foo.["));
114 1 EXPECT_TRUE(ec_pattern_match(strview("*.[a"), dir, "/dir/foo.[a"));
115
116 1 EXPECT_TRUE(ec_pattern_match(strview("*.[abc]def"), dir, "/dir/foo.bdef"));
117
118 1 EXPECT_TRUE(ec_pattern_match(strview("x{{foo,},}"), dir, "/dir/x"));
119 1 EXPECT_TRUE(ec_pattern_match(strview("x{{foo,},}"), dir, "/dir/xfoo"));
120
121 1 EXPECT_TRUE(ec_pattern_match(strview("file.{,,x,,y,,}"), dir, "/dir/file.x"));
122 1 EXPECT_TRUE(ec_pattern_match(strview("file.{,,x,,y,,}"), dir, "/dir/file."));
123 1 EXPECT_FALSE(ec_pattern_match(strview("file.{,,x,,y,,}"), dir, "/dir/file.z"));
124
125 1 EXPECT_TRUE(ec_pattern_match(strview("*.x,y,z"), dir, "/dir/file.x,y,z"));
126 1 EXPECT_TRUE(ec_pattern_match(strview("*.{x,y,z}"), dir, "/dir/file.y"));
127 1 EXPECT_FALSE(ec_pattern_match(strview("*.{x,y,z}"), dir, "/dir/file.x,y,z"));
128 1 EXPECT_FALSE(ec_pattern_match(strview("*.{x,y,z}"), dir, "/dir/file.{x,y,z}"));
129
130 1 EXPECT_TRUE(ec_pattern_match(strview("file.{{{a,b,{c,,d}}}}"), dir, "/dir/file.d"));
131 1 EXPECT_TRUE(ec_pattern_match(strview("file.{{{a,b,{c,,d}}}}"), dir, "/dir/file."));
132 1 EXPECT_FALSE(ec_pattern_match(strview("file.{{{a,b,{c,d}}}}"), dir, "/dir/file."));
133
134 1 EXPECT_TRUE(ec_pattern_match(strview("file.{c[vl]d,inc}"), dir, "/dir/file.cvd"));
135 1 EXPECT_TRUE(ec_pattern_match(strview("file.{c[vl]d,inc}"), dir, "/dir/file.cld"));
136 1 EXPECT_TRUE(ec_pattern_match(strview("file.{c[vl]d,inc}"), dir, "/dir/file.inc"));
137 1 EXPECT_FALSE(ec_pattern_match(strview("file.{c[vl]d,inc}"), dir, "/dir/file.cd"));
138
139 1 EXPECT_TRUE(ec_pattern_match(strview("a?b.c"), dir, "/dir/a_b.c"));
140 1 EXPECT_FALSE(ec_pattern_match(strview("a?b.c"), dir, "/dir/a/b.c"));
141
142 1 EXPECT_TRUE(ec_pattern_match(strview("a\\[.abc"), dir, "/dir/a[.abc"));
143 1 EXPECT_TRUE(ec_pattern_match(strview("a\\{.abc"), dir, "/dir/a{.abc"));
144 1 EXPECT_TRUE(ec_pattern_match(strview("a\\*.abc"), dir, "/dir/a*.abc"));
145 1 EXPECT_TRUE(ec_pattern_match(strview("a\\?.abc"), dir, "/dir/a?.abc"));
146 1 EXPECT_FALSE(ec_pattern_match(strview("a\\*.abc"), dir, "/dir/az.abc"));
147 1 EXPECT_FALSE(ec_pattern_match(strview("a\\?.abc"), dir, "/dir/az.abc"));
148
149 1 EXPECT_TRUE(ec_pattern_match(strview("{{{a}}}"), dir, "/dir/a"));
150 1 EXPECT_FALSE(ec_pattern_match(strview("{{{a}}"), dir, "/dir/a"));
151
152 1 EXPECT_TRUE(ec_pattern_match(strview("/dir2/**.ext"), dir, "/dir/dir2/file.ext"));
153 1 EXPECT_TRUE(ec_pattern_match(strview("/dir2/**.ext"), dir, "/dir/dir2/dir3/file.ext"));
154 1 EXPECT_FALSE(ec_pattern_match(strview("/dir2/**.ext"), dir, "/x/dir2/dir3/file.ext"));
155
156 // It's debatable whether this edge case behavior is sensible,
157 // but it's tested here anyway for the sake of UBSan coverage
158 1 EXPECT_TRUE(ec_pattern_match(strview("*.xyz\\"), dir, "/dir/file.xyz\\"));
159 1 EXPECT_FALSE(ec_pattern_match(strview("*.xyz\\"), dir, "/dir/file.xyz"));
160 1 }
161
162 1 static void test_ec_options_struct(TestContext *ctx)
163 {
164 1 const EditorConfigOptions opts = {
165 .indent_size = INDENT_WIDTH_MAX,
166 .tab_width = TAB_WIDTH_MAX,
167 .max_line_length = TEXT_WIDTH_MAX,
168 .indent_style = INDENT_STYLE_SPACE,
169 .indent_size_is_tab = true,
170 };
171
172 // Ensure bitfield widths are sufficient for maximum values
173 1 EXPECT_EQ(opts.indent_size, INDENT_WIDTH_MAX);
174 1 EXPECT_EQ(opts.tab_width, TAB_WIDTH_MAX);
175 1 EXPECT_EQ(opts.max_line_length, TEXT_WIDTH_MAX);
176 1 EXPECT_EQ(opts.indent_style, INDENT_STYLE_SPACE);
177 1 EXPECT_TRUE(opts.indent_size_is_tab);
178 1 EXPECT_EQ(umax_bitwidth(INDENT_WIDTH_MAX), 4);
179 1 EXPECT_EQ(umax_bitwidth(TAB_WIDTH_MAX), 4);
180 1 EXPECT_EQ(umax_bitwidth(TEXT_WIDTH_MAX), 10);
181 1 EXPECT_EQ(umax_bitwidth(INDENT_STYLE_SPACE), 2);
182 1 }
183
184 1 static void test_get_editorconfig_options(TestContext *ctx)
185 {
186 1 char *path = path_absolute("test/data/file.0foo.z");
187 1 ASSERT_NONNULL(path);
188 1 EditorConfigOptions opts = get_editorconfig_options(path);
189 1 free(path);
190 1 EXPECT_EQ(opts.indent_style, INDENT_STYLE_SPACE);
191 1 EXPECT_EQ(opts.indent_size, 3);
192 1 EXPECT_EQ(opts.tab_width, 3);
193 1 EXPECT_EQ(opts.max_line_length, 68);
194 1 EXPECT_FALSE(opts.indent_size_is_tab);
195
196 1 path = path_absolute("test/data/file.foo");
197 1 ASSERT_NONNULL(path);
198 1 opts = get_editorconfig_options(path);
199 1 free(path);
200 1 EXPECT_EQ(opts.indent_style, INDENT_STYLE_UNSPECIFIED);
201 1 EXPECT_EQ(opts.indent_size, 0);
202 1 EXPECT_EQ(opts.tab_width, 0);
203 1 EXPECT_EQ(opts.max_line_length, 0);
204 1 EXPECT_FALSE(opts.indent_size_is_tab);
205 1 }
206
207 static const TestEntry tests[] = {
208 TEST(test_ini_parse),
209 TEST(test_ec_pattern_to_regex),
210 TEST(test_ec_pattern_match),
211 TEST(test_ec_options_struct),
212 TEST(test_get_editorconfig_options),
213 };
214
215 const TestGroup editorconfig_tests = TEST_GROUP(tests);
216