Clang Project

clang_source_code/unittests/Format/SortIncludesTest.cpp
1//===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "FormatTestUtils.h"
10#include "clang/Format/Format.h"
11#include "llvm/Support/Debug.h"
12#include "gtest/gtest.h"
13
14#define DEBUG_TYPE "format-test"
15
16namespace clang {
17namespace format {
18namespace {
19
20class SortIncludesTest : public ::testing::Test {
21protected:
22  std::vector<tooling::Range> GetCodeRange(StringRef Code) {
23    return std::vector<tooling::Range>(1, tooling::Range(0, Code.size()));
24  }
25
26  std::string sort(StringRef Code, std::vector<tooling::Range> Ranges,
27                   StringRef FileName = "input.cc") {
28    auto Replaces = sortIncludes(FmtStyle, Code, Ranges, FileName);
29    Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
30    auto Sorted = applyAllReplacements(Code, Replaces);
31    EXPECT_TRUE(static_cast<bool>(Sorted));
32    auto Result = applyAllReplacements(
33        *Sorted, reformat(FmtStyle, *Sorted, Ranges, FileName));
34    EXPECT_TRUE(static_cast<bool>(Result));
35    return *Result;
36  }
37
38  std::string sort(StringRef Code, StringRef FileName = "input.cpp") {
39    return sort(Code, GetCodeRange(Code), FileName);
40  }
41
42  unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
43    sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.cpp", &Cursor);
44    return Cursor;
45  }
46
47  FormatStyle FmtStyle = getLLVMStyle();
48  tooling::IncludeStyle &Style = FmtStyle.IncludeStyle;
49};
50
51TEST_F(SortIncludesTest, BasicSorting) {
52  EXPECT_EQ("#include \"a.h\"\n"
53            "#include \"b.h\"\n"
54            "#include \"c.h\"\n",
55            sort("#include \"a.h\"\n"
56                 "#include \"c.h\"\n"
57                 "#include \"b.h\"\n"));
58
59  EXPECT_EQ("// comment\n"
60            "#include <a>\n"
61            "#include <b>\n",
62            sort("// comment\n"
63                 "#include <b>\n"
64                 "#include <a>\n",
65                 {tooling::Range(25, 1)}));
66}
67
68TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
69  // Identical #includes have led to a failure with an unstable sort.
70  std::string Code = "#include <a>\n"
71                     "#include <b>\n"
72                     "#include <c>\n"
73                     "#include <d>\n"
74                     "#include <e>\n"
75                     "#include <f>\n";
76  EXPECT_TRUE(sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a.cc").empty());
77}
78
79TEST_F(SortIncludesTest, SortedIncludesInMultipleBlocksAreMerged) {
80  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
81  EXPECT_EQ("#include \"a.h\"\n"
82            "#include \"b.h\"\n"
83            "#include \"c.h\"\n",
84            sort("#include \"a.h\"\n"
85                 "#include \"c.h\"\n"
86                 "\n"
87                 "\n"
88                 "#include \"b.h\"\n"));
89
90  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
91  EXPECT_EQ("#include \"a.h\"\n"
92            "#include \"b.h\"\n"
93            "#include \"c.h\"\n",
94            sort("#include \"a.h\"\n"
95                 "#include \"c.h\"\n"
96                 "\n"
97                 "\n"
98                 "#include \"b.h\"\n"));
99}
100
101TEST_F(SortIncludesTest, SupportClangFormatOff) {
102  EXPECT_EQ("#include <a>\n"
103            "#include <b>\n"
104            "#include <c>\n"
105            "// clang-format off\n"
106            "#include <b>\n"
107            "#include <a>\n"
108            "#include <c>\n"
109            "// clang-format on\n",
110            sort("#include <b>\n"
111                 "#include <a>\n"
112                 "#include <c>\n"
113                 "// clang-format off\n"
114                 "#include <b>\n"
115                 "#include <a>\n"
116                 "#include <c>\n"
117                 "// clang-format on\n"));
118}
119
120TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) {
121  EXPECT_EQ("#include <a>\n"
122            "#include <b>\n"
123            "#include <c>\n"
124            "/* clang-format off */\n"
125            "#include <b>\n"
126            "#include <a>\n"
127            "#include <c>\n"
128            "/* clang-format on */\n",
129            sort("#include <b>\n"
130                 "#include <a>\n"
131                 "#include <c>\n"
132                 "/* clang-format off */\n"
133                 "#include <b>\n"
134                 "#include <a>\n"
135                 "#include <c>\n"
136                 "/* clang-format on */\n"));
137
138  // Not really turning it off
139  EXPECT_EQ("#include <a>\n"
140            "#include <b>\n"
141            "#include <c>\n"
142            "/* clang-format offically */\n"
143            "#include <a>\n"
144            "#include <b>\n"
145            "#include <c>\n"
146            "/* clang-format onwards */\n",
147            sort("#include <b>\n"
148                 "#include <a>\n"
149                 "#include <c>\n"
150                 "/* clang-format offically */\n"
151                 "#include <b>\n"
152                 "#include <a>\n"
153                 "#include <c>\n"
154                 "/* clang-format onwards */\n"));
155}
156
157TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
158  FmtStyle.SortIncludes = false;
159  EXPECT_EQ("#include \"a.h\"\n"
160            "#include \"c.h\"\n"
161            "#include \"b.h\"\n",
162            sort("#include \"a.h\"\n"
163                 "#include \"c.h\"\n"
164                 "#include \"b.h\"\n"));
165}
166
167TEST_F(SortIncludesTest, MixIncludeAndImport) {
168  EXPECT_EQ("#include \"a.h\"\n"
169            "#import \"b.h\"\n"
170            "#include \"c.h\"\n",
171            sort("#include \"a.h\"\n"
172                 "#include \"c.h\"\n"
173                 "#import \"b.h\"\n"));
174}
175
176TEST_F(SortIncludesTest, FixTrailingComments) {
177  EXPECT_EQ("#include \"a.h\"  // comment\n"
178            "#include \"bb.h\" // comment\n"
179            "#include \"ccc.h\"\n",
180            sort("#include \"a.h\" // comment\n"
181                 "#include \"ccc.h\"\n"
182                 "#include \"bb.h\" // comment\n"));
183}
184
185TEST_F(SortIncludesTest, LeadingWhitespace) {
186  EXPECT_EQ("#include \"a.h\"\n"
187            "#include \"b.h\"\n"
188            "#include \"c.h\"\n",
189            sort(" #include \"a.h\"\n"
190                 "  #include \"c.h\"\n"
191                 "   #include \"b.h\"\n"));
192  EXPECT_EQ("#include \"a.h\"\n"
193            "#include \"b.h\"\n"
194            "#include \"c.h\"\n",
195            sort("# include \"a.h\"\n"
196                 "#  include \"c.h\"\n"
197                 "#   include \"b.h\"\n"));
198}
199
200TEST_F(SortIncludesTest, GreaterInComment) {
201  EXPECT_EQ("#include \"a.h\"\n"
202            "#include \"b.h\" // >\n"
203            "#include \"c.h\"\n",
204            sort("#include \"a.h\"\n"
205                 "#include \"c.h\"\n"
206                 "#include \"b.h\" // >\n"));
207}
208
209TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
210  EXPECT_EQ("#include \"a.h\"\n"
211            "#include \"c.h\"\n"
212            "\n"
213            "#include \"b.h\"\n",
214            sort("#include \"a.h\"\n"
215                 "#include \"c.h\"\n"
216                 "\n"
217                 "#include \"b.h\"\n"));
218}
219
220TEST_F(SortIncludesTest, SortsAllBlocksWhenMerging) {
221  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
222  EXPECT_EQ("#include \"a.h\"\n"
223            "#include \"b.h\"\n"
224            "#include \"c.h\"\n",
225            sort("#include \"a.h\"\n"
226                 "#include \"c.h\"\n"
227                 "\n"
228                 "#include \"b.h\"\n"));
229}
230
231TEST_F(SortIncludesTest, CommentsAlwaysSeparateGroups) {
232  EXPECT_EQ("#include \"a.h\"\n"
233            "#include \"c.h\"\n"
234            "// comment\n"
235            "#include \"b.h\"\n",
236            sort("#include \"c.h\"\n"
237                 "#include \"a.h\"\n"
238                 "// comment\n"
239                 "#include \"b.h\"\n"));
240
241  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
242  EXPECT_EQ("#include \"a.h\"\n"
243            "#include \"c.h\"\n"
244            "// comment\n"
245            "#include \"b.h\"\n",
246            sort("#include \"c.h\"\n"
247                 "#include \"a.h\"\n"
248                 "// comment\n"
249                 "#include \"b.h\"\n"));
250
251  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
252  EXPECT_EQ("#include \"a.h\"\n"
253            "#include \"c.h\"\n"
254            "// comment\n"
255            "#include \"b.h\"\n",
256            sort("#include \"c.h\"\n"
257                 "#include \"a.h\"\n"
258                 "// comment\n"
259                 "#include \"b.h\"\n"));
260}
261
262TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
263  EXPECT_EQ("#include \"a.h\"\n"
264            "#include \"c.h\"\n"
265            "#include <b.h>\n"
266            "#include <d.h>\n",
267            sort("#include <d.h>\n"
268                 "#include <b.h>\n"
269                 "#include \"c.h\"\n"
270                 "#include \"a.h\"\n"));
271
272  FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp);
273  EXPECT_EQ("#include <b.h>\n"
274            "#include <d.h>\n"
275            "#include \"a.h\"\n"
276            "#include \"c.h\"\n",
277            sort("#include <d.h>\n"
278                 "#include <b.h>\n"
279                 "#include \"c.h\"\n"
280                 "#include \"a.h\"\n"));
281}
282
283TEST_F(SortIncludesTest, RegroupsAngledIncludesInSeparateBlocks) {
284  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
285  EXPECT_EQ("#include \"a.h\"\n"
286            "#include \"c.h\"\n"
287            "\n"
288            "#include <b.h>\n"
289            "#include <d.h>\n",
290            sort("#include <d.h>\n"
291                 "#include <b.h>\n"
292                 "#include \"c.h\"\n"
293                 "#include \"a.h\"\n"));
294}
295
296TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
297  EXPECT_EQ("#include \"a.h\"\n"
298            "#include \"b.h\"\n"
299            "#include \"c.h\"\n",
300            sort("#include \"a.h\"\n"
301                 "#include \\\n"
302                 "\"c.h\"\n"
303                 "#include \"b.h\"\n"));
304}
305
306TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
307  Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
308  EXPECT_EQ("#include \"llvm/a.h\"\n"
309            "#include \"b.h\"\n"
310            "#include \"c.h\"\n",
311            sort("#include \"llvm/a.h\"\n"
312                 "#include \"c.h\"\n"
313                 "#include \"b.h\"\n",
314                 "a.cc"));
315  EXPECT_EQ("#include \"llvm/a.h\"\n"
316            "#include \"b.h\"\n"
317            "#include \"c.h\"\n",
318            sort("#include \"llvm/a.h\"\n"
319                 "#include \"c.h\"\n"
320                 "#include \"b.h\"\n",
321                 "a_test.cc"));
322  EXPECT_EQ("#include \"llvm/input.h\"\n"
323            "#include \"b.h\"\n"
324            "#include \"c.h\"\n",
325            sort("#include \"llvm/input.h\"\n"
326                 "#include \"c.h\"\n"
327                 "#include \"b.h\"\n",
328                 "input.mm"));
329
330  // Don't allow prefixes.
331  EXPECT_EQ("#include \"b.h\"\n"
332            "#include \"c.h\"\n"
333            "#include \"llvm/not_a.h\"\n",
334            sort("#include \"llvm/not_a.h\"\n"
335                 "#include \"c.h\"\n"
336                 "#include \"b.h\"\n",
337                 "a.cc"));
338
339  // Don't do this for _main and other suffixes.
340  EXPECT_EQ("#include \"b.h\"\n"
341            "#include \"c.h\"\n"
342            "#include \"llvm/a.h\"\n",
343            sort("#include \"llvm/a.h\"\n"
344                 "#include \"c.h\"\n"
345                 "#include \"b.h\"\n",
346                 "a_main.cc"));
347
348  // Don't do this in headers.
349  EXPECT_EQ("#include \"b.h\"\n"
350            "#include \"c.h\"\n"
351            "#include \"llvm/a.h\"\n",
352            sort("#include \"llvm/a.h\"\n"
353                 "#include \"c.h\"\n"
354                 "#include \"b.h\"\n",
355                 "a.h"));
356
357  // Only do this in the first #include block.
358  EXPECT_EQ("#include <a>\n"
359            "\n"
360            "#include \"b.h\"\n"
361            "#include \"c.h\"\n"
362            "#include \"llvm/a.h\"\n",
363            sort("#include <a>\n"
364                 "\n"
365                 "#include \"llvm/a.h\"\n"
366                 "#include \"c.h\"\n"
367                 "#include \"b.h\"\n",
368                 "a.cc"));
369
370  // Only recognize the first #include with a matching basename as main include.
371  EXPECT_EQ("#include \"a.h\"\n"
372            "#include \"b.h\"\n"
373            "#include \"c.h\"\n"
374            "#include \"llvm/a.h\"\n",
375            sort("#include \"b.h\"\n"
376                 "#include \"a.h\"\n"
377                 "#include \"c.h\"\n"
378                 "#include \"llvm/a.h\"\n",
379                 "a.cc"));
380}
381
382TEST_F(SortIncludesTest, RecognizeMainHeaderInAllGroups) {
383  Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
384  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
385
386  EXPECT_EQ("#include \"c.h\"\n"
387            "#include \"a.h\"\n"
388            "#include \"b.h\"\n",
389            sort("#include \"b.h\"\n"
390                 "\n"
391                 "#include \"a.h\"\n"
392                 "#include \"c.h\"\n",
393                 "c.cc"));
394}
395
396TEST_F(SortIncludesTest, MainHeaderIsSeparatedWhenRegroupping) {
397  Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
398  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
399
400  EXPECT_EQ("#include \"a.h\"\n"
401            "\n"
402            "#include \"b.h\"\n"
403            "#include \"c.h\"\n",
404            sort("#include \"b.h\"\n"
405                 "\n"
406                 "#include \"a.h\"\n"
407                 "#include \"c.h\"\n",
408                 "a.cc"));
409}
410
411TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) {
412  // Setup an regex for main includes so we can cover those as well.
413  Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
414
415  // Ensure both main header detection and grouping work in a case insensitive
416  // manner.
417  EXPECT_EQ("#include \"llvm/A.h\"\n"
418            "#include \"b.h\"\n"
419            "#include \"c.h\"\n"
420            "#include \"LLVM/z.h\"\n"
421            "#include \"llvm/X.h\"\n"
422            "#include \"GTest/GTest.h\"\n"
423            "#include \"gmock/gmock.h\"\n",
424            sort("#include \"c.h\"\n"
425                 "#include \"b.h\"\n"
426                 "#include \"GTest/GTest.h\"\n"
427                 "#include \"llvm/A.h\"\n"
428                 "#include \"gmock/gmock.h\"\n"
429                 "#include \"llvm/X.h\"\n"
430                 "#include \"LLVM/z.h\"\n",
431                 "a_TEST.cc"));
432}
433
434TEST_F(SortIncludesTest, NegativePriorities) {
435  Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
436  EXPECT_EQ("#include \"important_os_header.h\"\n"
437            "#include \"c_main.h\"\n"
438            "#include \"a_other.h\"\n",
439            sort("#include \"c_main.h\"\n"
440                 "#include \"a_other.h\"\n"
441                 "#include \"important_os_header.h\"\n",
442                 "c_main.cc"));
443
444  // check stable when re-run
445  EXPECT_EQ("#include \"important_os_header.h\"\n"
446            "#include \"c_main.h\"\n"
447            "#include \"a_other.h\"\n",
448            sort("#include \"important_os_header.h\"\n"
449                 "#include \"c_main.h\"\n"
450                 "#include \"a_other.h\"\n",
451                 "c_main.cc"));
452}
453
454TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) {
455  Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
456  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
457
458  EXPECT_EQ("#include \"important_os_header.h\"\n"
459            "\n"
460            "#include \"c_main.h\"\n"
461            "\n"
462            "#include \"a_other.h\"\n",
463            sort("#include \"c_main.h\"\n"
464                 "#include \"a_other.h\"\n"
465                 "#include \"important_os_header.h\"\n",
466                 "c_main.cc"));
467
468  // check stable when re-run
469  EXPECT_EQ("#include \"important_os_header.h\"\n"
470            "\n"
471            "#include \"c_main.h\"\n"
472            "\n"
473            "#include \"a_other.h\"\n",
474            sort("#include \"important_os_header.h\"\n"
475                 "\n"
476                 "#include \"c_main.h\"\n"
477                 "\n"
478                 "#include \"a_other.h\"\n",
479                 "c_main.cc"));
480}
481
482TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
483  std::string Code = "#include <ccc>\n"    // Start of line: 0
484                     "#include <bbbbbb>\n" // Start of line: 15
485                     "#include <a>\n";     // Start of line: 33
486  EXPECT_EQ(31u, newCursor(Code, 0));
487  EXPECT_EQ(13u, newCursor(Code, 15));
488  EXPECT_EQ(0u, newCursor(Code, 33));
489
490  EXPECT_EQ(41u, newCursor(Code, 10));
491  EXPECT_EQ(23u, newCursor(Code, 25));
492  EXPECT_EQ(10u, newCursor(Code, 43));
493}
494
495TEST_F(SortIncludesTest, DeduplicateIncludes) {
496  EXPECT_EQ("#include <a>\n"
497            "#include <b>\n"
498            "#include <c>\n",
499            sort("#include <a>\n"
500                 "#include <b>\n"
501                 "#include <b>\n"
502                 "#include <b>\n"
503                 "#include <b>\n"
504                 "#include <c>\n"));
505
506  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
507  EXPECT_EQ("#include <a>\n"
508            "#include <b>\n"
509            "#include <c>\n",
510            sort("#include <a>\n"
511                 "#include <b>\n"
512                 "\n"
513                 "#include <b>\n"
514                 "\n"
515                 "#include <b>\n"
516                 "#include <c>\n"));
517
518  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
519  EXPECT_EQ("#include <a>\n"
520            "#include <b>\n"
521            "#include <c>\n",
522            sort("#include <a>\n"
523                 "#include <b>\n"
524                 "\n"
525                 "#include <b>\n"
526                 "\n"
527                 "#include <b>\n"
528                 "#include <c>\n"));
529}
530
531TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) {
532  EXPECT_EQ("#include <a>\n"
533            "#include <b>\n"
534            "#include <c>\n",
535            sort("#include <b>\n"
536                 "#include <a>\n"
537                 "#include <b>\n"
538                 "#include <b>\n"
539                 "#include <c>\n"
540                 "#include <b>\n"));
541
542  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge;
543  EXPECT_EQ("#include <a>\n"
544            "#include <b>\n"
545            "#include <c>\n",
546            sort("#include <b>\n"
547                 "#include <a>\n"
548                 "\n"
549                 "#include <b>\n"
550                 "\n"
551                 "#include <c>\n"
552                 "#include <b>\n"));
553
554  Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
555  EXPECT_EQ("#include <a>\n"
556            "#include <b>\n"
557            "#include <c>\n",
558            sort("#include <b>\n"
559                 "#include <a>\n"
560                 "\n"
561                 "#include <b>\n"
562                 "\n"
563                 "#include <c>\n"
564                 "#include <b>\n"));
565}
566
567TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) {
568  std::string Code = "#include <b>\n"      // Start of line: 0
569                     "#include <a>\n"      // Start of line: 13
570                     "#include <b>\n"      // Start of line: 26
571                     "#include <b>\n"      // Start of line: 39
572                     "#include <c>\n"      // Start of line: 52
573                     "#include <b>\n";     // Start of line: 65
574  std::string Expected = "#include <a>\n"  // Start of line: 0
575                         "#include <b>\n"  // Start of line: 13
576                         "#include <c>\n"; // Start of line: 26
577  EXPECT_EQ(Expected, sort(Code));
578  // Cursor on 'i' in "#include <a>".
579  EXPECT_EQ(1u, newCursor(Code, 14));
580  // Cursor on 'b' in "#include <b>".
581  EXPECT_EQ(23u, newCursor(Code, 10));
582  EXPECT_EQ(23u, newCursor(Code, 36));
583  EXPECT_EQ(23u, newCursor(Code, 49));
584  EXPECT_EQ(23u, newCursor(Code, 36));
585  EXPECT_EQ(23u, newCursor(Code, 75));
586  // Cursor on '#' in "#include <c>".
587  EXPECT_EQ(26u, newCursor(Code, 52));
588}
589
590TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) {
591  EXPECT_EQ("#include <a>\n"
592            "#include <b>\n"
593            "\n"
594            "#include <b>\n"
595            "#include <c>\n",
596            sort("#include <a>\n"
597                 "#include <b>\n"
598                 "\n"
599                 "#include <c>\n"
600                 "#include <b>\n"
601                 "#include <b>\n"));
602}
603
604TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) {
605  std::string Code = "#include <a>\n"
606                     "#include <b>\n"
607                     "#include <a>\n"
608                     "#include <a>\n"
609                     "\n"
610                     "   int     x ;";
611  std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)};
612  auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp");
613  Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges);
614  EXPECT_EQ(1u, Ranges.size());
615  EXPECT_EQ(0u, Ranges[0].getOffset());
616  EXPECT_EQ(26u, Ranges[0].getLength());
617}
618
619TEST_F(SortIncludesTest, DoNotSortLikelyXml) {
620  EXPECT_EQ("<!--;\n"
621            "#include <b>\n"
622            "#include <a>\n"
623            "-->",
624            sort("<!--;\n"
625                 "#include <b>\n"
626                 "#include <a>\n"
627                 "-->"));
628}
629
630} // end namespace
631} // end namespace format
632} // end namespace clang
633