dte test coverage


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

test/filetype.c
Line Branch Exec Source
1 #include "test.h"
2 #include "filetype.h"
3
4 1 static void test_is_valid_filetype_name(TestContext *ctx)
5 {
6 1 EXPECT_TRUE(is_valid_filetype_name("c"));
7 1 EXPECT_TRUE(is_valid_filetype_name("asm"));
8 1 EXPECT_TRUE(is_valid_filetype_name("abc-XYZ_128.90"));
9 1 EXPECT_FALSE(is_valid_filetype_name(""));
10 1 EXPECT_FALSE(is_valid_filetype_name("x/y"));
11 1 EXPECT_FALSE(is_valid_filetype_name(" "));
12 1 EXPECT_FALSE(is_valid_filetype_name("/"));
13 1 EXPECT_FALSE(is_valid_filetype_name("-c"));
14 1 EXPECT_FALSE(is_valid_filetype_name("abc xyz"));
15 1 EXPECT_FALSE(is_valid_filetype_name("abc\txyz"));
16 1 EXPECT_FALSE(is_valid_filetype_name("xyz "));
17 1 EXPECT_FALSE(is_valid_filetype_name("foo\n"));
18
19 1 char str[65];
20 1 size_t n = sizeof(str) - 1;
21 1 memset(str, 'a', n);
22 1 str[n] = '\0';
23 1 ASSERT_EQ(strlen(str), 64);
24 1 EXPECT_FALSE(is_valid_filetype_name(str));
25 1 str[n - 1] = '\0';
26 1 ASSERT_EQ(strlen(str), 63);
27 1 EXPECT_TRUE(is_valid_filetype_name(str));
28
29 1 StringView filetype = STRING_VIEW("zero\0\0");
30 1 EXPECT_EQ(filetype.length, 6);
31 1 EXPECT_FALSE(is_valid_filetype_name_sv(filetype));
32 1 EXPECT_EQ(strview_remove_suffix(&filetype, 1), 1);
33 1 EXPECT_FALSE(is_valid_filetype_name_sv(filetype));
34 1 EXPECT_EQ(strview_remove_suffix(&filetype, 1), 1);
35 1 EXPECT_TRUE(is_valid_filetype_name_sv(filetype));
36 1 }
37
38 1 static void test_find_ft_filename(TestContext *ctx)
39 {
40 1 static const struct {
41 const char *filename;
42 const char *expected_filetype;
43 } tests[] = {
44 {"/usr/local/include/lib.h", "c"},
45 {"test.C", "c"},
46 {"test.H", "c"},
47 {"test.S", "asm"},
48 {"test.1", "roff"},
49 {"test.5", "roff"},
50 {"test.c++", "c"},
51 {"test.cc~", "c"},
52 {"test.csv", "csv"},
53 {"test.d", "d"},
54 {"test.d2", "d2"},
55 {"test.gcode", "gcode"},
56 {"test.json", "json"},
57 {"test.kt", "kotlin"},
58 {"test.kts", "kotlin"},
59 {"test.l", "lex"},
60 {"test.lua", "lua"},
61 {"test.m", "objc"},
62 {"test.opml", "xml"},
63 {"test.py", "python"},
64 {"test.re", "c"},
65 {"test.rs", "rust"},
66 {"test.rss", "xml"},
67 {"test.s", "asm"},
68 {"test.tsv", "tsv"},
69 {"test.v", "verilog"},
70 {"test.y", "yacc"},
71 {"test.bats", "sh"},
72 {"test.tlv", "tl-verilog"},
73 {"test.typ", "typst"},
74 {"test.weechatlog", "weechatlog"},
75 {"test.xml", "xml"},
76 {"makefile", "make"},
77 {"GNUmakefile", "make"},
78 {".file.yml", "yaml"},
79 {"/etc/nginx.conf", "nginx"},
80 {"file..rb", "ruby"},
81 {"file.rb", "ruby"},
82 {"/etc/hosts", "config"},
83 {"/etc/fstab", "config"},
84 {"/boot/grub/menu.lst", "config"},
85 {"/etc/krb5.conf", "ini"},
86 {"/etc/ld.so.conf", "config"},
87 {"/etc/default/grub", "sh"},
88 {"/etc/systemd/user.conf", "ini"},
89 {"/etc/nginx/mime.types", "nginx"},
90 {"/etc/pam.d/login", "config"},
91 {"/etc/iptables/iptables.rules", "config"},
92 {"/etc/iptables/ip6tables.rules", "config"},
93 {"/root/.bash_profile", "sh"},
94 {".bash_profile", "sh"},
95 {".clang-format", "yaml"},
96 {".drirc", "xml"},
97 {".dterc", "dte"},
98 {".editorconfig", "ini"},
99 {".gitattributes", "config"},
100 {".gitconfig", "ini"},
101 {".gitmodules", "ini"},
102 {".jshintrc", "json"},
103 {".zshrc", "sh"},
104 {".XCompose", "config"},
105 {".tmux.conf", "tmux"},
106 {"zshrc", "sh"},
107 {"dot_zshrc", "sh"},
108 {"gnus", "lisp"},
109 {".gnus", "lisp"},
110 {"dot_gnus", "lisp"},
111 {"bash_functions", "sh"},
112 {".bash_functions", "sh"},
113 {"dot_bash_functions", "sh"},
114 {"dot_watchmanconfig", "json"},
115 {"file.flatpakref", "ini"},
116 {"file.automount", "ini"},
117 {"file.nginxconf", "nginx"},
118 {"meson_options.txt", "meson"},
119 {".git-blame-ignore-revs", "config"},
120 {"tags", "ctags"},
121 {"Pipfile", "toml"},
122 {"Pipfile.lock", "json"},
123 {"user-dirs.dirs", "config"},
124 {"Makefile.am", "make"},
125 {"Makefile.in", "make"},
126 {"Makefile.i_", NULL},
127 {"Makefile.a_", NULL},
128 {"Makefile._m", NULL},
129 {"M_______.am", NULL},
130 {".Makefile", NULL},
131 {"file.glslf", "glsl"},
132 {"file.glslv", "glsl"},
133 {"file.gl_lv", NULL},
134 {"file.gls_v", NULL},
135 {"file.gl__v", NULL},
136 {"._", NULL},
137 {".1234", NULL},
138 {".12345", NULL},
139 {".123456", NULL},
140 {".dot_zshrc", NULL},
141 {".doa_", NULL},
142 {"dot_", NULL},
143 {"dot_z", NULL},
144 {"/etc../etc.c.old/c.old", NULL},
145 {".c~", NULL},
146 {".ini~", NULL},
147 {".yml.bak", NULL},
148 {"test.c.bak", "c"},
149 {"test.c.new", "c"},
150 {"test.c.old~", "c"},
151 {"test.c.orig", "c"},
152 {"test.c.pacnew", "c"},
153 {"test.c.pacorig", "c"},
154 {"test.c.pacsave", "c"},
155 {"test.c.dpkg-dist", "c"},
156 {"test.c.dpkg-old", "c"},
157 {"test.c.dpkg-backup", "c"},
158 {"test.c.dpkg-remove", "c"},
159 {"test.c.rpmnew", "c"},
160 {"test.c.rpmsave", "c"},
161 {"test.@", NULL},
162 {"test.~", NULL},
163 {"test.", NULL},
164 {"test..", NULL},
165 {"1", NULL},
166 {"/", NULL},
167 {".c", NULL},
168 {".", NULL},
169 {"", NULL},
170 {NULL, NULL},
171 };
172
173 1 const PointerArray arr = PTR_ARRAY_INIT;
174 1 const StringView empty_line = STRING_VIEW_INIT;
175
176
2/2
✓ Branch 6 → 3 taken 127 times.
✓ Branch 6 → 7 taken 1 time.
128 FOR_EACH_I(i, tests) {
177 127 const char *ft = find_ft(&arr, tests[i].filename, empty_line);
178 127 IEXPECT_STREQ(ft, tests[i].expected_filetype);
179 }
180 1 }
181
182 1 static void test_find_ft_firstline(TestContext *ctx)
183 {
184 1 static const struct {
185 const char *line;
186 const char *expected_filetype;
187 } tests[] = {
188 {"<!DOCTYPE html>", "html"},
189 {"<!doctype HTML", "html"},
190 {"<!doctype htm", NULL},
191 {"<!DOCTYPE fontconfig", "xml"},
192 {"<!DOCTYPE colormap", "xml"},
193 {"<!DOCTYPE busconfig", "xml"},
194 {"<!doctype busconfig", NULL},
195 {"<?xml version=\"1.0\" encoding=\"UTF-8\"?>", "xml"},
196 {"ISO-10303-21;", "step"},
197 {"%YAML 1.1", "yaml"},
198 {"%YamL", NULL},
199 {"[wrap-file]", "ini"},
200 {"[wrap-file", NULL},
201 {"[section] \t", "ini"},
202 {" [section]", NULL},
203 {"[section \t", NULL},
204 {"[ section]", NULL},
205 {"[1]", NULL},
206 {"diff --git a/example.txt b/example.txt", "diff"},
207 {".TH DTE 1", NULL},
208 {"", NULL},
209 {" ", NULL},
210 {" <?xml", NULL},
211 {"\0<?xml", NULL},
212 {"#autoload", "sh"},
213 {"#compdef dte", "sh"},
214 {"#compdef", NULL},
215 {"stash@{0}: WIP on master: ...", "gitstash"},
216 {"stash@", NULL},
217 {"commit 8c6db8e8f8fbf055633ffb7a8bb449bb177adf01 (...)", "gitlog"},
218 {"commit 8c6db8e8f8fbf055633ffb7a8bb449bb177adf01", "gitlog"},
219 {"commit 8c6db8e8f8fbf055633ffb7a8bb449bb177adf01 ", NULL},
220 {"commit 8c6db8e8f8fbf055633ffb7a8bb449bb177adf0 (...)", NULL},
221
222 // Emacs style file-local variables
223 {"<!--*-xml-*-->", "xml"},
224 {"% -*-latex-*-", "tex"},
225 {"# -*-shell-script-*-", "sh"},
226 {"// -*- c -*-", "c"},
227 {".. -*-rst-*-", "rst"},
228 {";; -*-scheme-*-", "scheme"},
229 {"-- -*-lua-*-", "lua"},
230 {"\\input texinfo @c -*-texinfo-*-", "texinfo"},
231
232 // Not yet handled
233 {".. -*- mode: rst -*-", NULL},
234 {".. -*- Mode: rst -*-", NULL},
235 {".. -*- mode: rst; -*-", NULL},
236 {".. -*- coding: utf-8; mode: rst; fill-column: 75; -*- ", NULL},
237 {";; -*- mode: Lisp; fill-column: 75; comment-column: 50; -*-", NULL},
238 {";; -*- mode: fallback ; mode: lisp -*- ", NULL},
239
240 // These could be handled, but currently aren't (mostly due to heuristics
241 // intended to avoid doing extra work, if unlikely to detect anything)
242 {" <!--*-xml-*-->", NULL},
243 {"~ -*- c -*-", NULL},
244 {"xyz -*- c -*-", NULL},
245 {"d -*- c -*-", NULL},
246
247 // Hashbangs
248 {"#!/usr/bin/ash", "sh"},
249 {"#!/usr/bin/awk", "awk"},
250 {"#!/usr/bin/bash", "sh"},
251 {"#!/usr/bin/bats", "sh"},
252 {"#!/usr/bin/bigloo", "scheme"},
253 {"#!/usr/bin/ccl", "lisp"},
254 {"#!/usr/bin/chicken", "scheme"},
255 {"#!/usr/bin/clisp", "lisp"},
256 {"#!/usr/bin/coffee", "coffee"},
257 {"#!/usr/bin/crystal", "ruby"},
258 {"#!/usr/bin/dash", "sh"},
259 {"#!/usr/bin/deno", "typescript"},
260 {"#!/usr/bin/ecl", "lisp"},
261 {"#!/usr/bin/gawk", "awk"},
262 {"#!/usr/bin/gmake", "make"},
263 {"#!/usr/bin/gnuplot", "gnuplot"},
264 {"#!/usr/bin/gojq", "jq"},
265 {"#!/usr/bin/groovy", "groovy"},
266 {"#!/usr/bin/gsed", "sed"},
267 {"#!/usr/bin/guile", "scheme"},
268 {"#!/usr/bin/jaq", "jq"},
269 {"#!/usr/bin/jq", "jq"},
270 {"#!/usr/bin/jruby", "ruby"},
271 {"#!/usr/bin/ksh", "sh"},
272 {"#!/usr/bin/lisp", "lisp"},
273 {"#!/usr/bin/luajit", "lua"},
274 {"#!/usr/bin/lua", "lua"},
275 {"#!/usr/bin/macruby", "ruby"},
276 {"#!/usr/bin/make", "make"},
277 {"#!/usr/bin/mawk", "awk"},
278 {"#!/usr/bin/mksh", "sh"},
279 {"#!/usr/bin/moon", "moonscript"},
280 {"#!/usr/bin/nawk", "awk"},
281 {"#!/usr/bin/node", "javascript"},
282 {"#!/usr/bin/nodejs", "javascript"},
283 {"#!/usr/bin/openrc-run", "sh"},
284 {"#!/usr/bin/pdksh", "sh"},
285 {"#!/usr/bin/perl", "perl"},
286 {"#!/usr/bin/php", "php"},
287 {"#!/usr/bin/pypy3", "python"},
288 {"#!/usr/bin/python", "python"},
289 {"#!/usr/bin/r6rs", "scheme"},
290 {"#!/usr/bin/racket", "scheme"},
291 {"#!/usr/bin/rake", "ruby"},
292 {"#!/usr/bin/ruby", "ruby"},
293 {"#!/usr/bin/runhaskell", "haskell"},
294 {"#!/usr/bin/rust-script", "rust"},
295 {"#!/usr/bin/sbcl", "lisp"},
296 {"#!/usr/bin/sed", "sed"},
297 {"#!/bin/sh", "sh"},
298 {"#!/usr/bin/tcc", "c"},
299 {"#!/usr/bin/tclsh", "tcl"},
300 {"#!/usr/bin/ts-node", "typescript"},
301 {"#!/usr/bin/wish", "tcl"},
302 {"#!/usr/bin/zsh", "sh"},
303 {"#!/usr/bin/lua5.3", "lua"},
304 {"#!/usr/bin/env lua", "lua"},
305 {"#!/usr/bin/env lua5.3", "lua"},
306 {"#! /usr/bin/env lua5.3", "lua"},
307 {"#! /usr/bin/env lua5.3", "lua"},
308 {"#!/usr/bin/env /usr/bin/lua", "lua"},
309 {"#!/lua", "lua"},
310 {"#!/usr/bin/_unhaskell", NULL},
311 {"#!/usr/bin/runhaskel_", NULL},
312 {"#!/usr/bin/unknown", NULL},
313 {"#!lua", NULL},
314 {"#!/usr/bin/ lua", NULL},
315 {"#!/usr/bin/", NULL},
316 {"#!/usr/bin/env", NULL},
317 {"#!/usr/bin/env ", NULL},
318 {"#!/usr/bin/env ", NULL},
319 {"#!/usr/bin/env/ lua", NULL},
320 {"#!/lua/", NULL},
321 };
322
323 1 const PointerArray arr = PTR_ARRAY_INIT;
324
325
2/2
✓ Branch 6 → 3 taken 124 times.
✓ Branch 6 → 7 taken 1 time.
125 FOR_EACH_I(i, tests) {
326 124 const char *ft = find_ft(&arr, NULL, strview(tests[i].line));
327 124 IEXPECT_STREQ(ft, tests[i].expected_filetype);
328 }
329 1 }
330
331 1 static void test_find_ft_dynamic(TestContext *ctx)
332 {
333 1 PointerArray a = PTR_ARRAY_INIT;
334 1 const char *ft = "test1";
335 1 StringView line = STRING_VIEW_INIT;
336 1 EXPECT_FALSE(is_ft(&a, ft));
337 1 EXPECT_TRUE(add_filetype(&a, ft, "ext-test", FT_EXTENSION, NULL));
338 1 EXPECT_TRUE(is_ft(&a, ft));
339 1 EXPECT_STREQ(find_ft(&a, "/tmp/file.ext-test", line), ft);
340
341 1 ft = "test2";
342 1 EXPECT_TRUE(add_filetype(&a, ft, "/zdir/__[A-Z]+$", FT_FILENAME, NULL));
343 1 EXPECT_STREQ(find_ft(&a, "/tmp/zdir/__TESTFILE", line), ft);
344 1 EXPECT_STREQ(find_ft(&a, "/tmp/zdir/__testfile", line), NULL);
345
346 1 ft = "test3";
347 1 EXPECT_TRUE(add_filetype(&a, ft, "._fiLeName", FT_BASENAME, NULL));
348 1 EXPECT_STREQ(find_ft(&a, "/tmp/._fiLeName", line), ft);
349 1 EXPECT_STREQ(find_ft(&a, "/tmp/._filename", line), NULL);
350
351 1 ft = "test4";
352 1 line = strview("!!42");
353 1 EXPECT_TRUE(add_filetype(&a, ft, "^!+42$", FT_CONTENT, NULL));
354 1 EXPECT_STREQ(find_ft(&a, NULL, line), ft);
355
356 1 ft = "test5";
357 1 line = strview("#!/usr/bin/xyzlang4.2");
358 1 EXPECT_TRUE(add_filetype(&a, ft, "xyzlang", FT_INTERPRETER, NULL));
359 1 EXPECT_STREQ(find_ft(&a, NULL, line), ft);
360
361 1 EXPECT_TRUE(is_ft(&a, "test1"));
362 1 EXPECT_TRUE(is_ft(&a, "test2"));
363 1 EXPECT_TRUE(is_ft(&a, "test3"));
364 1 EXPECT_TRUE(is_ft(&a, "test4"));
365 1 EXPECT_TRUE(is_ft(&a, "test5"));
366 1 EXPECT_FALSE(is_ft(&a, "test0"));
367 1 EXPECT_FALSE(is_ft(&a, "test"));
368
369 1 free_filetypes(&a);
370 1 }
371
372 1 static void test_is_ft(TestContext *ctx)
373 {
374 1 const PointerArray a = PTR_ARRAY_INIT;
375 1 EXPECT_TRUE(is_ft(&a, "ada"));
376 1 EXPECT_TRUE(is_ft(&a, "asm"));
377 1 EXPECT_TRUE(is_ft(&a, "awk"));
378 1 EXPECT_TRUE(is_ft(&a, "c"));
379 1 EXPECT_TRUE(is_ft(&a, "d"));
380 1 EXPECT_TRUE(is_ft(&a, "dte"));
381 1 EXPECT_TRUE(is_ft(&a, "hare"));
382 1 EXPECT_TRUE(is_ft(&a, "java"));
383 1 EXPECT_TRUE(is_ft(&a, "javascript"));
384 1 EXPECT_TRUE(is_ft(&a, "lua"));
385 1 EXPECT_TRUE(is_ft(&a, "mail"));
386 1 EXPECT_TRUE(is_ft(&a, "make"));
387 1 EXPECT_TRUE(is_ft(&a, "pkg-config"));
388 1 EXPECT_TRUE(is_ft(&a, "rst"));
389 1 EXPECT_TRUE(is_ft(&a, "sh"));
390 1 EXPECT_TRUE(is_ft(&a, "yaml"));
391 1 EXPECT_TRUE(is_ft(&a, "zig"));
392
393 1 EXPECT_FALSE(is_ft(&a, ""));
394 1 EXPECT_FALSE(is_ft(&a, "-"));
395 1 EXPECT_FALSE(is_ft(&a, "a"));
396 1 EXPECT_FALSE(is_ft(&a, "C"));
397 1 EXPECT_FALSE(is_ft(&a, "MAKE"));
398 1 }
399
400 static const TestEntry tests[] = {
401 TEST(test_is_valid_filetype_name),
402 TEST(test_find_ft_filename),
403 TEST(test_find_ft_firstline),
404 TEST(test_find_ft_dynamic),
405 TEST(test_is_ft),
406 };
407
408 const TestGroup filetype_tests = TEST_GROUP(tests);
409