xref: /llvm-project/clang/unittests/Format/MatchFilePathTest.cpp (revision cd239493c1023cbccfe6b1e9be32e68592a7f304)
18f9803b5SOwen Pan //===- unittest/Format/MatchFilePathTest.cpp ------------------------------===//
28f9803b5SOwen Pan //
38f9803b5SOwen Pan // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48f9803b5SOwen Pan // See https://llvm.org/LICENSE.txt for license information.
58f9803b5SOwen Pan // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68f9803b5SOwen Pan //
78f9803b5SOwen Pan //===----------------------------------------------------------------------===//
88f9803b5SOwen Pan 
98f9803b5SOwen Pan #include "../../lib/Format/MatchFilePath.h"
108f9803b5SOwen Pan #include "gtest/gtest.h"
118f9803b5SOwen Pan 
128f9803b5SOwen Pan namespace clang {
138f9803b5SOwen Pan namespace format {
148f9803b5SOwen Pan namespace {
158f9803b5SOwen Pan 
161c58208dSOwen Pan class MatchFilePathTest : public testing::Test {
178f9803b5SOwen Pan protected:
188f9803b5SOwen Pan   bool match(llvm::StringRef FilePath, llvm::StringRef Pattern) {
198f9803b5SOwen Pan     return matchFilePath(Pattern, FilePath);
208f9803b5SOwen Pan   }
218f9803b5SOwen Pan };
228f9803b5SOwen Pan 
238f9803b5SOwen Pan // Most of the test cases below are from:
248f9803b5SOwen Pan // https://github.com/python/cpython/blob/main/Lib/test/test_fnmatch.py
258f9803b5SOwen Pan 
268f9803b5SOwen Pan TEST_F(MatchFilePathTest, Wildcard) {
278f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "?*?"));
288f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "???*"));
298f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "*???"));
308f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "???"));
318f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "*"));
328f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "ab[cd]"));
338f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "ab[!de]"));
348f9803b5SOwen Pan   EXPECT_FALSE(match("abc", "ab[de]"));
358f9803b5SOwen Pan   EXPECT_FALSE(match("a", "??"));
368f9803b5SOwen Pan   EXPECT_FALSE(match("a", "b"));
378f9803b5SOwen Pan }
388f9803b5SOwen Pan 
398f9803b5SOwen Pan TEST_F(MatchFilePathTest, Backslash) {
408f9803b5SOwen Pan   EXPECT_TRUE(match("a?", R"(a\?)"));
418f9803b5SOwen Pan   EXPECT_FALSE(match("a\\", R"(a\)"));
428f9803b5SOwen Pan   EXPECT_TRUE(match("\\", R"([\])"));
438f9803b5SOwen Pan   EXPECT_TRUE(match("a", R"([!\])"));
448f9803b5SOwen Pan   EXPECT_FALSE(match("\\", R"([!\])"));
458f9803b5SOwen Pan }
468f9803b5SOwen Pan 
478f9803b5SOwen Pan TEST_F(MatchFilePathTest, Newline) {
488f9803b5SOwen Pan   EXPECT_TRUE(match("foo\nbar", "foo*"));
498f9803b5SOwen Pan   EXPECT_TRUE(match("foo\nbar\n", "foo*"));
508f9803b5SOwen Pan   EXPECT_FALSE(match("\nfoo", "foo*"));
518f9803b5SOwen Pan   EXPECT_TRUE(match("\n", "*"));
528f9803b5SOwen Pan }
538f9803b5SOwen Pan 
548f9803b5SOwen Pan TEST_F(MatchFilePathTest, Star) {
558f9803b5SOwen Pan   EXPECT_TRUE(match(std::string(50, 'a'), "*a*a*a*a*a*a*a*a*a*a"));
569fa17feaSOwen Pan   EXPECT_FALSE(match(std::string(50, 'a') + 'b', "*a*a*a*a*a*a*a*a*a*a"));
578f9803b5SOwen Pan }
588f9803b5SOwen Pan 
598f9803b5SOwen Pan TEST_F(MatchFilePathTest, CaseSensitive) {
608f9803b5SOwen Pan   EXPECT_TRUE(match("abc", "abc"));
618f9803b5SOwen Pan   EXPECT_FALSE(match("AbC", "abc"));
628f9803b5SOwen Pan   EXPECT_FALSE(match("abc", "AbC"));
638f9803b5SOwen Pan   EXPECT_TRUE(match("AbC", "AbC"));
648f9803b5SOwen Pan }
658f9803b5SOwen Pan 
668f9803b5SOwen Pan TEST_F(MatchFilePathTest, PathSeparators) {
678f9803b5SOwen Pan   EXPECT_TRUE(match("usr/bin", "usr/bin"));
688f9803b5SOwen Pan   EXPECT_TRUE(match("usr\\bin", R"(usr\\bin)"));
698f9803b5SOwen Pan }
708f9803b5SOwen Pan 
718f9803b5SOwen Pan TEST_F(MatchFilePathTest, NumericEscapeSequence) {
728f9803b5SOwen Pan   EXPECT_TRUE(match("test", "te*"));
738f9803b5SOwen Pan   EXPECT_TRUE(match("test\xff", "te*\xff"));
748f9803b5SOwen Pan   EXPECT_TRUE(match("foo\nbar", "foo*"));
758f9803b5SOwen Pan }
768f9803b5SOwen Pan 
778f9803b5SOwen Pan TEST_F(MatchFilePathTest, ValidBrackets) {
788f9803b5SOwen Pan   EXPECT_TRUE(match("z", "[az]"));
798f9803b5SOwen Pan   EXPECT_FALSE(match("z", "[!az]"));
808f9803b5SOwen Pan   EXPECT_TRUE(match("a", "[aa]"));
818f9803b5SOwen Pan   EXPECT_TRUE(match("^", "[^az]"));
828f9803b5SOwen Pan   EXPECT_TRUE(match("[", "[[az]"));
838f9803b5SOwen Pan   EXPECT_FALSE(match("]", "[!]]"));
848f9803b5SOwen Pan }
858f9803b5SOwen Pan 
868f9803b5SOwen Pan TEST_F(MatchFilePathTest, InvalidBrackets) {
878f9803b5SOwen Pan   EXPECT_TRUE(match("[", "["));
888f9803b5SOwen Pan   EXPECT_TRUE(match("[]", "[]"));
898f9803b5SOwen Pan   EXPECT_TRUE(match("[!", "[!"));
908f9803b5SOwen Pan   EXPECT_TRUE(match("[!]", "[!]"));
918f9803b5SOwen Pan }
928f9803b5SOwen Pan 
938f9803b5SOwen Pan TEST_F(MatchFilePathTest, Range) {
948f9803b5SOwen Pan   EXPECT_TRUE(match("c", "[b-d]"));
958f9803b5SOwen Pan   EXPECT_FALSE(match("c", "[!b-d]"));
968f9803b5SOwen Pan   EXPECT_TRUE(match("y", "[b-dx-z]"));
978f9803b5SOwen Pan   EXPECT_FALSE(match("y", "[!b-dx-z]"));
988f9803b5SOwen Pan }
998f9803b5SOwen Pan 
1008f9803b5SOwen Pan TEST_F(MatchFilePathTest, Hyphen) {
1018f9803b5SOwen Pan   EXPECT_FALSE(match("#", "[!-#]"));
1028f9803b5SOwen Pan   EXPECT_FALSE(match("-", "[!--.]"));
1038f9803b5SOwen Pan   EXPECT_TRUE(match("_", "[^-`]"));
1048f9803b5SOwen Pan   EXPECT_TRUE(match("]", "[[-^]"));
1058f9803b5SOwen Pan   EXPECT_TRUE(match("]", R"([\-^])"));
1068f9803b5SOwen Pan   EXPECT_TRUE(match("-", "[b-]"));
1078f9803b5SOwen Pan   EXPECT_FALSE(match("-", "[!b-]"));
1088f9803b5SOwen Pan   EXPECT_TRUE(match("-", "[-b]"));
1098f9803b5SOwen Pan   EXPECT_FALSE(match("-", "[!-b]"));
1108f9803b5SOwen Pan   EXPECT_TRUE(match("-", "[-]"));
1118f9803b5SOwen Pan   EXPECT_FALSE(match("-", "[!-]"));
1128f9803b5SOwen Pan }
1138f9803b5SOwen Pan 
1148f9803b5SOwen Pan TEST_F(MatchFilePathTest, UpperLELower) {
1158f9803b5SOwen Pan   EXPECT_FALSE(match("c", "[d-b]"));
1168f9803b5SOwen Pan   EXPECT_TRUE(match("c", "[!d-b]"));
1178f9803b5SOwen Pan   EXPECT_TRUE(match("y", "[d-bx-z]"));
1188f9803b5SOwen Pan   EXPECT_FALSE(match("y", "[!d-bx-z]"));
1198f9803b5SOwen Pan   EXPECT_TRUE(match("_", "[d-b^-`]"));
1208f9803b5SOwen Pan   EXPECT_TRUE(match("]", "[d-b[-^]"));
1218f9803b5SOwen Pan   EXPECT_TRUE(match("b", "[b-b]"));
1228f9803b5SOwen Pan }
1238f9803b5SOwen Pan 
1248f9803b5SOwen Pan TEST_F(MatchFilePathTest, SlashAndBackslashInBrackets) {
1258f9803b5SOwen Pan   EXPECT_FALSE(match("/", "[/]"));
1268f9803b5SOwen Pan   EXPECT_TRUE(match("\\", R"([\])"));
1278f9803b5SOwen Pan   EXPECT_TRUE(match("[/]", "[/]"));
1288f9803b5SOwen Pan   EXPECT_TRUE(match("\\", R"([\t])"));
1298f9803b5SOwen Pan   EXPECT_TRUE(match("t", R"([\t])"));
1308f9803b5SOwen Pan   EXPECT_FALSE(match("\t", R"([\t])"));
1318f9803b5SOwen Pan }
1328f9803b5SOwen Pan 
1338f9803b5SOwen Pan TEST_F(MatchFilePathTest, SlashAndBackslashInRange) {
1348f9803b5SOwen Pan   EXPECT_FALSE(match("a/b", "a[.-0]b"));
1358f9803b5SOwen Pan   EXPECT_TRUE(match("a\\b", "a[Z-^]b"));
1368f9803b5SOwen Pan   EXPECT_FALSE(match("a/b", "a[/-0]b"));
1378f9803b5SOwen Pan   EXPECT_TRUE(match("a[/-0]b", "a[/-0]b"));
1388f9803b5SOwen Pan   EXPECT_FALSE(match("a/b", "a[.-/]b"));
1398f9803b5SOwen Pan   EXPECT_TRUE(match("a[.-/]b", "a[.-/]b"));
1408f9803b5SOwen Pan   EXPECT_TRUE(match("a\\b", R"(a[\-^]b)"));
1418f9803b5SOwen Pan   EXPECT_TRUE(match("a\\b", R"(a[Z-\]b)"));
1428f9803b5SOwen Pan }
1438f9803b5SOwen Pan 
1448f9803b5SOwen Pan TEST_F(MatchFilePathTest, Brackets) {
1458f9803b5SOwen Pan   EXPECT_TRUE(match("[", "[[]"));
1468f9803b5SOwen Pan   EXPECT_TRUE(match("&", "[a&&b]"));
1478f9803b5SOwen Pan   EXPECT_TRUE(match("|", "[a||b]"));
1488f9803b5SOwen Pan   EXPECT_TRUE(match("~", "[a~~b]"));
1498f9803b5SOwen Pan   EXPECT_TRUE(match(",", "[a-z+--A-Z]"));
1508f9803b5SOwen Pan   EXPECT_FALSE(match(".", "[a-z--/A-Z]"));
1518f9803b5SOwen Pan }
1528f9803b5SOwen Pan 
1538f9803b5SOwen Pan TEST_F(MatchFilePathTest, Path) {
1548f9803b5SOwen Pan   EXPECT_TRUE(match(".clang-format", "*"));
1558f9803b5SOwen Pan   EXPECT_TRUE(match(".git", "*git*"));
1568f9803b5SOwen Pan   EXPECT_TRUE(match(".gitignore", "*git*"));
1578f9803b5SOwen Pan   EXPECT_TRUE(match("foo/bar", "foo*/*bar"));
1588f9803b5SOwen Pan   EXPECT_TRUE(match("foo/bar", "*/*"));
1598f9803b5SOwen Pan   EXPECT_TRUE(match("foo/bar", R"(*foo*\/*bar*)"));
1608f9803b5SOwen Pan   EXPECT_FALSE(match("foo/bar", "foo*"));
1618f9803b5SOwen Pan   EXPECT_FALSE(match("foo/bar", "foo?bar"));
1628f9803b5SOwen Pan   EXPECT_FALSE(match("foo/bar", "foo*bar"));
1638f9803b5SOwen Pan   EXPECT_FALSE(match("foobar", "foo*/*"));
1648f9803b5SOwen Pan   EXPECT_FALSE(match("foo\\", R"(foo*\)"));
1658f9803b5SOwen Pan }
1668f9803b5SOwen Pan 
167*cd239493SOwen Pan TEST_F(MatchFilePathTest, Globstar) {
168*cd239493SOwen Pan   EXPECT_TRUE(match("/", "**"));
169*cd239493SOwen Pan   EXPECT_TRUE(match("foo", "**"));
170*cd239493SOwen Pan   EXPECT_TRUE(match("/foo", "**"));
171*cd239493SOwen Pan   EXPECT_TRUE(match("foo/", "**"));
172*cd239493SOwen Pan   EXPECT_TRUE(match("foo/bar", "**"));
173*cd239493SOwen Pan 
174*cd239493SOwen Pan   EXPECT_TRUE(match("/", "**/"));
175*cd239493SOwen Pan   EXPECT_TRUE(match("foo/", "**/"));
176*cd239493SOwen Pan   EXPECT_TRUE(match("/foo/", "**/"));
177*cd239493SOwen Pan   EXPECT_TRUE(match("foo/bar/", "**/"));
178*cd239493SOwen Pan 
179*cd239493SOwen Pan   EXPECT_TRUE(match("/", "/**"));
180*cd239493SOwen Pan   EXPECT_TRUE(match("/foo", "/**"));
181*cd239493SOwen Pan   EXPECT_TRUE(match("/foo/", "/**"));
182*cd239493SOwen Pan   EXPECT_TRUE(match("/foo/bar", "/**"));
183*cd239493SOwen Pan 
184*cd239493SOwen Pan   EXPECT_TRUE(match("foo", "**/foo"));
185*cd239493SOwen Pan   EXPECT_TRUE(match("/foo", "**/foo"));
186*cd239493SOwen Pan   EXPECT_TRUE(match("foo/bar", "**/bar"));
187*cd239493SOwen Pan   EXPECT_TRUE(match("/foo/bar", "**/foo/bar"));
188*cd239493SOwen Pan   EXPECT_TRUE(match("foo/bar/baz", "**/bar/baz"));
189*cd239493SOwen Pan 
190*cd239493SOwen Pan   EXPECT_TRUE(match("abc/foo", "abc/**"));
191*cd239493SOwen Pan   EXPECT_TRUE(match("abc/foo/", "abc/**"));
192*cd239493SOwen Pan   EXPECT_TRUE(match("abc/foo/bar", "abc/**"));
193*cd239493SOwen Pan 
194*cd239493SOwen Pan   EXPECT_TRUE(match("a/b", "a/**/b"));
195*cd239493SOwen Pan   EXPECT_TRUE(match("a/x/b", "a/**/b"));
196*cd239493SOwen Pan   EXPECT_TRUE(match("a/x/y/b", "a/**/b"));
197*cd239493SOwen Pan 
198*cd239493SOwen Pan   EXPECT_FALSE(match("a/x/b", "a**/b"));
199*cd239493SOwen Pan   EXPECT_FALSE(match("a/x/b", "a/**b"));
200*cd239493SOwen Pan }
201*cd239493SOwen Pan 
2028f9803b5SOwen Pan } // namespace
2038f9803b5SOwen Pan } // namespace format
2048f9803b5SOwen Pan } // namespace clang
205