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