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
12namespace clang {
13namespace format {
14namespace {
15
16class MatchFilePathTest : public ::testing::Test {
17protected:
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
26TEST_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
39TEST_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
47TEST_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
54TEST_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
59TEST_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
66TEST_F(MatchFilePathTest, PathSeparators) {
67 EXPECT_TRUE(match("usr/bin", "usr/bin"));
68 EXPECT_TRUE(match("usr\\bin", R"(usr\\bin)"));
69}
70
71TEST_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
77TEST_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
86TEST_F(MatchFilePathTest, InvalidBrackets) {
87 EXPECT_TRUE(match("[", "["));
88 EXPECT_TRUE(match("[]", "[]"));
89 EXPECT_TRUE(match("[!", "[!"));
90 EXPECT_TRUE(match("[!]", "[!]"));
91}
92
93TEST_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
100TEST_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
114TEST_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
124TEST_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
133TEST_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
144TEST_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
153TEST_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} // namespace
168} // namespace format
169} // namespace clang
170

source code of clang/unittests/Format/MatchFilePathTest.cpp