1 | //===- UsingDeclarationsSorterTest.cpp - Formatting unit tests ------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | |
9 | #include "clang/Format/Format.h" |
10 | |
11 | #include "llvm/Support/Debug.h" |
12 | #include "gtest/gtest.h" |
13 | |
14 | #define DEBUG_TYPE "using-declarations-sorter-test" |
15 | |
16 | namespace clang { |
17 | namespace format { |
18 | namespace { |
19 | |
20 | class UsingDeclarationsSorterTest : public ::testing::Test { |
21 | protected: |
22 | std::string sortUsingDeclarations(llvm::StringRef Code, |
23 | const std::vector<tooling::Range> &Ranges, |
24 | const FormatStyle &Style = getLLVMStyle()) { |
25 | LLVM_DEBUG(llvm::errs() << "---\n"); |
26 | LLVM_DEBUG(llvm::errs() << Code << "\n\n"); |
27 | tooling::Replacements Replaces = |
28 | clang::format::sortUsingDeclarations(Style, Code, Ranges, "<stdin>"); |
29 | auto Result = applyAllReplacements(Code, Replaces); |
30 | EXPECT_TRUE(static_cast<bool>(Result)); |
31 | LLVM_DEBUG(llvm::errs() << "\n" << *Result << "\n\n"); |
32 | return *Result; |
33 | } |
34 | |
35 | std::string sortUsingDeclarations(llvm::StringRef Code, |
36 | const FormatStyle &Style = getLLVMStyle()) { |
37 | return sortUsingDeclarations(Code, |
38 | /*Ranges=*/{1, tooling::Range(0, Code.size())}, |
39 | Style); |
40 | } |
41 | }; |
42 | |
43 | TEST_F(UsingDeclarationsSorterTest, SwapsTwoConsecutiveUsingDeclarations) { |
44 | EXPECT_EQ("using a;\n" |
45 | "using b;", |
46 | sortUsingDeclarations("using a;\n" |
47 | "using b;")); |
48 | EXPECT_EQ("using a;\n" |
49 | "using aa;", |
50 | sortUsingDeclarations("using aa;\n" |
51 | "using a;")); |
52 | EXPECT_EQ("using a;\n" |
53 | "using ::a;", |
54 | sortUsingDeclarations("using a;\n" |
55 | "using ::a;")); |
56 | |
57 | EXPECT_EQ("using a::bcd;\n" |
58 | "using a::cd;", |
59 | sortUsingDeclarations("using a::cd;\n" |
60 | "using a::bcd;")); |
61 | |
62 | EXPECT_EQ("using a;\n" |
63 | "using a::a;", |
64 | sortUsingDeclarations("using a::a;\n" |
65 | "using a;")); |
66 | |
67 | EXPECT_EQ("using a::ba::aa;\n" |
68 | "using a::bb::ccc;", |
69 | sortUsingDeclarations("using a::bb::ccc;\n" |
70 | "using a::ba::aa;")); |
71 | |
72 | EXPECT_EQ("using a;\n" |
73 | "using typename a;", |
74 | sortUsingDeclarations("using typename a;\n" |
75 | "using a;")); |
76 | |
77 | EXPECT_EQ("using typename z;\n" |
78 | "using typenamea;", |
79 | sortUsingDeclarations("using typenamea;\n" |
80 | "using typename z;")); |
81 | |
82 | EXPECT_EQ("using a, b;\n" |
83 | "using aa;", |
84 | sortUsingDeclarations("using aa;\n" |
85 | "using a, b;")); |
86 | } |
87 | |
88 | TEST_F(UsingDeclarationsSorterTest, UsingDeclarationOrder) { |
89 | EXPECT_EQ("using A;\n" |
90 | "using a;", |
91 | sortUsingDeclarations("using A;\n" |
92 | "using a;")); |
93 | EXPECT_EQ("using a;\n" |
94 | "using A;", |
95 | sortUsingDeclarations("using a;\n" |
96 | "using A;")); |
97 | EXPECT_EQ("using a;\n" |
98 | "using B;", |
99 | sortUsingDeclarations("using B;\n" |
100 | "using a;")); |
101 | |
102 | // Ignores leading '::'. |
103 | EXPECT_EQ("using ::a;\n" |
104 | "using A;", |
105 | sortUsingDeclarations("using ::a;\n" |
106 | "using A;")); |
107 | |
108 | EXPECT_EQ("using ::A;\n" |
109 | "using a;", |
110 | sortUsingDeclarations("using ::A;\n" |
111 | "using a;")); |
112 | |
113 | // Sorts '_' before 'a' and 'A'. |
114 | EXPECT_EQ("using _;\n" |
115 | "using A;", |
116 | sortUsingDeclarations("using A;\n" |
117 | "using _;")); |
118 | EXPECT_EQ("using _;\n" |
119 | "using a;", |
120 | sortUsingDeclarations("using a;\n" |
121 | "using _;")); |
122 | EXPECT_EQ("using a::_;\n" |
123 | "using a::a;", |
124 | sortUsingDeclarations("using a::a;\n" |
125 | "using a::_;")); |
126 | |
127 | // Sorts non-namespace names before namespace names at the same level. |
128 | EXPECT_EQ("using ::testing::_;\n" |
129 | "using ::testing::Aardvark;\n" |
130 | "using ::testing::kMax;\n" |
131 | "using ::testing::Xylophone;\n" |
132 | "using ::testing::apple::Honeycrisp;\n" |
133 | "using ::testing::zebra::Stripes;", |
134 | sortUsingDeclarations("using ::testing::Aardvark;\n" |
135 | "using ::testing::Xylophone;\n" |
136 | "using ::testing::kMax;\n" |
137 | "using ::testing::_;\n" |
138 | "using ::testing::apple::Honeycrisp;\n" |
139 | "using ::testing::zebra::Stripes;")); |
140 | } |
141 | |
142 | TEST_F(UsingDeclarationsSorterTest, SortsStably) { |
143 | EXPECT_EQ("using a;\n" |
144 | "using A;\n" |
145 | "using a;\n" |
146 | "using A;\n" |
147 | "using a;\n" |
148 | "using A;\n" |
149 | "using a;\n" |
150 | "using B;\n" |
151 | "using b;\n" |
152 | "using B;\n" |
153 | "using b;\n" |
154 | "using B;\n" |
155 | "using b;", |
156 | sortUsingDeclarations("using a;\n" |
157 | "using B;\n" |
158 | "using a;\n" |
159 | "using b;\n" |
160 | "using A;\n" |
161 | "using a;\n" |
162 | "using b;\n" |
163 | "using B;\n" |
164 | "using b;\n" |
165 | "using A;\n" |
166 | "using a;\n" |
167 | "using b;\n" |
168 | "using b;\n" |
169 | "using B;\n" |
170 | "using b;\n" |
171 | "using A;\n" |
172 | "using a;")); |
173 | } |
174 | |
175 | TEST_F(UsingDeclarationsSorterTest, SortsMultipleTopLevelDeclarations) { |
176 | EXPECT_EQ("using a;\n" |
177 | "using b;\n" |
178 | "using c;\n" |
179 | "using d;\n" |
180 | "using e;", |
181 | sortUsingDeclarations("using d;\n" |
182 | "using b;\n" |
183 | "using e;\n" |
184 | "using a;\n" |
185 | "using c;")); |
186 | |
187 | EXPECT_EQ("#include <iostream>\n" |
188 | "using std::cin;\n" |
189 | "using std::cout;\n" |
190 | "using ::std::endl;\n" |
191 | "int main();", |
192 | sortUsingDeclarations("#include <iostream>\n" |
193 | "using std::cout;\n" |
194 | "using ::std::endl;\n" |
195 | "using std::cin;\n" |
196 | "int main();")); |
197 | } |
198 | |
199 | TEST_F(UsingDeclarationsSorterTest, BreaksOnEmptyLines) { |
200 | EXPECT_EQ("using b;\n" |
201 | "using c;\n" |
202 | "\n" |
203 | "using a;\n" |
204 | "using d;", |
205 | sortUsingDeclarations("using c;\n" |
206 | "using b;\n" |
207 | "\n" |
208 | "using d;\n" |
209 | "using a;")); |
210 | } |
211 | |
212 | TEST_F(UsingDeclarationsSorterTest, BreaksOnUsingNamespace) { |
213 | EXPECT_EQ("using b;\n" |
214 | "using namespace std;\n" |
215 | "using a;", |
216 | sortUsingDeclarations("using b;\n" |
217 | "using namespace std;\n" |
218 | "using a;")); |
219 | } |
220 | |
221 | TEST_F(UsingDeclarationsSorterTest, KeepsUsingDeclarationsInPPDirectives) { |
222 | EXPECT_EQ("#define A \\\n" |
223 | "using b;\\\n" |
224 | "using a;", |
225 | sortUsingDeclarations("#define A \\\n" |
226 | "using b;\\\n" |
227 | "using a;")); |
228 | } |
229 | |
230 | TEST_F(UsingDeclarationsSorterTest, KeepsTypeAliases) { |
231 | auto Code = "struct C { struct B { struct A; }; };\n" |
232 | "using B = C::B;\n" |
233 | "using A = B::A;"; |
234 | EXPECT_EQ(Code, sortUsingDeclarations(Code)); |
235 | } |
236 | |
237 | TEST_F(UsingDeclarationsSorterTest, MovesTrailingCommentsWithDeclarations) { |
238 | EXPECT_EQ("using a; // line a1\n" |
239 | "using b; /* line b1\n" |
240 | " * line b2\n" |
241 | " * line b3 */\n" |
242 | "using c; // line c1\n" |
243 | " // line c2", |
244 | sortUsingDeclarations("using c; // line c1\n" |
245 | " // line c2\n" |
246 | "using b; /* line b1\n" |
247 | " * line b2\n" |
248 | " * line b3 */\n" |
249 | "using a; // line a1")); |
250 | } |
251 | |
252 | TEST_F(UsingDeclarationsSorterTest, SortsInStructScope) { |
253 | EXPECT_EQ("struct pt3 : pt2 {\n" |
254 | " using pt2::x;\n" |
255 | " using pt2::y;\n" |
256 | " float z;\n" |
257 | "};", |
258 | sortUsingDeclarations("struct pt3 : pt2 {\n" |
259 | " using pt2::y;\n" |
260 | " using pt2::x;\n" |
261 | " float z;\n" |
262 | "};")); |
263 | } |
264 | |
265 | TEST_F(UsingDeclarationsSorterTest, KeepsOperators) { |
266 | EXPECT_EQ("using a::operator();\n" |
267 | "using a::operator-;\n" |
268 | "using a::operator+;", |
269 | sortUsingDeclarations("using a::operator();\n" |
270 | "using a::operator-;\n" |
271 | "using a::operator+;")); |
272 | } |
273 | |
274 | TEST_F(UsingDeclarationsSorterTest, SortsUsingDeclarationsInsideNamespaces) { |
275 | EXPECT_EQ("namespace A {\n" |
276 | "struct B;\n" |
277 | "struct C;\n" |
278 | "}\n" |
279 | "namespace X {\n" |
280 | "using A::B;\n" |
281 | "using A::C;\n" |
282 | "}", |
283 | sortUsingDeclarations("namespace A {\n" |
284 | "struct B;\n" |
285 | "struct C;\n" |
286 | "}\n" |
287 | "namespace X {\n" |
288 | "using A::C;\n" |
289 | "using A::B;\n" |
290 | "}")); |
291 | } |
292 | |
293 | TEST_F(UsingDeclarationsSorterTest, SupportsClangFormatOff) { |
294 | EXPECT_EQ("// clang-format off\n" |
295 | "using b;\n" |
296 | "using a;\n" |
297 | "// clang-format on\n" |
298 | "using c;\n" |
299 | "using d;", |
300 | sortUsingDeclarations("// clang-format off\n" |
301 | "using b;\n" |
302 | "using a;\n" |
303 | "// clang-format on\n" |
304 | "using d;\n" |
305 | "using c;")); |
306 | } |
307 | |
308 | TEST_F(UsingDeclarationsSorterTest, SortsPartialRangeOfUsingDeclarations) { |
309 | // Sorts the whole block of using declarations surrounding the range. |
310 | EXPECT_EQ("using a;\n" |
311 | "using b;\n" |
312 | "using c;", |
313 | sortUsingDeclarations("using b;\n" |
314 | "using c;\n" // starts at offset 10 |
315 | "using a;", |
316 | {tooling::Range(10, 15)})); |
317 | EXPECT_EQ("using a;\n" |
318 | "using b;\n" |
319 | "using c;\n" |
320 | "using A = b;", |
321 | sortUsingDeclarations("using b;\n" |
322 | "using c;\n" // starts at offset 10 |
323 | "using a;\n" |
324 | "using A = b;", |
325 | {tooling::Range(10, 15)})); |
326 | |
327 | EXPECT_EQ("using d;\n" |
328 | "using c;\n" |
329 | "\n" |
330 | "using a;\n" |
331 | "using b;\n" |
332 | "\n" |
333 | "using f;\n" |
334 | "using e;", |
335 | sortUsingDeclarations("using d;\n" |
336 | "using c;\n" |
337 | "\n" |
338 | "using b;\n" // starts at offset 19 |
339 | "using a;\n" |
340 | "\n" |
341 | "using f;\n" |
342 | "using e;", |
343 | {tooling::Range(19, 1)})); |
344 | } |
345 | |
346 | TEST_F(UsingDeclarationsSorterTest, SortsUsingDeclarationsWithLeadingkComments) { |
347 | EXPECT_EQ("/* comment */ using a;\n" |
348 | "/* comment */ using b;", |
349 | sortUsingDeclarations("/* comment */ using b;\n" |
350 | "/* comment */ using a;")); |
351 | } |
352 | |
353 | TEST_F(UsingDeclarationsSorterTest, DeduplicatesUsingDeclarations) { |
354 | EXPECT_EQ("using a;\n" |
355 | "using b;\n" |
356 | "using c;\n" |
357 | "\n" |
358 | "using a;\n" |
359 | "using e;", |
360 | sortUsingDeclarations("using c;\n" |
361 | "using a;\n" |
362 | "using b;\n" |
363 | "using a;\n" |
364 | "using b;\n" |
365 | "\n" |
366 | "using e;\n" |
367 | "using a;\n" |
368 | "using e;")); |
369 | |
370 | } |
371 | |
372 | } // end namespace |
373 | } // end namespace format |
374 | } // end namespace clang |
375 | |