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