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, StringRef FileName = "input.cpp") {
28     auto Ranges = GetCodeRange(Code);
29     std::string Sorted =
30         applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName));
31     return applyAllReplacements(Sorted,
32                                 reformat(Style, Sorted, Ranges, FileName));
33   }
34 
35   unsigned newCursor(llvm::StringRef Code, unsigned Cursor) {
36     sortIncludes(Style, Code, GetCodeRange(Code), "input.cpp", &Cursor);
37     return Cursor;
38   }
39 
40   FormatStyle Style = getLLVMStyle();
41 
42 };
43 
44 TEST_F(SortIncludesTest, BasicSorting) {
45   EXPECT_EQ("#include \"a.h\"\n"
46             "#include \"b.h\"\n"
47             "#include \"c.h\"\n",
48             sort("#include \"a.h\"\n"
49                  "#include \"c.h\"\n"
50                  "#include \"b.h\"\n"));
51 }
52 
53 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) {
54   // Identical #includes have led to a failure with an unstable sort.
55   std::string Code = "#include <a>\n"
56                      "#include <b>\n"
57                      "#include <b>\n"
58                      "#include <b>\n"
59                      "#include <b>\n"
60                      "#include <c>\n";
61   EXPECT_TRUE(sortIncludes(Style, Code, GetCodeRange(Code), "a.cc").empty());
62 }
63 
64 TEST_F(SortIncludesTest, SupportClangFormatOff) {
65   EXPECT_EQ("#include <a>\n"
66             "#include <b>\n"
67             "#include <c>\n"
68             "// clang-format off\n"
69             "#include <b>\n"
70             "#include <a>\n"
71             "#include <c>\n"
72             "// clang-format on\n",
73             sort("#include <b>\n"
74                  "#include <a>\n"
75                  "#include <c>\n"
76                  "// clang-format off\n"
77                  "#include <b>\n"
78                  "#include <a>\n"
79                  "#include <c>\n"
80                  "// clang-format on\n"));
81 }
82 
83 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) {
84   Style.SortIncludes = false;
85   EXPECT_EQ("#include \"a.h\"\n"
86             "#include \"c.h\"\n"
87             "#include \"b.h\"\n",
88             sort("#include \"a.h\"\n"
89                  "#include \"c.h\"\n"
90                  "#include \"b.h\"\n"));
91 }
92 
93 TEST_F(SortIncludesTest, MixIncludeAndImport) {
94   EXPECT_EQ("#include \"a.h\"\n"
95             "#import \"b.h\"\n"
96             "#include \"c.h\"\n",
97             sort("#include \"a.h\"\n"
98                  "#include \"c.h\"\n"
99                  "#import \"b.h\"\n"));
100 }
101 
102 TEST_F(SortIncludesTest, FixTrailingComments) {
103   EXPECT_EQ("#include \"a.h\"  // comment\n"
104             "#include \"bb.h\" // comment\n"
105             "#include \"ccc.h\"\n",
106             sort("#include \"a.h\" // comment\n"
107                  "#include \"ccc.h\"\n"
108                  "#include \"bb.h\" // comment\n"));
109 }
110 
111 TEST_F(SortIncludesTest, LeadingWhitespace) {
112   EXPECT_EQ("#include \"a.h\"\n"
113             "#include \"b.h\"\n"
114             "#include \"c.h\"\n",
115             sort(" #include \"a.h\"\n"
116                  "  #include \"c.h\"\n"
117                  "   #include \"b.h\"\n"));
118   EXPECT_EQ("#include \"a.h\"\n"
119             "#include \"b.h\"\n"
120             "#include \"c.h\"\n",
121             sort("# include \"a.h\"\n"
122                  "#  include \"c.h\"\n"
123                  "#   include \"b.h\"\n"));
124 }
125 
126 TEST_F(SortIncludesTest, GreaterInComment) {
127   EXPECT_EQ("#include \"a.h\"\n"
128             "#include \"b.h\" // >\n"
129             "#include \"c.h\"\n",
130             sort("#include \"a.h\"\n"
131                  "#include \"c.h\"\n"
132                  "#include \"b.h\" // >\n"));
133 }
134 
135 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) {
136   EXPECT_EQ("#include \"a.h\"\n"
137             "#include \"c.h\"\n"
138             "\n"
139             "#include \"b.h\"\n",
140             sort("#include \"a.h\"\n"
141                  "#include \"c.h\"\n"
142                  "\n"
143                  "#include \"b.h\"\n"));
144 }
145 
146 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) {
147   EXPECT_EQ("#include \"a.h\"\n"
148             "#include \"c.h\"\n"
149             "#include <b.h>\n"
150             "#include <d.h>\n",
151             sort("#include <d.h>\n"
152                  "#include <b.h>\n"
153                  "#include \"c.h\"\n"
154                  "#include \"a.h\"\n"));
155 
156   Style = getGoogleStyle(FormatStyle::LK_Cpp);
157   EXPECT_EQ("#include <b.h>\n"
158             "#include <d.h>\n"
159             "#include \"a.h\"\n"
160             "#include \"c.h\"\n",
161             sort("#include <d.h>\n"
162                  "#include <b.h>\n"
163                  "#include \"c.h\"\n"
164                  "#include \"a.h\"\n"));
165 }
166 
167 TEST_F(SortIncludesTest, HandlesMultilineIncludes) {
168   EXPECT_EQ("#include \"a.h\"\n"
169             "#include \"b.h\"\n"
170             "#include \"c.h\"\n",
171             sort("#include \"a.h\"\n"
172                  "#include \\\n"
173                  "\"c.h\"\n"
174                  "#include \"b.h\"\n"));
175 }
176 
177 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) {
178   Style.IncludeIsMainRegex = "([-_](test|unittest))?$";
179   EXPECT_EQ("#include \"llvm/a.h\"\n"
180             "#include \"b.h\"\n"
181             "#include \"c.h\"\n",
182             sort("#include \"llvm/a.h\"\n"
183                  "#include \"c.h\"\n"
184                  "#include \"b.h\"\n",
185                  "a.cc"));
186   EXPECT_EQ("#include \"llvm/a.h\"\n"
187             "#include \"b.h\"\n"
188             "#include \"c.h\"\n",
189             sort("#include \"llvm/a.h\"\n"
190                  "#include \"c.h\"\n"
191                  "#include \"b.h\"\n",
192                  "a_test.cc"));
193   EXPECT_EQ("#include \"llvm/input.h\"\n"
194             "#include \"b.h\"\n"
195             "#include \"c.h\"\n",
196             sort("#include \"llvm/input.h\"\n"
197                  "#include \"c.h\"\n"
198                  "#include \"b.h\"\n",
199                  "input.mm"));
200 
201   // Don't allow prefixes.
202   EXPECT_EQ("#include \"b.h\"\n"
203             "#include \"c.h\"\n"
204             "#include \"llvm/not_a.h\"\n",
205             sort("#include \"llvm/not_a.h\"\n"
206                  "#include \"c.h\"\n"
207                  "#include \"b.h\"\n",
208                  "a.cc"));
209 
210   // Don't do this for _main and other suffixes.
211   EXPECT_EQ("#include \"b.h\"\n"
212             "#include \"c.h\"\n"
213             "#include \"llvm/a.h\"\n",
214             sort("#include \"llvm/a.h\"\n"
215                  "#include \"c.h\"\n"
216                  "#include \"b.h\"\n",
217                  "a_main.cc"));
218 
219   // Don't do this in headers.
220   EXPECT_EQ("#include \"b.h\"\n"
221             "#include \"c.h\"\n"
222             "#include \"llvm/a.h\"\n",
223             sort("#include \"llvm/a.h\"\n"
224                  "#include \"c.h\"\n"
225                  "#include \"b.h\"\n",
226                  "a.h"));
227 
228   // Only do this in the first #include block.
229   EXPECT_EQ("#include <a>\n"
230             "\n"
231             "#include \"b.h\"\n"
232             "#include \"c.h\"\n"
233             "#include \"llvm/a.h\"\n",
234             sort("#include <a>\n"
235                  "\n"
236                  "#include \"llvm/a.h\"\n"
237                  "#include \"c.h\"\n"
238                  "#include \"b.h\"\n",
239                  "a.cc"));
240 
241   // Only recognize the first #include with a matching basename as main include.
242   EXPECT_EQ("#include \"a.h\"\n"
243             "#include \"b.h\"\n"
244             "#include \"c.h\"\n"
245             "#include \"llvm/a.h\"\n",
246             sort("#include \"b.h\"\n"
247                  "#include \"a.h\"\n"
248                  "#include \"c.h\"\n"
249                  "#include \"llvm/a.h\"\n",
250                  "a.cc"));
251 }
252 
253 TEST_F(SortIncludesTest, NegativePriorities) {
254   Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
255   EXPECT_EQ("#include \"important_os_header.h\"\n"
256             "#include \"c_main.h\"\n"
257             "#include \"a_other.h\"\n",
258             sort("#include \"c_main.h\"\n"
259                  "#include \"a_other.h\"\n"
260                  "#include \"important_os_header.h\"\n",
261                  "c_main.cc"));
262 
263   // check stable when re-run
264   EXPECT_EQ("#include \"important_os_header.h\"\n"
265             "#include \"c_main.h\"\n"
266             "#include \"a_other.h\"\n",
267             sort("#include \"important_os_header.h\"\n"
268                  "#include \"c_main.h\"\n"
269                  "#include \"a_other.h\"\n",
270                  "c_main.cc"));
271 }
272 
273 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
274   std::string Code = "#include <ccc>\n"    // Start of line: 0
275                      "#include <bbbbbb>\n" // Start of line: 15
276                      "#include <a>\n";     // Start of line: 33
277   EXPECT_EQ(31u, newCursor(Code, 0));
278   EXPECT_EQ(13u, newCursor(Code, 15));
279   EXPECT_EQ(0u, newCursor(Code, 33));
280 
281   EXPECT_EQ(41u, newCursor(Code, 10));
282   EXPECT_EQ(23u, newCursor(Code, 25));
283   EXPECT_EQ(10u, newCursor(Code, 43));
284 }
285 
286 } // end namespace
287 } // end namespace format
288 } // end namespace clang
289