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 = true; 36 } 37 }; 38 39 TEST_F(SortImportsTestJava, StaticSplitFromNormal) { 40 EXPECT_EQ("import static org.b;\n" 41 "\n" 42 "import org.a;\n", 43 sort("import org.a;\n" 44 "import static org.b;\n")); 45 } 46 47 TEST_F(SortImportsTestJava, CapitalBeforeLowercase) { 48 EXPECT_EQ("import org.Test;\n" 49 "import org.a.Test;\n" 50 "import org.b;\n", 51 sort("import org.a.Test;\n" 52 "import org.Test;\n" 53 "import org.b;\n")); 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;\n", 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;\n")); 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;\n", 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;\n")); 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;\n", 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;\n")); 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\n", 126 sort("import org.b;\n" 127 "import org.a;\n" 128 "// comments\n" 129 "// that do\n" 130 "// nothing\n", 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\n", 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\n", 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;\n", 157 sort("import org.aa;\n" 158 "import org.a.a;\n" 159 "import org.a.*;\n" 160 "import org.aA;\n")); 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\n", 167 sort("import org.a; // static\n" 168 "import org.c; // static\n" 169 "import org.b;\n")); 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;\n", 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;\n")); 187 } 188 189 TEST_F(SortImportsTestJava, CommentWithUnaffectedImports) { 190 EXPECT_EQ("import org.a;\n" 191 "// comment\n" 192 "import org.b;\n", 193 sort("import org.a;\n" 194 "// comment\n" 195 "import org.b;\n")); 196 } 197 198 TEST_F(SortImportsTestJava, CommentAfterAffectedImports) { 199 EXPECT_EQ("import org.a;\n" 200 "import org.b;\n" 201 "// comment\n", 202 sort("import org.b;\n" 203 "import org.a;\n" 204 "// comment\n")); 205 } 206 207 TEST_F(SortImportsTestJava, CommentBeforeAffectedImports) { 208 EXPECT_EQ("// comment\n" 209 "import org.a;\n" 210 "import org.b;\n", 211 sort("// comment\n" 212 "import org.b;\n" 213 "import org.a;\n")); 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\n", 221 sort("// clang-format off\n" 222 "import org.b;\n" 223 "import org.a;\n" 224 "// clang-format on\n")); 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;\n", 232 sort("// clang-format off\n" 233 "// clang-format on\n" 234 "import org.b;\n" 235 "import org.a;\n")); 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;\n", 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;\n")); 251 } 252 253 TEST_F(SortImportsTestJava, DeduplicateImports) { 254 EXPECT_EQ("import org.a;\n", sort("import org.a;\n" 255 "import org.a;\n")); 256 } 257 258 TEST_F(SortImportsTestJava, NoNewlineAtEnd) { 259 EXPECT_EQ("import org.a;\n" 260 "import org.b;", 261 sort("import org.b;\n" 262 "import org.a;")); 263 } 264 265 TEST_F(SortImportsTestJava, NoReplacementsForValidImports) { 266 // Identical #includes have led to a failure with an unstable sort. 267 std::string Code = "import org.a;\n" 268 "import org.b;\n"; 269 EXPECT_TRUE( 270 sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty()); 271 } 272 273 } // end namespace 274 } // end namespace format 275 } // end namespace clang 276