xref: /llvm-project/clang/unittests/Format/SortIncludesTest.cpp (revision 141c544c03702ac7c50522373ad781ede3685e0a)
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 "FormatTestBase.h"
10 #include "clang/Format/Format.h"
11 #include "llvm/ADT/StringRef.h"
12 #include "llvm/Support/Debug.h"
13 #include "gtest/gtest.h"
14 
15 #define DEBUG_TYPE "sort-includes-test"
16 
17 namespace clang {
18 namespace format {
19 namespace {
20 
21 class SortIncludesTest : public test::FormatTestBase {
22 protected:
23   std::vector<tooling::Range> GetCodeRange(StringRef Code) {
24     return std::vector<tooling::Range>(1, tooling::Range(0, Code.size()));
25   }
26 
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 
41   std::string sort(StringRef Code, StringRef FileName = "input.cpp",
42                    unsigned ExpectedNumRanges = 1) {
43     return sort(Code, GetCodeRange(Code), FileName, ExpectedNumRanges);
44   }
45 
46   unsigned newCursor(StringRef Code, unsigned Cursor) {
47     sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.cpp", &Cursor);
48     return Cursor;
49   }
50 
51   FormatStyle FmtStyle = getLLVMStyle();
52   tooling::IncludeStyle &Style = FmtStyle.IncludeStyle;
53 };
54 
55 TEST_F(SortIncludesTest, BasicSorting) {
56   verifyFormat("#include \"a.h\"\n"
57                "#include \"b.h\"\n"
58                "#include \"c.h\"",
59                sort("#include \"a.h\"\n"
60                     "#include \"c.h\"\n"
61                     "#include \"b.h\""));
62 
63   verifyFormat("// comment\n"
64                "#include <a>\n"
65                "#include <b>",
66                sort("// comment\n"
67                     "#include <b>\n"
68                     "#include <a>",
69                     {tooling::Range(25, 1)}));
70 }
71 
72 TEST_F(SortIncludesTest, TrailingComments) {
73   verifyFormat("#include \"a.h\"\n"
74                "#include \"b.h\" /* long\n"
75                "                  * long\n"
76                "                  * comment*/\n"
77                "#include \"c.h\"\n"
78                "#include \"d.h\"",
79                sort("#include \"a.h\"\n"
80                     "#include \"c.h\"\n"
81                     "#include \"b.h\" /* long\n"
82                     "                  * long\n"
83                     "                  * comment*/\n"
84                     "#include \"d.h\""));
85 }
86 
87 TEST_F(SortIncludesTest, SortedIncludesUsingSortPriorityAttribute) {
88   FmtStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
89   FmtStyle.IncludeStyle.IncludeCategories = {
90       {"^<sys/param\\.h>", 1, 0, false},
91       {"^<sys/types\\.h>", 1, 1, false},
92       {"^<sys.*/", 1, 2, false},
93       {"^<uvm/", 2, 3, false},
94       {"^<machine/", 3, 4, false},
95       {"^<dev/", 4, 5, false},
96       {"^<net.*/", 5, 6, false},
97       {"^<protocols/", 5, 7, false},
98       {"^<(fs|miscfs|msdosfs|nfs|ntfs|ufs)/", 6, 8, false},
99       {"^<(x86|amd64|i386|xen)/", 7, 8, false},
100       {"<path", 9, 11, false},
101       {"^<[^/].*\\.h>", 8, 10, false},
102       {"^\".*\\.h\"", 10, 12, false}};
103   verifyFormat("#include <sys/param.h>\n"
104                "#include <sys/types.h>\n"
105                "#include <sys/ioctl.h>\n"
106                "#include <sys/socket.h>\n"
107                "#include <sys/stat.h>\n"
108                "#include <sys/wait.h>\n"
109                "\n"
110                "#include <net/if.h>\n"
111                "#include <net/if_dl.h>\n"
112                "#include <net/route.h>\n"
113                "#include <netinet/in.h>\n"
114                "#include <protocols/rwhod.h>\n"
115                "\n"
116                "#include <assert.h>\n"
117                "#include <errno.h>\n"
118                "#include <inttypes.h>\n"
119                "#include <stdio.h>\n"
120                "#include <stdlib.h>\n"
121                "\n"
122                "#include <paths.h>\n"
123                "\n"
124                "#include \"pathnames.h\"",
125                sort("#include <sys/param.h>\n"
126                     "#include <sys/types.h>\n"
127                     "#include <sys/ioctl.h>\n"
128                     "#include <net/if_dl.h>\n"
129                     "#include <net/route.h>\n"
130                     "#include <netinet/in.h>\n"
131                     "#include <sys/socket.h>\n"
132                     "#include <sys/stat.h>\n"
133                     "#include <sys/wait.h>\n"
134                     "#include <net/if.h>\n"
135                     "#include <protocols/rwhod.h>\n"
136                     "#include <assert.h>\n"
137                     "#include <paths.h>\n"
138                     "#include \"pathnames.h\"\n"
139                     "#include <errno.h>\n"
140                     "#include <inttypes.h>\n"
141                     "#include <stdio.h>\n"
142                     "#include <stdlib.h>"));
143 }
144 TEST_F(SortIncludesTest, SortPriorityNotDefined) {
145   FmtStyle = getLLVMStyle();
146   verifyFormat("#include \"FormatTestUtils.h\"\n"
147                "#include \"clang/Format/Format.h\"\n"
148                "#include \"llvm/ADT/None.h\"\n"
149                "#include \"llvm/Support/Debug.h\"\n"
150                "#include \"gtest/gtest.h\"",
151                sort("#include \"clang/Format/Format.h\"\n"
152                     "#include \"llvm/ADT/None.h\"\n"
153                     "#include \"FormatTestUtils.h\"\n"
154                     "#include \"gtest/gtest.h\"\n"
155                     "#include \"llvm/Support/Debug.h\""));
156 }
157 
158 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
159   // Identical #includes have led to a failure with an unstable sort.
160   StringRef Code = "#include <a>\n"
161                    "#include <b>\n"
162                    "#include <c>\n"
163                    "#include <d>\n"
164                    "#include <e>\n"
165                    "#include <f>\n";
166   EXPECT_TRUE(sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a.cc").empty());
167 }
168 
169 TEST_F(SortIncludesTest, MainFileHeader) {
170   StringRef Code = "#include <string>\n"
171                    "\n"
172                    "#include \"a/extra_action.proto.h\"\n";
173   FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp);
174   EXPECT_TRUE(
175       sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a/extra_action.cc")
176           .empty());
177 
178   verifyFormat("#include \"foo.bar.h\"\n"
179                "\n"
180                "#include \"a.h\"",
181                sort("#include \"a.h\"\n"
182                     "#include \"foo.bar.h\"",
183                     "foo.bar.cc"));
184 }
185 
186 TEST_F(SortIncludesTest, SortedIncludesInMultipleBlocksAreMerged) {
187   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
188   verifyFormat("#include \"a.h\"\n"
189                "#include \"b.h\"\n"
190                "#include \"c.h\"",
191                sort("#include \"a.h\"\n"
192                     "#include \"c.h\"\n"
193                     "\n"
194                     "\n"
195                     "#include \"b.h\""));
196 
197   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
198   verifyFormat("#include \"a.h\"\n"
199                "#include \"b.h\"\n"
200                "#include \"c.h\"",
201                sort("#include \"a.h\"\n"
202                     "#include \"c.h\"\n"
203                     "\n"
204                     "\n"
205                     "#include \"b.h\""));
206 }
207 
208 TEST_F(SortIncludesTest, SupportClangFormatOff) {
209   verifyFormat("#include <a>\n"
210                "#include <b>\n"
211                "#include <c>\n"
212                "// clang-format off\n"
213                "#include <b>\n"
214                "#include <a>\n"
215                "#include <c>\n"
216                "// clang-format on",
217                sort("#include <b>\n"
218                     "#include <a>\n"
219                     "#include <c>\n"
220                     "// clang-format off\n"
221                     "#include <b>\n"
222                     "#include <a>\n"
223                     "#include <c>\n"
224                     "// clang-format on"));
225 
226   Style.IncludeBlocks = Style.IBS_Merge;
227   StringRef Code = "// clang-format off\r\n"
228                    "#include \"d.h\"\r\n"
229                    "#include \"b.h\"\r\n"
230                    "// clang-format on\r\n"
231                    "\r\n"
232                    "#include \"c.h\"\r\n"
233                    "#include \"a.h\"\r\n"
234                    "#include \"e.h\"\r\n";
235 
236   StringRef Expected = "// clang-format off\r\n"
237                        "#include \"d.h\"\r\n"
238                        "#include \"b.h\"\r\n"
239                        "// clang-format on\r\n"
240                        "\r\n"
241                        "#include \"e.h\"\r\n"
242                        "#include \"a.h\"\r\n"
243                        "#include \"c.h\"\r\n";
244 
245   verifyFormat(Expected, sort(Code, "e.cpp", 1));
246 }
247 
248 TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) {
249   verifyFormat("#include <a>\n"
250                "#include <b>\n"
251                "#include <c>\n"
252                "/* clang-format off */\n"
253                "#include <b>\n"
254                "#include <a>\n"
255                "#include <c>\n"
256                "/* clang-format on */",
257                sort("#include <b>\n"
258                     "#include <a>\n"
259                     "#include <c>\n"
260                     "/* clang-format off */\n"
261                     "#include <b>\n"
262                     "#include <a>\n"
263                     "#include <c>\n"
264                     "/* clang-format on */"));
265 
266   // Not really turning it off
267   verifyFormat("#include <a>\n"
268                "#include <b>\n"
269                "#include <c>\n"
270                "/* clang-format offically */\n"
271                "#include <a>\n"
272                "#include <b>\n"
273                "#include <c>\n"
274                "/* clang-format onwards */",
275                sort("#include <b>\n"
276                     "#include <a>\n"
277                     "#include <c>\n"
278                     "/* clang-format offically */\n"
279                     "#include <b>\n"
280                     "#include <a>\n"
281                     "#include <c>\n"
282                     "/* clang-format onwards */",
283                     "input.h", 2));
284 }
285 
286 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
287   FmtStyle.SortIncludes = FormatStyle::SI_Never;
288   verifyFormat("#include \"a.h\"\n"
289                "#include \"c.h\"\n"
290                "#include \"b.h\"",
291                sort("#include \"a.h\"\n"
292                     "#include \"c.h\"\n"
293                     "#include \"b.h\"",
294                     "input.h", 0));
295 }
296 
297 TEST_F(SortIncludesTest, MixIncludeAndImport) {
298   verifyFormat("#include \"a.h\"\n"
299                "#import \"b.h\"\n"
300                "#include \"c.h\"",
301                sort("#include \"a.h\"\n"
302                     "#include \"c.h\"\n"
303                     "#import \"b.h\""));
304 }
305 
306 TEST_F(SortIncludesTest, FixTrailingComments) {
307   verifyFormat("#include \"a.h\"  // comment\n"
308                "#include \"bb.h\" // comment\n"
309                "#include \"ccc.h\"",
310                sort("#include \"a.h\" // comment\n"
311                     "#include \"ccc.h\"\n"
312                     "#include \"bb.h\" // comment"));
313 }
314 
315 TEST_F(SortIncludesTest, LeadingWhitespace) {
316   verifyFormat("#include \"a.h\"\n"
317                "#include \"b.h\"\n"
318                "#include \"c.h\"",
319                sort(" #include \"a.h\"\n"
320                     "  #include \"c.h\"\n"
321                     "   #include \"b.h\""));
322   verifyFormat("#include \"a.h\"\n"
323                "#include \"b.h\"\n"
324                "#include \"c.h\"",
325                sort("# include \"a.h\"\n"
326                     "#  include \"c.h\"\n"
327                     "#   include \"b.h\""));
328   verifyFormat("#include \"a.h\"", sort("#include \"a.h\"\n"
329                                         " #include \"a.h\""));
330 }
331 
332 TEST_F(SortIncludesTest, TrailingWhitespace) {
333   verifyFormat("#include \"a.h\"\n"
334                "#include \"b.h\"\n"
335                "#include \"c.h\"",
336                sort("#include \"a.h\" \n"
337                     "#include \"c.h\"  \n"
338                     "#include \"b.h\"   "));
339   verifyFormat("#include \"a.h\"", sort("#include \"a.h\"\n"
340                                         "#include \"a.h\" "));
341 }
342 
343 TEST_F(SortIncludesTest, GreaterInComment) {
344   verifyFormat("#include \"a.h\"\n"
345                "#include \"b.h\" // >\n"
346                "#include \"c.h\"",
347                sort("#include \"a.h\"\n"
348                     "#include \"c.h\"\n"
349                     "#include \"b.h\" // >"));
350 }
351 
352 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
353   verifyFormat("#include \"a.h\"\n"
354                "#include \"c.h\"\n"
355                "\n"
356                "#include \"b.h\"",
357                sort("#include \"a.h\"\n"
358                     "#include \"c.h\"\n"
359                     "\n"
360                     "#include \"b.h\"",
361                     "input.h", 0));
362 }
363 
364 TEST_F(SortIncludesTest, SortsAllBlocksWhenMerging) {
365   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
366   verifyFormat("#include \"a.h\"\n"
367                "#include \"b.h\"\n"
368                "#include \"c.h\"",
369                sort("#include \"a.h\"\n"
370                     "#include \"c.h\"\n"
371                     "\n"
372                     "#include \"b.h\""));
373 }
374 
375 TEST_F(SortIncludesTest, CommentsAlwaysSeparateGroups) {
376   verifyFormat("#include \"a.h\"\n"
377                "#include \"c.h\"\n"
378                "// comment\n"
379                "#include \"b.h\"",
380                sort("#include \"c.h\"\n"
381                     "#include \"a.h\"\n"
382                     "// comment\n"
383                     "#include \"b.h\""));
384 
385   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
386   verifyFormat("#include \"a.h\"\n"
387                "#include \"c.h\"\n"
388                "// comment\n"
389                "#include \"b.h\"",
390                sort("#include \"c.h\"\n"
391                     "#include \"a.h\"\n"
392                     "// comment\n"
393                     "#include \"b.h\""));
394 
395   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
396   verifyFormat("#include \"a.h\"\n"
397                "#include \"c.h\"\n"
398                "// comment\n"
399                "#include \"b.h\"",
400                sort("#include \"c.h\"\n"
401                     "#include \"a.h\"\n"
402                     "// comment\n"
403                     "#include \"b.h\""));
404 }
405 
406 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
407   verifyFormat("#include \"a.h\"\n"
408                "#include \"c.h\"\n"
409                "#include <array>\n"
410                "#include <b.h>\n"
411                "#include <d.h>\n"
412                "#include <vector>",
413                sort("#include <vector>\n"
414                     "#include <d.h>\n"
415                     "#include <array>\n"
416                     "#include <b.h>\n"
417                     "#include \"c.h\"\n"
418                     "#include \"a.h\""));
419 
420   FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp);
421   verifyFormat("#include <b.h>\n"
422                "#include <d.h>\n"
423                "\n"
424                "#include <array>\n"
425                "#include <vector>\n"
426                "\n"
427                "#include \"a.h\"\n"
428                "#include \"c.h\"",
429                sort("#include <vector>\n"
430                     "#include <d.h>\n"
431                     "#include <array>\n"
432                     "#include <b.h>\n"
433                     "#include \"c.h\"\n"
434                     "#include \"a.h\""));
435 }
436 
437 TEST_F(SortIncludesTest, RegroupsAngledIncludesInSeparateBlocks) {
438   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
439   verifyFormat("#include \"a.h\"\n"
440                "#include \"c.h\"\n"
441                "\n"
442                "#include <b.h>\n"
443                "#include <d.h>",
444                sort("#include <d.h>\n"
445                     "#include <b.h>\n"
446                     "#include \"c.h\"\n"
447                     "#include \"a.h\""));
448 }
449 
450 TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
451   verifyFormat("#include \"a.h\"\n"
452                "#include \"b.h\"\n"
453                "#include \"c.h\"",
454                sort("#include \"a.h\"\n"
455                     "#include \\\n"
456                     "\"c.h\"\n"
457                     "#include \"b.h\""));
458 }
459 
460 TEST_F(SortIncludesTest, HandlesTrailingCommentsWithAngleBrackets) {
461   // Regression test from the discussion at https://reviews.llvm.org/D121370.
462   verifyFormat("#include <cstdint>\n"
463                "\n"
464                "#include \"util/bar.h\"\n"
465                "#include \"util/foo/foo.h\" // foo<T>",
466                sort("#include <cstdint>\n"
467                     "\n"
468                     "#include \"util/bar.h\"\n"
469                     "#include \"util/foo/foo.h\" // foo<T>",
470                     /*FileName=*/"input.cc",
471                     /*ExpectedNumRanges=*/0));
472 }
473 
474 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
475   Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
476   verifyFormat("#include \"llvm/a.h\"\n"
477                "#include \"b.h\"\n"
478                "#include \"c.h\"",
479                sort("#include \"llvm/a.h\"\n"
480                     "#include \"c.h\"\n"
481                     "#include \"b.h\"",
482                     "a.cc"));
483   verifyFormat("#include \"llvm/a.h\"\n"
484                "#include \"b.h\"\n"
485                "#include \"c.h\"",
486                sort("#include \"llvm/a.h\"\n"
487                     "#include \"c.h\"\n"
488                     "#include \"b.h\"",
489                     "a_test.cc"));
490   verifyFormat("#include \"llvm/input.h\"\n"
491                "#include \"b.h\"\n"
492                "#include \"c.h\"",
493                sort("#include \"llvm/input.h\"\n"
494                     "#include \"c.h\"\n"
495                     "#include \"b.h\"",
496                     "input.mm"));
497 
498   // Don't allow prefixes.
499   verifyFormat("#include \"b.h\"\n"
500                "#include \"c.h\"\n"
501                "#include \"llvm/not_a.h\"",
502                sort("#include \"llvm/not_a.h\"\n"
503                     "#include \"c.h\"\n"
504                     "#include \"b.h\"",
505                     "a.cc"));
506 
507   // Don't do this for _main and other suffixes.
508   verifyFormat("#include \"b.h\"\n"
509                "#include \"c.h\"\n"
510                "#include \"llvm/a.h\"",
511                sort("#include \"llvm/a.h\"\n"
512                     "#include \"c.h\"\n"
513                     "#include \"b.h\"",
514                     "a_main.cc"));
515 
516   // Don't do this in headers.
517   verifyFormat("#include \"b.h\"\n"
518                "#include \"c.h\"\n"
519                "#include \"llvm/a.h\"",
520                sort("#include \"llvm/a.h\"\n"
521                     "#include \"c.h\"\n"
522                     "#include \"b.h\"",
523                     "a.h"));
524 
525   // Only do this in the first #include block.
526   verifyFormat("#include <a>\n"
527                "\n"
528                "#include \"b.h\"\n"
529                "#include \"c.h\"\n"
530                "#include \"llvm/a.h\"",
531                sort("#include <a>\n"
532                     "\n"
533                     "#include \"llvm/a.h\"\n"
534                     "#include \"c.h\"\n"
535                     "#include \"b.h\"",
536                     "a.cc"));
537 
538   // Only recognize the first #include with a matching basename as main include.
539   verifyFormat("#include \"a.h\"\n"
540                "#include \"b.h\"\n"
541                "#include \"c.h\"\n"
542                "#include \"llvm/a.h\"",
543                sort("#include \"b.h\"\n"
544                     "#include \"a.h\"\n"
545                     "#include \"c.h\"\n"
546                     "#include \"llvm/a.h\"",
547                     "a.cc"));
548 }
549 
550 TEST_F(SortIncludesTest, LeavesMainHeaderFirstInAdditionalExtensions) {
551   Style.IncludeIsMainRegex = "([-_](test|unittest))?|(Impl)?$";
552   verifyFormat("#include \"b.h\"\n"
553                "#include \"c.h\"\n"
554                "#include \"llvm/a.h\"",
555                sort("#include \"llvm/a.h\"\n"
556                     "#include \"c.h\"\n"
557                     "#include \"b.h\"",
558                     "a_test.xxx"));
559   verifyFormat("#include \"b.h\"\n"
560                "#include \"c.h\"\n"
561                "#include \"llvm/a.h\"",
562                sort("#include \"llvm/a.h\"\n"
563                     "#include \"c.h\"\n"
564                     "#include \"b.h\"",
565                     "aImpl.hpp"));
566 
567   // .cpp extension is considered "main" by default
568   verifyFormat("#include \"llvm/a.h\"\n"
569                "#include \"b.h\"\n"
570                "#include \"c.h\"",
571                sort("#include \"llvm/a.h\"\n"
572                     "#include \"c.h\"\n"
573                     "#include \"b.h\"",
574                     "aImpl.cpp"));
575   verifyFormat("#include \"llvm/a.h\"\n"
576                "#include \"b.h\"\n"
577                "#include \"c.h\"",
578                sort("#include \"llvm/a.h\"\n"
579                     "#include \"c.h\"\n"
580                     "#include \"b.h\"",
581                     "a_test.cpp"));
582 
583   // Allow additional filenames / extensions
584   Style.IncludeIsMainSourceRegex = "(Impl\\.hpp)|(\\.xxx)$";
585   verifyFormat("#include \"llvm/a.h\"\n"
586                "#include \"b.h\"\n"
587                "#include \"c.h\"",
588                sort("#include \"llvm/a.h\"\n"
589                     "#include \"c.h\"\n"
590                     "#include \"b.h\"",
591                     "a_test.xxx"));
592   verifyFormat("#include \"llvm/a.h\"\n"
593                "#include \"b.h\"\n"
594                "#include \"c.h\"",
595                sort("#include \"llvm/a.h\"\n"
596                     "#include \"c.h\"\n"
597                     "#include \"b.h\"",
598                     "aImpl.hpp"));
599 }
600 
601 TEST_F(SortIncludesTest, RecognizeMainHeaderInAllGroups) {
602   Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
603   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
604 
605   verifyFormat("#include \"c.h\"\n"
606                "#include \"a.h\"\n"
607                "#include \"b.h\"",
608                sort("#include \"b.h\"\n"
609                     "\n"
610                     "#include \"a.h\"\n"
611                     "#include \"c.h\"",
612                     "c.cc"));
613 }
614 
615 TEST_F(SortIncludesTest, MainHeaderIsSeparatedWhenRegroupping) {
616   Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
617   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
618 
619   verifyFormat("#include \"a.h\"\n"
620                "\n"
621                "#include \"b.h\"\n"
622                "#include \"c.h\"",
623                sort("#include \"b.h\"\n"
624                     "\n"
625                     "#include \"a.h\"\n"
626                     "#include \"c.h\"",
627                     "a.cc"));
628 }
629 
630 TEST_F(SortIncludesTest, SupportOptionalCaseSensitiveSorting) {
631   EXPECT_FALSE(FmtStyle.SortIncludes == FormatStyle::SI_CaseInsensitive);
632 
633   FmtStyle.SortIncludes = FormatStyle::SI_CaseInsensitive;
634 
635   verifyFormat("#include \"A/B.h\"\n"
636                "#include \"A/b.h\"\n"
637                "#include \"a/b.h\"\n"
638                "#include \"B/A.h\"\n"
639                "#include \"B/a.h\"",
640                sort("#include \"B/a.h\"\n"
641                     "#include \"B/A.h\"\n"
642                     "#include \"A/B.h\"\n"
643                     "#include \"a/b.h\"\n"
644                     "#include \"A/b.h\"",
645                     "a.h"));
646 
647   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
648   Style.IncludeCategories = {
649       {"^\"", 1, 0, false}, {"^<.*\\.h>$", 2, 0, false}, {"^<", 3, 0, false}};
650 
651   StringRef UnsortedCode = "#include \"qt.h\"\n"
652                            "#include <algorithm>\n"
653                            "#include <qtwhatever.h>\n"
654                            "#include <Qtwhatever.h>\n"
655                            "#include <Algorithm>\n"
656                            "#include \"vlib.h\"\n"
657                            "#include \"Vlib.h\"\n"
658                            "#include \"AST.h\"";
659 
660   verifyFormat("#include \"AST.h\"\n"
661                "#include \"qt.h\"\n"
662                "#include \"Vlib.h\"\n"
663                "#include \"vlib.h\"\n"
664                "\n"
665                "#include <Qtwhatever.h>\n"
666                "#include <qtwhatever.h>\n"
667                "\n"
668                "#include <Algorithm>\n"
669                "#include <algorithm>",
670                sort(UnsortedCode));
671 }
672 
673 TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) {
674   // Setup an regex for main includes so we can cover those as well.
675   Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
676 
677   // Ensure both main header detection and grouping work in a case insensitive
678   // manner.
679   verifyFormat("#include \"llvm/A.h\"\n"
680                "#include \"b.h\"\n"
681                "#include \"c.h\"\n"
682                "#include \"LLVM/z.h\"\n"
683                "#include \"llvm/X.h\"\n"
684                "#include \"GTest/GTest.h\"\n"
685                "#include \"gmock/gmock.h\"",
686                sort("#include \"c.h\"\n"
687                     "#include \"b.h\"\n"
688                     "#include \"GTest/GTest.h\"\n"
689                     "#include \"llvm/A.h\"\n"
690                     "#include \"gmock/gmock.h\"\n"
691                     "#include \"llvm/X.h\"\n"
692                     "#include \"LLVM/z.h\"",
693                     "a_TEST.cc"));
694 }
695 
696 TEST_F(SortIncludesTest, SupportOptionalCaseSensitiveMachting) {
697   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
698   Style.IncludeCategories = {{"^\"", 1, 0, false},
699                              {"^<.*\\.h>$", 2, 0, false},
700                              {"^<Q[A-Z][^\\.]*>", 3, 0, false},
701                              {"^<Qt[^\\.]*>", 4, 0, false},
702                              {"^<", 5, 0, false}};
703 
704   StringRef UnsortedCode = "#include <QWidget>\n"
705                            "#include \"qt.h\"\n"
706                            "#include <algorithm>\n"
707                            "#include <windows.h>\n"
708                            "#include <QLabel>\n"
709                            "#include \"qa.h\"\n"
710                            "#include <queue>\n"
711                            "#include <qtwhatever.h>\n"
712                            "#include <QtGlobal>";
713 
714   verifyFormat("#include \"qa.h\"\n"
715                "#include \"qt.h\"\n"
716                "\n"
717                "#include <qtwhatever.h>\n"
718                "#include <windows.h>\n"
719                "\n"
720                "#include <QLabel>\n"
721                "#include <QWidget>\n"
722                "#include <QtGlobal>\n"
723                "#include <queue>\n"
724                "\n"
725                "#include <algorithm>",
726                sort(UnsortedCode));
727 
728   Style.IncludeCategories[2].RegexIsCaseSensitive = true;
729   Style.IncludeCategories[3].RegexIsCaseSensitive = true;
730   verifyFormat("#include \"qa.h\"\n"
731                "#include \"qt.h\"\n"
732                "\n"
733                "#include <qtwhatever.h>\n"
734                "#include <windows.h>\n"
735                "\n"
736                "#include <QLabel>\n"
737                "#include <QWidget>\n"
738                "\n"
739                "#include <QtGlobal>\n"
740                "\n"
741                "#include <algorithm>\n"
742                "#include <queue>",
743                sort(UnsortedCode));
744 }
745 
746 TEST_F(SortIncludesTest, NegativePriorities) {
747   Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false},
748                              {".*", 1, 0, false}};
749   verifyFormat("#include \"important_os_header.h\"\n"
750                "#include \"c_main.h\"\n"
751                "#include \"a_other.h\"",
752                sort("#include \"c_main.h\"\n"
753                     "#include \"a_other.h\"\n"
754                     "#include \"important_os_header.h\"",
755                     "c_main.cc"));
756 
757   // check stable when re-run
758   verifyFormat("#include \"important_os_header.h\"\n"
759                "#include \"c_main.h\"\n"
760                "#include \"a_other.h\"",
761                sort("#include \"important_os_header.h\"\n"
762                     "#include \"c_main.h\"\n"
763                     "#include \"a_other.h\"",
764                     "c_main.cc", 0));
765 }
766 
767 TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) {
768   Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false},
769                              {".*", 1, 0, false}};
770   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
771 
772   verifyFormat("#include \"important_os_header.h\"\n"
773                "\n"
774                "#include \"c_main.h\"\n"
775                "\n"
776                "#include \"a_other.h\"",
777                sort("#include \"c_main.h\"\n"
778                     "#include \"a_other.h\"\n"
779                     "#include \"important_os_header.h\"",
780                     "c_main.cc"));
781 
782   // check stable when re-run
783   verifyFormat("#include \"important_os_header.h\"\n"
784                "\n"
785                "#include \"c_main.h\"\n"
786                "\n"
787                "#include \"a_other.h\"",
788                sort("#include \"important_os_header.h\"\n"
789                     "\n"
790                     "#include \"c_main.h\"\n"
791                     "\n"
792                     "#include \"a_other.h\"",
793                     "c_main.cc", 0));
794 }
795 
796 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
797   StringRef Code = "#include <ccc>\n"    // Start of line: 0
798                    "#include <bbbbbb>\n" // Start of line: 15
799                    "#include <a>\n";     // Start of line: 33
800   EXPECT_EQ(31u, newCursor(Code, 0));
801   EXPECT_EQ(13u, newCursor(Code, 15));
802   EXPECT_EQ(0u, newCursor(Code, 33));
803 
804   EXPECT_EQ(41u, newCursor(Code, 10));
805   EXPECT_EQ(23u, newCursor(Code, 25));
806   EXPECT_EQ(10u, newCursor(Code, 43));
807 }
808 
809 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionWithRegrouping) {
810   Style.IncludeBlocks = Style.IBS_Regroup;
811   StringRef Code = "#include \"b\"\n"      // Start of line: 0
812                    "\n"                    // Start of line: 13
813                    "#include \"aa\"\n"     // Start of line: 14
814                    "int i;";               // Start of line: 28
815   StringRef Expected = "#include \"aa\"\n" // Start of line: 0
816                        "#include \"b\"\n"  // Start of line: 14
817                        "int i;";           // Start of line: 27
818   verifyFormat(Expected, sort(Code));
819   EXPECT_EQ(12u, newCursor(Code, 26)); // Closing quote of "aa"
820   EXPECT_EQ(26u, newCursor(Code, 27)); // Newline after "aa"
821   EXPECT_EQ(27u, newCursor(Code, 28)); // Start of last line
822 }
823 
824 TEST_F(SortIncludesTest,
825        CalculatesCorrectCursorPositionWhenNoReplacementsWithRegroupingAndCRLF) {
826   Style.IncludeBlocks = Style.IBS_Regroup;
827   FmtStyle.LineEnding = FormatStyle::LE_CRLF;
828   Style.IncludeCategories = {
829       {"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}};
830   StringRef Code = "#include \"a\"\r\n" // Start of line: 0
831                    "\r\n"               // Start of line: 14
832                    "#include \"b\"\r\n" // Start of line: 16
833                    "\r\n"               // Start of line: 30
834                    "#include \"c\"\r\n" // Start of line: 32
835                    "\r\n"               // Start of line: 46
836                    "int i;";            // Start of line: 48
837   verifyFormat(Code);
838   EXPECT_EQ(0u, newCursor(Code, 0));
839   EXPECT_EQ(14u, newCursor(Code, 14));
840   EXPECT_EQ(16u, newCursor(Code, 16));
841   EXPECT_EQ(30u, newCursor(Code, 30));
842   EXPECT_EQ(32u, newCursor(Code, 32));
843   EXPECT_EQ(46u, newCursor(Code, 46));
844   EXPECT_EQ(48u, newCursor(Code, 48));
845 }
846 
847 TEST_F(
848     SortIncludesTest,
849     CalculatesCorrectCursorPositionWhenRemoveLinesReplacementsWithRegroupingAndCRLF) {
850   Style.IncludeBlocks = Style.IBS_Regroup;
851   FmtStyle.LineEnding = FormatStyle::LE_CRLF;
852   Style.IncludeCategories = {{".*", 0, 0, false}};
853   StringRef Code = "#include \"a\"\r\n"     // Start of line: 0
854                    "\r\n"                   // Start of line: 14
855                    "#include \"b\"\r\n"     // Start of line: 16
856                    "\r\n"                   // Start of line: 30
857                    "#include \"c\"\r\n"     // Start of line: 32
858                    "\r\n"                   // Start of line: 46
859                    "int i;";                // Start of line: 48
860   StringRef Expected = "#include \"a\"\r\n" // Start of line: 0
861                        "#include \"b\"\r\n" // Start of line: 14
862                        "#include \"c\"\r\n" // Start of line: 28
863                        "\r\n"               // Start of line: 42
864                        "int i;";            // Start of line: 44
865   verifyFormat(Expected, sort(Code));
866   EXPECT_EQ(0u, newCursor(Code, 0));
867   EXPECT_EQ(
868       14u,
869       newCursor(Code, 14)); // cursor on empty line in include block is ignored
870   EXPECT_EQ(14u, newCursor(Code, 16));
871   EXPECT_EQ(
872       30u,
873       newCursor(Code, 30)); // cursor on empty line in include block is ignored
874   EXPECT_EQ(28u, newCursor(Code, 32));
875   EXPECT_EQ(42u, newCursor(Code, 46));
876   EXPECT_EQ(44u, newCursor(Code, 48));
877 }
878 
879 // FIXME: the tests below should pass.
880 #if 0
881 TEST_F(
882     SortIncludesTest,
883     CalculatesCorrectCursorPositionWhenNewLineReplacementsWithRegroupingAndCRLF) {
884   Style.IncludeBlocks = Style.IBS_Regroup;
885   FmtStyle.LineEnding = FormatStyle::LE_CRLF;
886   Style.IncludeCategories = {
887       {"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}};
888   StringRef Code = "#include \"a\"\r\n"     // Start of line: 0
889                    "#include \"b\"\r\n"     // Start of line: 14
890                    "#include \"c\"\r\n"     // Start of line: 28
891                    "\r\n"                   // Start of line: 42
892                    "int i;";                // Start of line: 44
893   StringRef Expected = "#include \"a\"\r\n" // Start of line: 0
894                        "\r\n"               // Start of line: 14
895                        "#include \"b\"\r\n" // Start of line: 16
896                        "\r\n"               // Start of line: 30
897                        "#include \"c\"\r\n" // Start of line: 32
898                        "\r\n"               // Start of line: 46
899                        "int i;";            // Start of line: 48
900   verifyFormat(Expected, sort(Code));
901   EXPECT_EQ(0u, newCursor(Code, 0));
902   EXPECT_EQ(15u, newCursor(Code, 16));
903   EXPECT_EQ(30u, newCursor(Code, 32));
904   EXPECT_EQ(44u, newCursor(Code, 46));
905   EXPECT_EQ(46u, newCursor(Code, 48));
906 }
907 
908 TEST_F(
909     SortIncludesTest,
910     CalculatesCorrectCursorPositionWhenNoNewLineReplacementsWithRegroupingAndCRLF) {
911   Style.IncludeBlocks = Style.IBS_Regroup;
912   FmtStyle.LineEnding = FormatStyle::LE_CRLF;
913   Style.IncludeCategories = {
914       {"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}};
915   StringRef Code = "#include \"a\"\r\n"     // Start of line: 0
916                    "\r\n"                   // Start of line: 14
917                    "#include \"c\"\r\n"     // Start of line: 16
918                    "\r\n"                   // Start of line: 30
919                    "#include \"b\"\r\n"     // Start of line: 32
920                    "\r\n"                   // Start of line: 46
921                    "int i;";                // Start of line: 48
922   StringRef Expected = "#include \"a\"\r\n" // Start of line: 0
923                        "\r\n"               // Start of line: 14
924                        "#include \"b\"\r\n" // Start of line: 16
925                        "\r\n"               // Start of line: 30
926                        "#include \"c\"\r\n" // Start of line: 32
927                        "\r\n"               // Start of line: 46
928                        "int i;";            // Start of line: 48
929   verifyFormat(Expected, sort(Code));
930   EXPECT_EQ(0u, newCursor(Code, 0));
931   EXPECT_EQ(14u, newCursor(Code, 14));
932   EXPECT_EQ(30u, newCursor(Code, 32));
933   EXPECT_EQ(30u, newCursor(Code, 30));
934   EXPECT_EQ(15u, newCursor(Code, 15));
935   EXPECT_EQ(44u, newCursor(Code, 46));
936   EXPECT_EQ(46u, newCursor(Code, 48));
937 }
938 #endif
939 
940 TEST_F(SortIncludesTest, DeduplicateIncludes) {
941   verifyFormat("#include <a>\n"
942                "#include <b>\n"
943                "#include <c>",
944                sort("#include <a>\n"
945                     "#include <b>\n"
946                     "#include <b>\n"
947                     "#include <b>\n"
948                     "#include <b>\n"
949                     "#include <c>"));
950 
951   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
952   verifyFormat("#include <a>\n"
953                "#include <b>\n"
954                "#include <c>",
955                sort("#include <a>\n"
956                     "#include <b>\n"
957                     "\n"
958                     "#include <b>\n"
959                     "\n"
960                     "#include <b>\n"
961                     "#include <c>"));
962 
963   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
964   verifyFormat("#include <a>\n"
965                "#include <b>\n"
966                "#include <c>",
967                sort("#include <a>\n"
968                     "#include <b>\n"
969                     "\n"
970                     "#include <b>\n"
971                     "\n"
972                     "#include <b>\n"
973                     "#include <c>"));
974 }
975 
976 TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) {
977   verifyFormat("#include <a>\n"
978                "#include <b>\n"
979                "#include <c>",
980                sort("#include <b>\n"
981                     "#include <a>\n"
982                     "#include <b>\n"
983                     "#include <b>\n"
984                     "#include <c>\n"
985                     "#include <b>"));
986 
987   verifyFormat("/* COPYRIGHT *\\\n"
988                "\\* (C) 2024  */\n"
989                "\n"
990                "#include <a>\n"
991                "#include <b>",
992                sort("/* COPYRIGHT *\\\n"
993                     "\\* (C) 2024  */\n"
994                     "\n"
995                     "#include <b>\n"
996                     "#include <a>\n"
997                     "#include <b>"));
998 
999   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
1000   verifyFormat("#include <a>\n"
1001                "#include <b>\n"
1002                "#include <c>",
1003                sort("#include <b>\n"
1004                     "#include <a>\n"
1005                     "\n"
1006                     "#include <b>\n"
1007                     "\n"
1008                     "#include <c>\n"
1009                     "#include <b>"));
1010 
1011   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1012   verifyFormat("#include <a>\n"
1013                "#include <b>\n"
1014                "#include <c>",
1015                sort("#include <b>\n"
1016                     "#include <a>\n"
1017                     "\n"
1018                     "#include <b>\n"
1019                     "\n"
1020                     "#include <c>\n"
1021                     "#include <b>"));
1022 }
1023 
1024 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) {
1025   StringRef Code = "#include <b>\n"      // Start of line: 0
1026                    "#include <a>\n"      // Start of line: 13
1027                    "#include <b>\n"      // Start of line: 26
1028                    "#include <b>\n"      // Start of line: 39
1029                    "#include <c>\n"      // Start of line: 52
1030                    "#include <b>\n";     // Start of line: 65
1031   StringRef Expected = "#include <a>\n"  // Start of line: 0
1032                        "#include <b>\n"  // Start of line: 13
1033                        "#include <c>\n"; // Start of line: 26
1034   verifyFormat(Expected, sort(Code));
1035   // Cursor on 'i' in "#include <a>".
1036   EXPECT_EQ(1u, newCursor(Code, 14));
1037   // Cursor on 'b' in "#include <b>".
1038   EXPECT_EQ(23u, newCursor(Code, 10));
1039   EXPECT_EQ(23u, newCursor(Code, 36));
1040   EXPECT_EQ(23u, newCursor(Code, 49));
1041   EXPECT_EQ(23u, newCursor(Code, 36));
1042   EXPECT_EQ(23u, newCursor(Code, 75));
1043   // Cursor on '#' in "#include <c>".
1044   EXPECT_EQ(26u, newCursor(Code, 52));
1045 }
1046 
1047 TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) {
1048   verifyFormat("#include <a>\n"
1049                "#include <b>\n"
1050                "\n"
1051                "#include <b>\n"
1052                "#include <c>",
1053                sort("#include <a>\n"
1054                     "#include <b>\n"
1055                     "\n"
1056                     "#include <c>\n"
1057                     "#include <b>\n"
1058                     "#include <b>"));
1059 }
1060 
1061 TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) {
1062   StringRef Code = "#include <a>\n"
1063                    "#include <b>\n"
1064                    "#include <a>\n"
1065                    "#include <a>\n"
1066                    "\n"
1067                    "   int     x ;";
1068   std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)};
1069   auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp");
1070   Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
1071   EXPECT_EQ(1u, Ranges.size());
1072   EXPECT_EQ(0u, Ranges[0].getOffset());
1073   EXPECT_EQ(26u, Ranges[0].getLength());
1074 }
1075 
1076 TEST_F(SortIncludesTest, DoNotSortLikelyXml) {
1077   verifyFormat("<!--;\n"
1078                "#include <b>\n"
1079                "#include <a>\n"
1080                "-->",
1081                sort("<!--;\n"
1082                     "#include <b>\n"
1083                     "#include <a>\n"
1084                     "-->",
1085                     "input.h", 0));
1086 }
1087 
1088 TEST_F(SortIncludesTest, DoNotOutputReplacementsForSortedBlocksWithRegrouping) {
1089   Style.IncludeBlocks = Style.IBS_Regroup;
1090   StringRef Code = "#include \"b.h\"\n"
1091                    "\n"
1092                    "#include <a.h>";
1093   verifyFormat(Code, sort(Code, "input.h", 0));
1094 }
1095 
1096 TEST_F(SortIncludesTest,
1097        DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows) {
1098   Style.IncludeBlocks = Style.IBS_Regroup;
1099   StringRef Code = "#include \"b.h\"\r\n"
1100                    "\r\n"
1101                    "#include <a.h>\r\n";
1102   verifyFormat(Code, sort(Code, "input.h", 0));
1103 }
1104 
1105 TEST_F(SortIncludesTest, MainIncludeChar) {
1106   StringRef Code = "#include <a>\n"
1107                    "#include \"quote/input.h\"\n"
1108                    "#include <angle-bracket/input.h>\n";
1109 
1110   // Default behavior
1111   verifyFormat("#include \"quote/input.h\"\n"
1112                "#include <a>\n"
1113                "#include <angle-bracket/input.h>\n",
1114                sort(Code, "input.cc", 1));
1115 
1116   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Quote;
1117   verifyFormat("#include \"quote/input.h\"\n"
1118                "#include <a>\n"
1119                "#include <angle-bracket/input.h>\n",
1120                sort(Code, "input.cc", 1));
1121 
1122   Style.MainIncludeChar = tooling::IncludeStyle::MICD_AngleBracket;
1123   verifyFormat("#include <angle-bracket/input.h>\n"
1124                "#include \"quote/input.h\"\n"
1125                "#include <a>\n",
1126                sort(Code, "input.cc", 1));
1127 }
1128 
1129 TEST_F(SortIncludesTest, MainIncludeCharAnyPickQuote) {
1130   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Any;
1131   verifyFormat("#include \"input.h\"\n"
1132                "#include <a>\n"
1133                "#include <b>\n",
1134                sort("#include <a>\n"
1135                     "#include \"input.h\"\n"
1136                     "#include <b>\n",
1137                     "input.cc", 1));
1138 }
1139 
1140 TEST_F(SortIncludesTest, MainIncludeCharAnyPickAngleBracket) {
1141   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Any;
1142   verifyFormat("#include <input.h>\n"
1143                "#include <a>\n"
1144                "#include <b>\n",
1145                sort("#include <a>\n"
1146                     "#include <input.h>\n"
1147                     "#include <b>\n",
1148                     "input.cc", 1));
1149 }
1150 
1151 TEST_F(SortIncludesTest, MainIncludeCharQuoteAndRegroup) {
1152   Style.IncludeCategories = {
1153       {"lib-a", 1, 0, false}, {"lib-b", 2, 0, false}, {"lib-c", 3, 0, false}};
1154   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1155   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Quote;
1156 
1157   verifyFormat("#include \"lib-b/input.h\"\n"
1158                "\n"
1159                "#include <lib-a/h-1.h>\n"
1160                "#include <lib-a/h-3.h>\n"
1161                "#include <lib-a/input.h>\n"
1162                "\n"
1163                "#include <lib-b/h-1.h>\n"
1164                "#include <lib-b/h-3.h>\n"
1165                "\n"
1166                "#include <lib-c/h-1.h>\n"
1167                "#include <lib-c/h-2.h>\n"
1168                "#include <lib-c/h-3.h>\n",
1169                sort("#include <lib-c/h-1.h>\n"
1170                     "#include <lib-c/h-2.h>\n"
1171                     "#include <lib-c/h-3.h>\n"
1172                     "#include <lib-b/h-1.h>\n"
1173                     "#include \"lib-b/input.h\"\n"
1174                     "#include <lib-b/h-3.h>\n"
1175                     "#include <lib-a/h-1.h>\n"
1176                     "#include <lib-a/input.h>\n"
1177                     "#include <lib-a/h-3.h>\n",
1178                     "input.cc"));
1179 }
1180 
1181 TEST_F(SortIncludesTest, MainIncludeCharAngleBracketAndRegroup) {
1182   Style.IncludeCategories = {
1183       {"lib-a", 1, 0, false}, {"lib-b", 2, 0, false}, {"lib-c", 3, 0, false}};
1184   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1185   Style.MainIncludeChar = tooling::IncludeStyle::MICD_AngleBracket;
1186 
1187   verifyFormat("#include <lib-a/input.h>\n"
1188                "\n"
1189                "#include <lib-a/h-1.h>\n"
1190                "#include <lib-a/h-3.h>\n"
1191                "\n"
1192                "#include \"lib-b/input.h\"\n"
1193                "#include <lib-b/h-1.h>\n"
1194                "#include <lib-b/h-3.h>\n"
1195                "\n"
1196                "#include <lib-c/h-1.h>\n"
1197                "#include <lib-c/h-2.h>\n"
1198                "#include <lib-c/h-3.h>\n",
1199                sort("#include <lib-c/h-1.h>\n"
1200                     "#include <lib-c/h-2.h>\n"
1201                     "#include <lib-c/h-3.h>\n"
1202                     "#include <lib-b/h-1.h>\n"
1203                     "#include \"lib-b/input.h\"\n"
1204                     "#include <lib-b/h-3.h>\n"
1205                     "#include <lib-a/h-1.h>\n"
1206                     "#include <lib-a/input.h>\n"
1207                     "#include <lib-a/h-3.h>\n",
1208                     "input.cc"));
1209 }
1210 
1211 TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) {
1212   FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC);
1213 
1214   verifyFormat("#include <a.h>\n"
1215                "#include <b.h>\n"
1216                "#include \"a.h\"",
1217                sort("#include <b.h>\n"
1218                     "#include <a.h>\n"
1219                     "#include \"a.h\""));
1220 }
1221 
1222 TEST_F(SortIncludesTest, DoNotTreatPrecompiledHeadersAsFirstBlock) {
1223   Style.IncludeBlocks = Style.IBS_Merge;
1224   StringRef Code = "#include \"d.h\"\r\n"
1225                    "#include \"b.h\"\r\n"
1226                    "#pragma hdrstop\r\n"
1227                    "\r\n"
1228                    "#include \"c.h\"\r\n"
1229                    "#include \"a.h\"\r\n"
1230                    "#include \"e.h\"\r\n";
1231 
1232   StringRef Expected = "#include \"b.h\"\r\n"
1233                        "#include \"d.h\"\r\n"
1234                        "#pragma hdrstop\r\n"
1235                        "\r\n"
1236                        "#include \"e.h\"\r\n"
1237                        "#include \"a.h\"\r\n"
1238                        "#include \"c.h\"\r\n";
1239 
1240   verifyFormat(Expected, sort(Code, "e.cpp", 2));
1241 
1242   Code = "#include \"d.h\"\n"
1243          "#include \"b.h\"\n"
1244          "#pragma hdrstop( \"c:\\projects\\include\\myinc.pch\" )\n"
1245          "\n"
1246          "#include \"c.h\"\n"
1247          "#include \"a.h\"\n"
1248          "#include \"e.h\"\n";
1249 
1250   Expected = "#include \"b.h\"\n"
1251              "#include \"d.h\"\n"
1252              "#pragma hdrstop(\"c:\\projects\\include\\myinc.pch\")\n"
1253              "\n"
1254              "#include \"e.h\"\n"
1255              "#include \"a.h\"\n"
1256              "#include \"c.h\"\n";
1257 
1258   verifyFormat(Expected, sort(Code, "e.cpp", 2));
1259 }
1260 
1261 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkMerge) {
1262   Style.IncludeBlocks = Style.IBS_Merge;
1263   StringRef Code = "\xEF\xBB\xBF#include \"d.h\"\r\n"
1264                    "#include \"b.h\"\r\n"
1265                    "\r\n"
1266                    "#include \"c.h\"\r\n"
1267                    "#include \"a.h\"\r\n"
1268                    "#include \"e.h\"\r\n";
1269 
1270   StringRef Expected = "\xEF\xBB\xBF#include \"e.h\"\r\n"
1271                        "#include \"a.h\"\r\n"
1272                        "#include \"b.h\"\r\n"
1273                        "#include \"c.h\"\r\n"
1274                        "#include \"d.h\"\r\n";
1275 
1276   verifyFormat(Expected, sort(Code, "e.cpp", 1));
1277 }
1278 
1279 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkPreserve) {
1280   Style.IncludeBlocks = Style.IBS_Preserve;
1281   StringRef Code = "\xEF\xBB\xBF#include \"d.h\"\r\n"
1282                    "#include \"b.h\"\r\n"
1283                    "\r\n"
1284                    "#include \"c.h\"\r\n"
1285                    "#include \"a.h\"\r\n"
1286                    "#include \"e.h\"\r\n";
1287 
1288   StringRef Expected = "\xEF\xBB\xBF#include \"b.h\"\r\n"
1289                        "#include \"d.h\"\r\n"
1290                        "\r\n"
1291                        "#include \"a.h\"\r\n"
1292                        "#include \"c.h\"\r\n"
1293                        "#include \"e.h\"\r\n";
1294 
1295   verifyFormat(Expected, sort(Code, "e.cpp", 2));
1296 }
1297 
1298 TEST_F(SortIncludesTest, MergeLines) {
1299   Style.IncludeBlocks = Style.IBS_Merge;
1300   StringRef Code = "#include \"c.h\"\r\n"
1301                    "#include \"b\\\r\n"
1302                    ".h\"\r\n"
1303                    "#include \"a.h\"\r\n";
1304 
1305   StringRef Expected = "#include \"a.h\"\r\n"
1306                        "#include \"b\\\r\n"
1307                        ".h\"\r\n"
1308                        "#include \"c.h\"\r\n";
1309 
1310   verifyFormat(Expected, sort(Code, "a.cpp", 1));
1311 }
1312 
1313 TEST_F(SortIncludesTest, DisableFormatDisablesIncludeSorting) {
1314   StringRef Sorted = "#include <a.h>\n"
1315                      "#include <b.h>\n";
1316   StringRef Unsorted = "#include <b.h>\n"
1317                        "#include <a.h>\n";
1318   verifyFormat(Sorted, sort(Unsorted));
1319   FmtStyle.DisableFormat = true;
1320   verifyFormat(Unsorted, sort(Unsorted, "input.cpp", 0));
1321 }
1322 
1323 TEST_F(SortIncludesTest, DisableRawStringLiteralSorting) {
1324 
1325   verifyFormat("const char *t = R\"(\n"
1326                "#include <b.h>\n"
1327                "#include <a.h>\n"
1328                ")\";",
1329                sort("const char *t = R\"(\n"
1330                     "#include <b.h>\n"
1331                     "#include <a.h>\n"
1332                     ")\";",
1333                     "test.cxx", 0));
1334   verifyFormat("const char *t = R\"x(\n"
1335                "#include <b.h>\n"
1336                "#include <a.h>\n"
1337                ")x\";",
1338                sort("const char *t = R\"x(\n"
1339                     "#include <b.h>\n"
1340                     "#include <a.h>\n"
1341                     ")x\";",
1342                     "test.cxx", 0));
1343   verifyFormat("const char *t = R\"xyz(\n"
1344                "#include <b.h>\n"
1345                "#include <a.h>\n"
1346                ")xyz\";",
1347                sort("const char *t = R\"xyz(\n"
1348                     "#include <b.h>\n"
1349                     "#include <a.h>\n"
1350                     ")xyz\";",
1351                     "test.cxx", 0));
1352 
1353   verifyFormat("#include <a.h>\n"
1354                "#include <b.h>\n"
1355                "const char *t = R\"(\n"
1356                "#include <b.h>\n"
1357                "#include <a.h>\n"
1358                ")\";\n"
1359                "#include <c.h>\n"
1360                "#include <d.h>\n"
1361                "const char *t = R\"x(\n"
1362                "#include <f.h>\n"
1363                "#include <e.h>\n"
1364                ")x\";\n"
1365                "#include <g.h>\n"
1366                "#include <h.h>\n"
1367                "const char *t = R\"xyz(\n"
1368                "#include <j.h>\n"
1369                "#include <i.h>\n"
1370                ")xyz\";\n"
1371                "#include <k.h>\n"
1372                "#include <l.h>",
1373                sort("#include <b.h>\n"
1374                     "#include <a.h>\n"
1375                     "const char *t = R\"(\n"
1376                     "#include <b.h>\n"
1377                     "#include <a.h>\n"
1378                     ")\";\n"
1379                     "#include <d.h>\n"
1380                     "#include <c.h>\n"
1381                     "const char *t = R\"x(\n"
1382                     "#include <f.h>\n"
1383                     "#include <e.h>\n"
1384                     ")x\";\n"
1385                     "#include <h.h>\n"
1386                     "#include <g.h>\n"
1387                     "const char *t = R\"xyz(\n"
1388                     "#include <j.h>\n"
1389                     "#include <i.h>\n"
1390                     ")xyz\";\n"
1391                     "#include <l.h>\n"
1392                     "#include <k.h>",
1393                     "test.cc", 4));
1394 
1395   verifyFormat("const char *t = R\"AMZ029amz(\n"
1396                "#include <b.h>\n"
1397                "#include <a.h>\n"
1398                ")AMZ029amz\";",
1399                sort("const char *t = R\"AMZ029amz(\n"
1400                     "#include <b.h>\n"
1401                     "#include <a.h>\n"
1402                     ")AMZ029amz\";",
1403                     "test.cxx", 0));
1404 
1405   verifyFormat("const char *t = R\"-AMZ029amz(\n"
1406                "#include <b.h>\n"
1407                "#include <a.h>\n"
1408                ")-AMZ029amz\";",
1409                sort("const char *t = R\"-AMZ029amz(\n"
1410                     "#include <b.h>\n"
1411                     "#include <a.h>\n"
1412                     ")-AMZ029amz\";",
1413                     "test.cxx", 0));
1414 
1415   verifyFormat("const char *t = R\"AMZ029amz-(\n"
1416                "#include <b.h>\n"
1417                "#include <a.h>\n"
1418                ")AMZ029amz-\";",
1419                sort("const char *t = R\"AMZ029amz-(\n"
1420                     "#include <b.h>\n"
1421                     "#include <a.h>\n"
1422                     ")AMZ029amz-\";",
1423                     "test.cxx", 0));
1424 
1425   verifyFormat("const char *t = R\"AM|029amz-(\n"
1426                "#include <b.h>\n"
1427                "#include <a.h>\n"
1428                ")AM|029amz-\";",
1429                sort("const char *t = R\"AM|029amz-(\n"
1430                     "#include <b.h>\n"
1431                     "#include <a.h>\n"
1432                     ")AM|029amz-\";",
1433                     "test.cxx", 0));
1434 
1435   verifyFormat("const char *t = R\"AM[029amz-(\n"
1436                "#include <b.h>\n"
1437                "#include <a.h>\n"
1438                ")AM[029amz-\";",
1439                sort("const char *t = R\"AM[029amz-(\n"
1440                     "#include <b.h>\n"
1441                     "#include <a.h>\n"
1442                     ")AM[029amz-\";",
1443                     "test.cxx", 0));
1444 
1445   verifyFormat("const char *t = R\"AM]029amz-(\n"
1446                "#include <b.h>\n"
1447                "#include <a.h>\n"
1448                ")AM]029amz-\";",
1449                sort("const char *t = R\"AM]029amz-(\n"
1450                     "#include <b.h>\n"
1451                     "#include <a.h>\n"
1452                     ")AM]029amz-\";",
1453                     "test.cxx", 0));
1454 
1455 #define X "AMZ029amz{}+!%*=_:;',.<>|/?#~-$"
1456 
1457   verifyFormat("const char *t = R\"" X "(\n"
1458                "#include <b.h>\n"
1459                "#include <a.h>\n"
1460                ")" X "\";",
1461                sort("const char *t = R\"" X "(\n"
1462                     "#include <b.h>\n"
1463                     "#include <a.h>\n"
1464                     ")" X "\";",
1465                     "test.cxx", 0));
1466 
1467 #undef X
1468 }
1469 
1470 TEST_F(SortIncludesTest, BlockCommentedOutIncludes) {
1471   StringRef Code{"/* #include \"foo.h\"\n"
1472                  "#include \"bar.h\" */\n"
1473                  "#include <chrono>"};
1474 
1475   FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp);
1476   verifyFormat(Code, sort(Code, "input.cpp", 0));
1477 }
1478 
1479 } // end namespace
1480 } // end namespace format
1481 } // end namespace clang
1482