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:
sort(llvm::StringRef Code,StringRef FileName="input.cpp")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 
newCursor(llvm::StringRef Code,unsigned Cursor)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 
TEST_F(SortIncludesTest,BasicSorting)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 
TEST_F(SortIncludesTest,SupportClangFormatOff)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 
TEST_F(SortIncludesTest,IncludeSortingCanBeDisabled)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 
TEST_F(SortIncludesTest,MixIncludeAndImport)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 
TEST_F(SortIncludesTest,FixTrailingComments)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 
TEST_F(SortIncludesTest,LeadingWhitespace)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 
TEST_F(SortIncludesTest,GreaterInComment)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 
TEST_F(SortIncludesTest,SortsLocallyInEachBlock)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 
TEST_F(SortIncludesTest,HandlesAngledIncludesAsSeparateBlocks)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 
TEST_F(SortIncludesTest,HandlesMultilineIncludes)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 
TEST_F(SortIncludesTest,LeavesMainHeaderFirst)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                  "a.cc"));
171   EXPECT_EQ("#include \"llvm/a.h\"\n"
172             "#include \"b.h\"\n"
173             "#include \"c.h\"\n",
174             sort("#include \"llvm/a.h\"\n"
175                  "#include \"c.h\"\n"
176                  "#include \"b.h\"\n",
177                  "a_main.cc"));
178   EXPECT_EQ("#include \"llvm/input.h\"\n"
179             "#include \"b.h\"\n"
180             "#include \"c.h\"\n",
181             sort("#include \"llvm/input.h\"\n"
182                  "#include \"c.h\"\n"
183                  "#include \"b.h\"\n",
184                  "input.mm"));
185 
186   // Don't do this in headers.
187   EXPECT_EQ("#include \"b.h\"\n"
188             "#include \"c.h\"\n"
189             "#include \"llvm/a.h\"\n",
190             sort("#include \"llvm/a.h\"\n"
191                  "#include \"c.h\"\n"
192                  "#include \"b.h\"\n",
193                  "a.h"));
194 
195   // Only do this in the first #include block.
196   EXPECT_EQ("#include <a>\n"
197             "\n"
198             "#include \"b.h\"\n"
199             "#include \"c.h\"\n"
200             "#include \"llvm/a.h\"\n",
201             sort("#include <a>\n"
202                  "\n"
203                  "#include \"llvm/a.h\"\n"
204                  "#include \"c.h\"\n"
205                  "#include \"b.h\"\n",
206                  "a.cc"));
207 
208   // Only recognize the first #include with a matching basename as main include.
209   EXPECT_EQ("#include \"a.h\"\n"
210             "#include \"b.h\"\n"
211             "#include \"c.h\"\n"
212             "#include \"llvm/a.h\"\n",
213             sort("#include \"b.h\"\n"
214                  "#include \"a.h\"\n"
215                  "#include \"c.h\"\n"
216                  "#include \"llvm/a.h\"\n",
217                  "a.cc"));
218 }
219 
TEST_F(SortIncludesTest,NegativePriorities)220 TEST_F(SortIncludesTest, NegativePriorities) {
221   Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}};
222   EXPECT_EQ("#include \"important_os_header.h\"\n"
223             "#include \"c_main.h\"\n"
224             "#include \"a_other.h\"\n",
225             sort("#include \"c_main.h\"\n"
226                  "#include \"a_other.h\"\n"
227                  "#include \"important_os_header.h\"\n",
228                  "c_main.cc"));
229 
230   // check stable when re-run
231   EXPECT_EQ("#include \"important_os_header.h\"\n"
232             "#include \"c_main.h\"\n"
233             "#include \"a_other.h\"\n",
234             sort("#include \"important_os_header.h\"\n"
235                  "#include \"c_main.h\"\n"
236                  "#include \"a_other.h\"\n",
237                  "c_main.cc"));
238 }
239 
TEST_F(SortIncludesTest,CalculatesCorrectCursorPosition)240 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) {
241   std::string Code = "#include <ccc>\n"    // Start of line: 0
242                      "#include <bbbbbb>\n" // Start of line: 15
243                      "#include <a>\n";     // Start of line: 33
244   EXPECT_EQ(31u, newCursor(Code, 0));
245   EXPECT_EQ(13u, newCursor(Code, 15));
246   EXPECT_EQ(0u, newCursor(Code, 33));
247 
248   EXPECT_EQ(41u, newCursor(Code, 10));
249   EXPECT_EQ(23u, newCursor(Code, 25));
250   EXPECT_EQ(10u, newCursor(Code, 43));
251 }
252 
253 } // end namespace
254 } // end namespace format
255 } // end namespace clang
256