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