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:
GetCodeRange(StringRef Code)12 std::vector<tooling::Range> GetCodeRange(StringRef Code) {
13 return std::vector<tooling::Range>(1, tooling::Range(0, Code.size()));
14 }
15
sort(StringRef Code,std::vector<tooling::Range> Ranges)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
sort(StringRef Code)27 std::string sort(StringRef Code) { return sort(Code, GetCodeRange(Code)); }
28
29 FormatStyle FmtStyle;
30
31 public:
SortImportsTestJava()32 SortImportsTestJava() {
33 FmtStyle = getGoogleStyle(FormatStyle::LK_Java);
34 FmtStyle.JavaImportGroups = {"com.test", "org", "com"};
35 FmtStyle.SortIncludes = true;
36 }
37 };
38
TEST_F(SortImportsTestJava,StaticSplitFromNormal)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
TEST_F(SortImportsTestJava,CapitalBeforeLowercase)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
TEST_F(SortImportsTestJava,KeepSplitGroupsWithOneNewImport)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
TEST_F(SortImportsTestJava,SplitGroupsWithNewline)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
TEST_F(SortImportsTestJava,UnspecifiedGroupAfterAllGroups)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
TEST_F(SortImportsTestJava,NoSortOutsideRange)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
TEST_F(SortImportsTestJava,SortWhenRangeContainsOneLine)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
TEST_F(SortImportsTestJava,SortLexicographically)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
TEST_F(SortImportsTestJava,StaticInCommentHasNoEffect)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
TEST_F(SortImportsTestJava,CommentsWithAffectedImports)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
TEST_F(SortImportsTestJava,CommentWithUnaffectedImports)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
TEST_F(SortImportsTestJava,CommentAfterAffectedImports)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
TEST_F(SortImportsTestJava,CommentBeforeAffectedImports)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
TEST_F(SortImportsTestJava,FormatTotallyOff)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
TEST_F(SortImportsTestJava,FormatTotallyOn)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
TEST_F(SortImportsTestJava,FormatPariallyOnShouldNotReorder)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
TEST_F(SortImportsTestJava,SortJavaStaticImport)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;\n",
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;\n"));
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;\n",
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;\n"));
293 }
294
TEST_F(SortImportsTestJava,SortJavaStaticImportAsGroup)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;\n",
303 sort("import com.test.a;\n"
304 "import static org.a;\n"
305 "import com.test.b;\n"
306 "import static org.b;\n"));
307 }
308
TEST_F(SortImportsTestJava,DeduplicateImports)309 TEST_F(SortImportsTestJava, DeduplicateImports) {
310 EXPECT_EQ("import org.a;\n", sort("import org.a;\n"
311 "import org.a;\n"));
312 }
313
TEST_F(SortImportsTestJava,NoNewlineAtEnd)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
TEST_F(SortImportsTestJava,ImportNamedFunction)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 "}\n",
328 sort("import X;\n"
329 "class C {\n"
330 " void m() {\n"
331 " importFile();\n"
332 " }\n"
333 "}\n"));
334 }
335
TEST_F(SortImportsTestJava,NoReplacementsForValidImports)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
TEST_F(SortImportsTestJava,NoReplacementsForValidImportsWindows)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