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 = FormatStyle::SI_Never; 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, SupportOptionalCaseSensitiveSorting) { 602 EXPECT_FALSE(FmtStyle.SortIncludes == FormatStyle::SI_CaseSensitive); 603 604 FmtStyle.SortIncludes = FormatStyle::SI_CaseSensitive; 605 606 EXPECT_EQ("#include \"A/B.h\"\n" 607 "#include \"A/b.h\"\n" 608 "#include \"a/b.h\"\n" 609 "#include \"B/A.h\"\n" 610 "#include \"B/a.h\"\n", 611 sort("#include \"B/a.h\"\n" 612 "#include \"B/A.h\"\n" 613 "#include \"A/B.h\"\n" 614 "#include \"a/b.h\"\n" 615 "#include \"A/b.h\"\n", 616 "a.h")); 617 618 Style.IncludeBlocks = clang::tooling::IncludeStyle::IBS_Regroup; 619 Style.IncludeCategories = { 620 {"^\"", 1, 0, false}, {"^<.*\\.h>$", 2, 0, false}, {"^<", 3, 0, false}}; 621 622 StringRef UnsortedCode = "#include \"qt.h\"\n" 623 "#include <algorithm>\n" 624 "#include <qtwhatever.h>\n" 625 "#include <Qtwhatever.h>\n" 626 "#include <Algorithm>\n" 627 "#include \"vlib.h\"\n" 628 "#include \"Vlib.h\"\n" 629 "#include \"AST.h\"\n"; 630 631 EXPECT_EQ("#include \"AST.h\"\n" 632 "#include \"qt.h\"\n" 633 "#include \"Vlib.h\"\n" 634 "#include \"vlib.h\"\n" 635 "\n" 636 "#include <Qtwhatever.h>\n" 637 "#include <qtwhatever.h>\n" 638 "\n" 639 "#include <Algorithm>\n" 640 "#include <algorithm>\n", 641 sort(UnsortedCode)); 642 } 643 644 TEST_F(SortIncludesTest, SupportCaseInsensitiveMatching) { 645 // Setup an regex for main includes so we can cover those as well. 646 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 647 648 // Ensure both main header detection and grouping work in a case insensitive 649 // manner. 650 EXPECT_EQ("#include \"llvm/A.h\"\n" 651 "#include \"b.h\"\n" 652 "#include \"c.h\"\n" 653 "#include \"LLVM/z.h\"\n" 654 "#include \"llvm/X.h\"\n" 655 "#include \"GTest/GTest.h\"\n" 656 "#include \"gmock/gmock.h\"\n", 657 sort("#include \"c.h\"\n" 658 "#include \"b.h\"\n" 659 "#include \"GTest/GTest.h\"\n" 660 "#include \"llvm/A.h\"\n" 661 "#include \"gmock/gmock.h\"\n" 662 "#include \"llvm/X.h\"\n" 663 "#include \"LLVM/z.h\"\n", 664 "a_TEST.cc")); 665 } 666 667 TEST_F(SortIncludesTest, SupportOptionalCaseSensitiveMachting) { 668 Style.IncludeBlocks = clang::tooling::IncludeStyle::IBS_Regroup; 669 Style.IncludeCategories = {{"^\"", 1, 0, false}, 670 {"^<.*\\.h>$", 2, 0, false}, 671 {"^<Q[A-Z][^\\.]*>", 3, 0, false}, 672 {"^<Qt[^\\.]*>", 4, 0, false}, 673 {"^<", 5, 0, false}}; 674 675 StringRef UnsortedCode = "#include <QWidget>\n" 676 "#include \"qt.h\"\n" 677 "#include <algorithm>\n" 678 "#include <windows.h>\n" 679 "#include <QLabel>\n" 680 "#include \"qa.h\"\n" 681 "#include <queue>\n" 682 "#include <qtwhatever.h>\n" 683 "#include <QtGlobal>\n"; 684 685 EXPECT_EQ("#include \"qa.h\"\n" 686 "#include \"qt.h\"\n" 687 "\n" 688 "#include <qtwhatever.h>\n" 689 "#include <windows.h>\n" 690 "\n" 691 "#include <QLabel>\n" 692 "#include <QWidget>\n" 693 "#include <QtGlobal>\n" 694 "#include <queue>\n" 695 "\n" 696 "#include <algorithm>\n", 697 sort(UnsortedCode)); 698 699 Style.IncludeCategories[2].RegexIsCaseSensitive = true; 700 Style.IncludeCategories[3].RegexIsCaseSensitive = true; 701 EXPECT_EQ("#include \"qa.h\"\n" 702 "#include \"qt.h\"\n" 703 "\n" 704 "#include <qtwhatever.h>\n" 705 "#include <windows.h>\n" 706 "\n" 707 "#include <QLabel>\n" 708 "#include <QWidget>\n" 709 "\n" 710 "#include <QtGlobal>\n" 711 "\n" 712 "#include <algorithm>\n" 713 "#include <queue>\n", 714 sort(UnsortedCode)); 715 } 716 717 TEST_F(SortIncludesTest, NegativePriorities) { 718 Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false}, 719 {".*", 1, 0, false}}; 720 EXPECT_EQ("#include \"important_os_header.h\"\n" 721 "#include \"c_main.h\"\n" 722 "#include \"a_other.h\"\n", 723 sort("#include \"c_main.h\"\n" 724 "#include \"a_other.h\"\n" 725 "#include \"important_os_header.h\"\n", 726 "c_main.cc")); 727 728 // check stable when re-run 729 EXPECT_EQ("#include \"important_os_header.h\"\n" 730 "#include \"c_main.h\"\n" 731 "#include \"a_other.h\"\n", 732 sort("#include \"important_os_header.h\"\n" 733 "#include \"c_main.h\"\n" 734 "#include \"a_other.h\"\n", 735 "c_main.cc", 0)); 736 } 737 738 TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) { 739 Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false}, 740 {".*", 1, 0, false}}; 741 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 742 743 EXPECT_EQ("#include \"important_os_header.h\"\n" 744 "\n" 745 "#include \"c_main.h\"\n" 746 "\n" 747 "#include \"a_other.h\"\n", 748 sort("#include \"c_main.h\"\n" 749 "#include \"a_other.h\"\n" 750 "#include \"important_os_header.h\"\n", 751 "c_main.cc")); 752 753 // check stable when re-run 754 EXPECT_EQ("#include \"important_os_header.h\"\n" 755 "\n" 756 "#include \"c_main.h\"\n" 757 "\n" 758 "#include \"a_other.h\"\n", 759 sort("#include \"important_os_header.h\"\n" 760 "\n" 761 "#include \"c_main.h\"\n" 762 "\n" 763 "#include \"a_other.h\"\n", 764 "c_main.cc", 0)); 765 } 766 767 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { 768 std::string Code = "#include <ccc>\n" // Start of line: 0 769 "#include <bbbbbb>\n" // Start of line: 15 770 "#include <a>\n"; // Start of line: 33 771 EXPECT_EQ(31u, newCursor(Code, 0)); 772 EXPECT_EQ(13u, newCursor(Code, 15)); 773 EXPECT_EQ(0u, newCursor(Code, 33)); 774 775 EXPECT_EQ(41u, newCursor(Code, 10)); 776 EXPECT_EQ(23u, newCursor(Code, 25)); 777 EXPECT_EQ(10u, newCursor(Code, 43)); 778 } 779 780 TEST_F(SortIncludesTest, DeduplicateIncludes) { 781 EXPECT_EQ("#include <a>\n" 782 "#include <b>\n" 783 "#include <c>\n", 784 sort("#include <a>\n" 785 "#include <b>\n" 786 "#include <b>\n" 787 "#include <b>\n" 788 "#include <b>\n" 789 "#include <c>\n")); 790 791 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 792 EXPECT_EQ("#include <a>\n" 793 "#include <b>\n" 794 "#include <c>\n", 795 sort("#include <a>\n" 796 "#include <b>\n" 797 "\n" 798 "#include <b>\n" 799 "\n" 800 "#include <b>\n" 801 "#include <c>\n")); 802 803 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 804 EXPECT_EQ("#include <a>\n" 805 "#include <b>\n" 806 "#include <c>\n", 807 sort("#include <a>\n" 808 "#include <b>\n" 809 "\n" 810 "#include <b>\n" 811 "\n" 812 "#include <b>\n" 813 "#include <c>\n")); 814 } 815 816 TEST_F(SortIncludesTest, SortAndDeduplicateIncludes) { 817 EXPECT_EQ("#include <a>\n" 818 "#include <b>\n" 819 "#include <c>\n", 820 sort("#include <b>\n" 821 "#include <a>\n" 822 "#include <b>\n" 823 "#include <b>\n" 824 "#include <c>\n" 825 "#include <b>\n")); 826 827 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Merge; 828 EXPECT_EQ("#include <a>\n" 829 "#include <b>\n" 830 "#include <c>\n", 831 sort("#include <b>\n" 832 "#include <a>\n" 833 "\n" 834 "#include <b>\n" 835 "\n" 836 "#include <c>\n" 837 "#include <b>\n")); 838 839 Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup; 840 EXPECT_EQ("#include <a>\n" 841 "#include <b>\n" 842 "#include <c>\n", 843 sort("#include <b>\n" 844 "#include <a>\n" 845 "\n" 846 "#include <b>\n" 847 "\n" 848 "#include <c>\n" 849 "#include <b>\n")); 850 } 851 852 TEST_F(SortIncludesTest, CalculatesCorrectCursorPositionAfterDeduplicate) { 853 std::string Code = "#include <b>\n" // Start of line: 0 854 "#include <a>\n" // Start of line: 13 855 "#include <b>\n" // Start of line: 26 856 "#include <b>\n" // Start of line: 39 857 "#include <c>\n" // Start of line: 52 858 "#include <b>\n"; // Start of line: 65 859 std::string Expected = "#include <a>\n" // Start of line: 0 860 "#include <b>\n" // Start of line: 13 861 "#include <c>\n"; // Start of line: 26 862 EXPECT_EQ(Expected, sort(Code)); 863 // Cursor on 'i' in "#include <a>". 864 EXPECT_EQ(1u, newCursor(Code, 14)); 865 // Cursor on 'b' in "#include <b>". 866 EXPECT_EQ(23u, newCursor(Code, 10)); 867 EXPECT_EQ(23u, newCursor(Code, 36)); 868 EXPECT_EQ(23u, newCursor(Code, 49)); 869 EXPECT_EQ(23u, newCursor(Code, 36)); 870 EXPECT_EQ(23u, newCursor(Code, 75)); 871 // Cursor on '#' in "#include <c>". 872 EXPECT_EQ(26u, newCursor(Code, 52)); 873 } 874 875 TEST_F(SortIncludesTest, DeduplicateLocallyInEachBlock) { 876 EXPECT_EQ("#include <a>\n" 877 "#include <b>\n" 878 "\n" 879 "#include <b>\n" 880 "#include <c>\n", 881 sort("#include <a>\n" 882 "#include <b>\n" 883 "\n" 884 "#include <c>\n" 885 "#include <b>\n" 886 "#include <b>\n")); 887 } 888 889 TEST_F(SortIncludesTest, ValidAffactedRangesAfterDeduplicatingIncludes) { 890 std::string Code = "#include <a>\n" 891 "#include <b>\n" 892 "#include <a>\n" 893 "#include <a>\n" 894 "\n" 895 " int x ;"; 896 std::vector<tooling::Range> Ranges = {tooling::Range(0, 52)}; 897 auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.cpp"); 898 Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); 899 EXPECT_EQ(1u, Ranges.size()); 900 EXPECT_EQ(0u, Ranges[0].getOffset()); 901 EXPECT_EQ(26u, Ranges[0].getLength()); 902 } 903 904 TEST_F(SortIncludesTest, DoNotSortLikelyXml) { 905 EXPECT_EQ("<!--;\n" 906 "#include <b>\n" 907 "#include <a>\n" 908 "-->", 909 sort("<!--;\n" 910 "#include <b>\n" 911 "#include <a>\n" 912 "-->", 913 "input.h", 0)); 914 } 915 916 TEST_F(SortIncludesTest, DoNotOutputReplacementsForSortedBlocksWithRegrouping) { 917 Style.IncludeBlocks = Style.IBS_Regroup; 918 std::string Code = R"( 919 #include "b.h" 920 921 #include <a.h> 922 )"; 923 EXPECT_EQ(Code, sort(Code, "input.h", 0)); 924 } 925 926 TEST_F(SortIncludesTest, 927 DoNotOutputReplacementsForSortedBlocksWithRegroupingWindows) { 928 Style.IncludeBlocks = Style.IBS_Regroup; 929 std::string Code = "#include \"b.h\"\r\n" 930 "\r\n" 931 "#include <a.h>\r\n"; 932 EXPECT_EQ(Code, sort(Code, "input.h", 0)); 933 } 934 935 TEST_F(SortIncludesTest, DoNotRegroupGroupsInGoogleObjCStyle) { 936 FmtStyle = getGoogleStyle(FormatStyle::LK_ObjC); 937 938 EXPECT_EQ("#include <a.h>\n" 939 "#include <b.h>\n" 940 "#include \"a.h\"", 941 sort("#include <b.h>\n" 942 "#include <a.h>\n" 943 "#include \"a.h\"")); 944 } 945 946 TEST_F(SortIncludesTest, DoNotTreatPrecompiledHeadersAsFirstBlock) { 947 Style.IncludeBlocks = Style.IBS_Merge; 948 std::string Code = "#include \"d.h\"\r\n" 949 "#include \"b.h\"\r\n" 950 "#pragma hdrstop\r\n" 951 "\r\n" 952 "#include \"c.h\"\r\n" 953 "#include \"a.h\"\r\n" 954 "#include \"e.h\"\r\n"; 955 956 std::string Expected = "#include \"b.h\"\r\n" 957 "#include \"d.h\"\r\n" 958 "#pragma hdrstop\r\n" 959 "\r\n" 960 "#include \"e.h\"\r\n" 961 "#include \"a.h\"\r\n" 962 "#include \"c.h\"\r\n"; 963 964 EXPECT_EQ(Expected, sort(Code, "e.cpp", 2)); 965 966 Code = "#include \"d.h\"\n" 967 "#include \"b.h\"\n" 968 "#pragma hdrstop( \"c:\\projects\\include\\myinc.pch\" )\n" 969 "\n" 970 "#include \"c.h\"\n" 971 "#include \"a.h\"\n" 972 "#include \"e.h\"\n"; 973 974 Expected = "#include \"b.h\"\n" 975 "#include \"d.h\"\n" 976 "#pragma hdrstop(\"c:\\projects\\include\\myinc.pch\")\n" 977 "\n" 978 "#include \"e.h\"\n" 979 "#include \"a.h\"\n" 980 "#include \"c.h\"\n"; 981 982 EXPECT_EQ(Expected, sort(Code, "e.cpp", 2)); 983 } 984 985 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkMerge) { 986 Style.IncludeBlocks = Style.IBS_Merge; 987 std::string Code = "\xEF\xBB\xBF#include \"d.h\"\r\n" 988 "#include \"b.h\"\r\n" 989 "\r\n" 990 "#include \"c.h\"\r\n" 991 "#include \"a.h\"\r\n" 992 "#include \"e.h\"\r\n"; 993 994 std::string Expected = "\xEF\xBB\xBF#include \"e.h\"\r\n" 995 "#include \"a.h\"\r\n" 996 "#include \"b.h\"\r\n" 997 "#include \"c.h\"\r\n" 998 "#include \"d.h\"\r\n"; 999 1000 EXPECT_EQ(Expected, sort(Code, "e.cpp", 1)); 1001 } 1002 1003 TEST_F(SortIncludesTest, skipUTF8ByteOrderMarkPreserve) { 1004 Style.IncludeBlocks = Style.IBS_Preserve; 1005 std::string Code = "\xEF\xBB\xBF#include \"d.h\"\r\n" 1006 "#include \"b.h\"\r\n" 1007 "\r\n" 1008 "#include \"c.h\"\r\n" 1009 "#include \"a.h\"\r\n" 1010 "#include \"e.h\"\r\n"; 1011 1012 std::string Expected = "\xEF\xBB\xBF#include \"b.h\"\r\n" 1013 "#include \"d.h\"\r\n" 1014 "\r\n" 1015 "#include \"a.h\"\r\n" 1016 "#include \"c.h\"\r\n" 1017 "#include \"e.h\"\r\n"; 1018 1019 EXPECT_EQ(Expected, sort(Code, "e.cpp", 2)); 1020 } 1021 1022 TEST_F(SortIncludesTest, MergeLines) { 1023 Style.IncludeBlocks = Style.IBS_Merge; 1024 std::string Code = "#include \"c.h\"\r\n" 1025 "#include \"b\\\r\n" 1026 ".h\"\r\n" 1027 "#include \"a.h\"\r\n"; 1028 1029 std::string Expected = "#include \"a.h\"\r\n" 1030 "#include \"b\\\r\n" 1031 ".h\"\r\n" 1032 "#include \"c.h\"\r\n"; 1033 1034 EXPECT_EQ(Expected, sort(Code, "a.cpp", 1)); 1035 } 1036 1037 } // end namespace 1038 } // end namespace format 1039 } // end namespace clang 1040