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