1 //===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include "FormatTestUtils.h"
11 #include "clang/Format/Format.h"
12 #include "llvm/Support/Debug.h"
13 #include "gtest/gtest.h"
14
15 #define DEBUG_TYPE "format-test"
16
17 namespace clang {
18 namespace format {
19 namespace {
20
21 class SortIncludesTest : public ::testing::Test {
22 protected:
GetCodeRange(StringRef Code)23 std::vector<tooling::Range> GetCodeRange(StringRef Code) {
24 return std::vector<tooling::Range>(1, tooling::Range(0, Code.size()));
25 }
26
sort(StringRef Code,StringRef FileName="input.cpp")27 std::string sort(StringRef Code, StringRef FileName = "input.cpp") {
28 auto Ranges = GetCodeRange(Code);
29 auto Sorted =
30 applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName));
31 EXPECT_TRUE(static_cast<bool>(Sorted));
32 auto Result = applyAllReplacements(
33 *Sorted, reformat(Style, *Sorted, Ranges, FileName));
34 EXPECT_TRUE(static_cast<bool>(Result));
35 return *Result;
36 }
37
newCursor(llvm::StringRef Code,unsigned Cursor)38 unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
39 sortIncludes(Style, Code, GetCodeRange(Code), "input.cpp", &Cursor);
40 return Cursor;
41 }
42
43 FormatStyle Style = getLLVMStyle();
44
45 };
46
TEST_F(SortIncludesTest,BasicSorting)47 TEST_F(SortIncludesTest, BasicSorting) {
48 EXPECT_EQ("#include \"a.h\"\n"
49 "#include \"b.h\"\n"
50 "#include \"c.h\"\n",
51 sort("#include \"a.h\"\n"
52 "#include \"c.h\"\n"
53 "#include \"b.h\"\n"));
54 }
55
TEST_F(SortIncludesTest,NoReplacementsForValidIncludes)56 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
57 // Identical #includes have led to a failure with an unstable sort.
58 std::string Code = "#include <a>\n"
59 "#include <b>\n"
60 "#include <b>\n"
61 "#include <b>\n"
62 "#include <b>\n"
63 "#include <c>\n";
64 EXPECT_TRUE(sortIncludes(Style, Code, GetCodeRange(Code), "a.cc").empty());
65 }
66
TEST_F(SortIncludesTest,SupportClangFormatOff)67 TEST_F(SortIncludesTest, SupportClangFormatOff) {
68 EXPECT_EQ("#include <a>\n"
69 "#include <b>\n"
70 "#include <c>\n"
71 "// clang-format off\n"
72 "#include <b>\n"
73 "#include <a>\n"
74 "#include <c>\n"
75 "// clang-format on\n",
76 sort("#include <b>\n"
77 "#include <a>\n"
78 "#include <c>\n"
79 "// clang-format off\n"
80 "#include <b>\n"
81 "#include <a>\n"
82 "#include <c>\n"
83 "// clang-format on\n"));
84 }
85
TEST_F(SortIncludesTest,IncludeSortingCanBeDisabled)86 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
87 Style.SortIncludes = false;
88 EXPECT_EQ("#include \"a.h\"\n"
89 "#include \"c.h\"\n"
90 "#include \"b.h\"\n",
91 sort("#include \"a.h\"\n"
92 "#include \"c.h\"\n"
93 "#include \"b.h\"\n"));
94 }
95
TEST_F(SortIncludesTest,MixIncludeAndImport)96 TEST_F(SortIncludesTest, MixIncludeAndImport) {
97 EXPECT_EQ("#include \"a.h\"\n"
98 "#import \"b.h\"\n"
99 "#include \"c.h\"\n",
100 sort("#include \"a.h\"\n"
101 "#include \"c.h\"\n"
102 "#import \"b.h\"\n"));
103 }
104
TEST_F(SortIncludesTest,FixTrailingComments)105 TEST_F(SortIncludesTest, FixTrailingComments) {
106 EXPECT_EQ("#include \"a.h\" // comment\n"
107 "#include \"bb.h\" // comment\n"
108 "#include \"ccc.h\"\n",
109 sort("#include \"a.h\" // comment\n"
110 "#include \"ccc.h\"\n"
111 "#include \"bb.h\" // comment\n"));
112 }
113
TEST_F(SortIncludesTest,LeadingWhitespace)114 TEST_F(SortIncludesTest, LeadingWhitespace) {
115 EXPECT_EQ("#include \"a.h\"\n"
116 "#include \"b.h\"\n"
117 "#include \"c.h\"\n",
118 sort(" #include \"a.h\"\n"
119 " #include \"c.h\"\n"
120 " #include \"b.h\"\n"));
121 EXPECT_EQ("#include \"a.h\"\n"
122 "#include \"b.h\"\n"
123 "#include \"c.h\"\n",
124 sort("# include \"a.h\"\n"
125 "# include \"c.h\"\n"
126 "# include \"b.h\"\n"));
127 }
128
TEST_F(SortIncludesTest,GreaterInComment)129 TEST_F(SortIncludesTest, GreaterInComment) {
130 EXPECT_EQ("#include \"a.h\"\n"
131 "#include \"b.h\" // >\n"
132 "#include \"c.h\"\n",
133 sort("#include \"a.h\"\n"
134 "#include \"c.h\"\n"
135 "#include \"b.h\" // >\n"));
136 }
137
TEST_F(SortIncludesTest,SortsLocallyInEachBlock)138 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
139 EXPECT_EQ("#include \"a.h\"\n"
140 "#include \"c.h\"\n"
141 "\n"
142 "#include \"b.h\"\n",
143 sort("#include \"a.h\"\n"
144 "#include \"c.h\"\n"
145 "\n"
146 "#include \"b.h\"\n"));
147 }
148
TEST_F(SortIncludesTest,HandlesAngledIncludesAsSeparateBlocks)149 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
150 EXPECT_EQ("#include \"a.h\"\n"
151 "#include \"c.h\"\n"
152 "#include <b.h>\n"
153 "#include <d.h>\n",
154 sort("#include <d.h>\n"
155 "#include <b.h>\n"
156 "#include \"c.h\"\n"
157 "#include \"a.h\"\n"));
158
159 Style = getGoogleStyle(FormatStyle::LK_Cpp);
160 EXPECT_EQ("#include <b.h>\n"
161 "#include <d.h>\n"
162 "#include \"a.h\"\n"
163 "#include \"c.h\"\n",
164 sort("#include <d.h>\n"
165 "#include <b.h>\n"
166 "#include \"c.h\"\n"
167 "#include \"a.h\"\n"));
168 }
169
TEST_F(SortIncludesTest,HandlesMultilineIncludes)170 TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
171 EXPECT_EQ("#include \"a.h\"\n"
172 "#include \"b.h\"\n"
173 "#include \"c.h\"\n",
174 sort("#include \"a.h\"\n"
175 "#include \\\n"
176 "\"c.h\"\n"
177 "#include \"b.h\"\n"));
178 }
179
TEST_F(SortIncludesTest,LeavesMainHeaderFirst)180 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
181 Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
182 EXPECT_EQ("#include \"llvm/a.h\"\n"
183 "#include \"b.h\"\n"
184 "#include \"c.h\"\n",
185 sort("#include \"llvm/a.h\"\n"
186 "#include \"c.h\"\n"
187 "#include \"b.h\"\n",
188 "a.cc"));
189 EXPECT_EQ("#include \"llvm/a.h\"\n"
190 "#include \"b.h\"\n"
191 "#include \"c.h\"\n",
192 sort("#include \"llvm/a.h\"\n"
193 "#include \"c.h\"\n"
194 "#include \"b.h\"\n",
195 "a_test.cc"));
196 EXPECT_EQ("#include \"llvm/input.h\"\n"
197 "#include \"b.h\"\n"
198 "#include \"c.h\"\n",
199 sort("#include \"llvm/input.h\"\n"
200 "#include \"c.h\"\n"
201 "#include \"b.h\"\n",
202 "input.mm"));
203
204 // Don't allow prefixes.
205 EXPECT_EQ("#include \"b.h\"\n"
206 "#include \"c.h\"\n"
207 "#include \"llvm/not_a.h\"\n",
208 sort("#include \"llvm/not_a.h\"\n"
209 "#include \"c.h\"\n"
210 "#include \"b.h\"\n",
211 "a.cc"));
212
213 // Don't do this for _main and other suffixes.
214 EXPECT_EQ("#include \"b.h\"\n"
215 "#include \"c.h\"\n"
216 "#include \"llvm/a.h\"\n",
217 sort("#include \"llvm/a.h\"\n"
218 "#include \"c.h\"\n"
219 "#include \"b.h\"\n",
220 "a_main.cc"));
221
222 // Don't do this in headers.
223 EXPECT_EQ("#include \"b.h\"\n"
224 "#include \"c.h\"\n"
225 "#include \"llvm/a.h\"\n",
226 sort("#include \"llvm/a.h\"\n"
227 "#include \"c.h\"\n"
228 "#include \"b.h\"\n",
229 "a.h"));
230
231 // Only do this in the first #include block.
232 EXPECT_EQ("#include <a>\n"
233 "\n"
234 "#include \"b.h\"\n"
235 "#include \"c.h\"\n"
236 "#include \"llvm/a.h\"\n",
237 sort("#include <a>\n"
238 "\n"
239 "#include \"llvm/a.h\"\n"
240 "#include \"c.h\"\n"
241 "#include \"b.h\"\n",
242 "a.cc"));
243
244 // Only recognize the first #include with a matching basename as main include.
245 EXPECT_EQ("#include \"a.h\"\n"
246 "#include \"b.h\"\n"
247 "#include \"c.h\"\n"
248 "#include \"llvm/a.h\"\n",
249 sort("#include \"b.h\"\n"
250 "#include \"a.h\"\n"
251 "#include \"c.h\"\n"
252 "#include \"llvm/a.h\"\n",
253 "a.cc"));
254 }
255
TEST_F(SortIncludesTest,NegativePriorities)256 TEST_F(SortIncludesTest, NegativePriorities) {
257 Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
258 EXPECT_EQ("#include \"important_os_header.h\"\n"
259 "#include \"c_main.h\"\n"
260 "#include \"a_other.h\"\n",
261 sort("#include \"c_main.h\"\n"
262 "#include \"a_other.h\"\n"
263 "#include \"important_os_header.h\"\n",
264 "c_main.cc"));
265
266 // check stable when re-run
267 EXPECT_EQ("#include \"important_os_header.h\"\n"
268 "#include \"c_main.h\"\n"
269 "#include \"a_other.h\"\n",
270 sort("#include \"important_os_header.h\"\n"
271 "#include \"c_main.h\"\n"
272 "#include \"a_other.h\"\n",
273 "c_main.cc"));
274 }
275
TEST_F(SortIncludesTest,CalculatesCorrectCursorPosition)276 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
277 std::string Code = "#include <ccc>\n" // Start of line: 0
278 "#include <bbbbbb>\n" // Start of line: 15
279 "#include <a>\n"; // Start of line: 33
280 EXPECT_EQ(31u, newCursor(Code, 0));
281 EXPECT_EQ(13u, newCursor(Code, 15));
282 EXPECT_EQ(0u, newCursor(Code, 33));
283
284 EXPECT_EQ(41u, newCursor(Code, 10));
285 EXPECT_EQ(23u, newCursor(Code, 25));
286 EXPECT_EQ(10u, newCursor(Code, 43));
287 }
288
289 } // end namespace
290 } // end namespace format
291 } // end namespace clang
292