1 //===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===//
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 "FormatTestUtils.h"
10 #include "clang/Format/Format.h"
11 #include "llvm/ADT/None.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,std::vector<tooling::Range> Ranges,StringRef FileName="input.cc",unsigned ExpectedNumRanges=1)27 std::string sort(StringRef Code, std::vector<tooling::Range> Ranges,
28 StringRef FileName = "input.cc",
29 unsigned ExpectedNumRanges = 1) {
30 auto Replaces = sortIncludes(FmtStyle, Code, Ranges, FileName);
31 Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
32 EXPECT_EQ(ExpectedNumRanges, Replaces.size());
33 auto Sorted = applyAllReplacements(Code, Replaces);
34 EXPECT_TRUE(static_cast<bool>(Sorted));
35 auto Result = applyAllReplacements(
36 *Sorted, reformat(FmtStyle, *Sorted, Ranges, FileName));
37 EXPECT_TRUE(static_cast<bool>(Result));
38 return *Result;
39 }
40
sort(StringRef Code,StringRef FileName="input.cpp",unsigned ExpectedNumRanges=1)41 std::string sort(StringRef Code,
42 StringRef FileName = "input.cpp",
43 unsigned ExpectedNumRanges = 1) {
44 return sort(Code, GetCodeRange(Code), FileName, ExpectedNumRanges);
45 }
46
newCursor(llvm::StringRef Code,unsigned Cursor)47 unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
48 sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.cpp", &Cursor);
49 return Cursor;
50 }
51
52 FormatStyle FmtStyle = getLLVMStyle();
53 tooling::IncludeStyle &Style = FmtStyle.IncludeStyle;
54 };
55
TEST_F(SortIncludesTest,BasicSorting)56 TEST_F(SortIncludesTest, BasicSorting) {
57 EXPECT_EQ("#include \"a.h\"\n"
58 "#include \"b.h\"\n"
59 "#include \"c.h\"\n",
60 sort("#include \"a.h\"\n"
61 "#include \"c.h\"\n"
62 "#include \"b.h\"\n"));
63
64 EXPECT_EQ("// comment\n"
65 "#include <a>\n"
66 "#include <b>\n",
67 sort("// comment\n"
68 "#include <b>\n"
69 "#include <a>\n",
70 {tooling::Range(25, 1)}));
71 }
72
TEST_F(SortIncludesTest,SortedIncludesUsingSortPriorityAttribute)73 TEST_F(SortIncludesTest, SortedIncludesUsingSortPriorityAttribute) {
74 FmtStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
75 FmtStyle.IncludeStyle.IncludeCategories = {
76 {"^<sys/param\\.h>", 1, 0},
77 {"^<sys/types\\.h>", 1, 1},
78 {"^<sys.*/", 1, 2},
79 {"^<uvm/", 2, 3},
80 {"^<machine/", 3, 4},
81 {"^<dev/", 4, 5},
82 {"^<net.*/", 5, 6},
83 {"^<protocols/", 5, 7},
84 {"^<(fs|miscfs|msdosfs|nfs|ntfs|ufs)/", 6, 8},
85 {"^<(x86|amd64|i386|xen)/", 7, 8},
86 {"<path", 9, 11},
87 {"^<[^/].*\\.h>", 8, 10},
88 {"^\".*\\.h\"", 10, 12}};
89 EXPECT_EQ("#include <sys/param.h>\n"
90 "#include <sys/types.h>\n"
91 "#include <sys/ioctl.h>\n"
92 "#include <sys/socket.h>\n"
93 "#include <sys/stat.h>\n"
94 "#include <sys/wait.h>\n"
95 "\n"
96 "#include <net/if.h>\n"
97 "#include <net/if_dl.h>\n"
98 "#include <net/route.h>\n"
99 "#include <netinet/in.h>\n"
100 "#include <protocols/rwhod.h>\n"
101 "\n"
102 "#include <assert.h>\n"
103 "#include <errno.h>\n"
104 "#include <inttypes.h>\n"
105 "#include <stdio.h>\n"
106 "#include <stdlib.h>\n"
107 "\n"
108 "#include <paths.h>\n"
109 "\n"
110 "#include \"pathnames.h\"\n",
111 sort("#include <sys/param.h>\n"
112 "#include <sys/types.h>\n"
113 "#include <sys/ioctl.h>\n"
114 "#include <net/if_dl.h>\n"
115 "#include <net/route.h>\n"
116 "#include <netinet/in.h>\n"
117 "#include <sys/socket.h>\n"
118 "#include <sys/stat.h>\n"
119 "#include <sys/wait.h>\n"
120 "#include <net/if.h>\n"
121 "#include <protocols/rwhod.h>\n"
122 "#include <assert.h>\n"
123 "#include <paths.h>\n"
124 "#include \"pathnames.h\"\n"
125 "#include <errno.h>\n"
126 "#include <inttypes.h>\n"
127 "#include <stdio.h>\n"
128 "#include <stdlib.h>\n"));
129 }
TEST_F(SortIncludesTest,SortPriorityNotDefined)130 TEST_F(SortIncludesTest, SortPriorityNotDefined) {
131 FmtStyle = getLLVMStyle();
132 EXPECT_EQ("#include \"FormatTestUtils.h\"\n"
133 "#include \"clang/Format/Format.h\"\n"
134 "#include \"llvm/ADT/None.h\"\n"
135 "#include \"llvm/Support/Debug.h\"\n"
136 "#include \"gtest/gtest.h\"\n",
137 sort("#include \"clang/Format/Format.h\"\n"
138 "#include \"llvm/ADT/None.h\"\n"
139 "#include \"FormatTestUtils.h\"\n"
140 "#include \"gtest/gtest.h\"\n"
141 "#include \"llvm/Support/Debug.h\"\n"));
142 }
143
TEST_F(SortIncludesTest,NoReplacementsForValidIncludes)144 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
145 // Identical #includes have led to a failure with an unstable sort.
146 std::string Code = "#include <a>\n"
147 "#include <b>\n"
148 "#include <c>\n"
149 "#include <d>\n"
150 "#include <e>\n"
151 "#include <f>\n";
152 EXPECT_TRUE(sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a.cc").empty());
153 }
154
TEST_F(SortIncludesTest,SortedIncludesInMultipleBlocksAreMerged)155 TEST_F(SortIncludesTest, SortedIncludesInMultipleBlocksAreMerged) {
156 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
157 EXPECT_EQ("#include \"a.h\"\n"
158 "#include \"b.h\"\n"
159 "#include \"c.h\"\n",
160 sort("#include \"a.h\"\n"
161 "#include \"c.h\"\n"
162 "\n"
163 "\n"
164 "#include \"b.h\"\n"));
165
166 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
167 EXPECT_EQ("#include \"a.h\"\n"
168 "#include \"b.h\"\n"
169 "#include \"c.h\"\n",
170 sort("#include \"a.h\"\n"
171 "#include \"c.h\"\n"
172 "\n"
173 "\n"
174 "#include \"b.h\"\n"));
175 }
176
TEST_F(SortIncludesTest,SupportClangFormatOff)177 TEST_F(SortIncludesTest, SupportClangFormatOff) {
178 EXPECT_EQ("#include <a>\n"
179 "#include <b>\n"
180 "#include <c>\n"
181 "// clang-format off\n"
182 "#include <b>\n"
183 "#include <a>\n"
184 "#include <c>\n"
185 "// clang-format on\n",
186 sort("#include <b>\n"
187 "#include <a>\n"
188 "#include <c>\n"
189 "// clang-format off\n"
190 "#include <b>\n"
191 "#include <a>\n"
192 "#include <c>\n"
193 "// clang-format on\n"));
194 }
195
TEST_F(SortIncludesTest,SupportClangFormatOffCStyle)196 TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) {
197 EXPECT_EQ("#include <a>\n"
198 "#include <b>\n"
199 "#include <c>\n"
200 "/* clang-format off */\n"
201 "#include <b>\n"
202 "#include <a>\n"
203 "#include <c>\n"
204 "/* clang-format on */\n",
205 sort("#include <b>\n"
206 "#include <a>\n"
207 "#include <c>\n"
208 "/* clang-format off */\n"
209 "#include <b>\n"
210 "#include <a>\n"
211 "#include <c>\n"
212 "/* clang-format on */\n"));
213
214 // Not really turning it off
215 EXPECT_EQ("#include <a>\n"
216 "#include <b>\n"
217 "#include <c>\n"
218 "/* clang-format offically */\n"
219 "#include <a>\n"
220 "#include <b>\n"
221 "#include <c>\n"
222 "/* clang-format onwards */\n",
223 sort("#include <b>\n"
224 "#include <a>\n"
225 "#include <c>\n"
226 "/* clang-format offically */\n"
227 "#include <b>\n"
228 "#include <a>\n"
229 "#include <c>\n"
230 "/* clang-format onwards */\n", "input.h", 2));
231 }
232
TEST_F(SortIncludesTest,IncludeSortingCanBeDisabled)233 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
234 FmtStyle.SortIncludes = false;
235 EXPECT_EQ("#include \"a.h\"\n"
236 "#include \"c.h\"\n"
237 "#include \"b.h\"\n",
238 sort("#include \"a.h\"\n"
239 "#include \"c.h\"\n"
240 "#include \"b.h\"\n",
241 "input.h", 0));
242 }
243
TEST_F(SortIncludesTest,MixIncludeAndImport)244 TEST_F(SortIncludesTest, MixIncludeAndImport) {
245 EXPECT_EQ("#include \"a.h\"\n"
246 "#import \"b.h\"\n"
247 "#include \"c.h\"\n",
248 sort("#include \"a.h\"\n"
249 "#include \"c.h\"\n"
250 "#import \"b.h\"\n"));
251 }
252
TEST_F(SortIncludesTest,FixTrailingComments)253 TEST_F(SortIncludesTest, FixTrailingComments) {
254 EXPECT_EQ("#include \"a.h\" // comment\n"
255 "#include \"bb.h\" // comment\n"
256 "#include \"ccc.h\"\n",
257 sort("#include \"a.h\" // comment\n"
258 "#include \"ccc.h\"\n"
259 "#include \"bb.h\" // comment\n"));
260 }
261
TEST_F(SortIncludesTest,LeadingWhitespace)262 TEST_F(SortIncludesTest, LeadingWhitespace) {
263 EXPECT_EQ("#include \"a.h\"\n"
264 "#include \"b.h\"\n"
265 "#include \"c.h\"\n",
266 sort(" #include \"a.h\"\n"
267 " #include \"c.h\"\n"
268 " #include \"b.h\"\n"));
269 EXPECT_EQ("#include \"a.h\"\n"
270 "#include \"b.h\"\n"
271 "#include \"c.h\"\n",
272 sort("# include \"a.h\"\n"
273 "# include \"c.h\"\n"
274 "# include \"b.h\"\n"));
275 }
276
TEST_F(SortIncludesTest,GreaterInComment)277 TEST_F(SortIncludesTest, GreaterInComment) {
278 EXPECT_EQ("#include \"a.h\"\n"
279 "#include \"b.h\" // >\n"
280 "#include \"c.h\"\n",
281 sort("#include \"a.h\"\n"
282 "#include \"c.h\"\n"
283 "#include \"b.h\" // >\n"));
284 }
285
TEST_F(SortIncludesTest,SortsLocallyInEachBlock)286 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
287 EXPECT_EQ("#include \"a.h\"\n"
288 "#include \"c.h\"\n"
289 "\n"
290 "#include \"b.h\"\n",
291 sort("#include \"a.h\"\n"
292 "#include \"c.h\"\n"
293 "\n"
294 "#include \"b.h\"\n", "input.h", 0));
295 }
296
TEST_F(SortIncludesTest,SortsAllBlocksWhenMerging)297 TEST_F(SortIncludesTest, SortsAllBlocksWhenMerging) {
298 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
299 EXPECT_EQ("#include \"a.h\"\n"
300 "#include \"b.h\"\n"
301 "#include \"c.h\"\n",
302 sort("#include \"a.h\"\n"
303 "#include \"c.h\"\n"
304 "\n"
305 "#include \"b.h\"\n"));
306 }
307
TEST_F(SortIncludesTest,CommentsAlwaysSeparateGroups)308 TEST_F(SortIncludesTest, CommentsAlwaysSeparateGroups) {
309 EXPECT_EQ("#include \"a.h\"\n"
310 "#include \"c.h\"\n"
311 "// comment\n"
312 "#include \"b.h\"\n",
313 sort("#include \"c.h\"\n"
314 "#include \"a.h\"\n"
315 "// comment\n"
316 "#include \"b.h\"\n"));
317
318 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
319 EXPECT_EQ("#include \"a.h\"\n"
320 "#include \"c.h\"\n"
321 "// comment\n"
322 "#include \"b.h\"\n",
323 sort("#include \"c.h\"\n"
324 "#include \"a.h\"\n"
325 "// comment\n"
326 "#include \"b.h\"\n"));
327
328 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
329 EXPECT_EQ("#include \"a.h\"\n"
330 "#include \"c.h\"\n"
331 "// comment\n"
332 "#include \"b.h\"\n",
333 sort("#include \"c.h\"\n"
334 "#include \"a.h\"\n"
335 "// comment\n"
336 "#include \"b.h\"\n"));
337 }
338
TEST_F(SortIncludesTest,HandlesAngledIncludesAsSeparateBlocks)339 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
340 EXPECT_EQ("#include \"a.h\"\n"
341 "#include \"c.h\"\n"
342 "#include <array>\n"
343 "#include <b.h>\n"
344 "#include <d.h>\n"
345 "#include <vector>\n",
346 sort("#include <vector>\n"
347 "#include <d.h>\n"
348 "#include <array>\n"
349 "#include <b.h>\n"
350 "#include \"c.h\"\n"
351 "#include \"a.h\"\n"));
352
353 FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp);
354 EXPECT_EQ("#include <b.h>\n"
355 "#include <d.h>\n"
356 "\n"
357 "#include <array>\n"
358 "#include <vector>\n"
359 "\n"
360 "#include \"a.h\"\n"
361 "#include \"c.h\"\n",
362 sort("#include <vector>\n"
363 "#include <d.h>\n"
364 "#include <array>\n"
365 "#include <b.h>\n"
366 "#include \"c.h\"\n"
367 "#include \"a.h\"\n"));
368 }
369
TEST_F(SortIncludesTest,RegroupsAngledIncludesInSeparateBlocks)370 TEST_F(SortIncludesTest, RegroupsAngledIncludesInSeparateBlocks) {
371 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
372 EXPECT_EQ("#include \"a.h\"\n"
373 "#include \"c.h\"\n"
374 "\n"
375 "#include <b.h>\n"
376 "#include <d.h>\n",
377 sort("#include <d.h>\n"
378 "#include <b.h>\n"
379 "#include \"c.h\"\n"
380 "#include \"a.h\"\n"));
381 }
382
TEST_F(SortIncludesTest,HandlesMultilineIncludes)383 TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
384 EXPECT_EQ("#include \"a.h\"\n"
385 "#include \"b.h\"\n"
386 "#include \"c.h\"\n",
387 sort("#include \"a.h\"\n"
388 "#include \\\n"
389 "\"c.h\"\n"
390 "#include \"b.h\"\n"));
391 }
392
TEST_F(SortIncludesTest,LeavesMainHeaderFirst)393 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
394 Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
395 EXPECT_EQ("#include \"llvm/a.h\"\n"
396 "#include \"b.h\"\n"
397 "#include \"c.h\"\n",
398 sort("#include \"llvm/a.h\"\n"
399 "#include \"c.h\"\n"
400 "#include \"b.h\"\n",
401 "a.cc"));
402 EXPECT_EQ("#include \"llvm/a.h\"\n"
403 "#include \"b.h\"\n"
404 "#include \"c.h\"\n",
405 sort("#include \"llvm/a.h\"\n"
406 "#include \"c.h\"\n"
407 "#include \"b.h\"\n",
408 "a_test.cc"));
409 EXPECT_EQ("#include \"llvm/input.h\"\n"
410 "#include \"b.h\"\n"
411 "#include \"c.h\"\n",
412 sort("#include \"llvm/input.h\"\n"
413 "#include \"c.h\"\n"
414 "#include \"b.h\"\n",
415 "input.mm"));
416
417 // Don't allow prefixes.
418 EXPECT_EQ("#include \"b.h\"\n"
419 "#include \"c.h\"\n"
420 "#include \"llvm/not_a.h\"\n",
421 sort("#include \"llvm/not_a.h\"\n"
422 "#include \"c.h\"\n"
423 "#include \"b.h\"\n",
424 "a.cc"));
425
426 // Don't do this for _main and other suffixes.
427 EXPECT_EQ("#include \"b.h\"\n"
428 "#include \"c.h\"\n"
429 "#include \"llvm/a.h\"\n",
430 sort("#include \"llvm/a.h\"\n"
431 "#include \"c.h\"\n"
432 "#include \"b.h\"\n",
433 "a_main.cc"));
434
435 // Don't do this in headers.
436 EXPECT_EQ("#include \"b.h\"\n"
437 "#include \"c.h\"\n"
438 "#include \"llvm/a.h\"\n",
439 sort("#include \"llvm/a.h\"\n"
440 "#include \"c.h\"\n"
441 "#include \"b.h\"\n",
442 "a.h"));
443
444 // Only do this in the first #include block.
445 EXPECT_EQ("#include <a>\n"
446 "\n"
447 "#include \"b.h\"\n"
448 "#include \"c.h\"\n"
449 "#include \"llvm/a.h\"\n",
450 sort("#include <a>\n"
451 "\n"
452 "#include \"llvm/a.h\"\n"
453 "#include \"c.h\"\n"
454 "#include \"b.h\"\n",
455 "a.cc"));
456
457 // Only recognize the first #include with a matching basename as main include.
458 EXPECT_EQ("#include \"a.h\"\n"
459 "#include \"b.h\"\n"
460 "#include \"c.h\"\n"
461 "#include \"llvm/a.h\"\n",
462 sort("#include \"b.h\"\n"
463 "#include \"a.h\"\n"
464 "#include \"c.h\"\n"
465 "#include \"llvm/a.h\"\n",
466 "a.cc"));
467 }
468
TEST_F(SortIncludesTest,LeavesMainHeaderFirstInAdditionalExtensions)469 TEST_F(SortIncludesTest, LeavesMainHeaderFirstInAdditionalExtensions) {
470 Style.IncludeIsMainRegex = "([-_](test|unittest))?|(Impl)?$";
471 EXPECT_EQ("#include \"b.h\"\n"
472 "#include \"c.h\"\n"
473 "#include \"llvm/a.h\"\n",
474 sort("#include \"llvm/a.h\"\n"
475 "#include \"c.h\"\n"
476 "#include \"b.h\"\n",
477 "a_test.xxx"));
478 EXPECT_EQ("#include \"b.h\"\n"
479 "#include \"c.h\"\n"
480 "#include \"llvm/a.h\"\n",
481 sort("#include \"llvm/a.h\"\n"
482 "#include \"c.h\"\n"
483 "#include \"b.h\"\n",
484 "aImpl.hpp"));
485
486 // .cpp extension is considered "main" by default
487 EXPECT_EQ("#include \"llvm/a.h\"\n"
488 "#include \"b.h\"\n"
489 "#include \"c.h\"\n",
490 sort("#include \"llvm/a.h\"\n"
491 "#include \"c.h\"\n"
492 "#include \"b.h\"\n",
493 "aImpl.cpp"));
494 EXPECT_EQ("#include \"llvm/a.h\"\n"
495 "#include \"b.h\"\n"
496 "#include \"c.h\"\n",
497 sort("#include \"llvm/a.h\"\n"
498 "#include \"c.h\"\n"
499 "#include \"b.h\"\n",
500 "a_test.cpp"));
501
502 // Allow additional filenames / extensions
503 Style.IncludeIsMainSourceRegex = "(Impl\\.hpp)|(\\.xxx)$";
504 EXPECT_EQ("#include \"llvm/a.h\"\n"
505 "#include \"b.h\"\n"
506 "#include \"c.h\"\n",
507 sort("#include \"llvm/a.h\"\n"
508 "#include \"c.h\"\n"
509 "#include \"b.h\"\n",
510 "a_test.xxx"));
511 EXPECT_EQ("#include \"llvm/a.h\"\n"
512 "#include \"b.h\"\n"
513 "#include \"c.h\"\n",
514 sort("#include \"llvm/a.h\"\n"
515 "#include \"c.h\"\n"
516 "#include \"b.h\"\n",
517 "aImpl.hpp"));
518 }
519
TEST_F(SortIncludesTest,RecognizeMainHeaderInAllGroups)520 TEST_F(SortIncludesTest, RecognizeMainHeaderInAllGroups) {
521 Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
522 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
523
524 EXPECT_EQ("#include \"c.h\"\n"
525 "#include \"a.h\"\n"
526 "#include \"b.h\"\n",
527 sort("#include \"b.h\"\n"
528 "\n"
529 "#include \"a.h\"\n"
530 "#include \"c.h\"\n",
531 "c.cc"));
532 }
533
TEST_F(SortIncludesTest,MainHeaderIsSeparatedWhenRegroupping)534 TEST_F(SortIncludesTest, MainHeaderIsSeparatedWhenRegroupping) {
535 Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
536 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
537
538 EXPECT_EQ("#include \"a.h\"\n"
539 "\n"
540 "#include \"b.h\"\n"
541 "#include \"c.h\"\n",
542 sort("#include \"b.h\"\n"
543 "\n"
544 "#include \"a.h\"\n"
545 "#include \"c.h\"\n",
546 "a.cc"));
547 }
548
TEST_F(SortIncludesTest,SupportCaseInsensitiveMatching)549 TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) {
550 // Setup an regex for main includes so we can cover those as well.
551 Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
552
553 // Ensure both main header detection and grouping work in a case insensitive
554 // manner.
555 EXPECT_EQ("#include \"llvm/A.h\"\n"
556 "#include \"b.h\"\n"
557 "#include \"c.h\"\n"
558 "#include \"LLVM/z.h\"\n"
559 "#include \"llvm/X.h\"\n"
560 "#include \"GTest/GTest.h\"\n"
561 "#include \"gmock/gmock.h\"\n",
562 sort("#include \"c.h\"\n"
563 "#include \"b.h\"\n"
564 "#include \"GTest/GTest.h\"\n"
565 "#include \"llvm/A.h\"\n"
566 "#include \"gmock/gmock.h\"\n"
567 "#include \"llvm/X.h\"\n"
568 "#include \"LLVM/z.h\"\n",
569 "a_TEST.cc"));
570 }
571
TEST_F(SortIncludesTest,NegativePriorities)572 TEST_F(SortIncludesTest, NegativePriorities) {
573 Style.IncludeCategories = {{".*important_os_header.*", -1, 0}, {".*", 1, 0}};
574 EXPECT_EQ("#include \"important_os_header.h\"\n"
575 "#include \"c_main.h\"\n"
576 "#include \"a_other.h\"\n",
577 sort("#include \"c_main.h\"\n"
578 "#include \"a_other.h\"\n"
579 "#include \"important_os_header.h\"\n",
580 "c_main.cc"));
581
582 // check stable when re-run
583 EXPECT_EQ("#include \"important_os_header.h\"\n"
584 "#include \"c_main.h\"\n"
585 "#include \"a_other.h\"\n",
586 sort("#include \"important_os_header.h\"\n"
587 "#include \"c_main.h\"\n"
588 "#include \"a_other.h\"\n",
589 "c_main.cc", 0));
590 }
591
TEST_F(SortIncludesTest,PriorityGroupsAreSeparatedWhenRegroupping)592 TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) {
593 Style.IncludeCategories = {{".*important_os_header.*", -1, 0}, {".*", 1, 0}};
594 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
595
596 EXPECT_EQ("#include \"important_os_header.h\"\n"
597 "\n"
598 "#include \"c_main.h\"\n"
599 "\n"
600 "#include \"a_other.h\"\n",
601 sort("#include \"c_main.h\"\n"
602 "#include \"a_other.h\"\n"
603 "#include \"important_os_header.h\"\n",
604 "c_main.cc"));
605
606 // check stable when re-run
607 EXPECT_EQ("#include \"important_os_header.h\"\n"
608 "\n"
609 "#include \"c_main.h\"\n"
610 "\n"
611 "#include \"a_other.h\"\n",
612 sort("#include \"important_os_header.h\"\n"
613 "\n"
614 "#include \"c_main.h\"\n"
615 "\n"
616 "#include \"a_other.h\"\n",
617 "c_main.cc", 0));
618 }
619
TEST_F(SortIncludesTest,CalculatesCorrectCursorPosition)620 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
621 std::string Code = "#include <ccc>\n" // Start of line: 0
622 "#include <bbbbbb>\n" // Start of line: 15
623 "#include <a>\n"; // Start of line: 33
624 EXPECT_EQ(31u, newCursor(Code, 0));
625 EXPECT_EQ(13u, newCursor(Code, 15));
626 EXPECT_EQ(0u, newCursor(Code, 33));
627
628 EXPECT_EQ(41u, newCursor(Code, 10));
629 EXPECT_EQ(23u, newCursor(Code, 25));
630 EXPECT_EQ(10u, newCursor(Code, 43));
631 }
632
TEST_F(SortIncludesTest,DeduplicateIncludes)633 TEST_F(SortIncludesTest, DeduplicateIncludes) {
634 EXPECT_EQ("#include <a>\n"
635 "#include <b>\n"
636 "#include <c>\n",
637 sort("#include <a>\n"
638 "#include <b>\n"
639 "#include <b>\n"
640 "#include <b>\n"
641 "#include <b>\n"
642 "#include <c>\n"));
643
644 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
645 EXPECT_EQ("#include <a>\n"
646 "#include <b>\n"
647 "#include <c>\n",
648 sort("#include <a>\n"
649 "#include <b>\n"
650 "\n"
651 "#include <b>\n"
652 "\n"
653 "#include <b>\n"
654 "#include <c>\n"));
655
656 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
657 EXPECT_EQ("#include <a>\n"
658 "#include <b>\n"
659 "#include <c>\n",
660 sort("#include <a>\n"
661 "#include <b>\n"
662 "\n"
663 "#include <b>\n"
664 "\n"
665 "#include <b>\n"
666 "#include <c>\n"));
667 }
668
TEST_F(SortIncludesTest,SortAndDeduplicateIncludes)669 TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) {
670 EXPECT_EQ("#include <a>\n"
671 "#include <b>\n"
672 "#include <c>\n",
673 sort("#include <b>\n"
674 "#include <a>\n"
675 "#include <b>\n"
676 "#include <b>\n"
677 "#include <c>\n"
678 "#include <b>\n"));
679
680 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
681 EXPECT_EQ("#include <a>\n"
682 "#include <b>\n"
683 "#include <c>\n",
684 sort("#include <b>\n"
685 "#include <a>\n"
686 "\n"
687 "#include <b>\n"
688 "\n"
689 "#include <c>\n"
690 "#include <b>\n"));
691
692 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
693 EXPECT_EQ("#include <a>\n"
694 "#include <b>\n"
695 "#include <c>\n",
696 sort("#include <b>\n"
697 "#include <a>\n"
698 "\n"
699 "#include <b>\n"
700 "\n"
701 "#include <c>\n"
702 "#include <b>\n"));
703 }
704
TEST_F(SortIncludesTest,CalculatesCorrectCursorPositionAfterDeduplicate)705 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) {
706 std::string Code = "#include <b>\n" // Start of line: 0
707 "#include <a>\n" // Start of line: 13
708 "#include <b>\n" // Start of line: 26
709 "#include <b>\n" // Start of line: 39
710 "#include <c>\n" // Start of line: 52
711 "#include <b>\n"; // Start of line: 65
712 std::string Expected = "#include <a>\n" // Start of line: 0
713 "#include <b>\n" // Start of line: 13
714 "#include <c>\n"; // Start of line: 26
715 EXPECT_EQ(Expected, sort(Code));
716 // Cursor on 'i' in "#include <a>".
717 EXPECT_EQ(1u, newCursor(Code, 14));
718 // Cursor on 'b' in "#include <b>".
719 EXPECT_EQ(23u, newCursor(Code, 10));
720 EXPECT_EQ(23u, newCursor(Code, 36));
721 EXPECT_EQ(23u, newCursor(Code, 49));
722 EXPECT_EQ(23u, newCursor(Code, 36));
723 EXPECT_EQ(23u, newCursor(Code, 75));
724 // Cursor on '#' in "#include <c>".
725 EXPECT_EQ(26u, newCursor(Code, 52));
726 }
727
TEST_F(SortIncludesTest,DeduplicateLocallyInEachBlock)728 TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) {
729 EXPECT_EQ("#include <a>\n"
730 "#include <b>\n"
731 "\n"
732 "#include <b>\n"
733 "#include <c>\n",
734 sort("#include <a>\n"
735 "#include <b>\n"
736 "\n"
737 "#include <c>\n"
738 "#include <b>\n"
739 "#include <b>\n"));
740 }
741
TEST_F(SortIncludesTest,ValidAffactedRangesAfterDeduplicatingIncludes)742 TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) {
743 std::string Code = "#include <a>\n"
744 "#include <b>\n"
745 "#include <a>\n"
746 "#include <a>\n"
747 "\n"
748 " int x ;";
749 std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)};
750 auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp");
751 Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
752 EXPECT_EQ(1u, Ranges.size());
753 EXPECT_EQ(0u, Ranges[0].getOffset());
754 EXPECT_EQ(26u, Ranges[0].getLength());
755 }
756
TEST_F(SortIncludesTest,DoNotSortLikelyXml)757 TEST_F(SortIncludesTest, DoNotSortLikelyXml) {
758 EXPECT_EQ("<!--;\n"
759 "#include <b>\n"
760 "#include <a>\n"
761 "-->",
762 sort("<!--;\n"
763 "#include <b>\n"
764 "#include <a>\n"
765 "-->", "input.h", 0));
766 }
767
TEST_F(SortIncludesTest,DoNotOutputReplacementsForSortedBlocksWithRegrouping)768 TEST_F(SortIncludesTest, DoNotOutputReplacementsForSortedBlocksWithRegrouping) {
769 Style.IncludeBlocks = Style.IBS_Regroup;
770 std::string Code = R"(
771 #include "b.h"
772
773 #include <a.h>
774 )";
775 EXPECT_EQ(Code, sort(Code, "input.h", 0));
776 }
777
TEST_F(SortIncludesTest,DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows)778 TEST_F(SortIncludesTest,
779 DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows) {
780 Style.IncludeBlocks = Style.IBS_Regroup;
781 std::string Code = "#include \"b.h\"\r\n"
782 "\r\n"
783 "#include <a.h>\r\n";
784 EXPECT_EQ(Code, sort(Code, "input.h", 0));
785 }
786
TEST_F(SortIncludesTest,DoNotRegroupGroupsInGoogleObjCStyle)787 TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) {
788 FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC);
789
790 EXPECT_EQ("#include <a.h>\n"
791 "#include <b.h>\n"
792 "#include \"a.h\"",
793 sort("#include <b.h>\n"
794 "#include <a.h>\n"
795 "#include \"a.h\""));
796 }
797
798 } // end namespace
799 } // end namespace format
800 } // end namespace clang
801