1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package com.puppycrawl.tools.checkstyle.checks.imports;
21
22 import static com.puppycrawl.tools.checkstyle.checks.imports.ImportControlCheck.MSG_DISALLOWED;
23 import static com.puppycrawl.tools.checkstyle.checks.imports.ImportControlCheck.MSG_MISSING_FILE;
24 import static com.puppycrawl.tools.checkstyle.checks.imports.ImportControlCheck.MSG_UNKNOWN_PKG;
25 import static org.junit.Assert.assertArrayEquals;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.io.File;
30 import java.nio.charset.StandardCharsets;
31 import java.nio.file.Files;
32
33 import org.junit.Rule;
34 import org.junit.Test;
35 import org.junit.rules.TemporaryFolder;
36
37 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
38 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
39 import com.puppycrawl.tools.checkstyle.TreeWalker;
40 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
41 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
42 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
43
44 public class ImportControlCheckTest extends AbstractModuleTestSupport {
45
46 @Rule
47 public final TemporaryFolder temporaryFolder = new TemporaryFolder();
48
49 @Override
50 protected String getPackageLocation() {
51 return "com/puppycrawl/tools/checkstyle/checks/imports/importcontrol";
52 }
53
54 @Test
55 public void testGetRequiredTokens() {
56 final ImportControlCheck checkObj = new ImportControlCheck();
57 final int[] expected = {
58 TokenTypes.PACKAGE_DEF,
59 TokenTypes.IMPORT,
60 TokenTypes.STATIC_IMPORT,
61 };
62 assertArrayEquals("Default required tokens are invalid",
63 expected, checkObj.getRequiredTokens());
64 }
65
66 @Test
67 public void testOne() throws Exception {
68 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
69 checkConfig.addAttribute("file", getPath("InputImportControlOne.xml"));
70 final String[] expected = {"5:1: " + getCheckMessage(MSG_DISALLOWED, "java.io.File")};
71
72 verify(checkConfig, getPath("InputImportControl.java"), expected);
73 }
74
75 @Test
76 public void testTwo() throws Exception {
77 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
78 checkConfig.addAttribute("file", getPath("InputImportControlTwo.xml"));
79 final String[] expected = {
80 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
81 "4:1: " + getCheckMessage(MSG_DISALLOWED, "javax.swing.border.*"),
82 "6:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Button.ABORT"),
83 };
84
85 verify(checkConfig, getPath("InputImportControl.java"), expected);
86 }
87
88 @Test
89 public void testWrong() throws Exception {
90 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
91 checkConfig.addAttribute("file", getPath("InputImportControlWrong.xml"));
92 final String[] expected = {"1:1: " + getCheckMessage(MSG_UNKNOWN_PKG)};
93 verify(checkConfig, getPath("InputImportControl.java"), expected);
94 }
95
96 @Test
97 public void testMissing() throws Exception {
98 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
99 final String[] expected = {"1:1: " + getCheckMessage(MSG_MISSING_FILE)};
100 verify(checkConfig, getPath("InputImportControl.java"), expected);
101 }
102
103 @Test
104 public void testEmpty() throws Exception {
105 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
106 checkConfig.addAttribute("file", " ");
107 final String[] expected = {"1:1: " + getCheckMessage(MSG_MISSING_FILE)};
108 verify(checkConfig, getPath("InputImportControl.java"), expected);
109 }
110
111 @Test
112 public void testNull() throws Exception {
113 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
114 checkConfig.addAttribute("file", null);
115 final String[] expected = {"1:1: " + getCheckMessage(MSG_MISSING_FILE)};
116 verify(checkConfig, getPath("InputImportControl.java"), expected);
117 }
118
119 @Test
120 public void testUnknown() throws Exception {
121 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
122 checkConfig.addAttribute("file", "unknown-file");
123 try {
124 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
125 verify(checkConfig, getPath("InputImportControl.java"), expected);
126 fail("Test should fail if exception was not thrown");
127 }
128 catch (CheckstyleException ex) {
129 final String message = getCheckstyleExceptionMessage(ex);
130 final String messageStart = "Unable to find: ";
131
132 assertTrue("Invalid message, should start with: " + messageStart,
133 message.startsWith(message));
134 }
135 }
136
137 @Test
138 public void testBroken() throws Exception {
139 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
140 checkConfig.addAttribute("file", getPath("InputImportControlBroken.xml"));
141 try {
142 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
143 verify(checkConfig, getPath("InputImportControl.java"), expected);
144 fail("Test should fail if exception was not thrown");
145 }
146 catch (CheckstyleException ex) {
147 final String message = getCheckstyleExceptionMessage(ex);
148 final String messageStart = "Unable to load ";
149
150 assertTrue("Invalid message, should start with: " + messageStart,
151 message.startsWith(message));
152 }
153 }
154
155 @Test
156 public void testOneRegExp() throws Exception {
157 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
158 checkConfig.addAttribute("file", getPath("InputImportControlOneRegExp.xml"));
159 final String[] expected = {"5:1: " + getCheckMessage(MSG_DISALLOWED, "java.io.File")};
160
161 verify(checkConfig, getPath("InputImportControl.java"), expected);
162 }
163
164 @Test
165 public void testTwoRegExp() throws Exception {
166 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
167 checkConfig.addAttribute("file", getPath("InputImportControlTwoRegExp.xml"));
168 final String[] expected = {
169 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
170 "4:1: " + getCheckMessage(MSG_DISALLOWED, "javax.swing.border.*"),
171 "6:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Button.ABORT"),
172 };
173
174 verify(checkConfig, getPath("InputImportControl.java"), expected);
175 }
176
177 @Test
178 public void testNotRegExpNoMatch() throws Exception {
179 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
180 checkConfig.addAttribute("file", getPath("InputImportControlNotRegExpNoMatch.xml"));
181
182 verify(checkConfig, getPath("InputImportControl.java"), CommonUtil.EMPTY_STRING_ARRAY);
183 }
184
185 @Test
186 public void testBlacklist() throws Exception {
187 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
188 checkConfig.addAttribute("file", getPath("InputImportControlBlacklist.xml"));
189 final String[] expected = {
190 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.util.stream.Stream"),
191 "4:1: " + getCheckMessage(MSG_DISALLOWED, "java.util.Date"),
192 "6:1: " + getCheckMessage(MSG_DISALLOWED, "java.util.stream.Collectors"),
193 "7:1: " + getCheckMessage(MSG_DISALLOWED, "java.util.stream.IntStream"),
194 };
195
196 verify(checkConfig, getPath("InputImportControl_Blacklist.java"), expected);
197 }
198
199 @Test
200 public void testStrategyOnMismatchOne() throws Exception {
201 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
202 checkConfig.addAttribute("file", getPath("InputImportControlStrategyOnMismatchOne.xml"));
203 final String[] expected = {
204 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
205 "4:1: " + getCheckMessage(MSG_DISALLOWED, "javax.swing.border.*"),
206 "6:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Button.ABORT"),
207 };
208
209 verify(checkConfig, getPath("InputImportControl.java"), expected);
210 }
211
212 @Test
213 public void testStrategyOnMismatchTwo() throws Exception {
214 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
215 checkConfig.addAttribute("file", getPath("InputImportControlStrategyOnMismatchTwo.xml"));
216 final String[] expected = {
217 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
218 "6:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Button.ABORT"),
219 };
220
221 verify(checkConfig, getPath("InputImportControl.java"), expected);
222 }
223
224 @Test
225 public void testStrategyOnMismatchThree() throws Exception {
226 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
227 checkConfig.addAttribute("file", getPath("InputImportControlStrategyOnMismatchThree.xml"));
228 final String[] expected = {
229 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
230 };
231
232 verify(checkConfig, getPath("InputImportControl.java"), expected);
233 }
234
235 @Test
236 public void testStrategyOnMismatchFour() throws Exception {
237 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
238 checkConfig.addAttribute("file", getPath("InputImportControlStrategyOnMismatchFour.xml"));
239 final String[] expected = {
240 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
241 "4:1: " + getCheckMessage(MSG_DISALLOWED, "javax.swing.border.*"),
242 };
243
244 verify(checkConfig, getPath("InputImportControl.java"), expected);
245 }
246
247 @Test
248 public void testPkgRegExpInParent() throws Exception {
249 testRegExpInPackage("InputImportControlPkgRegExpInParent.xml");
250 }
251
252 @Test
253 public void testPkgRegExpInChild() throws Exception {
254 testRegExpInPackage("InputImportControlPkgRegExpInChild.xml");
255 }
256
257 @Test
258 public void testPkgRegExpInBoth() throws Exception {
259 testRegExpInPackage("InputImportControlPkgRegExpInBoth.xml");
260 }
261
262
263 private void testRegExpInPackage(String file) throws Exception {
264 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
265 checkConfig.addAttribute("file", getPath(file));
266 final String[] expected = {"5:1: " + getCheckMessage(MSG_DISALLOWED, "java.io.File")};
267
268 verify(checkConfig, getPath("InputImportControl.java"), expected);
269 }
270
271 @Test
272 public void testGetAcceptableTokens() {
273 final ImportControlCheck testCheckObject =
274 new ImportControlCheck();
275 final int[] actual = testCheckObject.getAcceptableTokens();
276 final int[] expected = {
277 TokenTypes.PACKAGE_DEF,
278 TokenTypes.IMPORT,
279 TokenTypes.STATIC_IMPORT,
280 };
281
282 assertArrayEquals("Default acceptable tokens are invalid", expected, actual);
283 }
284
285 @Test
286 public void testResource() throws Exception {
287 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
288 checkConfig.addAttribute("file", getResourcePath("InputImportControlOne.xml"));
289 final String[] expected = {"5:1: " + getCheckMessage(MSG_DISALLOWED, "java.io.File")};
290
291 verify(checkConfig, getPath("InputImportControl.java"), expected);
292 }
293
294 @Test
295 public void testResourceUnableToLoad() throws Exception {
296 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
297 checkConfig.addAttribute("file", getResourcePath("import-control_unknown.xml"));
298
299 try {
300 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
301 verify(checkConfig, getPath("InputImportControl.java"), expected);
302 fail("Test should fail if exception was not thrown");
303 }
304 catch (CheckstyleException ex) {
305 final String message = getCheckstyleExceptionMessage(ex);
306 final String messageStart = "Unable to find: ";
307
308 assertTrue("Invalid message, should start with: " + messageStart,
309 message.startsWith(message));
310 }
311 }
312
313 @Test
314 public void testUrlInFileProperty() throws Exception {
315 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
316 checkConfig.addAttribute("file", getUriString("InputImportControlOne.xml"));
317 final String[] expected = {"5:1: " + getCheckMessage(MSG_DISALLOWED, "java.io.File")};
318
319 verify(checkConfig, getPath("InputImportControl.java"), expected);
320 }
321
322 @Test
323 public void testUrlInFilePropertyUnableToLoad() throws Exception {
324 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
325 checkConfig.addAttribute("file", "https://UnableToLoadThisURL");
326
327 try {
328 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
329 verify(checkConfig, getPath("InputImportControl.java"), expected);
330 fail("Test should fail if exception was not thrown");
331 }
332 catch (CheckstyleException ex) {
333 final String message = getCheckstyleExceptionMessage(ex);
334 final String messageStart = "Unable to load ";
335
336 assertTrue("Invalid message, should start with: " + messageStart,
337 message.startsWith(message));
338 }
339 }
340
341 @Test
342 public void testCacheWhenFileExternalResourceContentDoesNotChange() throws Exception {
343 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
344 checkConfig.addAttribute("file", getPath("InputImportControlOneRegExp.xml"));
345
346 final DefaultConfiguration treeWalkerConfig = createModuleConfig(TreeWalker.class);
347 treeWalkerConfig.addChild(checkConfig);
348
349 final DefaultConfiguration checkerConfig = createRootConfig(treeWalkerConfig);
350 final File cacheFile = temporaryFolder.newFile();
351 checkerConfig.addAttribute("cacheFile", cacheFile.getPath());
352
353 final String filePath = temporaryFolder.newFile("EmptyFile.java").getPath();
354 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
355
356 verify(checkerConfig, filePath, expected);
357
358 verify(checkerConfig, filePath, expected);
359
360 assertTrue("External resource is not present in cache",
361 new String(Files.readAllBytes(cacheFile.toPath()),
362 StandardCharsets.UTF_8).contains("InputImportControlOneRegExp.xml"));
363 }
364
365 @Test
366 public void testPathRegexMatches() throws Exception {
367 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
368 checkConfig.addAttribute("file", getResourcePath("InputImportControlOne.xml"));
369 checkConfig.addAttribute("path", "^.*[\\\\/]src[\\\\/]test[\\\\/].*$");
370 final String[] expected = {"5:1: " + getCheckMessage(MSG_DISALLOWED, "java.io.File")};
371
372 verify(checkConfig, getPath("InputImportControl.java"), expected);
373 }
374
375 @Test
376 public void testPathRegexMatchesPartially() throws Exception {
377 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
378 checkConfig.addAttribute("file", getResourcePath("InputImportControlOne.xml"));
379 checkConfig.addAttribute("path", "[\\\\/]InputImportControl\\.java");
380 final String[] expected = {"5:1: " + getCheckMessage(MSG_DISALLOWED, "java.io.File")};
381
382 verify(checkConfig, getPath("InputImportControl.java"), expected);
383 }
384
385 @Test
386 public void testPathRegexDoesntMatch() throws Exception {
387 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
388 checkConfig.addAttribute("file", getResourcePath("InputImportControlOne.xml"));
389 checkConfig.addAttribute("path", "^.*[\\\\/]src[\\\\/]main[\\\\/].*$");
390 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
391
392 verify(checkConfig, getPath("InputImportControl.java"), expected);
393 }
394
395 @Test
396 public void testPathRegexDoesntMatchPartially() throws Exception {
397 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
398 checkConfig.addAttribute("file", getResourcePath("InputImportControlOne.xml"));
399 checkConfig.addAttribute("path", "[\\\\/]NoMatch\\.java");
400 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
401
402 verify(checkConfig, getPath("InputImportControl.java"), expected);
403 }
404
405 @Test
406 public void testDisallowClassOfAllowPackage() throws Exception {
407 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
408 checkConfig.addAttribute("file",
409 getPath("InputImportControlDisallowClassOfAllowPackage.xml"));
410 final String[] expected = {
411 "4:1: " + getCheckMessage(MSG_DISALLOWED, "java.util.Date"),
412 };
413
414 verify(checkConfig, getPath("InputImportControlDisallowClassOfAllowPackage.java"),
415 expected);
416 }
417
418 @Test
419 public void testFileName() throws Exception {
420 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
421 checkConfig.addAttribute("file", getResourcePath("InputImportControlFileName.xml"));
422 final String[] expected = {
423 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
424 };
425
426 verify(checkConfig, getPath("InputImportControlFileName.java"), expected);
427 }
428
429 @Test
430 public void testFileNameNoExtension() throws Exception {
431 final DefaultConfiguration checkConfig = createModuleConfig(ImportControlCheck.class);
432 checkConfig.addAttribute("file",
433 getResourcePath("InputImportControlFileNameNoExtension.xml"));
434 final DefaultConfiguration treewalkerConfig = createModuleConfig(TreeWalker.class);
435 treewalkerConfig.addAttribute("fileExtensions", "");
436 treewalkerConfig.addChild(checkConfig);
437 final String[] expected = {
438 "3:1: " + getCheckMessage(MSG_DISALLOWED, "java.awt.Image"),
439 };
440
441 verify(treewalkerConfig, getPath("InputImportControlFileNameNoExtension"), expected);
442 }
443
444
445
446
447
448
449
450
451
452
453 private static String getCheckstyleExceptionMessage(CheckstyleException exception) {
454 return exception.getCause().getCause().getCause().getCause().getMessage();
455 }
456
457 }