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