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