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