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 16 namespace clang { 17 namespace format { 18 namespace { 19 20 class UsingDeclarationsSorterTest : public ::testing::Test { 21 protected: 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 43 TEST_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 88 TEST_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 142 TEST_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 175 TEST_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 199 TEST_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 212 TEST_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 221 TEST_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 230 TEST_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 237 TEST_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 252 TEST_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 265 TEST_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 274 TEST_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 293 TEST_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 308 TEST_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 346 TEST_F(UsingDeclarationsSorterTest, 347 SortsUsingDeclarationsWithLeadingkComments) { 348 EXPECT_EQ("/* comment */ using a;\n" 349 "/* comment */ using b;", 350 sortUsingDeclarations("/* comment */ using b;\n" 351 "/* comment */ using a;")); 352 } 353 354 TEST_F(UsingDeclarationsSorterTest, DeduplicatesUsingDeclarations) { 355 EXPECT_EQ("using a;\n" 356 "using b;\n" 357 "using c;\n" 358 "\n" 359 "using a;\n" 360 "using e;", 361 sortUsingDeclarations("using c;\n" 362 "using a;\n" 363 "using b;\n" 364 "using a;\n" 365 "using b;\n" 366 "\n" 367 "using e;\n" 368 "using a;\n" 369 "using e;")); 370 } 371 372 } // end namespace 373 } // end namespace format 374 } // end namespace clang 375