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