1 //===- unittest/Format/SortIncludesTest.cpp - Include sort 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 "FormatTestUtils.h" 10 #include "clang/Format/Format.h" 11 #include "llvm/ADT/None.h" 12 #include "llvm/Support/Debug.h" 13 #include "gtest/gtest.h" 14 15 #define DEBUG_TYPE "format-test" 16 17 namespace clang { 18 namespace format { 19 namespace { 20 21 class SortIncludesTest : public ::testing::Test { 22 protected: 23 std::vector<tooling::Range> GetCodeRange(StringRef Code) { 24 return std::vector<tooling::Range>(1, tooling::Range(0, Code.size())); 25 } 26 27 std::string sort(StringRef Code, std::vector<tooling::Range> Ranges, 28 StringRef FileName = "input.cc", 29 unsigned ExpectedNumRanges = 1) { 30 auto Replaces = sortIncludes(FmtStyle, Code, Ranges, FileName); 31 Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); 32 EXPECT_EQ(ExpectedNumRanges, Replaces.size()); 33 auto Sorted = applyAllReplacements(Code, Replaces); 34 EXPECT_TRUE(static_cast<bool>(Sorted)); 35 auto Result = applyAllReplacements( 36 *Sorted, reformat(FmtStyle, *Sorted, Ranges, FileName)); 37 EXPECT_TRUE(static_cast<bool>(Result)); 38 return *Result; 39 } 40 41 std::string sort(StringRef Code, StringRef FileName = "input.cpp", 42 unsigned ExpectedNumRanges = 1) { 43 return sort(Code, GetCodeRange(Code), FileName, ExpectedNumRanges); 44 } 45 46 unsigned newCursor(llvm::StringRef Code, unsigned Cursor) { 47 sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.cpp", &Cursor); 48 return Cursor; 49 } 50 51 FormatStyle FmtStyle = getLLVMStyle(); 52 tooling::IncludeStyle &Style = FmtStyle.IncludeStyle; 53 }; 54 55 TEST_F(SortIncludesTest, BasicSorting) { 56 EXPECT_EQ("#include \"a.h\"\n" 57 "#include \"b.h\"\n" 58 "#include \"c.h\"\n", 59 sort("#include \"a.h\"\n" 60 "#include \"c.h\"\n" 61 "#include \"b.h\"\n")); 62 63 EXPECT_EQ("// comment\n" 64 "#include <a>\n" 65 "#include <b>\n", 66 sort("// comment\n" 67 "#include <b>\n" 68 "#include <a>\n", 69 {tooling::Range(25, 1)})); 70 } 71 72 TEST_F(SortIncludesTest, SortedIncludesUsingSortPriorityAttribute) { 73 FmtStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 74 FmtStyle.IncludeStyle.IncludeCategories = { 75 {"^<sys/param\\.h>", 1, 0, false}, 76 {"^<sys/types\\.h>", 1, 1, false}, 77 {"^<sys.*/", 1, 2, false}, 78 {"^<uvm/", 2, 3, false}, 79 {"^<machine/", 3, 4, false}, 80 {"^<dev/", 4, 5, false}, 81 {"^<net.*/", 5, 6, false}, 82 {"^<protocols/", 5, 7, false}, 83 {"^<(fs|miscfs|msdosfs|nfs|ntfs|ufs)/", 6, 8, false}, 84 {"^<(x86|amd64|i386|xen)/", 7, 8, false}, 85 {"<path", 9, 11, false}, 86 {"^<[^/].*\\.h>", 8, 10, false}, 87 {"^\".*\\.h\"", 10, 12, false}}; 88 EXPECT_EQ("#include <sys/param.h>\n" 89 "#include <sys/types.h>\n" 90 "#include <sys/ioctl.h>\n" 91 "#include <sys/socket.h>\n" 92 "#include <sys/stat.h>\n" 93 "#include <sys/wait.h>\n" 94 "\n" 95 "#include <net/if.h>\n" 96 "#include <net/if_dl.h>\n" 97 "#include <net/route.h>\n" 98 "#include <netinet/in.h>\n" 99 "#include <protocols/rwhod.h>\n" 100 "\n" 101 "#include <assert.h>\n" 102 "#include <errno.h>\n" 103 "#include <inttypes.h>\n" 104 "#include <stdio.h>\n" 105 "#include <stdlib.h>\n" 106 "\n" 107 "#include <paths.h>\n" 108 "\n" 109 "#include \"pathnames.h\"\n", 110 sort("#include <sys/param.h>\n" 111 "#include <sys/types.h>\n" 112 "#include <sys/ioctl.h>\n" 113 "#include <net/if_dl.h>\n" 114 "#include <net/route.h>\n" 115 "#include <netinet/in.h>\n" 116 "#include <sys/socket.h>\n" 117 "#include <sys/stat.h>\n" 118 "#include <sys/wait.h>\n" 119 "#include <net/if.h>\n" 120 "#include <protocols/rwhod.h>\n" 121 "#include <assert.h>\n" 122 "#include <paths.h>\n" 123 "#include \"pathnames.h\"\n" 124 "#include <errno.h>\n" 125 "#include <inttypes.h>\n" 126 "#include <stdio.h>\n" 127 "#include <stdlib.h>\n")); 128 } 129 TEST_F(SortIncludesTest, SortPriorityNotDefined) { 130 FmtStyle = getLLVMStyle(); 131 EXPECT_EQ("#include \"FormatTestUtils.h\"\n" 132 "#include \"clang/Format/Format.h\"\n" 133 "#include \"llvm/ADT/None.h\"\n" 134 "#include \"llvm/Support/Debug.h\"\n" 135 "#include \"gtest/gtest.h\"\n", 136 sort("#include \"clang/Format/Format.h\"\n" 137 "#include \"llvm/ADT/None.h\"\n" 138 "#include \"FormatTestUtils.h\"\n" 139 "#include \"gtest/gtest.h\"\n" 140 "#include \"llvm/Support/Debug.h\"\n")); 141 } 142 143 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) { 144 // Identical #includes have led to a failure with an unstable sort. 145 std::string Code = "#include <a>\n" 146 "#include <b>\n" 147 "#include <c>\n" 148 "#include <d>\n" 149 "#include <e>\n" 150 "#include <f>\n"; 151 EXPECT_TRUE(sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a.cc").empty()); 152 } 153 154 TEST_F(SortIncludesTest, MainFileHeader) { 155 std::string Code = "#include <string>\n" 156 "\n" 157 "#include \"a/extra_action.proto.h\"\n"; 158 FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp); 159 EXPECT_TRUE( 160 sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a/extra_action.cc") 161 .empty()); 162 163 EXPECT_EQ("#include \"foo.bar.h\"\n" 164 "\n" 165 "#include \"a.h\"\n", 166 sort("#include \"a.h\"\n" 167 "#include \"foo.bar.h\"\n", 168 "foo.bar.cc")); 169 } 170 171 TEST_F(SortIncludesTest, SortedIncludesInMultipleBlocksAreMerged) { 172 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 173 EXPECT_EQ("#include \"a.h\"\n" 174 "#include \"b.h\"\n" 175 "#include \"c.h\"\n", 176 sort("#include \"a.h\"\n" 177 "#include \"c.h\"\n" 178 "\n" 179 "\n" 180 "#include \"b.h\"\n")); 181 182 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 183 EXPECT_EQ("#include \"a.h\"\n" 184 "#include \"b.h\"\n" 185 "#include \"c.h\"\n", 186 sort("#include \"a.h\"\n" 187 "#include \"c.h\"\n" 188 "\n" 189 "\n" 190 "#include \"b.h\"\n")); 191 } 192 193 TEST_F(SortIncludesTest, SupportClangFormatOff) { 194 EXPECT_EQ("#include <a>\n" 195 "#include <b>\n" 196 "#include <c>\n" 197 "// clang-format off\n" 198 "#include <b>\n" 199 "#include <a>\n" 200 "#include <c>\n" 201 "// clang-format on\n", 202 sort("#include <b>\n" 203 "#include <a>\n" 204 "#include <c>\n" 205 "// clang-format off\n" 206 "#include <b>\n" 207 "#include <a>\n" 208 "#include <c>\n" 209 "// clang-format on\n")); 210 211 Style.IncludeBlocks = Style.IBS_Merge; 212 std::string Code = "// clang-format off\r\n" 213 "#include \"d.h\"\r\n" 214 "#include \"b.h\"\r\n" 215 "// clang-format on\r\n" 216 "\r\n" 217 "#include \"c.h\"\r\n" 218 "#include \"a.h\"\r\n" 219 "#include \"e.h\"\r\n"; 220 221 std::string Expected = "// clang-format off\r\n" 222 "#include \"d.h\"\r\n" 223 "#include \"b.h\"\r\n" 224 "// clang-format on\r\n" 225 "\r\n" 226 "#include \"e.h\"\r\n" 227 "#include \"a.h\"\r\n" 228 "#include \"c.h\"\r\n"; 229 230 EXPECT_EQ(Expected, sort(Code, "e.cpp", 1)); 231 } 232 233 TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) { 234 EXPECT_EQ("#include <a>\n" 235 "#include <b>\n" 236 "#include <c>\n" 237 "/* clang-format off */\n" 238 "#include <b>\n" 239 "#include <a>\n" 240 "#include <c>\n" 241 "/* clang-format on */\n", 242 sort("#include <b>\n" 243 "#include <a>\n" 244 "#include <c>\n" 245 "/* clang-format off */\n" 246 "#include <b>\n" 247 "#include <a>\n" 248 "#include <c>\n" 249 "/* clang-format on */\n")); 250 251 // Not really turning it off 252 EXPECT_EQ("#include <a>\n" 253 "#include <b>\n" 254 "#include <c>\n" 255 "/* clang-format offically */\n" 256 "#include <a>\n" 257 "#include <b>\n" 258 "#include <c>\n" 259 "/* clang-format onwards */\n", 260 sort("#include <b>\n" 261 "#include <a>\n" 262 "#include <c>\n" 263 "/* clang-format offically */\n" 264 "#include <b>\n" 265 "#include <a>\n" 266 "#include <c>\n" 267 "/* clang-format onwards */\n", 268 "input.h", 2)); 269 } 270 271 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) { 272 FmtStyle.SortIncludes = false; 273 EXPECT_EQ("#include \"a.h\"\n" 274 "#include \"c.h\"\n" 275 "#include \"b.h\"\n", 276 sort("#include \"a.h\"\n" 277 "#include \"c.h\"\n" 278 "#include \"b.h\"\n", 279 "input.h", 0)); 280 } 281 282 TEST_F(SortIncludesTest, MixIncludeAndImport) { 283 EXPECT_EQ("#include \"a.h\"\n" 284 "#import \"b.h\"\n" 285 "#include \"c.h\"\n", 286 sort("#include \"a.h\"\n" 287 "#include \"c.h\"\n" 288 "#import \"b.h\"\n")); 289 } 290 291 TEST_F(SortIncludesTest, FixTrailingComments) { 292 EXPECT_EQ("#include \"a.h\" // comment\n" 293 "#include \"bb.h\" // comment\n" 294 "#include \"ccc.h\"\n", 295 sort("#include \"a.h\" // comment\n" 296 "#include \"ccc.h\"\n" 297 "#include \"bb.h\" // comment\n")); 298 } 299 300 TEST_F(SortIncludesTest, LeadingWhitespace) { 301 EXPECT_EQ("#include \"a.h\"\n" 302 "#include \"b.h\"\n" 303 "#include \"c.h\"\n", 304 sort(" #include \"a.h\"\n" 305 " #include \"c.h\"\n" 306 " #include \"b.h\"\n")); 307 EXPECT_EQ("#include \"a.h\"\n" 308 "#include \"b.h\"\n" 309 "#include \"c.h\"\n", 310 sort("# include \"a.h\"\n" 311 "# include \"c.h\"\n" 312 "# include \"b.h\"\n")); 313 EXPECT_EQ("#include \"a.h\"\n", sort("#include \"a.h\"\n" 314 " #include \"a.h\"\n")); 315 } 316 317 TEST_F(SortIncludesTest, TrailingWhitespace) { 318 EXPECT_EQ("#include \"a.h\"\n" 319 "#include \"b.h\"\n" 320 "#include \"c.h\"\n", 321 sort("#include \"a.h\" \n" 322 "#include \"c.h\" \n" 323 "#include \"b.h\" \n")); 324 EXPECT_EQ("#include \"a.h\"\n", sort("#include \"a.h\"\n" 325 "#include \"a.h\" \n")); 326 } 327 328 TEST_F(SortIncludesTest, GreaterInComment) { 329 EXPECT_EQ("#include \"a.h\"\n" 330 "#include \"b.h\" // >\n" 331 "#include \"c.h\"\n", 332 sort("#include \"a.h\"\n" 333 "#include \"c.h\"\n" 334 "#include \"b.h\" // >\n")); 335 } 336 337 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) { 338 EXPECT_EQ("#include \"a.h\"\n" 339 "#include \"c.h\"\n" 340 "\n" 341 "#include \"b.h\"\n", 342 sort("#include \"a.h\"\n" 343 "#include \"c.h\"\n" 344 "\n" 345 "#include \"b.h\"\n", 346 "input.h", 0)); 347 } 348 349 TEST_F(SortIncludesTest, SortsAllBlocksWhenMerging) { 350 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 351 EXPECT_EQ("#include \"a.h\"\n" 352 "#include \"b.h\"\n" 353 "#include \"c.h\"\n", 354 sort("#include \"a.h\"\n" 355 "#include \"c.h\"\n" 356 "\n" 357 "#include \"b.h\"\n")); 358 } 359 360 TEST_F(SortIncludesTest, CommentsAlwaysSeparateGroups) { 361 EXPECT_EQ("#include \"a.h\"\n" 362 "#include \"c.h\"\n" 363 "// comment\n" 364 "#include \"b.h\"\n", 365 sort("#include \"c.h\"\n" 366 "#include \"a.h\"\n" 367 "// comment\n" 368 "#include \"b.h\"\n")); 369 370 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 371 EXPECT_EQ("#include \"a.h\"\n" 372 "#include \"c.h\"\n" 373 "// comment\n" 374 "#include \"b.h\"\n", 375 sort("#include \"c.h\"\n" 376 "#include \"a.h\"\n" 377 "// comment\n" 378 "#include \"b.h\"\n")); 379 380 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 381 EXPECT_EQ("#include \"a.h\"\n" 382 "#include \"c.h\"\n" 383 "// comment\n" 384 "#include \"b.h\"\n", 385 sort("#include \"c.h\"\n" 386 "#include \"a.h\"\n" 387 "// comment\n" 388 "#include \"b.h\"\n")); 389 } 390 391 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) { 392 EXPECT_EQ("#include \"a.h\"\n" 393 "#include \"c.h\"\n" 394 "#include <array>\n" 395 "#include <b.h>\n" 396 "#include <d.h>\n" 397 "#include <vector>\n", 398 sort("#include <vector>\n" 399 "#include <d.h>\n" 400 "#include <array>\n" 401 "#include <b.h>\n" 402 "#include \"c.h\"\n" 403 "#include \"a.h\"\n")); 404 405 FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp); 406 EXPECT_EQ("#include <b.h>\n" 407 "#include <d.h>\n" 408 "\n" 409 "#include <array>\n" 410 "#include <vector>\n" 411 "\n" 412 "#include \"a.h\"\n" 413 "#include \"c.h\"\n", 414 sort("#include <vector>\n" 415 "#include <d.h>\n" 416 "#include <array>\n" 417 "#include <b.h>\n" 418 "#include \"c.h\"\n" 419 "#include \"a.h\"\n")); 420 } 421 422 TEST_F(SortIncludesTest, RegroupsAngledIncludesInSeparateBlocks) { 423 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 424 EXPECT_EQ("#include \"a.h\"\n" 425 "#include \"c.h\"\n" 426 "\n" 427 "#include <b.h>\n" 428 "#include <d.h>\n", 429 sort("#include <d.h>\n" 430 "#include <b.h>\n" 431 "#include \"c.h\"\n" 432 "#include \"a.h\"\n")); 433 } 434 435 TEST_F(SortIncludesTest, HandlesMultilineIncludes) { 436 EXPECT_EQ("#include \"a.h\"\n" 437 "#include \"b.h\"\n" 438 "#include \"c.h\"\n", 439 sort("#include \"a.h\"\n" 440 "#include \\\n" 441 "\"c.h\"\n" 442 "#include \"b.h\"\n")); 443 } 444 445 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { 446 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 447 EXPECT_EQ("#include \"llvm/a.h\"\n" 448 "#include \"b.h\"\n" 449 "#include \"c.h\"\n", 450 sort("#include \"llvm/a.h\"\n" 451 "#include \"c.h\"\n" 452 "#include \"b.h\"\n", 453 "a.cc")); 454 EXPECT_EQ("#include \"llvm/a.h\"\n" 455 "#include \"b.h\"\n" 456 "#include \"c.h\"\n", 457 sort("#include \"llvm/a.h\"\n" 458 "#include \"c.h\"\n" 459 "#include \"b.h\"\n", 460 "a_test.cc")); 461 EXPECT_EQ("#include \"llvm/input.h\"\n" 462 "#include \"b.h\"\n" 463 "#include \"c.h\"\n", 464 sort("#include \"llvm/input.h\"\n" 465 "#include \"c.h\"\n" 466 "#include \"b.h\"\n", 467 "input.mm")); 468 469 // Don't allow prefixes. 470 EXPECT_EQ("#include \"b.h\"\n" 471 "#include \"c.h\"\n" 472 "#include \"llvm/not_a.h\"\n", 473 sort("#include \"llvm/not_a.h\"\n" 474 "#include \"c.h\"\n" 475 "#include \"b.h\"\n", 476 "a.cc")); 477 478 // Don't do this for _main and other suffixes. 479 EXPECT_EQ("#include \"b.h\"\n" 480 "#include \"c.h\"\n" 481 "#include \"llvm/a.h\"\n", 482 sort("#include \"llvm/a.h\"\n" 483 "#include \"c.h\"\n" 484 "#include \"b.h\"\n", 485 "a_main.cc")); 486 487 // Don't do this in headers. 488 EXPECT_EQ("#include \"b.h\"\n" 489 "#include \"c.h\"\n" 490 "#include \"llvm/a.h\"\n", 491 sort("#include \"llvm/a.h\"\n" 492 "#include \"c.h\"\n" 493 "#include \"b.h\"\n", 494 "a.h")); 495 496 // Only do this in the first #include block. 497 EXPECT_EQ("#include <a>\n" 498 "\n" 499 "#include \"b.h\"\n" 500 "#include \"c.h\"\n" 501 "#include \"llvm/a.h\"\n", 502 sort("#include <a>\n" 503 "\n" 504 "#include \"llvm/a.h\"\n" 505 "#include \"c.h\"\n" 506 "#include \"b.h\"\n", 507 "a.cc")); 508 509 // Only recognize the first #include with a matching basename as main include. 510 EXPECT_EQ("#include \"a.h\"\n" 511 "#include \"b.h\"\n" 512 "#include \"c.h\"\n" 513 "#include \"llvm/a.h\"\n", 514 sort("#include \"b.h\"\n" 515 "#include \"a.h\"\n" 516 "#include \"c.h\"\n" 517 "#include \"llvm/a.h\"\n", 518 "a.cc")); 519 } 520 521 TEST_F(SortIncludesTest, LeavesMainHeaderFirstInAdditionalExtensions) { 522 Style.IncludeIsMainRegex = "([-_](test|unittest))?|(Impl)?$"; 523 EXPECT_EQ("#include \"b.h\"\n" 524 "#include \"c.h\"\n" 525 "#include \"llvm/a.h\"\n", 526 sort("#include \"llvm/a.h\"\n" 527 "#include \"c.h\"\n" 528 "#include \"b.h\"\n", 529 "a_test.xxx")); 530 EXPECT_EQ("#include \"b.h\"\n" 531 "#include \"c.h\"\n" 532 "#include \"llvm/a.h\"\n", 533 sort("#include \"llvm/a.h\"\n" 534 "#include \"c.h\"\n" 535 "#include \"b.h\"\n", 536 "aImpl.hpp")); 537 538 // .cpp extension is considered "main" by default 539 EXPECT_EQ("#include \"llvm/a.h\"\n" 540 "#include \"b.h\"\n" 541 "#include \"c.h\"\n", 542 sort("#include \"llvm/a.h\"\n" 543 "#include \"c.h\"\n" 544 "#include \"b.h\"\n", 545 "aImpl.cpp")); 546 EXPECT_EQ("#include \"llvm/a.h\"\n" 547 "#include \"b.h\"\n" 548 "#include \"c.h\"\n", 549 sort("#include \"llvm/a.h\"\n" 550 "#include \"c.h\"\n" 551 "#include \"b.h\"\n", 552 "a_test.cpp")); 553 554 // Allow additional filenames / extensions 555 Style.IncludeIsMainSourceRegex = "(Impl\\.hpp)|(\\.xxx)$"; 556 EXPECT_EQ("#include \"llvm/a.h\"\n" 557 "#include \"b.h\"\n" 558 "#include \"c.h\"\n", 559 sort("#include \"llvm/a.h\"\n" 560 "#include \"c.h\"\n" 561 "#include \"b.h\"\n", 562 "a_test.xxx")); 563 EXPECT_EQ("#include \"llvm/a.h\"\n" 564 "#include \"b.h\"\n" 565 "#include \"c.h\"\n", 566 sort("#include \"llvm/a.h\"\n" 567 "#include \"c.h\"\n" 568 "#include \"b.h\"\n", 569 "aImpl.hpp")); 570 } 571 572 TEST_F(SortIncludesTest, RecognizeMainHeaderInAllGroups) { 573 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 574 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 575 576 EXPECT_EQ("#include \"c.h\"\n" 577 "#include \"a.h\"\n" 578 "#include \"b.h\"\n", 579 sort("#include \"b.h\"\n" 580 "\n" 581 "#include \"a.h\"\n" 582 "#include \"c.h\"\n", 583 "c.cc")); 584 } 585 586 TEST_F(SortIncludesTest, MainHeaderIsSeparatedWhenRegroupping) { 587 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 588 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 589 590 EXPECT_EQ("#include \"a.h\"\n" 591 "\n" 592 "#include \"b.h\"\n" 593 "#include \"c.h\"\n", 594 sort("#include \"b.h\"\n" 595 "\n" 596 "#include \"a.h\"\n" 597 "#include \"c.h\"\n", 598 "a.cc")); 599 } 600 601 TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) { 602 // Setup an regex for main includes so we can cover those as well. 603 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 604 605 // Ensure both main header detection and grouping work in a case insensitive 606 // manner. 607 EXPECT_EQ("#include \"llvm/A.h\"\n" 608 "#include \"b.h\"\n" 609 "#include \"c.h\"\n" 610 "#include \"LLVM/z.h\"\n" 611 "#include \"llvm/X.h\"\n" 612 "#include \"GTest/GTest.h\"\n" 613 "#include \"gmock/gmock.h\"\n", 614 sort("#include \"c.h\"\n" 615 "#include \"b.h\"\n" 616 "#include \"GTest/GTest.h\"\n" 617 "#include \"llvm/A.h\"\n" 618 "#include \"gmock/gmock.h\"\n" 619 "#include \"llvm/X.h\"\n" 620 "#include \"LLVM/z.h\"\n", 621 "a_TEST.cc")); 622 } 623 624 TEST_F(SortIncludesTest, SupportOptionalCaseSensitiveMachting) { 625 Style.IncludeBlocks = clang::tooling::IncludeStyle::IBS_Regroup; 626 Style.IncludeCategories = {{"^\"", 1, 0, false}, 627 {"^<.*\\.h>$", 2, 0, false}, 628 {"^<Q[A-Z][^\\.]*>", 3, 0, false}, 629 {"^<Qt[^\\.]*>", 4, 0, false}, 630 {"^<", 5, 0, false}}; 631 632 StringRef UnsortedCode = "#include <QWidget>\n" 633 "#include \"qt.h\"\n" 634 "#include <algorithm>\n" 635 "#include <windows.h>\n" 636 "#include <QLabel>\n" 637 "#include \"qa.h\"\n" 638 "#include <queue>\n" 639 "#include <qtwhatever.h>\n" 640 "#include <QtGlobal>\n"; 641 642 EXPECT_EQ("#include \"qa.h\"\n" 643 "#include \"qt.h\"\n" 644 "\n" 645 "#include <qtwhatever.h>\n" 646 "#include <windows.h>\n" 647 "\n" 648 "#include <QLabel>\n" 649 "#include <QWidget>\n" 650 "#include <QtGlobal>\n" 651 "#include <queue>\n" 652 "\n" 653 "#include <algorithm>\n", 654 sort(UnsortedCode)); 655 656 Style.IncludeCategories[2].RegexIsCaseSensitive = true; 657 Style.IncludeCategories[3].RegexIsCaseSensitive = true; 658 EXPECT_EQ("#include \"qa.h\"\n" 659 "#include \"qt.h\"\n" 660 "\n" 661 "#include <qtwhatever.h>\n" 662 "#include <windows.h>\n" 663 "\n" 664 "#include <QLabel>\n" 665 "#include <QWidget>\n" 666 "\n" 667 "#include <QtGlobal>\n" 668 "\n" 669 "#include <algorithm>\n" 670 "#include <queue>\n", 671 sort(UnsortedCode)); 672 } 673 674 TEST_F(SortIncludesTest, NegativePriorities) { 675 Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false}, 676 {".*", 1, 0, false}}; 677 EXPECT_EQ("#include \"important_os_header.h\"\n" 678 "#include \"c_main.h\"\n" 679 "#include \"a_other.h\"\n", 680 sort("#include \"c_main.h\"\n" 681 "#include \"a_other.h\"\n" 682 "#include \"important_os_header.h\"\n", 683 "c_main.cc")); 684 685 // check stable when re-run 686 EXPECT_EQ("#include \"important_os_header.h\"\n" 687 "#include \"c_main.h\"\n" 688 "#include \"a_other.h\"\n", 689 sort("#include \"important_os_header.h\"\n" 690 "#include \"c_main.h\"\n" 691 "#include \"a_other.h\"\n", 692 "c_main.cc", 0)); 693 } 694 695 TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) { 696 Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false}, 697 {".*", 1, 0, false}}; 698 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 699 700 EXPECT_EQ("#include \"important_os_header.h\"\n" 701 "\n" 702 "#include \"c_main.h\"\n" 703 "\n" 704 "#include \"a_other.h\"\n", 705 sort("#include \"c_main.h\"\n" 706 "#include \"a_other.h\"\n" 707 "#include \"important_os_header.h\"\n", 708 "c_main.cc")); 709 710 // check stable when re-run 711 EXPECT_EQ("#include \"important_os_header.h\"\n" 712 "\n" 713 "#include \"c_main.h\"\n" 714 "\n" 715 "#include \"a_other.h\"\n", 716 sort("#include \"important_os_header.h\"\n" 717 "\n" 718 "#include \"c_main.h\"\n" 719 "\n" 720 "#include \"a_other.h\"\n", 721 "c_main.cc", 0)); 722 } 723 724 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { 725 std::string Code = "#include <ccc>\n" // Start of line: 0 726 "#include <bbbbbb>\n" // Start of line: 15 727 "#include <a>\n"; // Start of line: 33 728 EXPECT_EQ(31u, newCursor(Code, 0)); 729 EXPECT_EQ(13u, newCursor(Code, 15)); 730 EXPECT_EQ(0u, newCursor(Code, 33)); 731 732 EXPECT_EQ(41u, newCursor(Code, 10)); 733 EXPECT_EQ(23u, newCursor(Code, 25)); 734 EXPECT_EQ(10u, newCursor(Code, 43)); 735 } 736 737 TEST_F(SortIncludesTest, DeduplicateIncludes) { 738 EXPECT_EQ("#include <a>\n" 739 "#include <b>\n" 740 "#include <c>\n", 741 sort("#include <a>\n" 742 "#include <b>\n" 743 "#include <b>\n" 744 "#include <b>\n" 745 "#include <b>\n" 746 "#include <c>\n")); 747 748 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 749 EXPECT_EQ("#include <a>\n" 750 "#include <b>\n" 751 "#include <c>\n", 752 sort("#include <a>\n" 753 "#include <b>\n" 754 "\n" 755 "#include <b>\n" 756 "\n" 757 "#include <b>\n" 758 "#include <c>\n")); 759 760 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 761 EXPECT_EQ("#include <a>\n" 762 "#include <b>\n" 763 "#include <c>\n", 764 sort("#include <a>\n" 765 "#include <b>\n" 766 "\n" 767 "#include <b>\n" 768 "\n" 769 "#include <b>\n" 770 "#include <c>\n")); 771 } 772 773 TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) { 774 EXPECT_EQ("#include <a>\n" 775 "#include <b>\n" 776 "#include <c>\n", 777 sort("#include <b>\n" 778 "#include <a>\n" 779 "#include <b>\n" 780 "#include <b>\n" 781 "#include <c>\n" 782 "#include <b>\n")); 783 784 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 785 EXPECT_EQ("#include <a>\n" 786 "#include <b>\n" 787 "#include <c>\n", 788 sort("#include <b>\n" 789 "#include <a>\n" 790 "\n" 791 "#include <b>\n" 792 "\n" 793 "#include <c>\n" 794 "#include <b>\n")); 795 796 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 797 EXPECT_EQ("#include <a>\n" 798 "#include <b>\n" 799 "#include <c>\n", 800 sort("#include <b>\n" 801 "#include <a>\n" 802 "\n" 803 "#include <b>\n" 804 "\n" 805 "#include <c>\n" 806 "#include <b>\n")); 807 } 808 809 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) { 810 std::string Code = "#include <b>\n" // Start of line: 0 811 "#include <a>\n" // Start of line: 13 812 "#include <b>\n" // Start of line: 26 813 "#include <b>\n" // Start of line: 39 814 "#include <c>\n" // Start of line: 52 815 "#include <b>\n"; // Start of line: 65 816 std::string Expected = "#include <a>\n" // Start of line: 0 817 "#include <b>\n" // Start of line: 13 818 "#include <c>\n"; // Start of line: 26 819 EXPECT_EQ(Expected, sort(Code)); 820 // Cursor on 'i' in "#include <a>". 821 EXPECT_EQ(1u, newCursor(Code, 14)); 822 // Cursor on 'b' in "#include <b>". 823 EXPECT_EQ(23u, newCursor(Code, 10)); 824 EXPECT_EQ(23u, newCursor(Code, 36)); 825 EXPECT_EQ(23u, newCursor(Code, 49)); 826 EXPECT_EQ(23u, newCursor(Code, 36)); 827 EXPECT_EQ(23u, newCursor(Code, 75)); 828 // Cursor on '#' in "#include <c>". 829 EXPECT_EQ(26u, newCursor(Code, 52)); 830 } 831 832 TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) { 833 EXPECT_EQ("#include <a>\n" 834 "#include <b>\n" 835 "\n" 836 "#include <b>\n" 837 "#include <c>\n", 838 sort("#include <a>\n" 839 "#include <b>\n" 840 "\n" 841 "#include <c>\n" 842 "#include <b>\n" 843 "#include <b>\n")); 844 } 845 846 TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) { 847 std::string Code = "#include <a>\n" 848 "#include <b>\n" 849 "#include <a>\n" 850 "#include <a>\n" 851 "\n" 852 " int x ;"; 853 std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)}; 854 auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp"); 855 Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); 856 EXPECT_EQ(1u, Ranges.size()); 857 EXPECT_EQ(0u, Ranges[0].getOffset()); 858 EXPECT_EQ(26u, Ranges[0].getLength()); 859 } 860 861 TEST_F(SortIncludesTest, DoNotSortLikelyXml) { 862 EXPECT_EQ("<!--;\n" 863 "#include <b>\n" 864 "#include <a>\n" 865 "-->", 866 sort("<!--;\n" 867 "#include <b>\n" 868 "#include <a>\n" 869 "-->", 870 "input.h", 0)); 871 } 872 873 TEST_F(SortIncludesTest, DoNotOutputReplacementsForSortedBlocksWithRegrouping) { 874 Style.IncludeBlocks = Style.IBS_Regroup; 875 std::string Code = R"( 876 #include "b.h" 877 878 #include <a.h> 879 )"; 880 EXPECT_EQ(Code, sort(Code, "input.h", 0)); 881 } 882 883 TEST_F(SortIncludesTest, 884 DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows) { 885 Style.IncludeBlocks = Style.IBS_Regroup; 886 std::string Code = "#include \"b.h\"\r\n" 887 "\r\n" 888 "#include <a.h>\r\n"; 889 EXPECT_EQ(Code, sort(Code, "input.h", 0)); 890 } 891 892 TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) { 893 FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC); 894 895 EXPECT_EQ("#include <a.h>\n" 896 "#include <b.h>\n" 897 "#include \"a.h\"", 898 sort("#include <b.h>\n" 899 "#include <a.h>\n" 900 "#include \"a.h\"")); 901 } 902 903 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkMerge) { 904 Style.IncludeBlocks = Style.IBS_Merge; 905 std::string Code = "\xEF\xBB\xBF#include \"d.h\"\r\n" 906 "#include \"b.h\"\r\n" 907 "\r\n" 908 "#include \"c.h\"\r\n" 909 "#include \"a.h\"\r\n" 910 "#include \"e.h\"\r\n"; 911 912 std::string Expected = "\xEF\xBB\xBF#include \"e.h\"\r\n" 913 "#include \"a.h\"\r\n" 914 "#include \"b.h\"\r\n" 915 "#include \"c.h\"\r\n" 916 "#include \"d.h\"\r\n"; 917 918 EXPECT_EQ(Expected, sort(Code, "e.cpp", 1)); 919 } 920 921 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkPreserve) { 922 Style.IncludeBlocks = Style.IBS_Preserve; 923 std::string Code = "\xEF\xBB\xBF#include \"d.h\"\r\n" 924 "#include \"b.h\"\r\n" 925 "\r\n" 926 "#include \"c.h\"\r\n" 927 "#include \"a.h\"\r\n" 928 "#include \"e.h\"\r\n"; 929 930 std::string Expected = "\xEF\xBB\xBF#include \"b.h\"\r\n" 931 "#include \"d.h\"\r\n" 932 "\r\n" 933 "#include \"a.h\"\r\n" 934 "#include \"c.h\"\r\n" 935 "#include \"e.h\"\r\n"; 936 937 EXPECT_EQ(Expected, sort(Code, "e.cpp", 2)); 938 } 939 940 TEST_F(SortIncludesTest, MergeLines) { 941 Style.IncludeBlocks = Style.IBS_Merge; 942 std::string Code = "#include \"c.h\"\r\n" 943 "#include \"b\\\r\n" 944 ".h\"\r\n" 945 "#include \"a.h\"\r\n"; 946 947 std::string Expected = "#include \"a.h\"\r\n" 948 "#include \"b\\\r\n" 949 ".h\"\r\n" 950 "#include \"c.h\"\r\n"; 951 952 EXPECT_EQ(Expected, sort(Code, "a.cpp", 1)); 953 } 954 955 } // end namespace 956 } // end namespace format 957 } // end namespace clang 958