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::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, StringRef FileName = "input.cpp") { 28 auto Ranges = GetCodeRange(Code); 29 std::string Sorted = 30 applyAllReplacements(Code, sortIncludes(Style, Code, Ranges, FileName)); 31 return applyAllReplacements(Sorted, 32 reformat(Style, Sorted, Ranges, FileName)); 33 } 34 35 unsigned newCursor(llvm::StringRef Code, unsigned Cursor) { 36 sortIncludes(Style, Code, GetCodeRange(Code), "input.cpp", &Cursor); 37 return Cursor; 38 } 39 40 FormatStyle Style = getLLVMStyle(); 41 42 }; 43 44 TEST_F(SortIncludesTest, BasicSorting) { 45 EXPECT_EQ("#include \"a.h\"\n" 46 "#include \"b.h\"\n" 47 "#include \"c.h\"\n", 48 sort("#include \"a.h\"\n" 49 "#include \"c.h\"\n" 50 "#include \"b.h\"\n")); 51 } 52 53 TEST_F(SortIncludesTest, NoReplacementsForValidIncludes) { 54 // Identical #includes have led to a failure with an unstable sort. 55 std::string Code = "#include <a>\n" 56 "#include <b>\n" 57 "#include <b>\n" 58 "#include <b>\n" 59 "#include <b>\n" 60 "#include <c>\n"; 61 EXPECT_TRUE(sortIncludes(Style, Code, GetCodeRange(Code), "a.cc").empty()); 62 } 63 64 TEST_F(SortIncludesTest, SupportClangFormatOff) { 65 EXPECT_EQ("#include <a>\n" 66 "#include <b>\n" 67 "#include <c>\n" 68 "// clang-format off\n" 69 "#include <b>\n" 70 "#include <a>\n" 71 "#include <c>\n" 72 "// clang-format on\n", 73 sort("#include <b>\n" 74 "#include <a>\n" 75 "#include <c>\n" 76 "// clang-format off\n" 77 "#include <b>\n" 78 "#include <a>\n" 79 "#include <c>\n" 80 "// clang-format on\n")); 81 } 82 83 TEST_F(SortIncludesTest, IncludeSortingCanBeDisabled) { 84 Style.SortIncludes = false; 85 EXPECT_EQ("#include \"a.h\"\n" 86 "#include \"c.h\"\n" 87 "#include \"b.h\"\n", 88 sort("#include \"a.h\"\n" 89 "#include \"c.h\"\n" 90 "#include \"b.h\"\n")); 91 } 92 93 TEST_F(SortIncludesTest, MixIncludeAndImport) { 94 EXPECT_EQ("#include \"a.h\"\n" 95 "#import \"b.h\"\n" 96 "#include \"c.h\"\n", 97 sort("#include \"a.h\"\n" 98 "#include \"c.h\"\n" 99 "#import \"b.h\"\n")); 100 } 101 102 TEST_F(SortIncludesTest, FixTrailingComments) { 103 EXPECT_EQ("#include \"a.h\" // comment\n" 104 "#include \"bb.h\" // comment\n" 105 "#include \"ccc.h\"\n", 106 sort("#include \"a.h\" // comment\n" 107 "#include \"ccc.h\"\n" 108 "#include \"bb.h\" // comment\n")); 109 } 110 111 TEST_F(SortIncludesTest, LeadingWhitespace) { 112 EXPECT_EQ("#include \"a.h\"\n" 113 "#include \"b.h\"\n" 114 "#include \"c.h\"\n", 115 sort(" #include \"a.h\"\n" 116 " #include \"c.h\"\n" 117 " #include \"b.h\"\n")); 118 EXPECT_EQ("#include \"a.h\"\n" 119 "#include \"b.h\"\n" 120 "#include \"c.h\"\n", 121 sort("# include \"a.h\"\n" 122 "# include \"c.h\"\n" 123 "# include \"b.h\"\n")); 124 } 125 126 TEST_F(SortIncludesTest, GreaterInComment) { 127 EXPECT_EQ("#include \"a.h\"\n" 128 "#include \"b.h\" // >\n" 129 "#include \"c.h\"\n", 130 sort("#include \"a.h\"\n" 131 "#include \"c.h\"\n" 132 "#include \"b.h\" // >\n")); 133 } 134 135 TEST_F(SortIncludesTest, SortsLocallyInEachBlock) { 136 EXPECT_EQ("#include \"a.h\"\n" 137 "#include \"c.h\"\n" 138 "\n" 139 "#include \"b.h\"\n", 140 sort("#include \"a.h\"\n" 141 "#include \"c.h\"\n" 142 "\n" 143 "#include \"b.h\"\n")); 144 } 145 146 TEST_F(SortIncludesTest, HandlesAngledIncludesAsSeparateBlocks) { 147 EXPECT_EQ("#include \"a.h\"\n" 148 "#include \"c.h\"\n" 149 "#include <b.h>\n" 150 "#include <d.h>\n", 151 sort("#include <d.h>\n" 152 "#include <b.h>\n" 153 "#include \"c.h\"\n" 154 "#include \"a.h\"\n")); 155 156 Style = getGoogleStyle(FormatStyle::LK_Cpp); 157 EXPECT_EQ("#include <b.h>\n" 158 "#include <d.h>\n" 159 "#include \"a.h\"\n" 160 "#include \"c.h\"\n", 161 sort("#include <d.h>\n" 162 "#include <b.h>\n" 163 "#include \"c.h\"\n" 164 "#include \"a.h\"\n")); 165 } 166 167 TEST_F(SortIncludesTest, HandlesMultilineIncludes) { 168 EXPECT_EQ("#include \"a.h\"\n" 169 "#include \"b.h\"\n" 170 "#include \"c.h\"\n", 171 sort("#include \"a.h\"\n" 172 "#include \\\n" 173 "\"c.h\"\n" 174 "#include \"b.h\"\n")); 175 } 176 177 TEST_F(SortIncludesTest, LeavesMainHeaderFirst) { 178 Style.IncludeIsMainRegex = "([-_](test|unittest))?$"; 179 EXPECT_EQ("#include \"llvm/a.h\"\n" 180 "#include \"b.h\"\n" 181 "#include \"c.h\"\n", 182 sort("#include \"llvm/a.h\"\n" 183 "#include \"c.h\"\n" 184 "#include \"b.h\"\n", 185 "a.cc")); 186 EXPECT_EQ("#include \"llvm/a.h\"\n" 187 "#include \"b.h\"\n" 188 "#include \"c.h\"\n", 189 sort("#include \"llvm/a.h\"\n" 190 "#include \"c.h\"\n" 191 "#include \"b.h\"\n", 192 "a_test.cc")); 193 EXPECT_EQ("#include \"llvm/input.h\"\n" 194 "#include \"b.h\"\n" 195 "#include \"c.h\"\n", 196 sort("#include \"llvm/input.h\"\n" 197 "#include \"c.h\"\n" 198 "#include \"b.h\"\n", 199 "input.mm")); 200 201 // Don't allow prefixes. 202 EXPECT_EQ("#include \"b.h\"\n" 203 "#include \"c.h\"\n" 204 "#include \"llvm/not_a.h\"\n", 205 sort("#include \"llvm/not_a.h\"\n" 206 "#include \"c.h\"\n" 207 "#include \"b.h\"\n", 208 "a.cc")); 209 210 // Don't do this for _main and other suffixes. 211 EXPECT_EQ("#include \"b.h\"\n" 212 "#include \"c.h\"\n" 213 "#include \"llvm/a.h\"\n", 214 sort("#include \"llvm/a.h\"\n" 215 "#include \"c.h\"\n" 216 "#include \"b.h\"\n", 217 "a_main.cc")); 218 219 // Don't do this in headers. 220 EXPECT_EQ("#include \"b.h\"\n" 221 "#include \"c.h\"\n" 222 "#include \"llvm/a.h\"\n", 223 sort("#include \"llvm/a.h\"\n" 224 "#include \"c.h\"\n" 225 "#include \"b.h\"\n", 226 "a.h")); 227 228 // Only do this in the first #include block. 229 EXPECT_EQ("#include <a>\n" 230 "\n" 231 "#include \"b.h\"\n" 232 "#include \"c.h\"\n" 233 "#include \"llvm/a.h\"\n", 234 sort("#include <a>\n" 235 "\n" 236 "#include \"llvm/a.h\"\n" 237 "#include \"c.h\"\n" 238 "#include \"b.h\"\n", 239 "a.cc")); 240 241 // Only recognize the first #include with a matching basename as main include. 242 EXPECT_EQ("#include \"a.h\"\n" 243 "#include \"b.h\"\n" 244 "#include \"c.h\"\n" 245 "#include \"llvm/a.h\"\n", 246 sort("#include \"b.h\"\n" 247 "#include \"a.h\"\n" 248 "#include \"c.h\"\n" 249 "#include \"llvm/a.h\"\n", 250 "a.cc")); 251 } 252 253 TEST_F(SortIncludesTest, NegativePriorities) { 254 Style.IncludeCategories = {{".*important_os_header.*", -1}, {".*", 1}}; 255 EXPECT_EQ("#include \"important_os_header.h\"\n" 256 "#include \"c_main.h\"\n" 257 "#include \"a_other.h\"\n", 258 sort("#include \"c_main.h\"\n" 259 "#include \"a_other.h\"\n" 260 "#include \"important_os_header.h\"\n", 261 "c_main.cc")); 262 263 // check stable when re-run 264 EXPECT_EQ("#include \"important_os_header.h\"\n" 265 "#include \"c_main.h\"\n" 266 "#include \"a_other.h\"\n", 267 sort("#include \"important_os_header.h\"\n" 268 "#include \"c_main.h\"\n" 269 "#include \"a_other.h\"\n", 270 "c_main.cc")); 271 } 272 273 TEST_F(SortIncludesTest, CalculatesCorrectCursorPosition) { 274 std::string Code = "#include <ccc>\n" // Start of line: 0 275 "#include <bbbbbb>\n" // Start of line: 15 276 "#include <a>\n"; // Start of line: 33 277 EXPECT_EQ(31u, newCursor(Code, 0)); 278 EXPECT_EQ(13u, newCursor(Code, 15)); 279 EXPECT_EQ(0u, newCursor(Code, 33)); 280 281 EXPECT_EQ(41u, newCursor(Code, 10)); 282 EXPECT_EQ(23u, newCursor(Code, 25)); 283 EXPECT_EQ(10u, newCursor(Code, 43)); 284 } 285 286 } // end namespace 287 } // end namespace format 288 } // end namespace clang 289