Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <sys/stat.h> | ||
2 | #include "test.h" | ||
3 | #include "ctags.h" | ||
4 | #include "util/ptr-array.h" | ||
5 | #include "util/readfile.h" | ||
6 | #include "util/xmalloc.h" | ||
7 | #include "util/xreadwrite.h" | ||
8 | |||
9 | 1 | static void test_parse_ctags_line(TestContext *ctx) | |
10 | { | ||
11 | 1 | const char *line = "foo\tfile.c\t/^int foo(char *s)$/;\"\tf\tfile:"; | |
12 | 1 | Tag tag = {.pattern = NULL}; | |
13 | 1 | EXPECT_TRUE(parse_ctags_line(&tag, line, strlen(line))); | |
14 | 1 | EXPECT_EQ(tag.name.length, 3); | |
15 | 1 | EXPECT_PTREQ(tag.name.data, line); | |
16 | 1 | EXPECT_EQ(tag.filename.length, 6); | |
17 | 1 | EXPECT_PTREQ(tag.filename.data, line + 4); | |
18 | 1 | EXPECT_STREQ(tag.pattern, "^int foo(char \\*s)$"); | |
19 | 1 | EXPECT_EQ(tag.lineno, 0); | |
20 | 1 | EXPECT_EQ(tag.kind, 'f'); | |
21 | 1 | EXPECT_EQ(tag.local, true); | |
22 | 1 | free_tag(&tag); | |
23 | |||
24 | 1 | line = "abc\t123.py\t/^backslashes \\\\ in \\ \\: pattern$/"; | |
25 | 1 | tag = (Tag){.pattern = NULL}; | |
26 | 1 | EXPECT_TRUE(parse_ctags_line(&tag, line, strlen(line))); | |
27 | 1 | EXPECT_EQ(tag.filename.length, 6); | |
28 | 1 | EXPECT_STREQ(tag.pattern, "^backslashes \\\\ in : pattern$"); | |
29 | 1 | EXPECT_EQ(tag.lineno, 0); | |
30 | 1 | EXPECT_EQ(tag.kind, 0); | |
31 | 1 | free_tag(&tag); | |
32 | |||
33 | 1 | line = "example\tsrc/xyz.c\t488;\"\tk"; | |
34 | 1 | tag = (Tag){.pattern = NULL}; | |
35 | 1 | EXPECT_TRUE(parse_ctags_line(&tag, line, strlen(line))); | |
36 | 1 | EXPECT_EQ(tag.filename.length, 9); | |
37 | 1 | EXPECT_NULL(tag.pattern); | |
38 | 1 | EXPECT_EQ(tag.lineno, 488); | |
39 | 1 | EXPECT_EQ(tag.kind, 'k'); | |
40 | 1 | free_tag(&tag); | |
41 | |||
42 | 1 | line = "x\tstr.c\t12495\tz"; | |
43 | 1 | tag = (Tag){.pattern = NULL}; | |
44 | 1 | EXPECT_TRUE(parse_ctags_line(&tag, line, strlen(line))); | |
45 | 1 | EXPECT_NULL(tag.pattern); | |
46 | 1 | EXPECT_EQ(tag.lineno, 12495); | |
47 | 1 | EXPECT_EQ(tag.kind, 'z'); | |
48 | 1 | free_tag(&tag); | |
49 | |||
50 | 1 | line = "name\tfile.c\t/^char after pattern with no tab delimiter/t"; | |
51 | 1 | tag = (Tag){.pattern = NULL}; | |
52 | 1 | EXPECT_FALSE(parse_ctags_line(&tag, line, strlen(line))); | |
53 | 1 | free_tag(&tag); | |
54 | |||
55 | 1 | line = "bar\tsource.c\t/^unterminated pattern\tf"; | |
56 | 1 | EXPECT_FALSE(parse_ctags_line(&tag, line, strlen(line))); | |
57 | 1 | free_tag(&tag); | |
58 | |||
59 | 1 | StringView sv = STRING_VIEW("tag-name\tfile.txt\t/^embedded NUL \0 char/\tf"); | |
60 | 1 | EXPECT_FALSE(parse_ctags_line(&tag, sv.data, sv.length)); | |
61 | 1 | free_tag(&tag); | |
62 | 1 | } | |
63 | |||
64 | 1 | static void test_next_tag(TestContext *ctx) | |
65 | { | ||
66 | 1 | static const struct { | |
67 | const char *name; | ||
68 | char kind; | ||
69 | bool local; | ||
70 | } expected[] = { | ||
71 | {"MIN_SIZE", 'e', true}, | ||
72 | {"TOMBSTONE", 'e', true}, | ||
73 | {"hashmap_clear", 'f', false}, | ||
74 | {"hashmap_do_init", 'f', true}, | ||
75 | {"hashmap_do_insert", 'f', true}, | ||
76 | {"hashmap_find", 'f', false}, | ||
77 | {"hashmap_free", 'f', false}, | ||
78 | {"hashmap_init", 'f', false}, | ||
79 | {"hashmap_insert", 'f', false}, | ||
80 | {"hashmap_insert_or_replace", 'f', false}, | ||
81 | {"hashmap_remove", 'f', false}, | ||
82 | {"hashmap_resize", 'f', true}, | ||
83 | }; | ||
84 | |||
85 | 1 | char *buf; | |
86 | 1 | ssize_t len = read_file("test/data/ctags.txt", &buf, 8192); | |
87 | 1 | ASSERT_TRUE(len >= 64); | |
88 | |||
89 | 1 | StringView prefix = STRING_VIEW(""); | |
90 | 1 | Tag t; | |
91 |
2/2✓ Branch 0 taken 12 times.
✓ Branch 1 taken 1 times.
|
13 | for (size_t i = 0, pos = 0; next_tag(buf, len, &pos, &prefix, false, &t); i++) { |
92 | 12 | IEXPECT_TRUE(strview_equal_cstring(&t.name, expected[i].name)); | |
93 | 12 | IEXPECT_EQ(t.kind, expected[i].kind); | |
94 | 12 | IEXPECT_EQ(t.local, expected[i].local); | |
95 | 12 | IEXPECT_TRUE(strview_equal_cstring(&t.filename, "src/util/hashmap.c")); | |
96 | 12 | IEXPECT_EQ(t.lineno, 0); | |
97 | 12 | free_tag(&t); | |
98 | } | ||
99 | |||
100 | 1 | size_t pos = 0; | |
101 | 1 | t.name = string_view(NULL, 0); | |
102 | 1 | prefix = strview_from_cstring("hashmap_res"); | |
103 | 1 | EXPECT_TRUE(next_tag(buf, len, &pos, &prefix, false, &t)); | |
104 | 1 | EXPECT_TRUE(strview_equal_cstring(&t.name, "hashmap_resize")); | |
105 | 1 | free_tag(&t); | |
106 | 1 | EXPECT_FALSE(next_tag(buf, len, &pos, &prefix, false, &t)); | |
107 | 1 | pos = 0; | |
108 | 1 | EXPECT_FALSE(next_tag(buf, len, &pos, &prefix, true, &t)); | |
109 | |||
110 | 1 | free(buf); | |
111 | 1 | } | |
112 | |||
113 | static const TestEntry tests[] = { | ||
114 | TEST(test_parse_ctags_line), | ||
115 | TEST(test_next_tag), | ||
116 | }; | ||
117 | |||
118 | const TestGroup ctags_tests = TEST_GROUP(tests); | ||
119 |