xref: /llvm-project/clang/unittests/Format/UsingDeclarationsSorterTest.cpp (revision b03877ab836bf58fee5228e4ab9348eb1f970abb)
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, SortsMultipleTopLevelDeclarations) {
90   EXPECT_EQ("using a;\n"
91             "using b;\n"
92             "using c;\n"
93             "using d;\n"
94             "using e;",
95             sortUsingDeclarations("using d;\n"
96                                   "using b;\n"
97                                   "using e;\n"
98                                   "using a;\n"
99                                   "using c;"));
100 
101   EXPECT_EQ("#include <iostream>\n"
102             "using ::std::endl;\n"
103             "using std::cin;\n"
104             "using std::cout;\n"
105             "int main();",
106             sortUsingDeclarations("#include <iostream>\n"
107                                   "using std::cout;\n"
108                                   "using std::cin;\n"
109                                   "using ::std::endl;\n"
110                                   "int main();"));
111 }
112 
113 TEST_F(UsingDeclarationsSorterTest, BreaksOnEmptyLines) {
114   EXPECT_EQ("using b;\n"
115             "using c;\n"
116             "\n"
117             "using a;\n"
118             "using d;",
119             sortUsingDeclarations("using c;\n"
120                                   "using b;\n"
121                                   "\n"
122                                   "using d;\n"
123                                   "using a;"));
124 }
125 
126 TEST_F(UsingDeclarationsSorterTest, BreaksOnUsingNamespace) {
127   EXPECT_EQ("using b;\n"
128             "using namespace std;\n"
129             "using a;",
130             sortUsingDeclarations("using b;\n"
131                                   "using namespace std;\n"
132                                   "using a;"));
133 }
134 
135 TEST_F(UsingDeclarationsSorterTest, KeepsUsingDeclarationsInPPDirectives) {
136   EXPECT_EQ("#define A \\\n"
137             "using b;\\\n"
138             "using a;",
139             sortUsingDeclarations("#define A \\\n"
140                                   "using b;\\\n"
141                                   "using a;"));
142 }
143 
144 TEST_F(UsingDeclarationsSorterTest, KeepsTypeAliases) {
145   auto Code = "struct C { struct B { struct A; }; };\n"
146               "using B = C::B;\n"
147               "using A = B::A;";
148   EXPECT_EQ(Code, sortUsingDeclarations(Code));
149 }
150 
151 TEST_F(UsingDeclarationsSorterTest, MovesTrailingCommentsWithDeclarations) {
152   EXPECT_EQ("using a; // line a1\n"
153             "using b; /* line b1\n"
154             "          * line b2\n"
155             "          * line b3 */\n"
156             "using c; // line c1\n"
157             "         // line c2",
158             sortUsingDeclarations("using c; // line c1\n"
159                                   "         // line c2\n"
160                                   "using b; /* line b1\n"
161                                   "          * line b2\n"
162                                   "          * line b3 */\n"
163                                   "using a; // line a1"));
164 }
165 
166 TEST_F(UsingDeclarationsSorterTest, SortsInStructScope) {
167   EXPECT_EQ("struct pt3 : pt2 {\n"
168             "  using pt2::x;\n"
169             "  using pt2::y;\n"
170             "  float z;\n"
171             "};",
172             sortUsingDeclarations("struct pt3 : pt2 {\n"
173                                   "  using pt2::y;\n"
174                                   "  using pt2::x;\n"
175                                   "  float z;\n"
176                                   "};"));
177 }
178 
179 TEST_F(UsingDeclarationsSorterTest, KeepsOperators) {
180   EXPECT_EQ("using a::operator();\n"
181             "using a::operator-;\n"
182             "using a::operator+;",
183             sortUsingDeclarations("using a::operator();\n"
184                                   "using a::operator-;\n"
185                                   "using a::operator+;"));
186 }
187 
188 TEST_F(UsingDeclarationsSorterTest, SortsUsingDeclarationsInsideNamespaces) {
189   EXPECT_EQ("namespace A {\n"
190             "struct B;\n"
191             "struct C;\n"
192             "}\n"
193             "namespace X {\n"
194             "using A::B;\n"
195             "using A::C;\n"
196             "}",
197             sortUsingDeclarations("namespace A {\n"
198                                   "struct B;\n"
199                                   "struct C;\n"
200                                   "}\n"
201                                   "namespace X {\n"
202                                   "using A::C;\n"
203                                   "using A::B;\n"
204                                   "}"));
205 }
206 
207 TEST_F(UsingDeclarationsSorterTest, SupportsClangFormatOff) {
208   EXPECT_EQ("// clang-format off\n"
209             "using b;\n"
210             "using a;\n"
211             "// clang-format on\n"
212             "using c;\n"
213             "using d;",
214             sortUsingDeclarations("// clang-format off\n"
215                                   "using b;\n"
216                                   "using a;\n"
217                                   "// clang-format on\n"
218                                   "using d;\n"
219                                   "using c;"));
220 }
221 
222 TEST_F(UsingDeclarationsSorterTest, SortsPartialRangeOfUsingDeclarations) {
223   EXPECT_EQ("using b;\n"
224             "using a;\n"
225             "using c;",
226             sortUsingDeclarations("using b;\n"
227                                   "using c;\n" // starts at offset 10
228                                   "using a;",
229                                   {tooling::Range(10, 15)}));
230 }
231 
232 } // end namespace
233 } // end namespace format
234 } // end namespace clang
235