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:
sortUsingDeclarations(llvm::StringRef Code,const std::vector<tooling::Range> & Ranges,const FormatStyle & Style=getLLVMStyle ())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
sortUsingDeclarations(llvm::StringRef Code,const FormatStyle & Style=getLLVMStyle ())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
TEST_F(UsingDeclarationsSorterTest,SwapsTwoConsecutiveUsingDeclarations)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
TEST_F(UsingDeclarationsSorterTest,UsingDeclarationOrder)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
TEST_F(UsingDeclarationsSorterTest,SortsStably)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
TEST_F(UsingDeclarationsSorterTest,SortsMultipleTopLevelDeclarations)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
TEST_F(UsingDeclarationsSorterTest,BreaksOnEmptyLines)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
TEST_F(UsingDeclarationsSorterTest,BreaksOnUsingNamespace)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
TEST_F(UsingDeclarationsSorterTest,KeepsUsingDeclarationsInPPDirectives)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
TEST_F(UsingDeclarationsSorterTest,KeepsTypeAliases)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
TEST_F(UsingDeclarationsSorterTest,MovesTrailingCommentsWithDeclarations)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
TEST_F(UsingDeclarationsSorterTest,SortsInStructScope)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
TEST_F(UsingDeclarationsSorterTest,KeepsOperators)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
TEST_F(UsingDeclarationsSorterTest,SortsUsingDeclarationsInsideNamespaces)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
TEST_F(UsingDeclarationsSorterTest,SupportsClangFormatOff)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
TEST_F(UsingDeclarationsSorterTest,SortsPartialRangeOfUsingDeclarations)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
TEST_F(UsingDeclarationsSorterTest,SortsUsingDeclarationsWithLeadingkComments)346 TEST_F(UsingDeclarationsSorterTest,
347 SortsUsingDeclarationsWithLeadingkComments) {
348 EXPECT_EQ("/* comment */ using a;\n"
349 "/* comment */ using b;",
350 sortUsingDeclarations("/* comment */ using b;\n"
351 "/* comment */ using a;"));
352 }
353
TEST_F(UsingDeclarationsSorterTest,DeduplicatesUsingDeclarations)354 TEST_F(UsingDeclarationsSorterTest, DeduplicatesUsingDeclarations) {
355 EXPECT_EQ("using a;\n"
356 "using b;\n"
357 "using c;\n"
358 "\n"
359 "using a;\n"
360 "using e;",
361 sortUsingDeclarations("using c;\n"
362 "using a;\n"
363 "using b;\n"
364 "using a;\n"
365 "using b;\n"
366 "\n"
367 "using e;\n"
368 "using a;\n"
369 "using e;"));
370 }
371
372 } // end namespace
373 } // end namespace format
374 } // end namespace clang
375