1 #include "clang/Format/Format.h" 2 #include "gtest/gtest.h" 3 4 #define DEBUG_TYPE "format-test" 5 6 namespace clang { 7 namespace format { 8 namespace { 9 10 class SortImportsTestJava : public ::testing::Test { 11 protected: 12 std::vector<tooling::Range> GetCodeRange(StringRef Code) { 13 return std::vector<tooling::Range>(1, tooling::Range(0, Code.size())); 14 } 15 16 std::string sort(StringRef Code, std::vector<tooling::Range> Ranges) { 17 auto Replaces = sortIncludes(FmtStyle, Code, Ranges, "input.java"); 18 Ranges = tooling::calculateRangesAfterReplacements(Replaces, Ranges); 19 auto Sorted = applyAllReplacements(Code, Replaces); 20 EXPECT_TRUE(static_cast<bool>(Sorted)); 21 auto Result = applyAllReplacements( 22 *Sorted, reformat(FmtStyle, *Sorted, Ranges, "input.java")); 23 EXPECT_TRUE(static_cast<bool>(Result)); 24 return *Result; 25 } 26 27 std::string sort(StringRef Code) { return sort(Code, GetCodeRange(Code)); } 28 29 FormatStyle FmtStyle; 30 31 public: 32 SortImportsTestJava() { 33 FmtStyle = getGoogleStyle(FormatStyle::LK_Java); 34 FmtStyle.JavaImportGroups = {"com.test", "org", "com"}; 35 FmtStyle.SortIncludes = FormatStyle::SI_CaseInsensitive; 36 } 37 }; 38 39 TEST_F(SortImportsTestJava, StaticSplitFromNormal) { 40 EXPECT_EQ("import static org.b;\n" 41 "\n" 42 "import org.a;", 43 sort("import org.a;\n" 44 "import static org.b;")); 45 } 46 47 TEST_F(SortImportsTestJava, CapitalBeforeLowercase) { 48 EXPECT_EQ("import org.Test;\n" 49 "import org.a.Test;\n" 50 "import org.b;", 51 sort("import org.a.Test;\n" 52 "import org.Test;\n" 53 "import org.b;")); 54 } 55 56 TEST_F(SortImportsTestJava, KeepSplitGroupsWithOneNewImport) { 57 EXPECT_EQ("import static com.test.a;\n" 58 "\n" 59 "import static org.a;\n" 60 "\n" 61 "import static com.a;\n" 62 "\n" 63 "import com.test.b;\n" 64 "import com.test.c;\n" 65 "\n" 66 "import org.b;\n" 67 "\n" 68 "import com.b;", 69 sort("import static com.test.a;\n" 70 "\n" 71 "import static org.a;\n" 72 "\n" 73 "import static com.a;\n" 74 "\n" 75 "import com.test.b;\n" 76 "\n" 77 "import org.b;\n" 78 "\n" 79 "import com.b;\n" 80 "import com.test.c;")); 81 } 82 83 TEST_F(SortImportsTestJava, SplitGroupsWithNewline) { 84 EXPECT_EQ("import static com.test.a;\n" 85 "\n" 86 "import static org.a;\n" 87 "\n" 88 "import static com.a;\n" 89 "\n" 90 "import com.test.b;\n" 91 "\n" 92 "import org.b;\n" 93 "\n" 94 "import com.b;", 95 sort("import static com.test.a;\n" 96 "import static org.a;\n" 97 "import static com.a;\n" 98 "import com.test.b;\n" 99 "import org.b;\n" 100 "import com.b;")); 101 } 102 103 TEST_F(SortImportsTestJava, UnspecifiedGroupAfterAllGroups) { 104 EXPECT_EQ("import com.test.a;\n" 105 "\n" 106 "import org.a;\n" 107 "\n" 108 "import com.a;\n" 109 "\n" 110 "import abc.a;\n" 111 "import xyz.b;", 112 sort("import com.test.a;\n" 113 "import com.a;\n" 114 "import xyz.b;\n" 115 "import abc.a;\n" 116 "import org.a;")); 117 } 118 119 TEST_F(SortImportsTestJava, NoSortOutsideRange) { 120 std::vector<tooling::Range> Ranges = {tooling::Range(27, 15)}; 121 EXPECT_EQ("import org.b;\n" 122 "import org.a;\n" 123 "// comments\n" 124 "// that do\n" 125 "// nothing", 126 sort("import org.b;\n" 127 "import org.a;\n" 128 "// comments\n" 129 "// that do\n" 130 "// nothing", 131 Ranges)); 132 } 133 134 TEST_F(SortImportsTestJava, SortWhenRangeContainsOneLine) { 135 std::vector<tooling::Range> Ranges = {tooling::Range(27, 20)}; 136 EXPECT_EQ("import org.a;\n" 137 "import org.b;\n" 138 "\n" 139 "import com.a;\n" 140 "// comments\n" 141 "// that do\n" 142 "// nothing", 143 sort("import org.b;\n" 144 "import org.a;\n" 145 "import com.a;\n" 146 "// comments\n" 147 "// that do\n" 148 "// nothing", 149 Ranges)); 150 } 151 152 TEST_F(SortImportsTestJava, SortLexicographically) { 153 EXPECT_EQ("import org.a.*;\n" 154 "import org.a.a;\n" 155 "import org.aA;\n" 156 "import org.aa;", 157 sort("import org.aa;\n" 158 "import org.a.a;\n" 159 "import org.a.*;\n" 160 "import org.aA;")); 161 } 162 163 TEST_F(SortImportsTestJava, StaticInCommentHasNoEffect) { 164 EXPECT_EQ("import org.a; // static\n" 165 "import org.b;\n" 166 "import org.c; // static", 167 sort("import org.a; // static\n" 168 "import org.c; // static\n" 169 "import org.b;")); 170 } 171 172 TEST_F(SortImportsTestJava, CommentsWithAffectedImports) { 173 EXPECT_EQ("import org.a;\n" 174 "// commentB\n" 175 "/* commentB\n" 176 " commentB*/\n" 177 "import org.b;\n" 178 "// commentC\n" 179 "import org.c;", 180 sort("import org.a;\n" 181 "// commentC\n" 182 "import org.c;\n" 183 "// commentB\n" 184 "/* commentB\n" 185 " commentB*/\n" 186 "import org.b;")); 187 } 188 189 TEST_F(SortImportsTestJava, CommentWithUnaffectedImports) { 190 EXPECT_EQ("import org.a;\n" 191 "// comment\n" 192 "import org.b;", 193 sort("import org.a;\n" 194 "// comment\n" 195 "import org.b;")); 196 } 197 198 TEST_F(SortImportsTestJava, CommentAfterAffectedImports) { 199 EXPECT_EQ("import org.a;\n" 200 "import org.b;\n" 201 "// comment", 202 sort("import org.b;\n" 203 "import org.a;\n" 204 "// comment")); 205 } 206 207 TEST_F(SortImportsTestJava, CommentBeforeAffectedImports) { 208 EXPECT_EQ("// comment\n" 209 "import org.a;\n" 210 "import org.b;", 211 sort("// comment\n" 212 "import org.b;\n" 213 "import org.a;")); 214 } 215 216 TEST_F(SortImportsTestJava, FormatTotallyOff) { 217 EXPECT_EQ("// clang-format off\n" 218 "import org.b;\n" 219 "import org.a;\n" 220 "// clang-format on", 221 sort("// clang-format off\n" 222 "import org.b;\n" 223 "import org.a;\n" 224 "// clang-format on")); 225 } 226 227 TEST_F(SortImportsTestJava, FormatTotallyOn) { 228 EXPECT_EQ("// clang-format off\n" 229 "// clang-format on\n" 230 "import org.a;\n" 231 "import org.b;", 232 sort("// clang-format off\n" 233 "// clang-format on\n" 234 "import org.b;\n" 235 "import org.a;")); 236 } 237 238 TEST_F(SortImportsTestJava, FormatPariallyOnShouldNotReorder) { 239 EXPECT_EQ("// clang-format off\n" 240 "import org.b;\n" 241 "import org.a;\n" 242 "// clang-format on\n" 243 "import org.d;\n" 244 "import org.c;", 245 sort("// clang-format off\n" 246 "import org.b;\n" 247 "import org.a;\n" 248 "// clang-format on\n" 249 "import org.d;\n" 250 "import org.c;")); 251 } 252 253 TEST_F(SortImportsTestJava, SortJavaStaticImport) { 254 FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_Before; 255 EXPECT_EQ("import static com.test.a;\n" 256 "\n" 257 "import static org.a;\n" 258 "\n" 259 "import static com.a;\n" 260 "\n" 261 "import com.test.b;\n" 262 "\n" 263 "import org.b;\n" 264 "\n" 265 "import com.b;", 266 sort("import static com.test.a;\n" 267 "import static org.a;\n" 268 "import static com.a;\n" 269 "import com.test.b;\n" 270 "import org.b;\n" 271 "import com.b;")); 272 273 FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_After; 274 EXPECT_EQ("import com.test.b;\n" 275 "import com.test.c;\n" 276 "\n" 277 "import org.b;\n" 278 "\n" 279 "import com.b;\n" 280 "\n" 281 "import static com.test.a;\n" 282 "\n" 283 "import static org.a;\n" 284 "\n" 285 "import static com.a;", 286 sort("import static com.test.a;\n" 287 "import static org.a;\n" 288 "import static com.a;\n" 289 "import com.test.b;\n" 290 "import org.b;\n" 291 "import com.b;\n" 292 "import com.test.c;")); 293 } 294 295 TEST_F(SortImportsTestJava, SortJavaStaticImportAsGroup) { 296 FmtStyle.SortJavaStaticImport = FormatStyle::SJSIO_After; 297 298 EXPECT_EQ("import com.test.a;\n" 299 "import com.test.b;\n" 300 "\n" 301 "import static org.a;\n" 302 "import static org.b;", 303 sort("import com.test.a;\n" 304 "import static org.a;\n" 305 "import com.test.b;\n" 306 "import static org.b;")); 307 } 308 309 TEST_F(SortImportsTestJava, DeduplicateImports) { 310 EXPECT_EQ("import org.a;", sort("import org.a;\n" 311 "import org.a;")); 312 } 313 314 TEST_F(SortImportsTestJava, NoNewlineAtEnd) { 315 EXPECT_EQ("import org.a;\n" 316 "import org.b;", 317 sort("import org.b;\n" 318 "import org.a;")); 319 } 320 321 TEST_F(SortImportsTestJava, ImportNamedFunction) { 322 EXPECT_EQ("import X;\n" 323 "class C {\n" 324 " void m() {\n" 325 " importFile();\n" 326 " }\n" 327 "}", 328 sort("import X;\n" 329 "class C {\n" 330 " void m() {\n" 331 " importFile();\n" 332 " }\n" 333 "}")); 334 } 335 336 TEST_F(SortImportsTestJava, NoReplacementsForValidImports) { 337 // Identical #includes have led to a failure with an unstable sort. 338 std::string Code = "import org.a;\n" 339 "import org.b;\n"; 340 EXPECT_TRUE( 341 sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty()); 342 } 343 344 TEST_F(SortImportsTestJava, NoReplacementsForValidImportsWindows) { 345 std::string Code = "import org.a;\r\n" 346 "import org.b;\r\n"; 347 EXPECT_TRUE( 348 sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty()); 349 } 350 351 } // end namespace 352 } // end namespace format 353 } // end namespace clang 354