1 //===- unittest/Format/SortIncludesTest.cpp - Include sort unit tests -----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "FormatTestUtils.h" 11 #include "clang/Format/Format.h" 12 #include "llvm/Support/Debug.h" 13 #include "gtest/gtest.h" 14 15 #define DEBUG_TYPE "format-test" 16 17 namespace clang { 18 namespace format { 19 namespace { 20 21 class SortIncludesTest : public ::testing::Test { 22 protected: 23 std::string sort(llvm::StringRef Code, StringRef FileName = "input.cpp") { 24 std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); 25 std::string Sorted = 26 applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName)); 27 return applyAllReplacements(Sorted, 28 reformat(Style, Sorted, Ranges, FileName)); 29 } 30 31 unsigned newCursor(llvm::StringRef Code, unsigned Cursor) { 32 std::vector<tooling::Range> Ranges(1, tooling::Range(0, Code.size())); 33 sortIncludes(Style, Code, Ranges, "input.cpp", &Cursor); 34 return Cursor; 35 } 36 37 FormatStyle Style = getLLVMStyle(); 38 39 }; 40 41 TEST_F(SortIncludesTest, BasicSorting) { 42 EXPECT_EQ("#include \"a.h\"\n" 43 "#include \"b.h\"\n" 44 "#include \"c.h\"\n", 45 sort("#include \"a.h\"\n" 46 "#include \"c.h\"\n" 47 "#include \"b.h\"\n")); 48 } 49 50 TEST_F(SortIncludesTest, SupportClangFormatOff) { 51 EXPECT_EQ("#include <a>\n" 52 "#include <b>\n" 53 "#include <c>\n" 54 "// clang-format off\n" 55 "#include <b>\n" 56 "#include <a>\n" 57 "#include <c>\n" 58 "// clang-format on\n", 59 sort("#include <b>\n" 60 "#include <a>\n" 61 "#include <c>\n" 62 "// clang-format off\n" 63 "#include <b>\n" 64 "#include <a>\n" 65 "#include <c>\n" 66 "// clang-format on\n")); 67 } 68 69 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) { 70 Style.SortIncludes = false; 71 EXPECT_EQ("#include \"a.h\"\n" 72 "#include \"c.h\"\n" 73 "#include \"b.h\"\n", 74 sort("#include \"a.h\"\n" 75 "#include \"c.h\"\n" 76 "#include \"b.h\"\n")); 77 } 78 79 TEST_F(SortIncludesTest, MixIncludeAndImport) { 80 EXPECT_EQ("#include \"a.h\"\n" 81 "#import \"b.h\"\n" 82 "#include \"c.h\"\n", 83 sort("#include \"a.h\"\n" 84 "#include \"c.h\"\n" 85 "#import \"b.h\"\n")); 86 } 87 88 TEST_F(SortIncludesTest, FixTrailingComments) { 89 EXPECT_EQ("#include \"a.h\" // comment\n" 90 "#include \"bb.h\" // comment\n" 91 "#include \"ccc.h\"\n", 92 sort("#include \"a.h\" // comment\n" 93 "#include \"ccc.h\"\n" 94 "#include \"bb.h\" // comment\n")); 95 } 96 97 TEST_F(SortIncludesTest, LeadingWhitespace) { 98 EXPECT_EQ("#include \"a.h\"\n" 99 "#include \"b.h\"\n" 100 "#include \"c.h\"\n", 101 sort(" #include \"a.h\"\n" 102 " #include \"c.h\"\n" 103 " #include \"b.h\"\n")); 104 EXPECT_EQ("#include \"a.h\"\n" 105 "#include \"b.h\"\n" 106 "#include \"c.h\"\n", 107 sort("# include \"a.h\"\n" 108 "# include \"c.h\"\n" 109 "# include \"b.h\"\n")); 110 } 111 112 TEST_F(SortIncludesTest, GreaterInComment) { 113 EXPECT_EQ("#include \"a.h\"\n" 114 "#include \"b.h\" // >\n" 115 "#include \"c.h\"\n", 116 sort("#include \"a.h\"\n" 117 "#include \"c.h\"\n" 118 "#include \"b.h\" // >\n")); 119 } 120 121 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) { 122 EXPECT_EQ("#include \"a.h\"\n" 123 "#include \"c.h\"\n" 124 "\n" 125 "#include \"b.h\"\n", 126 sort("#include \"a.h\"\n" 127 "#include \"c.h\"\n" 128 "\n" 129 "#include \"b.h\"\n")); 130 } 131 132 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) { 133 EXPECT_EQ("#include \"a.h\"\n" 134 "#include \"c.h\"\n" 135 "#include <b.h>\n" 136 "#include <d.h>\n", 137 sort("#include <d.h>\n" 138 "#include <b.h>\n" 139 "#include \"c.h\"\n" 140 "#include \"a.h\"\n")); 141 142 Style = getGoogleStyle(FormatStyle::LK_Cpp); 143 EXPECT_EQ("#include <b.h>\n" 144 "#include <d.h>\n" 145 "#include \"a.h\"\n" 146 "#include \"c.h\"\n", 147 sort("#include <d.h>\n" 148 "#include <b.h>\n" 149 "#include \"c.h\"\n" 150 "#include \"a.h\"\n")); 151 } 152 153 TEST_F(SortIncludesTest, HandlesMultilineIncludes) { 154 EXPECT_EQ("#include \"a.h\"\n" 155 "#include \"b.h\"\n" 156 "#include \"c.h\"\n", 157 sort("#include \"a.h\"\n" 158 "#include \\\n" 159 "\"c.h\"\n" 160 "#include \"b.h\"\n")); 161 } 162 163 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { 164 EXPECT_EQ("#include \"llvm/a.h\"\n" 165 "#include \"b.h\"\n" 166 "#include \"c.h\"\n", 167 sort("#include \"llvm/a.h\"\n" 168 "#include \"c.h\"\n" 169 "#include \"b.h\"\n", 170 "a.cc")); 171 EXPECT_EQ("#include \"llvm/a.h\"\n" 172 "#include \"b.h\"\n" 173 "#include \"c.h\"\n", 174 sort("#include \"llvm/a.h\"\n" 175 "#include \"c.h\"\n" 176 "#include \"b.h\"\n", 177 "a_main.cc")); 178 EXPECT_EQ("#include \"llvm/input.h\"\n" 179 "#include \"b.h\"\n" 180 "#include \"c.h\"\n", 181 sort("#include \"llvm/input.h\"\n" 182 "#include \"c.h\"\n" 183 "#include \"b.h\"\n", 184 "input.mm")); 185 186 // Don't do this in headers. 187 EXPECT_EQ("#include \"b.h\"\n" 188 "#include \"c.h\"\n" 189 "#include \"llvm/a.h\"\n", 190 sort("#include \"llvm/a.h\"\n" 191 "#include \"c.h\"\n" 192 "#include \"b.h\"\n", 193 "a.h")); 194 195 // Only do this in the first #include block. 196 EXPECT_EQ("#include <a>\n" 197 "\n" 198 "#include \"b.h\"\n" 199 "#include \"c.h\"\n" 200 "#include \"llvm/a.h\"\n", 201 sort("#include <a>\n" 202 "\n" 203 "#include \"llvm/a.h\"\n" 204 "#include \"c.h\"\n" 205 "#include \"b.h\"\n", 206 "a.cc")); 207 208 // Only recognize the first #include with a matching basename as main include. 209 EXPECT_EQ("#include \"a.h\"\n" 210 "#include \"b.h\"\n" 211 "#include \"c.h\"\n" 212 "#include \"llvm/a.h\"\n", 213 sort("#include \"b.h\"\n" 214 "#include \"a.h\"\n" 215 "#include \"c.h\"\n" 216 "#include \"llvm/a.h\"\n", 217 "a.cc")); 218 } 219 220 TEST_F(SortIncludesTest, NegativePriorities) { 221 Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}}; 222 EXPECT_EQ("#include \"important_os_header.h\"\n" 223 "#include \"c_main.h\"\n" 224 "#include \"a_other.h\"\n", 225 sort("#include \"c_main.h\"\n" 226 "#include \"a_other.h\"\n" 227 "#include \"important_os_header.h\"\n", 228 "c_main.cc")); 229 230 // check stable when re-run 231 EXPECT_EQ("#include \"important_os_header.h\"\n" 232 "#include \"c_main.h\"\n" 233 "#include \"a_other.h\"\n", 234 sort("#include \"important_os_header.h\"\n" 235 "#include \"c_main.h\"\n" 236 "#include \"a_other.h\"\n", 237 "c_main.cc")); 238 } 239 240 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { 241 std::string Code = "#include <ccc>\n" // Start of line: 0 242 "#include <bbbbbb>\n" // Start of line: 15 243 "#include <a>\n"; // Start of line: 33 244 EXPECT_EQ(31u, newCursor(Code, 0)); 245 EXPECT_EQ(13u, newCursor(Code, 15)); 246 EXPECT_EQ(0u, newCursor(Code, 33)); 247 248 EXPECT_EQ(41u, newCursor(Code, 10)); 249 EXPECT_EQ(23u, newCursor(Code, 25)); 250 EXPECT_EQ(10u, newCursor(Code, 43)); 251 } 252 253 } // end namespace 254 } // end namespace format 255 } // end namespace clang 256