xref: /llvm-project/clang/unittests/Format/SortIncludesTest.cpp (revision 2de0bedfebb77a6c8a5b0d00902f796fa4022fd6)
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(llvm::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   EXPECT_EQ("#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   EXPECT_EQ("// 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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   std::string 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   std::string 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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   std::string 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   std::string 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   EXPECT_EQ(Expected, sort(Code, "e.cpp", 1));
246 }
247 
248 TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) {
249   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#include \"a.h\"", sort("#include \"a.h\"\n"
329                                      " #include \"a.h\""));
330 }
331 
332 TEST_F(SortIncludesTest, TrailingWhitespace) {
333   EXPECT_EQ("#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   EXPECT_EQ("#include \"a.h\"", sort("#include \"a.h\"\n"
340                                      "#include \"a.h\" "));
341 }
342 
343 TEST_F(SortIncludesTest, GreaterInComment) {
344   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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 = clang::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   EXPECT_EQ("#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   EXPECT_EQ("#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 = clang::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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   std::string 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   std::string 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   std::string Expected = "#include \"aa\"\n" // Start of line: 0
816                          "#include \"b\"\n"  // Start of line: 14
817                          "int i;";           // Start of line: 27
818   EXPECT_EQ(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   std::string 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   verifyNoChange(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   std::string 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   std::string 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   EXPECT_EQ(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   std::string 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   std::string 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   EXPECT_EQ(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   std::string 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   std::string 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   EXPECT_EQ(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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   EXPECT_EQ("#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   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
988   EXPECT_EQ("#include <a>\n"
989             "#include <b>\n"
990             "#include <c>",
991             sort("#include <b>\n"
992                  "#include <a>\n"
993                  "\n"
994                  "#include <b>\n"
995                  "\n"
996                  "#include <c>\n"
997                  "#include <b>"));
998 
999   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1000   EXPECT_EQ("#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 
1012 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) {
1013   std::string Code = "#include <b>\n"      // Start of line: 0
1014                      "#include <a>\n"      // Start of line: 13
1015                      "#include <b>\n"      // Start of line: 26
1016                      "#include <b>\n"      // Start of line: 39
1017                      "#include <c>\n"      // Start of line: 52
1018                      "#include <b>\n";     // Start of line: 65
1019   std::string Expected = "#include <a>\n"  // Start of line: 0
1020                          "#include <b>\n"  // Start of line: 13
1021                          "#include <c>\n"; // Start of line: 26
1022   EXPECT_EQ(Expected, sort(Code));
1023   // Cursor on 'i' in "#include <a>".
1024   EXPECT_EQ(1u, newCursor(Code, 14));
1025   // Cursor on 'b' in "#include <b>".
1026   EXPECT_EQ(23u, newCursor(Code, 10));
1027   EXPECT_EQ(23u, newCursor(Code, 36));
1028   EXPECT_EQ(23u, newCursor(Code, 49));
1029   EXPECT_EQ(23u, newCursor(Code, 36));
1030   EXPECT_EQ(23u, newCursor(Code, 75));
1031   // Cursor on '#' in "#include <c>".
1032   EXPECT_EQ(26u, newCursor(Code, 52));
1033 }
1034 
1035 TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) {
1036   EXPECT_EQ("#include <a>\n"
1037             "#include <b>\n"
1038             "\n"
1039             "#include <b>\n"
1040             "#include <c>",
1041             sort("#include <a>\n"
1042                  "#include <b>\n"
1043                  "\n"
1044                  "#include <c>\n"
1045                  "#include <b>\n"
1046                  "#include <b>"));
1047 }
1048 
1049 TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) {
1050   std::string Code = "#include <a>\n"
1051                      "#include <b>\n"
1052                      "#include <a>\n"
1053                      "#include <a>\n"
1054                      "\n"
1055                      "   int     x ;";
1056   std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)};
1057   auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp");
1058   Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
1059   EXPECT_EQ(1u, Ranges.size());
1060   EXPECT_EQ(0u, Ranges[0].getOffset());
1061   EXPECT_EQ(26u, Ranges[0].getLength());
1062 }
1063 
1064 TEST_F(SortIncludesTest, DoNotSortLikelyXml) {
1065   EXPECT_EQ("<!--;\n"
1066             "#include <b>\n"
1067             "#include <a>\n"
1068             "-->",
1069             sort("<!--;\n"
1070                  "#include <b>\n"
1071                  "#include <a>\n"
1072                  "-->",
1073                  "input.h", 0));
1074 }
1075 
1076 TEST_F(SortIncludesTest, DoNotOutputReplacementsForSortedBlocksWithRegrouping) {
1077   Style.IncludeBlocks = Style.IBS_Regroup;
1078   std::string Code = R"(
1079 #include "b.h"
1080 
1081 #include <a.h>
1082 )";
1083   EXPECT_EQ(Code, sort(Code, "input.h", 0));
1084 }
1085 
1086 TEST_F(SortIncludesTest,
1087        DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows) {
1088   Style.IncludeBlocks = Style.IBS_Regroup;
1089   std::string Code = "#include \"b.h\"\r\n"
1090                      "\r\n"
1091                      "#include <a.h>\r\n";
1092   EXPECT_EQ(Code, sort(Code, "input.h", 0));
1093 }
1094 
1095 TEST_F(SortIncludesTest, MainIncludeChar) {
1096   std::string Code = "#include <a>\n"
1097                      "#include \"quote/input.h\"\n"
1098                      "#include <angle-bracket/input.h>\n";
1099 
1100   // Default behavior
1101   EXPECT_EQ("#include \"quote/input.h\"\n"
1102             "#include <a>\n"
1103             "#include <angle-bracket/input.h>\n",
1104             sort(Code, "input.cc", 1));
1105 
1106   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Quote;
1107   EXPECT_EQ("#include \"quote/input.h\"\n"
1108             "#include <a>\n"
1109             "#include <angle-bracket/input.h>\n",
1110             sort(Code, "input.cc", 1));
1111 
1112   Style.MainIncludeChar = tooling::IncludeStyle::MICD_AngleBracket;
1113   EXPECT_EQ("#include <angle-bracket/input.h>\n"
1114             "#include \"quote/input.h\"\n"
1115             "#include <a>\n",
1116             sort(Code, "input.cc", 1));
1117 }
1118 
1119 TEST_F(SortIncludesTest, MainIncludeCharAnyPickQuote) {
1120   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Any;
1121   EXPECT_EQ("#include \"input.h\"\n"
1122             "#include <a>\n"
1123             "#include <b>\n",
1124             sort("#include <a>\n"
1125                  "#include \"input.h\"\n"
1126                  "#include <b>\n",
1127                  "input.cc", 1));
1128 }
1129 
1130 TEST_F(SortIncludesTest, MainIncludeCharAnyPickAngleBracket) {
1131   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Any;
1132   EXPECT_EQ("#include <input.h>\n"
1133             "#include <a>\n"
1134             "#include <b>\n",
1135             sort("#include <a>\n"
1136                  "#include <input.h>\n"
1137                  "#include <b>\n",
1138                  "input.cc", 1));
1139 }
1140 
1141 TEST_F(SortIncludesTest, MainIncludeCharQuoteAndRegroup) {
1142   Style.IncludeCategories = {
1143       {"lib-a", 1, 0, false}, {"lib-b", 2, 0, false}, {"lib-c", 3, 0, false}};
1144   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1145   Style.MainIncludeChar = tooling::IncludeStyle::MICD_Quote;
1146 
1147   EXPECT_EQ("#include \"lib-b/input.h\"\n"
1148             "\n"
1149             "#include <lib-a/h-1.h>\n"
1150             "#include <lib-a/h-3.h>\n"
1151             "#include <lib-a/input.h>\n"
1152             "\n"
1153             "#include <lib-b/h-1.h>\n"
1154             "#include <lib-b/h-3.h>\n"
1155             "\n"
1156             "#include <lib-c/h-1.h>\n"
1157             "#include <lib-c/h-2.h>\n"
1158             "#include <lib-c/h-3.h>\n",
1159             sort("#include <lib-c/h-1.h>\n"
1160                  "#include <lib-c/h-2.h>\n"
1161                  "#include <lib-c/h-3.h>\n"
1162                  "#include <lib-b/h-1.h>\n"
1163                  "#include \"lib-b/input.h\"\n"
1164                  "#include <lib-b/h-3.h>\n"
1165                  "#include <lib-a/h-1.h>\n"
1166                  "#include <lib-a/input.h>\n"
1167                  "#include <lib-a/h-3.h>\n",
1168                  "input.cc"));
1169 }
1170 
1171 TEST_F(SortIncludesTest, MainIncludeCharAngleBracketAndRegroup) {
1172   Style.IncludeCategories = {
1173       {"lib-a", 1, 0, false}, {"lib-b", 2, 0, false}, {"lib-c", 3, 0, false}};
1174   Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
1175   Style.MainIncludeChar = tooling::IncludeStyle::MICD_AngleBracket;
1176 
1177   EXPECT_EQ("#include <lib-a/input.h>\n"
1178             "\n"
1179             "#include <lib-a/h-1.h>\n"
1180             "#include <lib-a/h-3.h>\n"
1181             "\n"
1182             "#include \"lib-b/input.h\"\n"
1183             "#include <lib-b/h-1.h>\n"
1184             "#include <lib-b/h-3.h>\n"
1185             "\n"
1186             "#include <lib-c/h-1.h>\n"
1187             "#include <lib-c/h-2.h>\n"
1188             "#include <lib-c/h-3.h>\n",
1189             sort("#include <lib-c/h-1.h>\n"
1190                  "#include <lib-c/h-2.h>\n"
1191                  "#include <lib-c/h-3.h>\n"
1192                  "#include <lib-b/h-1.h>\n"
1193                  "#include \"lib-b/input.h\"\n"
1194                  "#include <lib-b/h-3.h>\n"
1195                  "#include <lib-a/h-1.h>\n"
1196                  "#include <lib-a/input.h>\n"
1197                  "#include <lib-a/h-3.h>\n",
1198                  "input.cc"));
1199 }
1200 
1201 TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) {
1202   FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC);
1203 
1204   EXPECT_EQ("#include <a.h>\n"
1205             "#include <b.h>\n"
1206             "#include \"a.h\"",
1207             sort("#include <b.h>\n"
1208                  "#include <a.h>\n"
1209                  "#include \"a.h\""));
1210 }
1211 
1212 TEST_F(SortIncludesTest, DoNotTreatPrecompiledHeadersAsFirstBlock) {
1213   Style.IncludeBlocks = Style.IBS_Merge;
1214   std::string Code = "#include \"d.h\"\r\n"
1215                      "#include \"b.h\"\r\n"
1216                      "#pragma hdrstop\r\n"
1217                      "\r\n"
1218                      "#include \"c.h\"\r\n"
1219                      "#include \"a.h\"\r\n"
1220                      "#include \"e.h\"\r\n";
1221 
1222   std::string Expected = "#include \"b.h\"\r\n"
1223                          "#include \"d.h\"\r\n"
1224                          "#pragma hdrstop\r\n"
1225                          "\r\n"
1226                          "#include \"e.h\"\r\n"
1227                          "#include \"a.h\"\r\n"
1228                          "#include \"c.h\"\r\n";
1229 
1230   EXPECT_EQ(Expected, sort(Code, "e.cpp", 2));
1231 
1232   Code = "#include \"d.h\"\n"
1233          "#include \"b.h\"\n"
1234          "#pragma hdrstop( \"c:\\projects\\include\\myinc.pch\" )\n"
1235          "\n"
1236          "#include \"c.h\"\n"
1237          "#include \"a.h\"\n"
1238          "#include \"e.h\"\n";
1239 
1240   Expected = "#include \"b.h\"\n"
1241              "#include \"d.h\"\n"
1242              "#pragma hdrstop(\"c:\\projects\\include\\myinc.pch\")\n"
1243              "\n"
1244              "#include \"e.h\"\n"
1245              "#include \"a.h\"\n"
1246              "#include \"c.h\"\n";
1247 
1248   EXPECT_EQ(Expected, sort(Code, "e.cpp", 2));
1249 }
1250 
1251 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkMerge) {
1252   Style.IncludeBlocks = Style.IBS_Merge;
1253   std::string Code = "\xEF\xBB\xBF#include \"d.h\"\r\n"
1254                      "#include \"b.h\"\r\n"
1255                      "\r\n"
1256                      "#include \"c.h\"\r\n"
1257                      "#include \"a.h\"\r\n"
1258                      "#include \"e.h\"\r\n";
1259 
1260   std::string Expected = "\xEF\xBB\xBF#include \"e.h\"\r\n"
1261                          "#include \"a.h\"\r\n"
1262                          "#include \"b.h\"\r\n"
1263                          "#include \"c.h\"\r\n"
1264                          "#include \"d.h\"\r\n";
1265 
1266   EXPECT_EQ(Expected, sort(Code, "e.cpp", 1));
1267 }
1268 
1269 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkPreserve) {
1270   Style.IncludeBlocks = Style.IBS_Preserve;
1271   std::string Code = "\xEF\xBB\xBF#include \"d.h\"\r\n"
1272                      "#include \"b.h\"\r\n"
1273                      "\r\n"
1274                      "#include \"c.h\"\r\n"
1275                      "#include \"a.h\"\r\n"
1276                      "#include \"e.h\"\r\n";
1277 
1278   std::string Expected = "\xEF\xBB\xBF#include \"b.h\"\r\n"
1279                          "#include \"d.h\"\r\n"
1280                          "\r\n"
1281                          "#include \"a.h\"\r\n"
1282                          "#include \"c.h\"\r\n"
1283                          "#include \"e.h\"\r\n";
1284 
1285   EXPECT_EQ(Expected, sort(Code, "e.cpp", 2));
1286 }
1287 
1288 TEST_F(SortIncludesTest, MergeLines) {
1289   Style.IncludeBlocks = Style.IBS_Merge;
1290   std::string Code = "#include \"c.h\"\r\n"
1291                      "#include \"b\\\r\n"
1292                      ".h\"\r\n"
1293                      "#include \"a.h\"\r\n";
1294 
1295   std::string Expected = "#include \"a.h\"\r\n"
1296                          "#include \"b\\\r\n"
1297                          ".h\"\r\n"
1298                          "#include \"c.h\"\r\n";
1299 
1300   EXPECT_EQ(Expected, sort(Code, "a.cpp", 1));
1301 }
1302 
1303 TEST_F(SortIncludesTest, DisableFormatDisablesIncludeSorting) {
1304   StringRef Sorted = "#include <a.h>\n"
1305                      "#include <b.h>\n";
1306   StringRef Unsorted = "#include <b.h>\n"
1307                        "#include <a.h>\n";
1308   EXPECT_EQ(Sorted, sort(Unsorted));
1309   FmtStyle.DisableFormat = true;
1310   EXPECT_EQ(Unsorted, sort(Unsorted, "input.cpp", 0));
1311 }
1312 
1313 TEST_F(SortIncludesTest, DisableRawStringLiteralSorting) {
1314 
1315   EXPECT_EQ("const char *t = R\"(\n"
1316             "#include <b.h>\n"
1317             "#include <a.h>\n"
1318             ")\";",
1319             sort("const char *t = R\"(\n"
1320                  "#include <b.h>\n"
1321                  "#include <a.h>\n"
1322                  ")\";",
1323                  "test.cxx", 0));
1324   EXPECT_EQ("const char *t = R\"x(\n"
1325             "#include <b.h>\n"
1326             "#include <a.h>\n"
1327             ")x\";",
1328             sort("const char *t = R\"x(\n"
1329                  "#include <b.h>\n"
1330                  "#include <a.h>\n"
1331                  ")x\";",
1332                  "test.cxx", 0));
1333   EXPECT_EQ("const char *t = R\"xyz(\n"
1334             "#include <b.h>\n"
1335             "#include <a.h>\n"
1336             ")xyz\";",
1337             sort("const char *t = R\"xyz(\n"
1338                  "#include <b.h>\n"
1339                  "#include <a.h>\n"
1340                  ")xyz\";",
1341                  "test.cxx", 0));
1342 
1343   EXPECT_EQ("#include <a.h>\n"
1344             "#include <b.h>\n"
1345             "const char *t = R\"(\n"
1346             "#include <b.h>\n"
1347             "#include <a.h>\n"
1348             ")\";\n"
1349             "#include <c.h>\n"
1350             "#include <d.h>\n"
1351             "const char *t = R\"x(\n"
1352             "#include <f.h>\n"
1353             "#include <e.h>\n"
1354             ")x\";\n"
1355             "#include <g.h>\n"
1356             "#include <h.h>\n"
1357             "const char *t = R\"xyz(\n"
1358             "#include <j.h>\n"
1359             "#include <i.h>\n"
1360             ")xyz\";\n"
1361             "#include <k.h>\n"
1362             "#include <l.h>",
1363             sort("#include <b.h>\n"
1364                  "#include <a.h>\n"
1365                  "const char *t = R\"(\n"
1366                  "#include <b.h>\n"
1367                  "#include <a.h>\n"
1368                  ")\";\n"
1369                  "#include <d.h>\n"
1370                  "#include <c.h>\n"
1371                  "const char *t = R\"x(\n"
1372                  "#include <f.h>\n"
1373                  "#include <e.h>\n"
1374                  ")x\";\n"
1375                  "#include <h.h>\n"
1376                  "#include <g.h>\n"
1377                  "const char *t = R\"xyz(\n"
1378                  "#include <j.h>\n"
1379                  "#include <i.h>\n"
1380                  ")xyz\";\n"
1381                  "#include <l.h>\n"
1382                  "#include <k.h>",
1383                  "test.cc", 4));
1384 
1385   EXPECT_EQ("const char *t = R\"AMZ029amz(\n"
1386             "#include <b.h>\n"
1387             "#include <a.h>\n"
1388             ")AMZ029amz\";",
1389             sort("const char *t = R\"AMZ029amz(\n"
1390                  "#include <b.h>\n"
1391                  "#include <a.h>\n"
1392                  ")AMZ029amz\";",
1393                  "test.cxx", 0));
1394 
1395   EXPECT_EQ("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   EXPECT_EQ("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   EXPECT_EQ("const char *t = R\"AM|029amz-(\n"
1416             "#include <b.h>\n"
1417             "#include <a.h>\n"
1418             ")AM|029amz-\";",
1419             sort("const char *t = R\"AM|029amz-(\n"
1420                  "#include <b.h>\n"
1421                  "#include <a.h>\n"
1422                  ")AM|029amz-\";",
1423                  "test.cxx", 0));
1424 
1425   EXPECT_EQ("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   EXPECT_EQ("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 #define X "AMZ029amz{}+!%*=_:;',.<>|/?#~-$"
1446 
1447   EXPECT_EQ("const char *t = R\"" X "(\n"
1448             "#include <b.h>\n"
1449             "#include <a.h>\n"
1450             ")" X "\";",
1451             sort("const char *t = R\"" X "(\n"
1452                  "#include <b.h>\n"
1453                  "#include <a.h>\n"
1454                  ")" X "\";",
1455                  "test.cxx", 0));
1456 
1457 #undef X
1458 }
1459 
1460 } // end namespace
1461 } // end namespace format
1462 } // end namespace clang
1463