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