xref: /llvm-project/clang/unittests/Format/UsingDeclarationsSorterTest.cpp (revision 9da65aa8585ad3d73cb3495bcd018b4e226cac53)
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, SortsCaseInsensitively) {
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   EXPECT_EQ("using _;\n"
103             "using a;",
104             sortUsingDeclarations("using a;\n"
105                                   "using _;"));
106   EXPECT_EQ("using a::_;\n"
107             "using a::a;",
108             sortUsingDeclarations("using a::a;\n"
109                                   "using a::_;"));
110 
111   EXPECT_EQ("using ::testing::_;\n"
112             "using ::testing::Aardvark;\n"
113             "using ::testing::apple::Honeycrisp;\n"
114             "using ::testing::Xylophone;\n"
115             "using ::testing::zebra::Stripes;",
116             sortUsingDeclarations("using ::testing::Aardvark;\n"
117                                   "using ::testing::Xylophone;\n"
118                                   "using ::testing::_;\n"
119                                   "using ::testing::apple::Honeycrisp;\n"
120                                   "using ::testing::zebra::Stripes;"));
121 }
122 
123 TEST_F(UsingDeclarationsSorterTest, SortsStably) {
124   EXPECT_EQ("using a;\n"
125             "using a;\n"
126             "using A;\n"
127             "using a;\n"
128             "using A;\n"
129             "using a;\n"
130             "using A;\n"
131             "using a;\n"
132             "using B;\n"
133             "using b;\n"
134             "using b;\n"
135             "using B;\n"
136             "using b;\n"
137             "using b;\n"
138             "using b;\n"
139             "using B;\n"
140             "using b;",
141             sortUsingDeclarations("using a;\n"
142                                   "using B;\n"
143                                   "using a;\n"
144                                   "using b;\n"
145                                   "using A;\n"
146                                   "using a;\n"
147                                   "using b;\n"
148                                   "using B;\n"
149                                   "using b;\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 A;\n"
157                                   "using a;"));
158 }
159 
160 TEST_F(UsingDeclarationsSorterTest, SortsMultipleTopLevelDeclarations) {
161   EXPECT_EQ("using a;\n"
162             "using b;\n"
163             "using c;\n"
164             "using d;\n"
165             "using e;",
166             sortUsingDeclarations("using d;\n"
167                                   "using b;\n"
168                                   "using e;\n"
169                                   "using a;\n"
170                                   "using c;"));
171 
172   EXPECT_EQ("#include <iostream>\n"
173             "using ::std::endl;\n"
174             "using std::cin;\n"
175             "using std::cout;\n"
176             "int main();",
177             sortUsingDeclarations("#include <iostream>\n"
178                                   "using std::cout;\n"
179                                   "using std::cin;\n"
180                                   "using ::std::endl;\n"
181                                   "int main();"));
182 }
183 
184 TEST_F(UsingDeclarationsSorterTest, BreaksOnEmptyLines) {
185   EXPECT_EQ("using b;\n"
186             "using c;\n"
187             "\n"
188             "using a;\n"
189             "using d;",
190             sortUsingDeclarations("using c;\n"
191                                   "using b;\n"
192                                   "\n"
193                                   "using d;\n"
194                                   "using a;"));
195 }
196 
197 TEST_F(UsingDeclarationsSorterTest, BreaksOnUsingNamespace) {
198   EXPECT_EQ("using b;\n"
199             "using namespace std;\n"
200             "using a;",
201             sortUsingDeclarations("using b;\n"
202                                   "using namespace std;\n"
203                                   "using a;"));
204 }
205 
206 TEST_F(UsingDeclarationsSorterTest, KeepsUsingDeclarationsInPPDirectives) {
207   EXPECT_EQ("#define A \\\n"
208             "using b;\\\n"
209             "using a;",
210             sortUsingDeclarations("#define A \\\n"
211                                   "using b;\\\n"
212                                   "using a;"));
213 }
214 
215 TEST_F(UsingDeclarationsSorterTest, KeepsTypeAliases) {
216   auto Code = "struct C { struct B { struct A; }; };\n"
217               "using B = C::B;\n"
218               "using A = B::A;";
219   EXPECT_EQ(Code, sortUsingDeclarations(Code));
220 }
221 
222 TEST_F(UsingDeclarationsSorterTest, MovesTrailingCommentsWithDeclarations) {
223   EXPECT_EQ("using a; // line a1\n"
224             "using b; /* line b1\n"
225             "          * line b2\n"
226             "          * line b3 */\n"
227             "using c; // line c1\n"
228             "         // line c2",
229             sortUsingDeclarations("using c; // line c1\n"
230                                   "         // line c2\n"
231                                   "using b; /* line b1\n"
232                                   "          * line b2\n"
233                                   "          * line b3 */\n"
234                                   "using a; // line a1"));
235 }
236 
237 TEST_F(UsingDeclarationsSorterTest, SortsInStructScope) {
238   EXPECT_EQ("struct pt3 : pt2 {\n"
239             "  using pt2::x;\n"
240             "  using pt2::y;\n"
241             "  float z;\n"
242             "};",
243             sortUsingDeclarations("struct pt3 : pt2 {\n"
244                                   "  using pt2::y;\n"
245                                   "  using pt2::x;\n"
246                                   "  float z;\n"
247                                   "};"));
248 }
249 
250 TEST_F(UsingDeclarationsSorterTest, KeepsOperators) {
251   EXPECT_EQ("using a::operator();\n"
252             "using a::operator-;\n"
253             "using a::operator+;",
254             sortUsingDeclarations("using a::operator();\n"
255                                   "using a::operator-;\n"
256                                   "using a::operator+;"));
257 }
258 
259 TEST_F(UsingDeclarationsSorterTest, SortsUsingDeclarationsInsideNamespaces) {
260   EXPECT_EQ("namespace A {\n"
261             "struct B;\n"
262             "struct C;\n"
263             "}\n"
264             "namespace X {\n"
265             "using A::B;\n"
266             "using A::C;\n"
267             "}",
268             sortUsingDeclarations("namespace A {\n"
269                                   "struct B;\n"
270                                   "struct C;\n"
271                                   "}\n"
272                                   "namespace X {\n"
273                                   "using A::C;\n"
274                                   "using A::B;\n"
275                                   "}"));
276 }
277 
278 TEST_F(UsingDeclarationsSorterTest, SupportsClangFormatOff) {
279   EXPECT_EQ("// clang-format off\n"
280             "using b;\n"
281             "using a;\n"
282             "// clang-format on\n"
283             "using c;\n"
284             "using d;",
285             sortUsingDeclarations("// clang-format off\n"
286                                   "using b;\n"
287                                   "using a;\n"
288                                   "// clang-format on\n"
289                                   "using d;\n"
290                                   "using c;"));
291 }
292 
293 TEST_F(UsingDeclarationsSorterTest, SortsPartialRangeOfUsingDeclarations) {
294   // Sorts the whole block of using declarations surrounding the range.
295   EXPECT_EQ("using a;\n"
296             "using b;\n"
297             "using c;",
298             sortUsingDeclarations("using b;\n"
299                                   "using c;\n" // starts at offset 10
300                                   "using a;",
301                                   {tooling::Range(10, 15)}));
302   EXPECT_EQ("using a;\n"
303             "using b;\n"
304             "using c;\n"
305             "using A = b;",
306             sortUsingDeclarations("using b;\n"
307                                   "using c;\n" // starts at offset 10
308                                   "using a;\n"
309                                   "using A = b;",
310                                   {tooling::Range(10, 15)}));
311 
312   EXPECT_EQ("using d;\n"
313             "using c;\n"
314             "\n"
315             "using a;\n"
316             "using b;\n"
317             "\n"
318             "using f;\n"
319             "using e;",
320             sortUsingDeclarations("using d;\n"
321                                   "using c;\n"
322                                   "\n"
323                                   "using b;\n" // starts at offset 19
324                                   "using a;\n"
325                                   "\n"
326                                   "using f;\n"
327                                   "using e;",
328                                   {tooling::Range(19, 1)}));
329 }
330 
331 } // end namespace
332 } // end namespace format
333 } // end namespace clang
334