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,DeduplicateImports)253 TEST_F(SortImportsTestJava, DeduplicateImports) {
254   EXPECT_EQ("import org.a;\n", sort("import org.a;\n"
255                                     "import org.a;\n"));
256 }
257 
TEST_F(SortImportsTestJava,NoNewlineAtEnd)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 
TEST_F(SortImportsTestJava,ImportNamedFunction)265 TEST_F(SortImportsTestJava, ImportNamedFunction) {
266   EXPECT_EQ("import X;\n"
267             "class C {\n"
268             "  void m() {\n"
269             "    importFile();\n"
270             "  }\n"
271             "}\n",
272             sort("import X;\n"
273                  "class C {\n"
274                  "  void m() {\n"
275                  "    importFile();\n"
276                  "  }\n"
277                  "}\n"));
278 }
279 
TEST_F(SortImportsTestJava,NoReplacementsForValidImports)280 TEST_F(SortImportsTestJava, NoReplacementsForValidImports) {
281   // Identical #includes have led to a failure with an unstable sort.
282   std::string Code = "import org.a;\n"
283                      "import org.b;\n";
284   EXPECT_TRUE(
285       sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty());
286 }
287 
TEST_F(SortImportsTestJava,NoReplacementsForValidImportsWindows)288 TEST_F(SortImportsTestJava, NoReplacementsForValidImportsWindows) {
289   std::string Code = "import org.a;\r\n"
290                      "import org.b;\r\n";
291   EXPECT_TRUE(
292       sortIncludes(FmtStyle, Code, GetCodeRange(Code), "input.java").empty());
293 }
294 
295 } // end namespace
296 } // end namespace format
297 } // end namespace clang
298