1d89ae9d3SDaniel Jasper //===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===// 2d89ae9d3SDaniel Jasper // 3d89ae9d3SDaniel Jasper // The LLVM Compiler Infrastructure 4d89ae9d3SDaniel Jasper // 5d89ae9d3SDaniel Jasper // This file is distributed under the University of Illinois Open Source 6d89ae9d3SDaniel Jasper // License. See LICENSE.TXT for details. 7d89ae9d3SDaniel Jasper // 8d89ae9d3SDaniel Jasper //===----------------------------------------------------------------------===// 9d89ae9d3SDaniel Jasper 10d89ae9d3SDaniel Jasper #include "FormatTestUtils.h" 11d89ae9d3SDaniel Jasper #include "clang/Format/Format.h" 12d89ae9d3SDaniel Jasper #include "llvm/Support/Debug.h" 13d89ae9d3SDaniel Jasper #include "gtest/gtest.h" 14d89ae9d3SDaniel Jasper 15d89ae9d3SDaniel Jasper #define DEBUG_TYPE "format-test" 16d89ae9d3SDaniel Jasper 17d89ae9d3SDaniel Jasper namespace clang { 18d89ae9d3SDaniel Jasper namespace format { 19d89ae9d3SDaniel Jasper namespace { 20d89ae9d3SDaniel Jasper 21d89ae9d3SDaniel Jasper class SortIncludesTest : public ::testing::Test { 22d89ae9d3SDaniel Jasper protected: 2394a96fceSDaniel Jasper std::vector<tooling::Range> GetCodeRange(StringRef Code) { 2494a96fceSDaniel Jasper return std::vector<tooling::Range>(1, tooling::Range(0, Code.size())); 2594a96fceSDaniel Jasper } 2694a96fceSDaniel Jasper 2794a96fceSDaniel Jasper std::string sort(StringRef Code, StringRef FileName = "input.cpp") { 2894a96fceSDaniel Jasper auto Ranges = GetCodeRange(Code); 29*4f8d9943SEric Liu auto Sorted = 3085c472dcSDaniel Jasper applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName)); 31*4f8d9943SEric Liu EXPECT_TRUE(static_cast<bool>(Sorted)); 32*4f8d9943SEric Liu auto Result = applyAllReplacements( 33*4f8d9943SEric Liu *Sorted, reformat(Style, *Sorted, Ranges, FileName)); 34*4f8d9943SEric Liu EXPECT_TRUE(static_cast<bool>(Result)); 35*4f8d9943SEric Liu return *Result; 36d89ae9d3SDaniel Jasper } 3785c472dcSDaniel Jasper 38b68aabf7SDaniel Jasper unsigned newCursor(llvm::StringRef Code, unsigned Cursor) { 3994a96fceSDaniel Jasper sortIncludes(Style, Code, GetCodeRange(Code), "input.cpp", &Cursor); 40b68aabf7SDaniel Jasper return Cursor; 41b68aabf7SDaniel Jasper } 42b68aabf7SDaniel Jasper 4385c472dcSDaniel Jasper FormatStyle Style = getLLVMStyle(); 44b68aabf7SDaniel Jasper 45d89ae9d3SDaniel Jasper }; 46d89ae9d3SDaniel Jasper 47d89ae9d3SDaniel Jasper TEST_F(SortIncludesTest, BasicSorting) { 48d89ae9d3SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 49d89ae9d3SDaniel Jasper "#include \"b.h\"\n" 50d89ae9d3SDaniel Jasper "#include \"c.h\"\n", 51d89ae9d3SDaniel Jasper sort("#include \"a.h\"\n" 52d89ae9d3SDaniel Jasper "#include \"c.h\"\n" 53d89ae9d3SDaniel Jasper "#include \"b.h\"\n")); 54d89ae9d3SDaniel Jasper } 55d89ae9d3SDaniel Jasper 5694a96fceSDaniel Jasper TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) { 5794a96fceSDaniel Jasper // Identical #includes have led to a failure with an unstable sort. 5894a96fceSDaniel Jasper std::string Code = "#include <a>\n" 5994a96fceSDaniel Jasper "#include <b>\n" 6094a96fceSDaniel Jasper "#include <b>\n" 6194a96fceSDaniel Jasper "#include <b>\n" 6294a96fceSDaniel Jasper "#include <b>\n" 6394a96fceSDaniel Jasper "#include <c>\n"; 6494a96fceSDaniel Jasper EXPECT_TRUE(sortIncludes(Style, Code, GetCodeRange(Code), "a.cc").empty()); 6594a96fceSDaniel Jasper } 6694a96fceSDaniel Jasper 679b8c7c72SDaniel Jasper TEST_F(SortIncludesTest, SupportClangFormatOff) { 689b8c7c72SDaniel Jasper EXPECT_EQ("#include <a>\n" 699b8c7c72SDaniel Jasper "#include <b>\n" 709b8c7c72SDaniel Jasper "#include <c>\n" 719b8c7c72SDaniel Jasper "// clang-format off\n" 729b8c7c72SDaniel Jasper "#include <b>\n" 739b8c7c72SDaniel Jasper "#include <a>\n" 749b8c7c72SDaniel Jasper "#include <c>\n" 759b8c7c72SDaniel Jasper "// clang-format on\n", 769b8c7c72SDaniel Jasper sort("#include <b>\n" 779b8c7c72SDaniel Jasper "#include <a>\n" 789b8c7c72SDaniel Jasper "#include <c>\n" 799b8c7c72SDaniel Jasper "// clang-format off\n" 809b8c7c72SDaniel Jasper "#include <b>\n" 819b8c7c72SDaniel Jasper "#include <a>\n" 829b8c7c72SDaniel Jasper "#include <c>\n" 839b8c7c72SDaniel Jasper "// clang-format on\n")); 849b8c7c72SDaniel Jasper } 859b8c7c72SDaniel Jasper 86da446770SDaniel Jasper TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) { 87da446770SDaniel Jasper Style.SortIncludes = false; 88da446770SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 89da446770SDaniel Jasper "#include \"c.h\"\n" 90da446770SDaniel Jasper "#include \"b.h\"\n", 91da446770SDaniel Jasper sort("#include \"a.h\"\n" 92da446770SDaniel Jasper "#include \"c.h\"\n" 93da446770SDaniel Jasper "#include \"b.h\"\n")); 94da446770SDaniel Jasper } 95da446770SDaniel Jasper 96ff06370eSNico Weber TEST_F(SortIncludesTest, MixIncludeAndImport) { 97ff06370eSNico Weber EXPECT_EQ("#include \"a.h\"\n" 98ff06370eSNico Weber "#import \"b.h\"\n" 99ff06370eSNico Weber "#include \"c.h\"\n", 100ff06370eSNico Weber sort("#include \"a.h\"\n" 101ff06370eSNico Weber "#include \"c.h\"\n" 102ff06370eSNico Weber "#import \"b.h\"\n")); 103ff06370eSNico Weber } 104ff06370eSNico Weber 105d89ae9d3SDaniel Jasper TEST_F(SortIncludesTest, FixTrailingComments) { 106d89ae9d3SDaniel Jasper EXPECT_EQ("#include \"a.h\" // comment\n" 107d89ae9d3SDaniel Jasper "#include \"bb.h\" // comment\n" 108d89ae9d3SDaniel Jasper "#include \"ccc.h\"\n", 109d89ae9d3SDaniel Jasper sort("#include \"a.h\" // comment\n" 110d89ae9d3SDaniel Jasper "#include \"ccc.h\"\n" 111d89ae9d3SDaniel Jasper "#include \"bb.h\" // comment\n")); 112d89ae9d3SDaniel Jasper } 113d89ae9d3SDaniel Jasper 114d89ae9d3SDaniel Jasper TEST_F(SortIncludesTest, LeadingWhitespace) { 115d89ae9d3SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 116d89ae9d3SDaniel Jasper "#include \"b.h\"\n" 117d89ae9d3SDaniel Jasper "#include \"c.h\"\n", 118d89ae9d3SDaniel Jasper sort(" #include \"a.h\"\n" 119d89ae9d3SDaniel Jasper " #include \"c.h\"\n" 120d89ae9d3SDaniel Jasper " #include \"b.h\"\n")); 121d89ae9d3SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 122d89ae9d3SDaniel Jasper "#include \"b.h\"\n" 123d89ae9d3SDaniel Jasper "#include \"c.h\"\n", 124d89ae9d3SDaniel Jasper sort("# include \"a.h\"\n" 125d89ae9d3SDaniel Jasper "# include \"c.h\"\n" 126d89ae9d3SDaniel Jasper "# include \"b.h\"\n")); 127d89ae9d3SDaniel Jasper } 128d89ae9d3SDaniel Jasper 129d89ae9d3SDaniel Jasper TEST_F(SortIncludesTest, GreaterInComment) { 130d89ae9d3SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 131d89ae9d3SDaniel Jasper "#include \"b.h\" // >\n" 132d89ae9d3SDaniel Jasper "#include \"c.h\"\n", 133d89ae9d3SDaniel Jasper sort("#include \"a.h\"\n" 134d89ae9d3SDaniel Jasper "#include \"c.h\"\n" 135d89ae9d3SDaniel Jasper "#include \"b.h\" // >\n")); 136d89ae9d3SDaniel Jasper } 137d89ae9d3SDaniel Jasper 138d89ae9d3SDaniel Jasper TEST_F(SortIncludesTest, SortsLocallyInEachBlock) { 139d89ae9d3SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 140d89ae9d3SDaniel Jasper "#include \"c.h\"\n" 141d89ae9d3SDaniel Jasper "\n" 142d89ae9d3SDaniel Jasper "#include \"b.h\"\n", 14385c472dcSDaniel Jasper sort("#include \"a.h\"\n" 14485c472dcSDaniel Jasper "#include \"c.h\"\n" 145d89ae9d3SDaniel Jasper "\n" 146d89ae9d3SDaniel Jasper "#include \"b.h\"\n")); 147d89ae9d3SDaniel Jasper } 148d89ae9d3SDaniel Jasper 149d89ae9d3SDaniel Jasper TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) { 15085c472dcSDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 15185c472dcSDaniel Jasper "#include \"c.h\"\n" 15285c472dcSDaniel Jasper "#include <b.h>\n" 15385c472dcSDaniel Jasper "#include <d.h>\n", 15485c472dcSDaniel Jasper sort("#include <d.h>\n" 15585c472dcSDaniel Jasper "#include <b.h>\n" 15685c472dcSDaniel Jasper "#include \"c.h\"\n" 15785c472dcSDaniel Jasper "#include \"a.h\"\n")); 15885c472dcSDaniel Jasper 15985c472dcSDaniel Jasper Style = getGoogleStyle(FormatStyle::LK_Cpp); 160d89ae9d3SDaniel Jasper EXPECT_EQ("#include <b.h>\n" 161d89ae9d3SDaniel Jasper "#include <d.h>\n" 162d89ae9d3SDaniel Jasper "#include \"a.h\"\n" 163d89ae9d3SDaniel Jasper "#include \"c.h\"\n", 164d89ae9d3SDaniel Jasper sort("#include <d.h>\n" 165d89ae9d3SDaniel Jasper "#include <b.h>\n" 166d89ae9d3SDaniel Jasper "#include \"c.h\"\n" 167d89ae9d3SDaniel Jasper "#include \"a.h\"\n")); 168d89ae9d3SDaniel Jasper } 169d89ae9d3SDaniel Jasper 170d89ae9d3SDaniel Jasper TEST_F(SortIncludesTest, HandlesMultilineIncludes) { 171d89ae9d3SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 172d89ae9d3SDaniel Jasper "#include \"b.h\"\n" 173d89ae9d3SDaniel Jasper "#include \"c.h\"\n", 174d89ae9d3SDaniel Jasper sort("#include \"a.h\"\n" 175d89ae9d3SDaniel Jasper "#include \\\n" 176d89ae9d3SDaniel Jasper "\"c.h\"\n" 177d89ae9d3SDaniel Jasper "#include \"b.h\"\n")); 178d89ae9d3SDaniel Jasper } 179d89ae9d3SDaniel Jasper 18085c472dcSDaniel Jasper TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { 1819c8ff355SDaniel Jasper Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 18285c472dcSDaniel Jasper EXPECT_EQ("#include \"llvm/a.h\"\n" 18385c472dcSDaniel Jasper "#include \"b.h\"\n" 18485c472dcSDaniel Jasper "#include \"c.h\"\n", 18585c472dcSDaniel Jasper sort("#include \"llvm/a.h\"\n" 18685c472dcSDaniel Jasper "#include \"c.h\"\n" 1870bfdeb4bSDaniel Jasper "#include \"b.h\"\n", 1880bfdeb4bSDaniel Jasper "a.cc")); 189afa62faeSNico Weber EXPECT_EQ("#include \"llvm/a.h\"\n" 190afa62faeSNico Weber "#include \"b.h\"\n" 191afa62faeSNico Weber "#include \"c.h\"\n", 192afa62faeSNico Weber sort("#include \"llvm/a.h\"\n" 193afa62faeSNico Weber "#include \"c.h\"\n" 194afa62faeSNico Weber "#include \"b.h\"\n", 1959c8ff355SDaniel Jasper "a_test.cc")); 1960bfdeb4bSDaniel Jasper EXPECT_EQ("#include \"llvm/input.h\"\n" 1970bfdeb4bSDaniel Jasper "#include \"b.h\"\n" 1980bfdeb4bSDaniel Jasper "#include \"c.h\"\n", 1990bfdeb4bSDaniel Jasper sort("#include \"llvm/input.h\"\n" 2000bfdeb4bSDaniel Jasper "#include \"c.h\"\n" 2010bfdeb4bSDaniel Jasper "#include \"b.h\"\n", 202afa62faeSNico Weber "input.mm")); 20385c472dcSDaniel Jasper 2049c8ff355SDaniel Jasper // Don't allow prefixes. 2059c8ff355SDaniel Jasper EXPECT_EQ("#include \"b.h\"\n" 2069c8ff355SDaniel Jasper "#include \"c.h\"\n" 2079c8ff355SDaniel Jasper "#include \"llvm/not_a.h\"\n", 2089c8ff355SDaniel Jasper sort("#include \"llvm/not_a.h\"\n" 2099c8ff355SDaniel Jasper "#include \"c.h\"\n" 2109c8ff355SDaniel Jasper "#include \"b.h\"\n", 2119c8ff355SDaniel Jasper "a.cc")); 2129c8ff355SDaniel Jasper 2139c8ff355SDaniel Jasper // Don't do this for _main and other suffixes. 2149c8ff355SDaniel Jasper EXPECT_EQ("#include \"b.h\"\n" 2159c8ff355SDaniel Jasper "#include \"c.h\"\n" 2169c8ff355SDaniel Jasper "#include \"llvm/a.h\"\n", 2179c8ff355SDaniel Jasper sort("#include \"llvm/a.h\"\n" 2189c8ff355SDaniel Jasper "#include \"c.h\"\n" 2199c8ff355SDaniel Jasper "#include \"b.h\"\n", 2209c8ff355SDaniel Jasper "a_main.cc")); 2219c8ff355SDaniel Jasper 22285c472dcSDaniel Jasper // Don't do this in headers. 22385c472dcSDaniel Jasper EXPECT_EQ("#include \"b.h\"\n" 22485c472dcSDaniel Jasper "#include \"c.h\"\n" 22585c472dcSDaniel Jasper "#include \"llvm/a.h\"\n", 22685c472dcSDaniel Jasper sort("#include \"llvm/a.h\"\n" 22785c472dcSDaniel Jasper "#include \"c.h\"\n" 22885c472dcSDaniel Jasper "#include \"b.h\"\n", 2290bfdeb4bSDaniel Jasper "a.h")); 23032d75fa2SDaniel Jasper 23132d75fa2SDaniel Jasper // Only do this in the first #include block. 23232d75fa2SDaniel Jasper EXPECT_EQ("#include <a>\n" 23332d75fa2SDaniel Jasper "\n" 23432d75fa2SDaniel Jasper "#include \"b.h\"\n" 23532d75fa2SDaniel Jasper "#include \"c.h\"\n" 23632d75fa2SDaniel Jasper "#include \"llvm/a.h\"\n", 23732d75fa2SDaniel Jasper sort("#include <a>\n" 23832d75fa2SDaniel Jasper "\n" 23932d75fa2SDaniel Jasper "#include \"llvm/a.h\"\n" 24032d75fa2SDaniel Jasper "#include \"c.h\"\n" 24132d75fa2SDaniel Jasper "#include \"b.h\"\n", 24232d75fa2SDaniel Jasper "a.cc")); 243a252f5d5SDaniel Jasper 244a252f5d5SDaniel Jasper // Only recognize the first #include with a matching basename as main include. 245a252f5d5SDaniel Jasper EXPECT_EQ("#include \"a.h\"\n" 246a252f5d5SDaniel Jasper "#include \"b.h\"\n" 247a252f5d5SDaniel Jasper "#include \"c.h\"\n" 248a252f5d5SDaniel Jasper "#include \"llvm/a.h\"\n", 249a252f5d5SDaniel Jasper sort("#include \"b.h\"\n" 250a252f5d5SDaniel Jasper "#include \"a.h\"\n" 251a252f5d5SDaniel Jasper "#include \"c.h\"\n" 252a252f5d5SDaniel Jasper "#include \"llvm/a.h\"\n", 253a252f5d5SDaniel Jasper "a.cc")); 25485c472dcSDaniel Jasper } 25585c472dcSDaniel Jasper 256d2629dc8SDaniel Jasper TEST_F(SortIncludesTest, NegativePriorities) { 257d2629dc8SDaniel Jasper Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}}; 258d2629dc8SDaniel Jasper EXPECT_EQ("#include \"important_os_header.h\"\n" 2590bfdeb4bSDaniel Jasper "#include \"c_main.h\"\n" 2600bfdeb4bSDaniel Jasper "#include \"a_other.h\"\n", 2610bfdeb4bSDaniel Jasper sort("#include \"c_main.h\"\n" 2620bfdeb4bSDaniel Jasper "#include \"a_other.h\"\n" 2630bfdeb4bSDaniel Jasper "#include \"important_os_header.h\"\n", 2640bfdeb4bSDaniel Jasper "c_main.cc")); 2650bfdeb4bSDaniel Jasper 2660bfdeb4bSDaniel Jasper // check stable when re-run 2670bfdeb4bSDaniel Jasper EXPECT_EQ("#include \"important_os_header.h\"\n" 2680bfdeb4bSDaniel Jasper "#include \"c_main.h\"\n" 2690bfdeb4bSDaniel Jasper "#include \"a_other.h\"\n", 2700bfdeb4bSDaniel Jasper sort("#include \"important_os_header.h\"\n" 2710bfdeb4bSDaniel Jasper "#include \"c_main.h\"\n" 2720bfdeb4bSDaniel Jasper "#include \"a_other.h\"\n", 2730bfdeb4bSDaniel Jasper "c_main.cc")); 274d2629dc8SDaniel Jasper } 275d2629dc8SDaniel Jasper 276b68aabf7SDaniel Jasper TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { 277b68aabf7SDaniel Jasper std::string Code = "#include <ccc>\n" // Start of line: 0 278b68aabf7SDaniel Jasper "#include <bbbbbb>\n" // Start of line: 15 279b68aabf7SDaniel Jasper "#include <a>\n"; // Start of line: 33 280b68aabf7SDaniel Jasper EXPECT_EQ(31u, newCursor(Code, 0)); 281b68aabf7SDaniel Jasper EXPECT_EQ(13u, newCursor(Code, 15)); 282b68aabf7SDaniel Jasper EXPECT_EQ(0u, newCursor(Code, 33)); 283b68aabf7SDaniel Jasper 284b68aabf7SDaniel Jasper EXPECT_EQ(41u, newCursor(Code, 10)); 285b68aabf7SDaniel Jasper EXPECT_EQ(23u, newCursor(Code, 25)); 286b68aabf7SDaniel Jasper EXPECT_EQ(10u, newCursor(Code, 43)); 287b68aabf7SDaniel Jasper } 288b68aabf7SDaniel Jasper 289d89ae9d3SDaniel Jasper } // end namespace 290d89ae9d3SDaniel Jasper } // end namespace format 291d89ae9d3SDaniel Jasper } // end namespace clang 292