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 | |