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 "FormatTestBase.h" 10 #include "clang/Format/Format.h" 11 #include "llvm/ADT/StringRef.h" 12 #include "llvm/Support/Debug.h" 13 #include "gtest/gtest.h" 14 15 #define DEBUG_TYPE "sort-includes-test" 16 17 namespace clang { 18 namespace format { 19 namespace { 20 21 class SortIncludesTest : public test::FormatTestBase { 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(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 verifyFormat("#include \"a.h\"\n" 57 "#include \"b.h\"\n" 58 "#include \"c.h\"", 59 sort("#include \"a.h\"\n" 60 "#include \"c.h\"\n" 61 "#include \"b.h\"")); 62 63 verifyFormat("// comment\n" 64 "#include <a>\n" 65 "#include <b>", 66 sort("// comment\n" 67 "#include <b>\n" 68 "#include <a>", 69 {tooling::Range(25, 1)})); 70 } 71 72 TEST_F(SortIncludesTest, TrailingComments) { 73 verifyFormat("#include \"a.h\"\n" 74 "#include \"b.h\" /* long\n" 75 " * long\n" 76 " * comment*/\n" 77 "#include \"c.h\"\n" 78 "#include \"d.h\"", 79 sort("#include \"a.h\"\n" 80 "#include \"c.h\"\n" 81 "#include \"b.h\" /* long\n" 82 " * long\n" 83 " * comment*/\n" 84 "#include \"d.h\"")); 85 } 86 87 TEST_F(SortIncludesTest, SortedIncludesUsingSortPriorityAttribute) { 88 FmtStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 89 FmtStyle.IncludeStyle.IncludeCategories = { 90 {"^<sys/param\\.h>", 1, 0, false}, 91 {"^<sys/types\\.h>", 1, 1, false}, 92 {"^<sys.*/", 1, 2, false}, 93 {"^<uvm/", 2, 3, false}, 94 {"^<machine/", 3, 4, false}, 95 {"^<dev/", 4, 5, false}, 96 {"^<net.*/", 5, 6, false}, 97 {"^<protocols/", 5, 7, false}, 98 {"^<(fs|miscfs|msdosfs|nfs|ntfs|ufs)/", 6, 8, false}, 99 {"^<(x86|amd64|i386|xen)/", 7, 8, false}, 100 {"<path", 9, 11, false}, 101 {"^<[^/].*\\.h>", 8, 10, false}, 102 {"^\".*\\.h\"", 10, 12, false}}; 103 verifyFormat("#include <sys/param.h>\n" 104 "#include <sys/types.h>\n" 105 "#include <sys/ioctl.h>\n" 106 "#include <sys/socket.h>\n" 107 "#include <sys/stat.h>\n" 108 "#include <sys/wait.h>\n" 109 "\n" 110 "#include <net/if.h>\n" 111 "#include <net/if_dl.h>\n" 112 "#include <net/route.h>\n" 113 "#include <netinet/in.h>\n" 114 "#include <protocols/rwhod.h>\n" 115 "\n" 116 "#include <assert.h>\n" 117 "#include <errno.h>\n" 118 "#include <inttypes.h>\n" 119 "#include <stdio.h>\n" 120 "#include <stdlib.h>\n" 121 "\n" 122 "#include <paths.h>\n" 123 "\n" 124 "#include \"pathnames.h\"", 125 sort("#include <sys/param.h>\n" 126 "#include <sys/types.h>\n" 127 "#include <sys/ioctl.h>\n" 128 "#include <net/if_dl.h>\n" 129 "#include <net/route.h>\n" 130 "#include <netinet/in.h>\n" 131 "#include <sys/socket.h>\n" 132 "#include <sys/stat.h>\n" 133 "#include <sys/wait.h>\n" 134 "#include <net/if.h>\n" 135 "#include <protocols/rwhod.h>\n" 136 "#include <assert.h>\n" 137 "#include <paths.h>\n" 138 "#include \"pathnames.h\"\n" 139 "#include <errno.h>\n" 140 "#include <inttypes.h>\n" 141 "#include <stdio.h>\n" 142 "#include <stdlib.h>")); 143 } 144 TEST_F(SortIncludesTest, SortPriorityNotDefined) { 145 FmtStyle = getLLVMStyle(); 146 verifyFormat("#include \"FormatTestUtils.h\"\n" 147 "#include \"clang/Format/Format.h\"\n" 148 "#include \"llvm/ADT/None.h\"\n" 149 "#include \"llvm/Support/Debug.h\"\n" 150 "#include \"gtest/gtest.h\"", 151 sort("#include \"clang/Format/Format.h\"\n" 152 "#include \"llvm/ADT/None.h\"\n" 153 "#include \"FormatTestUtils.h\"\n" 154 "#include \"gtest/gtest.h\"\n" 155 "#include \"llvm/Support/Debug.h\"")); 156 } 157 158 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) { 159 // Identical #includes have led to a failure with an unstable sort. 160 StringRef Code = "#include <a>\n" 161 "#include <b>\n" 162 "#include <c>\n" 163 "#include <d>\n" 164 "#include <e>\n" 165 "#include <f>\n"; 166 EXPECT_TRUE(sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a.cc").empty()); 167 } 168 169 TEST_F(SortIncludesTest, MainFileHeader) { 170 StringRef Code = "#include <string>\n" 171 "\n" 172 "#include \"a/extra_action.proto.h\"\n"; 173 FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp); 174 EXPECT_TRUE( 175 sortIncludes(FmtStyle, Code, GetCodeRange(Code), "a/extra_action.cc") 176 .empty()); 177 178 verifyFormat("#include \"foo.bar.h\"\n" 179 "\n" 180 "#include \"a.h\"", 181 sort("#include \"a.h\"\n" 182 "#include \"foo.bar.h\"", 183 "foo.bar.cc")); 184 } 185 186 TEST_F(SortIncludesTest, SortedIncludesInMultipleBlocksAreMerged) { 187 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 188 verifyFormat("#include \"a.h\"\n" 189 "#include \"b.h\"\n" 190 "#include \"c.h\"", 191 sort("#include \"a.h\"\n" 192 "#include \"c.h\"\n" 193 "\n" 194 "\n" 195 "#include \"b.h\"")); 196 197 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 198 verifyFormat("#include \"a.h\"\n" 199 "#include \"b.h\"\n" 200 "#include \"c.h\"", 201 sort("#include \"a.h\"\n" 202 "#include \"c.h\"\n" 203 "\n" 204 "\n" 205 "#include \"b.h\"")); 206 } 207 208 TEST_F(SortIncludesTest, SupportClangFormatOff) { 209 verifyFormat("#include <a>\n" 210 "#include <b>\n" 211 "#include <c>\n" 212 "// clang-format off\n" 213 "#include <b>\n" 214 "#include <a>\n" 215 "#include <c>\n" 216 "// clang-format on", 217 sort("#include <b>\n" 218 "#include <a>\n" 219 "#include <c>\n" 220 "// clang-format off\n" 221 "#include <b>\n" 222 "#include <a>\n" 223 "#include <c>\n" 224 "// clang-format on")); 225 226 Style.IncludeBlocks = Style.IBS_Merge; 227 StringRef Code = "// clang-format off\r\n" 228 "#include \"d.h\"\r\n" 229 "#include \"b.h\"\r\n" 230 "// clang-format on\r\n" 231 "\r\n" 232 "#include \"c.h\"\r\n" 233 "#include \"a.h\"\r\n" 234 "#include \"e.h\"\r\n"; 235 236 StringRef Expected = "// clang-format off\r\n" 237 "#include \"d.h\"\r\n" 238 "#include \"b.h\"\r\n" 239 "// clang-format on\r\n" 240 "\r\n" 241 "#include \"e.h\"\r\n" 242 "#include \"a.h\"\r\n" 243 "#include \"c.h\"\r\n"; 244 245 verifyFormat(Expected, sort(Code, "e.cpp", 1)); 246 } 247 248 TEST_F(SortIncludesTest, SupportClangFormatOffCStyle) { 249 verifyFormat("#include <a>\n" 250 "#include <b>\n" 251 "#include <c>\n" 252 "/* clang-format off */\n" 253 "#include <b>\n" 254 "#include <a>\n" 255 "#include <c>\n" 256 "/* clang-format on */", 257 sort("#include <b>\n" 258 "#include <a>\n" 259 "#include <c>\n" 260 "/* clang-format off */\n" 261 "#include <b>\n" 262 "#include <a>\n" 263 "#include <c>\n" 264 "/* clang-format on */")); 265 266 // Not really turning it off 267 verifyFormat("#include <a>\n" 268 "#include <b>\n" 269 "#include <c>\n" 270 "/* clang-format offically */\n" 271 "#include <a>\n" 272 "#include <b>\n" 273 "#include <c>\n" 274 "/* clang-format onwards */", 275 sort("#include <b>\n" 276 "#include <a>\n" 277 "#include <c>\n" 278 "/* clang-format offically */\n" 279 "#include <b>\n" 280 "#include <a>\n" 281 "#include <c>\n" 282 "/* clang-format onwards */", 283 "input.h", 2)); 284 } 285 286 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) { 287 FmtStyle.SortIncludes = FormatStyle::SI_Never; 288 verifyFormat("#include \"a.h\"\n" 289 "#include \"c.h\"\n" 290 "#include \"b.h\"", 291 sort("#include \"a.h\"\n" 292 "#include \"c.h\"\n" 293 "#include \"b.h\"", 294 "input.h", 0)); 295 } 296 297 TEST_F(SortIncludesTest, MixIncludeAndImport) { 298 verifyFormat("#include \"a.h\"\n" 299 "#import \"b.h\"\n" 300 "#include \"c.h\"", 301 sort("#include \"a.h\"\n" 302 "#include \"c.h\"\n" 303 "#import \"b.h\"")); 304 } 305 306 TEST_F(SortIncludesTest, FixTrailingComments) { 307 verifyFormat("#include \"a.h\" // comment\n" 308 "#include \"bb.h\" // comment\n" 309 "#include \"ccc.h\"", 310 sort("#include \"a.h\" // comment\n" 311 "#include \"ccc.h\"\n" 312 "#include \"bb.h\" // comment")); 313 } 314 315 TEST_F(SortIncludesTest, LeadingWhitespace) { 316 verifyFormat("#include \"a.h\"\n" 317 "#include \"b.h\"\n" 318 "#include \"c.h\"", 319 sort(" #include \"a.h\"\n" 320 " #include \"c.h\"\n" 321 " #include \"b.h\"")); 322 verifyFormat("#include \"a.h\"\n" 323 "#include \"b.h\"\n" 324 "#include \"c.h\"", 325 sort("# include \"a.h\"\n" 326 "# include \"c.h\"\n" 327 "# include \"b.h\"")); 328 verifyFormat("#include \"a.h\"", sort("#include \"a.h\"\n" 329 " #include \"a.h\"")); 330 } 331 332 TEST_F(SortIncludesTest, TrailingWhitespace) { 333 verifyFormat("#include \"a.h\"\n" 334 "#include \"b.h\"\n" 335 "#include \"c.h\"", 336 sort("#include \"a.h\" \n" 337 "#include \"c.h\" \n" 338 "#include \"b.h\" ")); 339 verifyFormat("#include \"a.h\"", sort("#include \"a.h\"\n" 340 "#include \"a.h\" ")); 341 } 342 343 TEST_F(SortIncludesTest, GreaterInComment) { 344 verifyFormat("#include \"a.h\"\n" 345 "#include \"b.h\" // >\n" 346 "#include \"c.h\"", 347 sort("#include \"a.h\"\n" 348 "#include \"c.h\"\n" 349 "#include \"b.h\" // >")); 350 } 351 352 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) { 353 verifyFormat("#include \"a.h\"\n" 354 "#include \"c.h\"\n" 355 "\n" 356 "#include \"b.h\"", 357 sort("#include \"a.h\"\n" 358 "#include \"c.h\"\n" 359 "\n" 360 "#include \"b.h\"", 361 "input.h", 0)); 362 } 363 364 TEST_F(SortIncludesTest, SortsAllBlocksWhenMerging) { 365 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 366 verifyFormat("#include \"a.h\"\n" 367 "#include \"b.h\"\n" 368 "#include \"c.h\"", 369 sort("#include \"a.h\"\n" 370 "#include \"c.h\"\n" 371 "\n" 372 "#include \"b.h\"")); 373 } 374 375 TEST_F(SortIncludesTest, CommentsAlwaysSeparateGroups) { 376 verifyFormat("#include \"a.h\"\n" 377 "#include \"c.h\"\n" 378 "// comment\n" 379 "#include \"b.h\"", 380 sort("#include \"c.h\"\n" 381 "#include \"a.h\"\n" 382 "// comment\n" 383 "#include \"b.h\"")); 384 385 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 386 verifyFormat("#include \"a.h\"\n" 387 "#include \"c.h\"\n" 388 "// comment\n" 389 "#include \"b.h\"", 390 sort("#include \"c.h\"\n" 391 "#include \"a.h\"\n" 392 "// comment\n" 393 "#include \"b.h\"")); 394 395 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 396 verifyFormat("#include \"a.h\"\n" 397 "#include \"c.h\"\n" 398 "// comment\n" 399 "#include \"b.h\"", 400 sort("#include \"c.h\"\n" 401 "#include \"a.h\"\n" 402 "// comment\n" 403 "#include \"b.h\"")); 404 } 405 406 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) { 407 verifyFormat("#include \"a.h\"\n" 408 "#include \"c.h\"\n" 409 "#include <array>\n" 410 "#include <b.h>\n" 411 "#include <d.h>\n" 412 "#include <vector>", 413 sort("#include <vector>\n" 414 "#include <d.h>\n" 415 "#include <array>\n" 416 "#include <b.h>\n" 417 "#include \"c.h\"\n" 418 "#include \"a.h\"")); 419 420 FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp); 421 verifyFormat("#include <b.h>\n" 422 "#include <d.h>\n" 423 "\n" 424 "#include <array>\n" 425 "#include <vector>\n" 426 "\n" 427 "#include \"a.h\"\n" 428 "#include \"c.h\"", 429 sort("#include <vector>\n" 430 "#include <d.h>\n" 431 "#include <array>\n" 432 "#include <b.h>\n" 433 "#include \"c.h\"\n" 434 "#include \"a.h\"")); 435 } 436 437 TEST_F(SortIncludesTest, RegroupsAngledIncludesInSeparateBlocks) { 438 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 439 verifyFormat("#include \"a.h\"\n" 440 "#include \"c.h\"\n" 441 "\n" 442 "#include <b.h>\n" 443 "#include <d.h>", 444 sort("#include <d.h>\n" 445 "#include <b.h>\n" 446 "#include \"c.h\"\n" 447 "#include \"a.h\"")); 448 } 449 450 TEST_F(SortIncludesTest, HandlesMultilineIncludes) { 451 verifyFormat("#include \"a.h\"\n" 452 "#include \"b.h\"\n" 453 "#include \"c.h\"", 454 sort("#include \"a.h\"\n" 455 "#include \\\n" 456 "\"c.h\"\n" 457 "#include \"b.h\"")); 458 } 459 460 TEST_F(SortIncludesTest, HandlesTrailingCommentsWithAngleBrackets) { 461 // Regression test from the discussion at https://reviews.llvm.org/D121370. 462 verifyFormat("#include <cstdint>\n" 463 "\n" 464 "#include \"util/bar.h\"\n" 465 "#include \"util/foo/foo.h\" // foo<T>", 466 sort("#include <cstdint>\n" 467 "\n" 468 "#include \"util/bar.h\"\n" 469 "#include \"util/foo/foo.h\" // foo<T>", 470 /*FileName=*/"input.cc", 471 /*ExpectedNumRanges=*/0)); 472 } 473 474 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { 475 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 476 verifyFormat("#include \"llvm/a.h\"\n" 477 "#include \"b.h\"\n" 478 "#include \"c.h\"", 479 sort("#include \"llvm/a.h\"\n" 480 "#include \"c.h\"\n" 481 "#include \"b.h\"", 482 "a.cc")); 483 verifyFormat("#include \"llvm/a.h\"\n" 484 "#include \"b.h\"\n" 485 "#include \"c.h\"", 486 sort("#include \"llvm/a.h\"\n" 487 "#include \"c.h\"\n" 488 "#include \"b.h\"", 489 "a_test.cc")); 490 verifyFormat("#include \"llvm/input.h\"\n" 491 "#include \"b.h\"\n" 492 "#include \"c.h\"", 493 sort("#include \"llvm/input.h\"\n" 494 "#include \"c.h\"\n" 495 "#include \"b.h\"", 496 "input.mm")); 497 498 // Don't allow prefixes. 499 verifyFormat("#include \"b.h\"\n" 500 "#include \"c.h\"\n" 501 "#include \"llvm/not_a.h\"", 502 sort("#include \"llvm/not_a.h\"\n" 503 "#include \"c.h\"\n" 504 "#include \"b.h\"", 505 "a.cc")); 506 507 // Don't do this for _main and other suffixes. 508 verifyFormat("#include \"b.h\"\n" 509 "#include \"c.h\"\n" 510 "#include \"llvm/a.h\"", 511 sort("#include \"llvm/a.h\"\n" 512 "#include \"c.h\"\n" 513 "#include \"b.h\"", 514 "a_main.cc")); 515 516 // Don't do this in headers. 517 verifyFormat("#include \"b.h\"\n" 518 "#include \"c.h\"\n" 519 "#include \"llvm/a.h\"", 520 sort("#include \"llvm/a.h\"\n" 521 "#include \"c.h\"\n" 522 "#include \"b.h\"", 523 "a.h")); 524 525 // Only do this in the first #include block. 526 verifyFormat("#include <a>\n" 527 "\n" 528 "#include \"b.h\"\n" 529 "#include \"c.h\"\n" 530 "#include \"llvm/a.h\"", 531 sort("#include <a>\n" 532 "\n" 533 "#include \"llvm/a.h\"\n" 534 "#include \"c.h\"\n" 535 "#include \"b.h\"", 536 "a.cc")); 537 538 // Only recognize the first #include with a matching basename as main include. 539 verifyFormat("#include \"a.h\"\n" 540 "#include \"b.h\"\n" 541 "#include \"c.h\"\n" 542 "#include \"llvm/a.h\"", 543 sort("#include \"b.h\"\n" 544 "#include \"a.h\"\n" 545 "#include \"c.h\"\n" 546 "#include \"llvm/a.h\"", 547 "a.cc")); 548 } 549 550 TEST_F(SortIncludesTest, LeavesMainHeaderFirstInAdditionalExtensions) { 551 Style.IncludeIsMainRegex = "([-_](test|unittest))?|(Impl)?$"; 552 verifyFormat("#include \"b.h\"\n" 553 "#include \"c.h\"\n" 554 "#include \"llvm/a.h\"", 555 sort("#include \"llvm/a.h\"\n" 556 "#include \"c.h\"\n" 557 "#include \"b.h\"", 558 "a_test.xxx")); 559 verifyFormat("#include \"b.h\"\n" 560 "#include \"c.h\"\n" 561 "#include \"llvm/a.h\"", 562 sort("#include \"llvm/a.h\"\n" 563 "#include \"c.h\"\n" 564 "#include \"b.h\"", 565 "aImpl.hpp")); 566 567 // .cpp extension is considered "main" by default 568 verifyFormat("#include \"llvm/a.h\"\n" 569 "#include \"b.h\"\n" 570 "#include \"c.h\"", 571 sort("#include \"llvm/a.h\"\n" 572 "#include \"c.h\"\n" 573 "#include \"b.h\"", 574 "aImpl.cpp")); 575 verifyFormat("#include \"llvm/a.h\"\n" 576 "#include \"b.h\"\n" 577 "#include \"c.h\"", 578 sort("#include \"llvm/a.h\"\n" 579 "#include \"c.h\"\n" 580 "#include \"b.h\"", 581 "a_test.cpp")); 582 583 // Allow additional filenames / extensions 584 Style.IncludeIsMainSourceRegex = "(Impl\\.hpp)|(\\.xxx)$"; 585 verifyFormat("#include \"llvm/a.h\"\n" 586 "#include \"b.h\"\n" 587 "#include \"c.h\"", 588 sort("#include \"llvm/a.h\"\n" 589 "#include \"c.h\"\n" 590 "#include \"b.h\"", 591 "a_test.xxx")); 592 verifyFormat("#include \"llvm/a.h\"\n" 593 "#include \"b.h\"\n" 594 "#include \"c.h\"", 595 sort("#include \"llvm/a.h\"\n" 596 "#include \"c.h\"\n" 597 "#include \"b.h\"", 598 "aImpl.hpp")); 599 } 600 601 TEST_F(SortIncludesTest, RecognizeMainHeaderInAllGroups) { 602 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 603 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 604 605 verifyFormat("#include \"c.h\"\n" 606 "#include \"a.h\"\n" 607 "#include \"b.h\"", 608 sort("#include \"b.h\"\n" 609 "\n" 610 "#include \"a.h\"\n" 611 "#include \"c.h\"", 612 "c.cc")); 613 } 614 615 TEST_F(SortIncludesTest, MainHeaderIsSeparatedWhenRegroupping) { 616 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 617 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 618 619 verifyFormat("#include \"a.h\"\n" 620 "\n" 621 "#include \"b.h\"\n" 622 "#include \"c.h\"", 623 sort("#include \"b.h\"\n" 624 "\n" 625 "#include \"a.h\"\n" 626 "#include \"c.h\"", 627 "a.cc")); 628 } 629 630 TEST_F(SortIncludesTest, SupportOptionalCaseSensitiveSorting) { 631 EXPECT_FALSE(FmtStyle.SortIncludes == FormatStyle::SI_CaseInsensitive); 632 633 FmtStyle.SortIncludes = FormatStyle::SI_CaseInsensitive; 634 635 verifyFormat("#include \"A/B.h\"\n" 636 "#include \"A/b.h\"\n" 637 "#include \"a/b.h\"\n" 638 "#include \"B/A.h\"\n" 639 "#include \"B/a.h\"", 640 sort("#include \"B/a.h\"\n" 641 "#include \"B/A.h\"\n" 642 "#include \"A/B.h\"\n" 643 "#include \"a/b.h\"\n" 644 "#include \"A/b.h\"", 645 "a.h")); 646 647 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 648 Style.IncludeCategories = { 649 {"^\"", 1, 0, false}, {"^<.*\\.h>$", 2, 0, false}, {"^<", 3, 0, false}}; 650 651 StringRef UnsortedCode = "#include \"qt.h\"\n" 652 "#include <algorithm>\n" 653 "#include <qtwhatever.h>\n" 654 "#include <Qtwhatever.h>\n" 655 "#include <Algorithm>\n" 656 "#include \"vlib.h\"\n" 657 "#include \"Vlib.h\"\n" 658 "#include \"AST.h\""; 659 660 verifyFormat("#include \"AST.h\"\n" 661 "#include \"qt.h\"\n" 662 "#include \"Vlib.h\"\n" 663 "#include \"vlib.h\"\n" 664 "\n" 665 "#include <Qtwhatever.h>\n" 666 "#include <qtwhatever.h>\n" 667 "\n" 668 "#include <Algorithm>\n" 669 "#include <algorithm>", 670 sort(UnsortedCode)); 671 } 672 673 TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) { 674 // Setup an regex for main includes so we can cover those as well. 675 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 676 677 // Ensure both main header detection and grouping work in a case insensitive 678 // manner. 679 verifyFormat("#include \"llvm/A.h\"\n" 680 "#include \"b.h\"\n" 681 "#include \"c.h\"\n" 682 "#include \"LLVM/z.h\"\n" 683 "#include \"llvm/X.h\"\n" 684 "#include \"GTest/GTest.h\"\n" 685 "#include \"gmock/gmock.h\"", 686 sort("#include \"c.h\"\n" 687 "#include \"b.h\"\n" 688 "#include \"GTest/GTest.h\"\n" 689 "#include \"llvm/A.h\"\n" 690 "#include \"gmock/gmock.h\"\n" 691 "#include \"llvm/X.h\"\n" 692 "#include \"LLVM/z.h\"", 693 "a_TEST.cc")); 694 } 695 696 TEST_F(SortIncludesTest, SupportOptionalCaseSensitiveMachting) { 697 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 698 Style.IncludeCategories = {{"^\"", 1, 0, false}, 699 {"^<.*\\.h>$", 2, 0, false}, 700 {"^<Q[A-Z][^\\.]*>", 3, 0, false}, 701 {"^<Qt[^\\.]*>", 4, 0, false}, 702 {"^<", 5, 0, false}}; 703 704 StringRef UnsortedCode = "#include <QWidget>\n" 705 "#include \"qt.h\"\n" 706 "#include <algorithm>\n" 707 "#include <windows.h>\n" 708 "#include <QLabel>\n" 709 "#include \"qa.h\"\n" 710 "#include <queue>\n" 711 "#include <qtwhatever.h>\n" 712 "#include <QtGlobal>"; 713 714 verifyFormat("#include \"qa.h\"\n" 715 "#include \"qt.h\"\n" 716 "\n" 717 "#include <qtwhatever.h>\n" 718 "#include <windows.h>\n" 719 "\n" 720 "#include <QLabel>\n" 721 "#include <QWidget>\n" 722 "#include <QtGlobal>\n" 723 "#include <queue>\n" 724 "\n" 725 "#include <algorithm>", 726 sort(UnsortedCode)); 727 728 Style.IncludeCategories[2].RegexIsCaseSensitive = true; 729 Style.IncludeCategories[3].RegexIsCaseSensitive = true; 730 verifyFormat("#include \"qa.h\"\n" 731 "#include \"qt.h\"\n" 732 "\n" 733 "#include <qtwhatever.h>\n" 734 "#include <windows.h>\n" 735 "\n" 736 "#include <QLabel>\n" 737 "#include <QWidget>\n" 738 "\n" 739 "#include <QtGlobal>\n" 740 "\n" 741 "#include <algorithm>\n" 742 "#include <queue>", 743 sort(UnsortedCode)); 744 } 745 746 TEST_F(SortIncludesTest, NegativePriorities) { 747 Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false}, 748 {".*", 1, 0, false}}; 749 verifyFormat("#include \"important_os_header.h\"\n" 750 "#include \"c_main.h\"\n" 751 "#include \"a_other.h\"", 752 sort("#include \"c_main.h\"\n" 753 "#include \"a_other.h\"\n" 754 "#include \"important_os_header.h\"", 755 "c_main.cc")); 756 757 // check stable when re-run 758 verifyFormat("#include \"important_os_header.h\"\n" 759 "#include \"c_main.h\"\n" 760 "#include \"a_other.h\"", 761 sort("#include \"important_os_header.h\"\n" 762 "#include \"c_main.h\"\n" 763 "#include \"a_other.h\"", 764 "c_main.cc", 0)); 765 } 766 767 TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) { 768 Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false}, 769 {".*", 1, 0, false}}; 770 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 771 772 verifyFormat("#include \"important_os_header.h\"\n" 773 "\n" 774 "#include \"c_main.h\"\n" 775 "\n" 776 "#include \"a_other.h\"", 777 sort("#include \"c_main.h\"\n" 778 "#include \"a_other.h\"\n" 779 "#include \"important_os_header.h\"", 780 "c_main.cc")); 781 782 // check stable when re-run 783 verifyFormat("#include \"important_os_header.h\"\n" 784 "\n" 785 "#include \"c_main.h\"\n" 786 "\n" 787 "#include \"a_other.h\"", 788 sort("#include \"important_os_header.h\"\n" 789 "\n" 790 "#include \"c_main.h\"\n" 791 "\n" 792 "#include \"a_other.h\"", 793 "c_main.cc", 0)); 794 } 795 796 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { 797 StringRef Code = "#include <ccc>\n" // Start of line: 0 798 "#include <bbbbbb>\n" // Start of line: 15 799 "#include <a>\n"; // Start of line: 33 800 EXPECT_EQ(31u, newCursor(Code, 0)); 801 EXPECT_EQ(13u, newCursor(Code, 15)); 802 EXPECT_EQ(0u, newCursor(Code, 33)); 803 804 EXPECT_EQ(41u, newCursor(Code, 10)); 805 EXPECT_EQ(23u, newCursor(Code, 25)); 806 EXPECT_EQ(10u, newCursor(Code, 43)); 807 } 808 809 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionWithRegrouping) { 810 Style.IncludeBlocks = Style.IBS_Regroup; 811 StringRef Code = "#include \"b\"\n" // Start of line: 0 812 "\n" // Start of line: 13 813 "#include \"aa\"\n" // Start of line: 14 814 "int i;"; // Start of line: 28 815 StringRef Expected = "#include \"aa\"\n" // Start of line: 0 816 "#include \"b\"\n" // Start of line: 14 817 "int i;"; // Start of line: 27 818 verifyFormat(Expected, sort(Code)); 819 EXPECT_EQ(12u, newCursor(Code, 26)); // Closing quote of "aa" 820 EXPECT_EQ(26u, newCursor(Code, 27)); // Newline after "aa" 821 EXPECT_EQ(27u, newCursor(Code, 28)); // Start of last line 822 } 823 824 TEST_F(SortIncludesTest, 825 CalculatesCorrectCursorPositionWhenNoReplacementsWithRegroupingAndCRLF) { 826 Style.IncludeBlocks = Style.IBS_Regroup; 827 FmtStyle.LineEnding = FormatStyle::LE_CRLF; 828 Style.IncludeCategories = { 829 {"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}}; 830 StringRef Code = "#include \"a\"\r\n" // Start of line: 0 831 "\r\n" // Start of line: 14 832 "#include \"b\"\r\n" // Start of line: 16 833 "\r\n" // Start of line: 30 834 "#include \"c\"\r\n" // Start of line: 32 835 "\r\n" // Start of line: 46 836 "int i;"; // Start of line: 48 837 verifyFormat(Code); 838 EXPECT_EQ(0u, newCursor(Code, 0)); 839 EXPECT_EQ(14u, newCursor(Code, 14)); 840 EXPECT_EQ(16u, newCursor(Code, 16)); 841 EXPECT_EQ(30u, newCursor(Code, 30)); 842 EXPECT_EQ(32u, newCursor(Code, 32)); 843 EXPECT_EQ(46u, newCursor(Code, 46)); 844 EXPECT_EQ(48u, newCursor(Code, 48)); 845 } 846 847 TEST_F( 848 SortIncludesTest, 849 CalculatesCorrectCursorPositionWhenRemoveLinesReplacementsWithRegroupingAndCRLF) { 850 Style.IncludeBlocks = Style.IBS_Regroup; 851 FmtStyle.LineEnding = FormatStyle::LE_CRLF; 852 Style.IncludeCategories = {{".*", 0, 0, false}}; 853 StringRef Code = "#include \"a\"\r\n" // Start of line: 0 854 "\r\n" // Start of line: 14 855 "#include \"b\"\r\n" // Start of line: 16 856 "\r\n" // Start of line: 30 857 "#include \"c\"\r\n" // Start of line: 32 858 "\r\n" // Start of line: 46 859 "int i;"; // Start of line: 48 860 StringRef Expected = "#include \"a\"\r\n" // Start of line: 0 861 "#include \"b\"\r\n" // Start of line: 14 862 "#include \"c\"\r\n" // Start of line: 28 863 "\r\n" // Start of line: 42 864 "int i;"; // Start of line: 44 865 verifyFormat(Expected, sort(Code)); 866 EXPECT_EQ(0u, newCursor(Code, 0)); 867 EXPECT_EQ( 868 14u, 869 newCursor(Code, 14)); // cursor on empty line in include block is ignored 870 EXPECT_EQ(14u, newCursor(Code, 16)); 871 EXPECT_EQ( 872 30u, 873 newCursor(Code, 30)); // cursor on empty line in include block is ignored 874 EXPECT_EQ(28u, newCursor(Code, 32)); 875 EXPECT_EQ(42u, newCursor(Code, 46)); 876 EXPECT_EQ(44u, newCursor(Code, 48)); 877 } 878 879 // FIXME: the tests below should pass. 880 #if 0 881 TEST_F( 882 SortIncludesTest, 883 CalculatesCorrectCursorPositionWhenNewLineReplacementsWithRegroupingAndCRLF) { 884 Style.IncludeBlocks = Style.IBS_Regroup; 885 FmtStyle.LineEnding = FormatStyle::LE_CRLF; 886 Style.IncludeCategories = { 887 {"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}}; 888 StringRef Code = "#include \"a\"\r\n" // Start of line: 0 889 "#include \"b\"\r\n" // Start of line: 14 890 "#include \"c\"\r\n" // Start of line: 28 891 "\r\n" // Start of line: 42 892 "int i;"; // Start of line: 44 893 StringRef Expected = "#include \"a\"\r\n" // Start of line: 0 894 "\r\n" // Start of line: 14 895 "#include \"b\"\r\n" // Start of line: 16 896 "\r\n" // Start of line: 30 897 "#include \"c\"\r\n" // Start of line: 32 898 "\r\n" // Start of line: 46 899 "int i;"; // Start of line: 48 900 verifyFormat(Expected, sort(Code)); 901 EXPECT_EQ(0u, newCursor(Code, 0)); 902 EXPECT_EQ(15u, newCursor(Code, 16)); 903 EXPECT_EQ(30u, newCursor(Code, 32)); 904 EXPECT_EQ(44u, newCursor(Code, 46)); 905 EXPECT_EQ(46u, newCursor(Code, 48)); 906 } 907 908 TEST_F( 909 SortIncludesTest, 910 CalculatesCorrectCursorPositionWhenNoNewLineReplacementsWithRegroupingAndCRLF) { 911 Style.IncludeBlocks = Style.IBS_Regroup; 912 FmtStyle.LineEnding = FormatStyle::LE_CRLF; 913 Style.IncludeCategories = { 914 {"^\"a\"", 0, 0, false}, {"^\"b\"", 1, 1, false}, {".*", 2, 2, false}}; 915 StringRef Code = "#include \"a\"\r\n" // Start of line: 0 916 "\r\n" // Start of line: 14 917 "#include \"c\"\r\n" // Start of line: 16 918 "\r\n" // Start of line: 30 919 "#include \"b\"\r\n" // Start of line: 32 920 "\r\n" // Start of line: 46 921 "int i;"; // Start of line: 48 922 StringRef Expected = "#include \"a\"\r\n" // Start of line: 0 923 "\r\n" // Start of line: 14 924 "#include \"b\"\r\n" // Start of line: 16 925 "\r\n" // Start of line: 30 926 "#include \"c\"\r\n" // Start of line: 32 927 "\r\n" // Start of line: 46 928 "int i;"; // Start of line: 48 929 verifyFormat(Expected, sort(Code)); 930 EXPECT_EQ(0u, newCursor(Code, 0)); 931 EXPECT_EQ(14u, newCursor(Code, 14)); 932 EXPECT_EQ(30u, newCursor(Code, 32)); 933 EXPECT_EQ(30u, newCursor(Code, 30)); 934 EXPECT_EQ(15u, newCursor(Code, 15)); 935 EXPECT_EQ(44u, newCursor(Code, 46)); 936 EXPECT_EQ(46u, newCursor(Code, 48)); 937 } 938 #endif 939 940 TEST_F(SortIncludesTest, DeduplicateIncludes) { 941 verifyFormat("#include <a>\n" 942 "#include <b>\n" 943 "#include <c>", 944 sort("#include <a>\n" 945 "#include <b>\n" 946 "#include <b>\n" 947 "#include <b>\n" 948 "#include <b>\n" 949 "#include <c>")); 950 951 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 952 verifyFormat("#include <a>\n" 953 "#include <b>\n" 954 "#include <c>", 955 sort("#include <a>\n" 956 "#include <b>\n" 957 "\n" 958 "#include <b>\n" 959 "\n" 960 "#include <b>\n" 961 "#include <c>")); 962 963 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 964 verifyFormat("#include <a>\n" 965 "#include <b>\n" 966 "#include <c>", 967 sort("#include <a>\n" 968 "#include <b>\n" 969 "\n" 970 "#include <b>\n" 971 "\n" 972 "#include <b>\n" 973 "#include <c>")); 974 } 975 976 TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) { 977 verifyFormat("#include <a>\n" 978 "#include <b>\n" 979 "#include <c>", 980 sort("#include <b>\n" 981 "#include <a>\n" 982 "#include <b>\n" 983 "#include <b>\n" 984 "#include <c>\n" 985 "#include <b>")); 986 987 verifyFormat("/* COPYRIGHT *\\\n" 988 "\\* (C) 2024 */\n" 989 "\n" 990 "#include <a>\n" 991 "#include <b>", 992 sort("/* COPYRIGHT *\\\n" 993 "\\* (C) 2024 */\n" 994 "\n" 995 "#include <b>\n" 996 "#include <a>\n" 997 "#include <b>")); 998 999 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 1000 verifyFormat("#include <a>\n" 1001 "#include <b>\n" 1002 "#include <c>", 1003 sort("#include <b>\n" 1004 "#include <a>\n" 1005 "\n" 1006 "#include <b>\n" 1007 "\n" 1008 "#include <c>\n" 1009 "#include <b>")); 1010 1011 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 1012 verifyFormat("#include <a>\n" 1013 "#include <b>\n" 1014 "#include <c>", 1015 sort("#include <b>\n" 1016 "#include <a>\n" 1017 "\n" 1018 "#include <b>\n" 1019 "\n" 1020 "#include <c>\n" 1021 "#include <b>")); 1022 } 1023 1024 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) { 1025 StringRef Code = "#include <b>\n" // Start of line: 0 1026 "#include <a>\n" // Start of line: 13 1027 "#include <b>\n" // Start of line: 26 1028 "#include <b>\n" // Start of line: 39 1029 "#include <c>\n" // Start of line: 52 1030 "#include <b>\n"; // Start of line: 65 1031 StringRef Expected = "#include <a>\n" // Start of line: 0 1032 "#include <b>\n" // Start of line: 13 1033 "#include <c>\n"; // Start of line: 26 1034 verifyFormat(Expected, sort(Code)); 1035 // Cursor on 'i' in "#include <a>". 1036 EXPECT_EQ(1u, newCursor(Code, 14)); 1037 // Cursor on 'b' in "#include <b>". 1038 EXPECT_EQ(23u, newCursor(Code, 10)); 1039 EXPECT_EQ(23u, newCursor(Code, 36)); 1040 EXPECT_EQ(23u, newCursor(Code, 49)); 1041 EXPECT_EQ(23u, newCursor(Code, 36)); 1042 EXPECT_EQ(23u, newCursor(Code, 75)); 1043 // Cursor on '#' in "#include <c>". 1044 EXPECT_EQ(26u, newCursor(Code, 52)); 1045 } 1046 1047 TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) { 1048 verifyFormat("#include <a>\n" 1049 "#include <b>\n" 1050 "\n" 1051 "#include <b>\n" 1052 "#include <c>", 1053 sort("#include <a>\n" 1054 "#include <b>\n" 1055 "\n" 1056 "#include <c>\n" 1057 "#include <b>\n" 1058 "#include <b>")); 1059 } 1060 1061 TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) { 1062 StringRef Code = "#include <a>\n" 1063 "#include <b>\n" 1064 "#include <a>\n" 1065 "#include <a>\n" 1066 "\n" 1067 " int x ;"; 1068 std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)}; 1069 auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp"); 1070 Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); 1071 EXPECT_EQ(1u, Ranges.size()); 1072 EXPECT_EQ(0u, Ranges[0].getOffset()); 1073 EXPECT_EQ(26u, Ranges[0].getLength()); 1074 } 1075 1076 TEST_F(SortIncludesTest, DoNotSortLikelyXml) { 1077 verifyFormat("<!--;\n" 1078 "#include <b>\n" 1079 "#include <a>\n" 1080 "-->", 1081 sort("<!--;\n" 1082 "#include <b>\n" 1083 "#include <a>\n" 1084 "-->", 1085 "input.h", 0)); 1086 } 1087 1088 TEST_F(SortIncludesTest, DoNotOutputReplacementsForSortedBlocksWithRegrouping) { 1089 Style.IncludeBlocks = Style.IBS_Regroup; 1090 StringRef Code = "#include \"b.h\"\n" 1091 "\n" 1092 "#include <a.h>"; 1093 verifyFormat(Code, sort(Code, "input.h", 0)); 1094 } 1095 1096 TEST_F(SortIncludesTest, 1097 DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows) { 1098 Style.IncludeBlocks = Style.IBS_Regroup; 1099 StringRef Code = "#include \"b.h\"\r\n" 1100 "\r\n" 1101 "#include <a.h>\r\n"; 1102 verifyFormat(Code, sort(Code, "input.h", 0)); 1103 } 1104 1105 TEST_F(SortIncludesTest, MainIncludeChar) { 1106 StringRef Code = "#include <a>\n" 1107 "#include \"quote/input.h\"\n" 1108 "#include <angle-bracket/input.h>\n"; 1109 1110 // Default behavior 1111 verifyFormat("#include \"quote/input.h\"\n" 1112 "#include <a>\n" 1113 "#include <angle-bracket/input.h>\n", 1114 sort(Code, "input.cc", 1)); 1115 1116 Style.MainIncludeChar = tooling::IncludeStyle::MICD_Quote; 1117 verifyFormat("#include \"quote/input.h\"\n" 1118 "#include <a>\n" 1119 "#include <angle-bracket/input.h>\n", 1120 sort(Code, "input.cc", 1)); 1121 1122 Style.MainIncludeChar = tooling::IncludeStyle::MICD_AngleBracket; 1123 verifyFormat("#include <angle-bracket/input.h>\n" 1124 "#include \"quote/input.h\"\n" 1125 "#include <a>\n", 1126 sort(Code, "input.cc", 1)); 1127 } 1128 1129 TEST_F(SortIncludesTest, MainIncludeCharAnyPickQuote) { 1130 Style.MainIncludeChar = tooling::IncludeStyle::MICD_Any; 1131 verifyFormat("#include \"input.h\"\n" 1132 "#include <a>\n" 1133 "#include <b>\n", 1134 sort("#include <a>\n" 1135 "#include \"input.h\"\n" 1136 "#include <b>\n", 1137 "input.cc", 1)); 1138 } 1139 1140 TEST_F(SortIncludesTest, MainIncludeCharAnyPickAngleBracket) { 1141 Style.MainIncludeChar = tooling::IncludeStyle::MICD_Any; 1142 verifyFormat("#include <input.h>\n" 1143 "#include <a>\n" 1144 "#include <b>\n", 1145 sort("#include <a>\n" 1146 "#include <input.h>\n" 1147 "#include <b>\n", 1148 "input.cc", 1)); 1149 } 1150 1151 TEST_F(SortIncludesTest, MainIncludeCharQuoteAndRegroup) { 1152 Style.IncludeCategories = { 1153 {"lib-a", 1, 0, false}, {"lib-b", 2, 0, false}, {"lib-c", 3, 0, false}}; 1154 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 1155 Style.MainIncludeChar = tooling::IncludeStyle::MICD_Quote; 1156 1157 verifyFormat("#include \"lib-b/input.h\"\n" 1158 "\n" 1159 "#include <lib-a/h-1.h>\n" 1160 "#include <lib-a/h-3.h>\n" 1161 "#include <lib-a/input.h>\n" 1162 "\n" 1163 "#include <lib-b/h-1.h>\n" 1164 "#include <lib-b/h-3.h>\n" 1165 "\n" 1166 "#include <lib-c/h-1.h>\n" 1167 "#include <lib-c/h-2.h>\n" 1168 "#include <lib-c/h-3.h>\n", 1169 sort("#include <lib-c/h-1.h>\n" 1170 "#include <lib-c/h-2.h>\n" 1171 "#include <lib-c/h-3.h>\n" 1172 "#include <lib-b/h-1.h>\n" 1173 "#include \"lib-b/input.h\"\n" 1174 "#include <lib-b/h-3.h>\n" 1175 "#include <lib-a/h-1.h>\n" 1176 "#include <lib-a/input.h>\n" 1177 "#include <lib-a/h-3.h>\n", 1178 "input.cc")); 1179 } 1180 1181 TEST_F(SortIncludesTest, MainIncludeCharAngleBracketAndRegroup) { 1182 Style.IncludeCategories = { 1183 {"lib-a", 1, 0, false}, {"lib-b", 2, 0, false}, {"lib-c", 3, 0, false}}; 1184 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 1185 Style.MainIncludeChar = tooling::IncludeStyle::MICD_AngleBracket; 1186 1187 verifyFormat("#include <lib-a/input.h>\n" 1188 "\n" 1189 "#include <lib-a/h-1.h>\n" 1190 "#include <lib-a/h-3.h>\n" 1191 "\n" 1192 "#include \"lib-b/input.h\"\n" 1193 "#include <lib-b/h-1.h>\n" 1194 "#include <lib-b/h-3.h>\n" 1195 "\n" 1196 "#include <lib-c/h-1.h>\n" 1197 "#include <lib-c/h-2.h>\n" 1198 "#include <lib-c/h-3.h>\n", 1199 sort("#include <lib-c/h-1.h>\n" 1200 "#include <lib-c/h-2.h>\n" 1201 "#include <lib-c/h-3.h>\n" 1202 "#include <lib-b/h-1.h>\n" 1203 "#include \"lib-b/input.h\"\n" 1204 "#include <lib-b/h-3.h>\n" 1205 "#include <lib-a/h-1.h>\n" 1206 "#include <lib-a/input.h>\n" 1207 "#include <lib-a/h-3.h>\n", 1208 "input.cc")); 1209 } 1210 1211 TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) { 1212 FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC); 1213 1214 verifyFormat("#include <a.h>\n" 1215 "#include <b.h>\n" 1216 "#include \"a.h\"", 1217 sort("#include <b.h>\n" 1218 "#include <a.h>\n" 1219 "#include \"a.h\"")); 1220 } 1221 1222 TEST_F(SortIncludesTest, DoNotTreatPrecompiledHeadersAsFirstBlock) { 1223 Style.IncludeBlocks = Style.IBS_Merge; 1224 StringRef Code = "#include \"d.h\"\r\n" 1225 "#include \"b.h\"\r\n" 1226 "#pragma hdrstop\r\n" 1227 "\r\n" 1228 "#include \"c.h\"\r\n" 1229 "#include \"a.h\"\r\n" 1230 "#include \"e.h\"\r\n"; 1231 1232 StringRef Expected = "#include \"b.h\"\r\n" 1233 "#include \"d.h\"\r\n" 1234 "#pragma hdrstop\r\n" 1235 "\r\n" 1236 "#include \"e.h\"\r\n" 1237 "#include \"a.h\"\r\n" 1238 "#include \"c.h\"\r\n"; 1239 1240 verifyFormat(Expected, sort(Code, "e.cpp", 2)); 1241 1242 Code = "#include \"d.h\"\n" 1243 "#include \"b.h\"\n" 1244 "#pragma hdrstop( \"c:\\projects\\include\\myinc.pch\" )\n" 1245 "\n" 1246 "#include \"c.h\"\n" 1247 "#include \"a.h\"\n" 1248 "#include \"e.h\"\n"; 1249 1250 Expected = "#include \"b.h\"\n" 1251 "#include \"d.h\"\n" 1252 "#pragma hdrstop(\"c:\\projects\\include\\myinc.pch\")\n" 1253 "\n" 1254 "#include \"e.h\"\n" 1255 "#include \"a.h\"\n" 1256 "#include \"c.h\"\n"; 1257 1258 verifyFormat(Expected, sort(Code, "e.cpp", 2)); 1259 } 1260 1261 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkMerge) { 1262 Style.IncludeBlocks = Style.IBS_Merge; 1263 StringRef Code = "\xEF\xBB\xBF#include \"d.h\"\r\n" 1264 "#include \"b.h\"\r\n" 1265 "\r\n" 1266 "#include \"c.h\"\r\n" 1267 "#include \"a.h\"\r\n" 1268 "#include \"e.h\"\r\n"; 1269 1270 StringRef Expected = "\xEF\xBB\xBF#include \"e.h\"\r\n" 1271 "#include \"a.h\"\r\n" 1272 "#include \"b.h\"\r\n" 1273 "#include \"c.h\"\r\n" 1274 "#include \"d.h\"\r\n"; 1275 1276 verifyFormat(Expected, sort(Code, "e.cpp", 1)); 1277 } 1278 1279 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkPreserve) { 1280 Style.IncludeBlocks = Style.IBS_Preserve; 1281 StringRef Code = "\xEF\xBB\xBF#include \"d.h\"\r\n" 1282 "#include \"b.h\"\r\n" 1283 "\r\n" 1284 "#include \"c.h\"\r\n" 1285 "#include \"a.h\"\r\n" 1286 "#include \"e.h\"\r\n"; 1287 1288 StringRef Expected = "\xEF\xBB\xBF#include \"b.h\"\r\n" 1289 "#include \"d.h\"\r\n" 1290 "\r\n" 1291 "#include \"a.h\"\r\n" 1292 "#include \"c.h\"\r\n" 1293 "#include \"e.h\"\r\n"; 1294 1295 verifyFormat(Expected, sort(Code, "e.cpp", 2)); 1296 } 1297 1298 TEST_F(SortIncludesTest, MergeLines) { 1299 Style.IncludeBlocks = Style.IBS_Merge; 1300 StringRef Code = "#include \"c.h\"\r\n" 1301 "#include \"b\\\r\n" 1302 ".h\"\r\n" 1303 "#include \"a.h\"\r\n"; 1304 1305 StringRef Expected = "#include \"a.h\"\r\n" 1306 "#include \"b\\\r\n" 1307 ".h\"\r\n" 1308 "#include \"c.h\"\r\n"; 1309 1310 verifyFormat(Expected, sort(Code, "a.cpp", 1)); 1311 } 1312 1313 TEST_F(SortIncludesTest, DisableFormatDisablesIncludeSorting) { 1314 StringRef Sorted = "#include <a.h>\n" 1315 "#include <b.h>\n"; 1316 StringRef Unsorted = "#include <b.h>\n" 1317 "#include <a.h>\n"; 1318 verifyFormat(Sorted, sort(Unsorted)); 1319 FmtStyle.DisableFormat = true; 1320 verifyFormat(Unsorted, sort(Unsorted, "input.cpp", 0)); 1321 } 1322 1323 TEST_F(SortIncludesTest, DisableRawStringLiteralSorting) { 1324 1325 verifyFormat("const char *t = R\"(\n" 1326 "#include <b.h>\n" 1327 "#include <a.h>\n" 1328 ")\";", 1329 sort("const char *t = R\"(\n" 1330 "#include <b.h>\n" 1331 "#include <a.h>\n" 1332 ")\";", 1333 "test.cxx", 0)); 1334 verifyFormat("const char *t = R\"x(\n" 1335 "#include <b.h>\n" 1336 "#include <a.h>\n" 1337 ")x\";", 1338 sort("const char *t = R\"x(\n" 1339 "#include <b.h>\n" 1340 "#include <a.h>\n" 1341 ")x\";", 1342 "test.cxx", 0)); 1343 verifyFormat("const char *t = R\"xyz(\n" 1344 "#include <b.h>\n" 1345 "#include <a.h>\n" 1346 ")xyz\";", 1347 sort("const char *t = R\"xyz(\n" 1348 "#include <b.h>\n" 1349 "#include <a.h>\n" 1350 ")xyz\";", 1351 "test.cxx", 0)); 1352 1353 verifyFormat("#include <a.h>\n" 1354 "#include <b.h>\n" 1355 "const char *t = R\"(\n" 1356 "#include <b.h>\n" 1357 "#include <a.h>\n" 1358 ")\";\n" 1359 "#include <c.h>\n" 1360 "#include <d.h>\n" 1361 "const char *t = R\"x(\n" 1362 "#include <f.h>\n" 1363 "#include <e.h>\n" 1364 ")x\";\n" 1365 "#include <g.h>\n" 1366 "#include <h.h>\n" 1367 "const char *t = R\"xyz(\n" 1368 "#include <j.h>\n" 1369 "#include <i.h>\n" 1370 ")xyz\";\n" 1371 "#include <k.h>\n" 1372 "#include <l.h>", 1373 sort("#include <b.h>\n" 1374 "#include <a.h>\n" 1375 "const char *t = R\"(\n" 1376 "#include <b.h>\n" 1377 "#include <a.h>\n" 1378 ")\";\n" 1379 "#include <d.h>\n" 1380 "#include <c.h>\n" 1381 "const char *t = R\"x(\n" 1382 "#include <f.h>\n" 1383 "#include <e.h>\n" 1384 ")x\";\n" 1385 "#include <h.h>\n" 1386 "#include <g.h>\n" 1387 "const char *t = R\"xyz(\n" 1388 "#include <j.h>\n" 1389 "#include <i.h>\n" 1390 ")xyz\";\n" 1391 "#include <l.h>\n" 1392 "#include <k.h>", 1393 "test.cc", 4)); 1394 1395 verifyFormat("const char *t = R\"AMZ029amz(\n" 1396 "#include <b.h>\n" 1397 "#include <a.h>\n" 1398 ")AMZ029amz\";", 1399 sort("const char *t = R\"AMZ029amz(\n" 1400 "#include <b.h>\n" 1401 "#include <a.h>\n" 1402 ")AMZ029amz\";", 1403 "test.cxx", 0)); 1404 1405 verifyFormat("const char *t = R\"-AMZ029amz(\n" 1406 "#include <b.h>\n" 1407 "#include <a.h>\n" 1408 ")-AMZ029amz\";", 1409 sort("const char *t = R\"-AMZ029amz(\n" 1410 "#include <b.h>\n" 1411 "#include <a.h>\n" 1412 ")-AMZ029amz\";", 1413 "test.cxx", 0)); 1414 1415 verifyFormat("const char *t = R\"AMZ029amz-(\n" 1416 "#include <b.h>\n" 1417 "#include <a.h>\n" 1418 ")AMZ029amz-\";", 1419 sort("const char *t = R\"AMZ029amz-(\n" 1420 "#include <b.h>\n" 1421 "#include <a.h>\n" 1422 ")AMZ029amz-\";", 1423 "test.cxx", 0)); 1424 1425 verifyFormat("const char *t = R\"AM|029amz-(\n" 1426 "#include <b.h>\n" 1427 "#include <a.h>\n" 1428 ")AM|029amz-\";", 1429 sort("const char *t = R\"AM|029amz-(\n" 1430 "#include <b.h>\n" 1431 "#include <a.h>\n" 1432 ")AM|029amz-\";", 1433 "test.cxx", 0)); 1434 1435 verifyFormat("const char *t = R\"AM[029amz-(\n" 1436 "#include <b.h>\n" 1437 "#include <a.h>\n" 1438 ")AM[029amz-\";", 1439 sort("const char *t = R\"AM[029amz-(\n" 1440 "#include <b.h>\n" 1441 "#include <a.h>\n" 1442 ")AM[029amz-\";", 1443 "test.cxx", 0)); 1444 1445 verifyFormat("const char *t = R\"AM]029amz-(\n" 1446 "#include <b.h>\n" 1447 "#include <a.h>\n" 1448 ")AM]029amz-\";", 1449 sort("const char *t = R\"AM]029amz-(\n" 1450 "#include <b.h>\n" 1451 "#include <a.h>\n" 1452 ")AM]029amz-\";", 1453 "test.cxx", 0)); 1454 1455 #define X "AMZ029amz{}+!%*=_:;',.<>|/?#~-$" 1456 1457 verifyFormat("const char *t = R\"" X "(\n" 1458 "#include <b.h>\n" 1459 "#include <a.h>\n" 1460 ")" X "\";", 1461 sort("const char *t = R\"" X "(\n" 1462 "#include <b.h>\n" 1463 "#include <a.h>\n" 1464 ")" X "\";", 1465 "test.cxx", 0)); 1466 1467 #undef X 1468 } 1469 1470 TEST_F(SortIncludesTest, BlockCommentedOutIncludes) { 1471 StringRef Code{"/* #include \"foo.h\"\n" 1472 "#include \"bar.h\" */\n" 1473 "#include <chrono>"}; 1474 1475 FmtStyle = getGoogleStyle(FormatStyle::LK_Cpp); 1476 verifyFormat(Code, sort(Code, "input.cpp", 0)); 1477 } 1478 1479 } // end namespace 1480 } // end namespace format 1481 } // end namespace clang 1482