Clang Project

clang_source_code/unittests/Format/UsingDeclarationsSorterTest.cpp
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
16namespace clang {
17namespace format {
18namespace {
19
20class UsingDeclarationsSorterTest : public ::testing::Test {
21protected:
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
43TEST_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
88TEST_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
142TEST_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
175TEST_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
199TEST_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
212TEST_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
221TEST_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
230TEST_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
237TEST_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
252TEST_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
265TEST_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
274TEST_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
293TEST_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
308TEST_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
346TEST_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
353TEST_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