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