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::string sort(llvm::StringRef Code, StringRef FileName = "input.cpp") {
24     std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
25     std::string Sorted =
26         applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName));
27     return applyAllReplacements(Sorted,
28                                 reformat(Style, Sorted, Ranges, FileName));
29   }
30 
31   unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
32     std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size()));
33     sortIncludes(Style, Code, Ranges, "input.cpp", &Cursor);
34     return Cursor;
35   }
36 
37   FormatStyle Style = getLLVMStyle();
38 
39 };
40 
41 TEST_F(SortIncludesTest, BasicSorting) {
42   EXPECT_EQ("#include \"a.h\"\n"
43             "#include \"b.h\"\n"
44             "#include \"c.h\"\n",
45             sort("#include \"a.h\"\n"
46                  "#include \"c.h\"\n"
47                  "#include \"b.h\"\n"));
48 }
49 
50 TEST_F(SortIncludesTest, SupportClangFormatOff) {
51   EXPECT_EQ("#include <a>\n"
52             "#include <b>\n"
53             "#include <c>\n"
54             "// clang-format off\n"
55             "#include <b>\n"
56             "#include <a>\n"
57             "#include <c>\n"
58             "// clang-format on\n",
59             sort("#include <b>\n"
60                  "#include <a>\n"
61                  "#include <c>\n"
62                  "// clang-format off\n"
63                  "#include <b>\n"
64                  "#include <a>\n"
65                  "#include <c>\n"
66                  "// clang-format on\n"));
67 }
68 
69 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
70   Style.SortIncludes = false;
71   EXPECT_EQ("#include \"a.h\"\n"
72             "#include \"c.h\"\n"
73             "#include \"b.h\"\n",
74             sort("#include \"a.h\"\n"
75                  "#include \"c.h\"\n"
76                  "#include \"b.h\"\n"));
77 }
78 
79 TEST_F(SortIncludesTest, MixIncludeAndImport) {
80   EXPECT_EQ("#include \"a.h\"\n"
81             "#import \"b.h\"\n"
82             "#include \"c.h\"\n",
83             sort("#include \"a.h\"\n"
84                  "#include \"c.h\"\n"
85                  "#import \"b.h\"\n"));
86 }
87 
88 TEST_F(SortIncludesTest, FixTrailingComments) {
89   EXPECT_EQ("#include \"a.h\"  // comment\n"
90             "#include \"bb.h\" // comment\n"
91             "#include \"ccc.h\"\n",
92             sort("#include \"a.h\" // comment\n"
93                  "#include \"ccc.h\"\n"
94                  "#include \"bb.h\" // comment\n"));
95 }
96 
97 TEST_F(SortIncludesTest, LeadingWhitespace) {
98   EXPECT_EQ("#include \"a.h\"\n"
99             "#include \"b.h\"\n"
100             "#include \"c.h\"\n",
101             sort(" #include \"a.h\"\n"
102                  "  #include \"c.h\"\n"
103                  "   #include \"b.h\"\n"));
104   EXPECT_EQ("#include \"a.h\"\n"
105             "#include \"b.h\"\n"
106             "#include \"c.h\"\n",
107             sort("# include \"a.h\"\n"
108                  "#  include \"c.h\"\n"
109                  "#   include \"b.h\"\n"));
110 }
111 
112 TEST_F(SortIncludesTest, GreaterInComment) {
113   EXPECT_EQ("#include \"a.h\"\n"
114             "#include \"b.h\" // >\n"
115             "#include \"c.h\"\n",
116             sort("#include \"a.h\"\n"
117                  "#include \"c.h\"\n"
118                  "#include \"b.h\" // >\n"));
119 }
120 
121 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
122   EXPECT_EQ("#include \"a.h\"\n"
123             "#include \"c.h\"\n"
124             "\n"
125             "#include \"b.h\"\n",
126             sort("#include \"a.h\"\n"
127                  "#include \"c.h\"\n"
128                  "\n"
129                  "#include \"b.h\"\n"));
130 }
131 
132 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
133   EXPECT_EQ("#include \"a.h\"\n"
134             "#include \"c.h\"\n"
135             "#include <b.h>\n"
136             "#include <d.h>\n",
137             sort("#include <d.h>\n"
138                  "#include <b.h>\n"
139                  "#include \"c.h\"\n"
140                  "#include \"a.h\"\n"));
141 
142   Style = getGoogleStyle(FormatStyle::LK_Cpp);
143   EXPECT_EQ("#include <b.h>\n"
144             "#include <d.h>\n"
145             "#include \"a.h\"\n"
146             "#include \"c.h\"\n",
147             sort("#include <d.h>\n"
148                  "#include <b.h>\n"
149                  "#include \"c.h\"\n"
150                  "#include \"a.h\"\n"));
151 }
152 
153 TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
154   EXPECT_EQ("#include \"a.h\"\n"
155             "#include \"b.h\"\n"
156             "#include \"c.h\"\n",
157             sort("#include \"a.h\"\n"
158                  "#include \\\n"
159                  "\"c.h\"\n"
160                  "#include \"b.h\"\n"));
161 }
162 
163 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
164   EXPECT_EQ("#include \"llvm/a.h\"\n"
165             "#include \"b.h\"\n"
166             "#include \"c.h\"\n",
167             sort("#include \"llvm/a.h\"\n"
168                  "#include \"c.h\"\n"
169                  "#include \"b.h\"\n"));
170   EXPECT_EQ("#include \"llvm/a.h\"\n"
171             "#include \"b.h\"\n"
172             "#include \"c.h\"\n",
173             sort("#include \"llvm/a.h\"\n"
174                  "#include \"c.h\"\n"
175                  "#include \"b.h\"\n",
176                  "input.mm"));
177 
178   // Don't do this in headers.
179   EXPECT_EQ("#include \"b.h\"\n"
180             "#include \"c.h\"\n"
181             "#include \"llvm/a.h\"\n",
182             sort("#include \"llvm/a.h\"\n"
183                  "#include \"c.h\"\n"
184                  "#include \"b.h\"\n",
185                  "some_header.h"));
186 }
187 
188 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
189   std::string Code = "#include <ccc>\n"    // Start of line: 0
190                      "#include <bbbbbb>\n" // Start of line: 15
191                      "#include <a>\n";     // Start of line: 33
192   EXPECT_EQ(31u, newCursor(Code, 0));
193   EXPECT_EQ(13u, newCursor(Code, 15));
194   EXPECT_EQ(0u, newCursor(Code, 33));
195 
196   EXPECT_EQ(41u, newCursor(Code, 10));
197   EXPECT_EQ(23u, newCursor(Code, 25));
198   EXPECT_EQ(10u, newCursor(Code, 43));
199 }
200 
201 } // end namespace
202 } // end namespace format
203 } // end namespace clang
204