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