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(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 | |
31 | public: |
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 | |
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 | |