xref: /llvm-project/clang/unittests/Format/UsingDeclarationsSorterTest.cpp (revision ece7e95f02cdcdf9fa7c6fdfbf6db92e4cc0c87e)
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,
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 
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