1#include "clang/Format/Format.h"
2#include "gtest/gtest.h"
3
4#define DEBUG_TYPE "format-test"
5
6namespace clang {
7namespace format {
8namespace {
9
10class SortImportsTestJava : public ::testing::Test {
11protected:
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(Style: FmtStyle, Code, Ranges, FileName: "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 Code: *Sorted, Replaces: reformat(Style: FmtStyle, Code: *Sorted, Ranges, FileName: "input.java"));
23 EXPECT_TRUE(static_cast<bool>(Result));
24 return *Result;
25 }
26
27 std::string sort(StringRef Code) { return sort(Code, Ranges: GetCodeRange(Code)); }
28
29 FormatStyle FmtStyle;
30
31public:
32 SortImportsTestJava() {
33 FmtStyle = getGoogleStyle(Language: FormatStyle::LK_Java);
34 FmtStyle.JavaImportGroups = {"com.test", "org", "com"};
35 FmtStyle.SortIncludes = FormatStyle::SI_CaseInsensitive;
36 }
37};
38
39TEST_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
47TEST_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
56TEST_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
83TEST_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
103TEST_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
119TEST_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
134TEST_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
152TEST_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
163TEST_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
172TEST_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
189TEST_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
198TEST_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
207TEST_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
216TEST_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
227TEST_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
238TEST_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
253TEST_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
295TEST_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
309TEST_F(SortImportsTestJava, DeduplicateImports) {
310 EXPECT_EQ("import org.a;", sort("import org.a;\n"
311 "import org.a;"));
312}
313
314TEST_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
321TEST_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
336TEST_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
344TEST_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

source code of clang/unittests/Format/SortImportsTestJava.cpp