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