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