xref: /llvm-project/clang/unittests/Format/MatchFilePathTest.cpp (revision cd239493c1023cbccfe6b1e9be32e68592a7f304)
1 //===- unittest/Format/MatchFilePathTest.cpp ------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "../../lib/Format/MatchFilePath.h"
10 #include "gtest/gtest.h"
11 
12 namespace clang {
13 namespace format {
14 namespace {
15 
16 class MatchFilePathTest : public testing::Test {
17 protected:
18   bool match(llvm::StringRef FilePath, llvm::StringRef Pattern) {
19     return matchFilePath(Pattern, FilePath);
20   }
21 };
22 
23 // Most of the test cases below are from:
24 // https://github.com/python/cpython/blob/main/Lib/test/test_fnmatch.py
25 
26 TEST_F(MatchFilePathTest, Wildcard) {
27   EXPECT_TRUE(match("abc", "?*?"));
28   EXPECT_TRUE(match("abc", "???*"));
29   EXPECT_TRUE(match("abc", "*???"));
30   EXPECT_TRUE(match("abc", "???"));
31   EXPECT_TRUE(match("abc", "*"));
32   EXPECT_TRUE(match("abc", "ab[cd]"));
33   EXPECT_TRUE(match("abc", "ab[!de]"));
34   EXPECT_FALSE(match("abc", "ab[de]"));
35   EXPECT_FALSE(match("a", "??"));
36   EXPECT_FALSE(match("a", "b"));
37 }
38 
39 TEST_F(MatchFilePathTest, Backslash) {
40   EXPECT_TRUE(match("a?", R"(a\?)"));
41   EXPECT_FALSE(match("a\\", R"(a\)"));
42   EXPECT_TRUE(match("\\", R"([\])"));
43   EXPECT_TRUE(match("a", R"([!\])"));
44   EXPECT_FALSE(match("\\", R"([!\])"));
45 }
46 
47 TEST_F(MatchFilePathTest, Newline) {
48   EXPECT_TRUE(match("foo\nbar", "foo*"));
49   EXPECT_TRUE(match("foo\nbar\n", "foo*"));
50   EXPECT_FALSE(match("\nfoo", "foo*"));
51   EXPECT_TRUE(match("\n", "*"));
52 }
53 
54 TEST_F(MatchFilePathTest, Star) {
55   EXPECT_TRUE(match(std::string(50, 'a'), "*a*a*a*a*a*a*a*a*a*a"));
56   EXPECT_FALSE(match(std::string(50, 'a') + 'b', "*a*a*a*a*a*a*a*a*a*a"));
57 }
58 
59 TEST_F(MatchFilePathTest, CaseSensitive) {
60   EXPECT_TRUE(match("abc", "abc"));
61   EXPECT_FALSE(match("AbC", "abc"));
62   EXPECT_FALSE(match("abc", "AbC"));
63   EXPECT_TRUE(match("AbC", "AbC"));
64 }
65 
66 TEST_F(MatchFilePathTest, PathSeparators) {
67   EXPECT_TRUE(match("usr/bin", "usr/bin"));
68   EXPECT_TRUE(match("usr\\bin", R"(usr\\bin)"));
69 }
70 
71 TEST_F(MatchFilePathTest, NumericEscapeSequence) {
72   EXPECT_TRUE(match("test", "te*"));
73   EXPECT_TRUE(match("test\xff", "te*\xff"));
74   EXPECT_TRUE(match("foo\nbar", "foo*"));
75 }
76 
77 TEST_F(MatchFilePathTest, ValidBrackets) {
78   EXPECT_TRUE(match("z", "[az]"));
79   EXPECT_FALSE(match("z", "[!az]"));
80   EXPECT_TRUE(match("a", "[aa]"));
81   EXPECT_TRUE(match("^", "[^az]"));
82   EXPECT_TRUE(match("[", "[[az]"));
83   EXPECT_FALSE(match("]", "[!]]"));
84 }
85 
86 TEST_F(MatchFilePathTest, InvalidBrackets) {
87   EXPECT_TRUE(match("[", "["));
88   EXPECT_TRUE(match("[]", "[]"));
89   EXPECT_TRUE(match("[!", "[!"));
90   EXPECT_TRUE(match("[!]", "[!]"));
91 }
92 
93 TEST_F(MatchFilePathTest, Range) {
94   EXPECT_TRUE(match("c", "[b-d]"));
95   EXPECT_FALSE(match("c", "[!b-d]"));
96   EXPECT_TRUE(match("y", "[b-dx-z]"));
97   EXPECT_FALSE(match("y", "[!b-dx-z]"));
98 }
99 
100 TEST_F(MatchFilePathTest, Hyphen) {
101   EXPECT_FALSE(match("#", "[!-#]"));
102   EXPECT_FALSE(match("-", "[!--.]"));
103   EXPECT_TRUE(match("_", "[^-`]"));
104   EXPECT_TRUE(match("]", "[[-^]"));
105   EXPECT_TRUE(match("]", R"([\-^])"));
106   EXPECT_TRUE(match("-", "[b-]"));
107   EXPECT_FALSE(match("-", "[!b-]"));
108   EXPECT_TRUE(match("-", "[-b]"));
109   EXPECT_FALSE(match("-", "[!-b]"));
110   EXPECT_TRUE(match("-", "[-]"));
111   EXPECT_FALSE(match("-", "[!-]"));
112 }
113 
114 TEST_F(MatchFilePathTest, UpperLELower) {
115   EXPECT_FALSE(match("c", "[d-b]"));
116   EXPECT_TRUE(match("c", "[!d-b]"));
117   EXPECT_TRUE(match("y", "[d-bx-z]"));
118   EXPECT_FALSE(match("y", "[!d-bx-z]"));
119   EXPECT_TRUE(match("_", "[d-b^-`]"));
120   EXPECT_TRUE(match("]", "[d-b[-^]"));
121   EXPECT_TRUE(match("b", "[b-b]"));
122 }
123 
124 TEST_F(MatchFilePathTest, SlashAndBackslashInBrackets) {
125   EXPECT_FALSE(match("/", "[/]"));
126   EXPECT_TRUE(match("\\", R"([\])"));
127   EXPECT_TRUE(match("[/]", "[/]"));
128   EXPECT_TRUE(match("\\", R"([\t])"));
129   EXPECT_TRUE(match("t", R"([\t])"));
130   EXPECT_FALSE(match("\t", R"([\t])"));
131 }
132 
133 TEST_F(MatchFilePathTest, SlashAndBackslashInRange) {
134   EXPECT_FALSE(match("a/b", "a[.-0]b"));
135   EXPECT_TRUE(match("a\\b", "a[Z-^]b"));
136   EXPECT_FALSE(match("a/b", "a[/-0]b"));
137   EXPECT_TRUE(match("a[/-0]b", "a[/-0]b"));
138   EXPECT_FALSE(match("a/b", "a[.-/]b"));
139   EXPECT_TRUE(match("a[.-/]b", "a[.-/]b"));
140   EXPECT_TRUE(match("a\\b", R"(a[\-^]b)"));
141   EXPECT_TRUE(match("a\\b", R"(a[Z-\]b)"));
142 }
143 
144 TEST_F(MatchFilePathTest, Brackets) {
145   EXPECT_TRUE(match("[", "[[]"));
146   EXPECT_TRUE(match("&", "[a&&b]"));
147   EXPECT_TRUE(match("|", "[a||b]"));
148   EXPECT_TRUE(match("~", "[a~~b]"));
149   EXPECT_TRUE(match(",", "[a-z+--A-Z]"));
150   EXPECT_FALSE(match(".", "[a-z--/A-Z]"));
151 }
152 
153 TEST_F(MatchFilePathTest, Path) {
154   EXPECT_TRUE(match(".clang-format", "*"));
155   EXPECT_TRUE(match(".git", "*git*"));
156   EXPECT_TRUE(match(".gitignore", "*git*"));
157   EXPECT_TRUE(match("foo/bar", "foo*/*bar"));
158   EXPECT_TRUE(match("foo/bar", "*/*"));
159   EXPECT_TRUE(match("foo/bar", R"(*foo*\/*bar*)"));
160   EXPECT_FALSE(match("foo/bar", "foo*"));
161   EXPECT_FALSE(match("foo/bar", "foo?bar"));
162   EXPECT_FALSE(match("foo/bar", "foo*bar"));
163   EXPECT_FALSE(match("foobar", "foo*/*"));
164   EXPECT_FALSE(match("foo\\", R"(foo*\)"));
165 }
166 
167 TEST_F(MatchFilePathTest, Globstar) {
168   EXPECT_TRUE(match("/", "**"));
169   EXPECT_TRUE(match("foo", "**"));
170   EXPECT_TRUE(match("/foo", "**"));
171   EXPECT_TRUE(match("foo/", "**"));
172   EXPECT_TRUE(match("foo/bar", "**"));
173 
174   EXPECT_TRUE(match("/", "**/"));
175   EXPECT_TRUE(match("foo/", "**/"));
176   EXPECT_TRUE(match("/foo/", "**/"));
177   EXPECT_TRUE(match("foo/bar/", "**/"));
178 
179   EXPECT_TRUE(match("/", "/**"));
180   EXPECT_TRUE(match("/foo", "/**"));
181   EXPECT_TRUE(match("/foo/", "/**"));
182   EXPECT_TRUE(match("/foo/bar", "/**"));
183 
184   EXPECT_TRUE(match("foo", "**/foo"));
185   EXPECT_TRUE(match("/foo", "**/foo"));
186   EXPECT_TRUE(match("foo/bar", "**/bar"));
187   EXPECT_TRUE(match("/foo/bar", "**/foo/bar"));
188   EXPECT_TRUE(match("foo/bar/baz", "**/bar/baz"));
189 
190   EXPECT_TRUE(match("abc/foo", "abc/**"));
191   EXPECT_TRUE(match("abc/foo/", "abc/**"));
192   EXPECT_TRUE(match("abc/foo/bar", "abc/**"));
193 
194   EXPECT_TRUE(match("a/b", "a/**/b"));
195   EXPECT_TRUE(match("a/x/b", "a/**/b"));
196   EXPECT_TRUE(match("a/x/y/b", "a/**/b"));
197 
198   EXPECT_FALSE(match("a/x/b", "a**/b"));
199   EXPECT_FALSE(match("a/x/b", "a/**b"));
200 }
201 
202 } // namespace
203 } // namespace format
204 } // namespace clang
205