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;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.Checker.EXCEPTION_MSG;
24 import static com.puppycrawl.tools.checkstyle.DefaultLogger.AUDIT_FINISHED_MESSAGE;
25 import static com.puppycrawl.tools.checkstyle.DefaultLogger.AUDIT_STARTED_MESSAGE;
26 import static com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck.MSG_KEY_NO_NEWLINE_EOF;
27 import static com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck.MSG_KEY;
28
29 import java.io.BufferedReader;
30 import java.io.BufferedWriter;
31 import java.io.ByteArrayInputStream;
32 import java.io.ByteArrayOutputStream;
33 import java.io.File;
34 import java.io.IOError;
35 import java.io.IOException;
36 import java.io.InputStream;
37 import java.io.InputStreamReader;
38 import java.io.LineNumberReader;
39 import java.io.OutputStream;
40 import java.io.Serial;
41 import java.io.UnsupportedEncodingException;
42 import java.nio.charset.StandardCharsets;
43 import java.nio.file.Files;
44 import java.util.ArrayList;
45 import java.util.Arrays;
46 import java.util.Collections;
47 import java.util.HashSet;
48 import java.util.List;
49 import java.util.Locale;
50 import java.util.Objects;
51 import java.util.Properties;
52 import java.util.Set;
53 import java.util.SortedSet;
54 import java.util.TreeSet;
55 import java.util.UUID;
56
57 import org.junit.jupiter.api.Test;
58 import org.junit.jupiter.api.io.TempDir;
59
60 import com.puppycrawl.tools.checkstyle.AbstractAutomaticBean.OutputStreamOptions;
61 import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
62 import com.puppycrawl.tools.checkstyle.api.AbstractFileSetCheck;
63 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
64 import com.puppycrawl.tools.checkstyle.api.AuditListener;
65 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
66 import com.puppycrawl.tools.checkstyle.api.Configuration;
67 import com.puppycrawl.tools.checkstyle.api.Context;
68 import com.puppycrawl.tools.checkstyle.api.DetailAST;
69 import com.puppycrawl.tools.checkstyle.api.ExternalResourceHolder;
70 import com.puppycrawl.tools.checkstyle.api.FileText;
71 import com.puppycrawl.tools.checkstyle.api.Filter;
72 import com.puppycrawl.tools.checkstyle.api.FilterSet;
73 import com.puppycrawl.tools.checkstyle.api.MessageDispatcher;
74 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
75 import com.puppycrawl.tools.checkstyle.api.Violation;
76 import com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck;
77 import com.puppycrawl.tools.checkstyle.checks.TranslationCheck;
78 import com.puppycrawl.tools.checkstyle.checks.coding.HiddenFieldCheck;
79 import com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck;
80 import com.puppycrawl.tools.checkstyle.filefilters.BeforeExecutionExclusionFileFilter;
81 import com.puppycrawl.tools.checkstyle.filters.SuppressionFilter;
82 import com.puppycrawl.tools.checkstyle.internal.testmodules.CheckWhichThrowsError;
83 import com.puppycrawl.tools.checkstyle.internal.testmodules.DebugAuditAdapter;
84 import com.puppycrawl.tools.checkstyle.internal.testmodules.DebugFilter;
85 import com.puppycrawl.tools.checkstyle.internal.testmodules.TestBeforeExecutionFileFilter;
86 import com.puppycrawl.tools.checkstyle.internal.testmodules.TestFileSetCheck;
87 import com.puppycrawl.tools.checkstyle.internal.utils.CloseAndFlushTestByteArrayOutputStream;
88 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
89 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
90 import de.thetaphi.forbiddenapis.SuppressForbidden;
91
92
93
94
95
96
97
98
99 public class CheckerTest extends AbstractModuleTestSupport {
100
101 @TempDir
102 public File temporaryFolder;
103
104 private File createTempFile(String prefix) throws IOException {
105 return createTempFile(prefix, ".tmp");
106 }
107
108 private File createTempFile(String prefix, String suffix) throws IOException {
109 final String name = Objects.requireNonNull(prefix)
110 + UUID.randomUUID()
111 + Objects.requireNonNull(suffix);
112 return Files.createFile(temporaryFolder.toPath().resolve(name)).toFile();
113 }
114
115 private static void invokeFireAuditFinished(Checker checker)
116 throws ReflectiveOperationException {
117 TestUtil.invokeMethod(checker, "fireAuditFinished");
118 }
119
120 private static void invokeFireAuditStartedMethod(Checker checker)
121 throws ReflectiveOperationException {
122 TestUtil.invokeMethod(checker, "fireAuditStarted");
123 }
124
125 @Override
126 protected String getPackageLocation() {
127 return "com/puppycrawl/tools/checkstyle/checker";
128 }
129
130 private String getLocalizedMessage(String messageKey, Object... args) {
131 final LocalizedMessage localizedMessage = new LocalizedMessage(
132 Definitions.CHECKSTYLE_BUNDLE, getClass(),
133 messageKey, args);
134
135 return localizedMessage.getMessage();
136 }
137
138 @Test
139 public void testDestroy() throws Exception {
140 final Checker checker = new Checker();
141 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
142 checker.addListener(auditAdapter);
143 final TestFileSetCheck fileSet = new TestFileSetCheck();
144 checker.addFileSetCheck(fileSet);
145 final DebugFilter filter = new DebugFilter();
146 checker.addFilter(filter);
147 final TestBeforeExecutionFileFilter fileFilter = new TestBeforeExecutionFileFilter();
148 checker.addBeforeExecutionFileFilter(fileFilter);
149
150
151 checker.destroy();
152
153 final File tempFile = createTempFile("junit");
154 checker.process(Collections.singletonList(tempFile));
155 final SortedSet<Violation> violations = new TreeSet<>();
156 violations.add(new Violation(1, 0, "a Bundle", "message.key",
157 new Object[] {"arg"}, null, getClass(), null));
158 checker.fireErrors("Some File Name", violations);
159
160 assertWithMessage("Checker.destroy() doesn't remove listeners.")
161 .that(auditAdapter.wasCalled())
162 .isFalse();
163 assertWithMessage("Checker.destroy() doesn't remove file sets.")
164 .that(fileSet.wasCalled())
165 .isFalse();
166 assertWithMessage("Checker.destroy() doesn't remove filters.")
167 .that(filter.wasCalled())
168 .isFalse();
169 assertWithMessage("Checker.destroy() doesn't remove file filters.")
170 .that(fileFilter.wasCalled())
171 .isFalse();
172 }
173
174 @Test
175 public void testAddListener() throws Exception {
176 final Checker checker = new Checker();
177 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
178 checker.addListener(auditAdapter);
179
180
181 invokeFireAuditStartedMethod(checker);
182 assertWithMessage("Checker.fireAuditStarted() doesn't call listener")
183 .that(auditAdapter.wasCalled())
184 .isTrue();
185 assertWithMessage("Checker.fireAuditStarted() doesn't pass event")
186 .that(auditAdapter.wasEventPassed())
187 .isTrue();
188
189 auditAdapter.resetListener();
190 invokeFireAuditFinished(checker);
191 assertWithMessage("Checker.fireAuditFinished() doesn't call listener")
192 .that(auditAdapter.wasCalled())
193 .isTrue();
194 assertWithMessage("Checker.fireAuditFinished() doesn't pass event")
195 .that(auditAdapter.wasEventPassed())
196 .isTrue();
197
198 auditAdapter.resetListener();
199 checker.fireFileStarted("Some File Name");
200 assertWithMessage("Checker.fireFileStarted() doesn't call listener")
201 .that(auditAdapter.wasCalled())
202 .isTrue();
203 assertWithMessage("Checker.fireFileStarted() doesn't pass event")
204 .that(auditAdapter.wasEventPassed())
205 .isTrue();
206
207 auditAdapter.resetListener();
208 checker.fireFileFinished("Some File Name");
209 assertWithMessage("Checker.fireFileFinished() doesn't call listener")
210 .that(auditAdapter.wasCalled())
211 .isTrue();
212 assertWithMessage("Checker.fireFileFinished() doesn't pass event")
213 .that(auditAdapter.wasEventPassed())
214 .isTrue();
215
216 auditAdapter.resetListener();
217 final SortedSet<Violation> violations = new TreeSet<>();
218 violations.add(new Violation(1, 0, "a Bundle", "message.key",
219 new Object[] {"arg"}, null, getClass(), null));
220 checker.fireErrors("Some File Name", violations);
221 assertWithMessage("Checker.fireErrors() doesn't call listener")
222 .that(auditAdapter.wasCalled())
223 .isTrue();
224 assertWithMessage("Checker.fireErrors() doesn't pass event")
225 .that(auditAdapter.wasEventPassed())
226 .isTrue();
227 }
228
229 @Test
230 public void testRemoveListener() throws Exception {
231 final Checker checker = new Checker();
232 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
233 final DebugAuditAdapter aa2 = new DebugAuditAdapter();
234 checker.addListener(auditAdapter);
235 checker.addListener(aa2);
236 checker.removeListener(auditAdapter);
237
238
239 invokeFireAuditStartedMethod(checker);
240 assertWithMessage("Checker.fireAuditStarted() doesn't call listener")
241 .that(aa2.wasCalled())
242 .isTrue();
243 assertWithMessage("Checker.fireAuditStarted() does call removed listener")
244 .that(auditAdapter.wasCalled())
245 .isFalse();
246
247 aa2.resetListener();
248 invokeFireAuditFinished(checker);
249 assertWithMessage("Checker.fireAuditFinished() doesn't call listener")
250 .that(aa2.wasCalled())
251 .isTrue();
252 assertWithMessage("Checker.fireAuditFinished() does call removed listener")
253 .that(auditAdapter.wasCalled())
254 .isFalse();
255
256 aa2.resetListener();
257 checker.fireFileStarted("Some File Name");
258 assertWithMessage("Checker.fireFileStarted() doesn't call listener")
259 .that(aa2.wasCalled())
260 .isTrue();
261 assertWithMessage("Checker.fireFileStarted() does call removed listener")
262 .that(auditAdapter.wasCalled())
263 .isFalse();
264
265 aa2.resetListener();
266 checker.fireFileFinished("Some File Name");
267 assertWithMessage("Checker.fireFileFinished() doesn't call listener")
268 .that(aa2.wasCalled())
269 .isTrue();
270 assertWithMessage("Checker.fireFileFinished() does call removed listener")
271 .that(auditAdapter.wasCalled())
272 .isFalse();
273
274 aa2.resetListener();
275 final SortedSet<Violation> violations = new TreeSet<>();
276 violations.add(new Violation(1, 0, "a Bundle", "message.key",
277 new Object[] {"arg"}, null, getClass(), null));
278 checker.fireErrors("Some File Name", violations);
279 assertWithMessage("Checker.fireErrors() doesn't call listener")
280 .that(aa2.wasCalled())
281 .isTrue();
282 assertWithMessage("Checker.fireErrors() does call removed listener")
283 .that(auditAdapter.wasCalled())
284 .isFalse();
285 }
286
287 @Test
288 public void testAddBeforeExecutionFileFilter() throws Exception {
289 final Checker checker = new Checker();
290 final TestBeforeExecutionFileFilter filter = new TestBeforeExecutionFileFilter();
291
292 checker.addBeforeExecutionFileFilter(filter);
293
294 filter.resetFilter();
295 checker.process(Collections.singletonList(new File("dummy.java")));
296 assertWithMessage("Checker.acceptFileStarted() doesn't call filter")
297 .that(filter.wasCalled())
298 .isTrue();
299 }
300
301 @Test
302 public void testRemoveBeforeExecutionFileFilter() throws Exception {
303 final Checker checker = new Checker();
304 final TestBeforeExecutionFileFilter filter = new TestBeforeExecutionFileFilter();
305 final TestBeforeExecutionFileFilter f2 = new TestBeforeExecutionFileFilter();
306 checker.addBeforeExecutionFileFilter(filter);
307 checker.addBeforeExecutionFileFilter(f2);
308 checker.removeBeforeExecutionFileFilter(filter);
309
310 f2.resetFilter();
311 checker.process(Collections.singletonList(new File("dummy.java")));
312 assertWithMessage("Checker.acceptFileStarted() doesn't call filter")
313 .that(f2.wasCalled())
314 .isTrue();
315 assertWithMessage("Checker.acceptFileStarted() does call removed filter")
316 .that(filter.wasCalled())
317 .isFalse();
318 }
319
320 @Test
321 public void testAddFilter() {
322 final Checker checker = new Checker();
323 final DebugFilter filter = new DebugFilter();
324
325 checker.addFilter(filter);
326
327 filter.resetFilter();
328 final SortedSet<Violation> violations = new TreeSet<>();
329 violations.add(new Violation(1, 0, "a Bundle", "message.key",
330 new Object[] {"arg"}, null, getClass(), null));
331 checker.fireErrors("Some File Name", violations);
332 assertWithMessage("Checker.fireErrors() doesn't call filter")
333 .that(filter.wasCalled())
334 .isTrue();
335 }
336
337 @Test
338 public void testRemoveFilter() {
339 final Checker checker = new Checker();
340 final DebugFilter filter = new DebugFilter();
341 final DebugFilter f2 = new DebugFilter();
342 checker.addFilter(filter);
343 checker.addFilter(f2);
344 checker.removeFilter(filter);
345
346 f2.resetFilter();
347 final SortedSet<Violation> violations = new TreeSet<>();
348 violations.add(new Violation(1, 0, "a Bundle", "message.key",
349 new Object[] {"arg"}, null, getClass(), null));
350 checker.fireErrors("Some File Name", violations);
351 assertWithMessage("Checker.fireErrors() doesn't call filter")
352 .that(f2.wasCalled())
353 .isTrue();
354 assertWithMessage("Checker.fireErrors() does call removed filter")
355 .that(filter.wasCalled())
356 .isFalse();
357 }
358
359 @Test
360 public void testFileExtensions() throws Exception {
361 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
362 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
363 checkerConfig.addProperty("cacheFile", createTempFile("junit").getPath());
364
365 final Checker checker = new Checker();
366 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
367 checker.configure(checkerConfig);
368
369 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
370 checker.addListener(auditAdapter);
371
372 final List<File> files = new ArrayList<>();
373 final File file = new File("file.pdf");
374 files.add(file);
375 final File otherFile = new File("file.java");
376 files.add(otherFile);
377 final String[] fileExtensions = {"java", "xml", "properties"};
378 checker.setFileExtensions(fileExtensions);
379 checker.setCacheFile(createTempFile("junit").getPath());
380 final int counter = checker.process(files);
381
382
383 final int numLegalFiles = 1;
384 final PropertyCacheFile cache = TestUtil.getInternalState(checker,
385 "cacheFile", PropertyCacheFile.class);
386 assertWithMessage("There were more legal files than expected")
387 .that(counter)
388 .isEqualTo(numLegalFiles);
389 assertWithMessage("Audit was started on larger amount of files than expected")
390 .that(auditAdapter.getNumFilesStarted())
391 .isEqualTo(numLegalFiles);
392 assertWithMessage("Audit was finished on larger amount of files than expected")
393 .that(auditAdapter.getNumFilesFinished())
394 .isEqualTo(numLegalFiles);
395 assertWithMessage("Cache shout not contain any file")
396 .that(cache.get(new File("file.java").getCanonicalPath()))
397 .isNull();
398 }
399
400 @Test
401 public void testIgnoredFileExtensions() throws Exception {
402 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
403 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
404 final File tempFile = createTempFile("junit");
405 checkerConfig.addProperty("cacheFile", tempFile.getPath());
406
407 final Checker checker = new Checker();
408 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
409 checker.configure(checkerConfig);
410
411 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
412 checker.addListener(auditAdapter);
413
414 final List<File> allIgnoredFiles = new ArrayList<>();
415 final File ignoredFile = new File("file.pdf");
416 allIgnoredFiles.add(ignoredFile);
417 final String[] fileExtensions = {"java", "xml", "properties"};
418 checker.setFileExtensions(fileExtensions);
419 checker.setCacheFile(createTempFile("junit").getPath());
420 final int counter = checker.process(allIgnoredFiles);
421
422
423 final int numLegalFiles = 0;
424 assertWithMessage("There were more legal files than expected")
425 .that(counter)
426 .isEqualTo(numLegalFiles);
427 assertWithMessage("Audit was started on larger amount of files than expected")
428 .that(auditAdapter.getNumFilesStarted())
429 .isEqualTo(numLegalFiles);
430 assertWithMessage("Audit was finished on larger amount of files than expected")
431 .that(auditAdapter.getNumFilesFinished())
432 .isEqualTo(numLegalFiles);
433 }
434
435 @Test
436 public void testSetters() {
437
438 final Checker checker = new Checker();
439 checker.setBasedir("some");
440 checker.setSeverity("ignore");
441
442 final PackageObjectFactory factory = new PackageObjectFactory(
443 new HashSet<>(), Thread.currentThread().getContextClassLoader());
444 checker.setModuleFactory(factory);
445
446 checker.setFileExtensions((String[]) null);
447 checker.setFileExtensions(".java", "xml");
448
449 try {
450 checker.setCharset("UNKNOWN-CHARSET");
451 assertWithMessage("Exception is expected").fail();
452 }
453 catch (UnsupportedEncodingException exc) {
454 assertWithMessage("Error message is not expected")
455 .that(exc.getMessage())
456 .isEqualTo("unsupported charset: 'UNKNOWN-CHARSET'");
457 }
458 }
459
460 @Test
461 public void testSetSeverity() throws Exception {
462 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
463
464 verifyWithInlineXmlConfig(getPath("InputCheckerTestSeverity.java"), expected);
465 }
466
467 @Test
468 public void testNoClassLoaderNoModuleFactory() {
469 final Checker checker = new Checker();
470
471 try {
472 checker.finishLocalSetup();
473 assertWithMessage("Exception is expected").fail();
474 }
475 catch (CheckstyleException exc) {
476 assertWithMessage("Error message is not expected")
477 .that(exc.getMessage())
478 .isEqualTo("if no custom moduleFactory is set,"
479 + " moduleClassLoader must be specified");
480 }
481 }
482
483 @Test
484 public void testNoModuleFactory() throws Exception {
485 final Checker checker = new Checker();
486 final ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
487
488 checker.setModuleClassLoader(classLoader);
489 checker.finishLocalSetup();
490 final Context actualCtx = TestUtil.getInternalState(checker, "childContext", Context.class);
491
492 assertWithMessage("Default module factory should be created when it is not specified")
493 .that(actualCtx.get("moduleFactory"))
494 .isNotNull();
495 }
496
497 @Test
498 public void testFinishLocalSetupFullyInitialized() throws Exception {
499 final Checker checker = new Checker();
500 final ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
501 checker.setModuleClassLoader(contextClassLoader);
502 final PackageObjectFactory factory = new PackageObjectFactory(
503 new HashSet<>(), contextClassLoader);
504 checker.setModuleFactory(factory);
505 checker.setBasedir("testBaseDir");
506 checker.setLocaleLanguage("it");
507 checker.setLocaleCountry("IT");
508 checker.finishLocalSetup();
509
510 final Context context = TestUtil.getInternalState(checker, "childContext", Context.class);
511 final String encoding = StandardCharsets.UTF_8.name();
512 assertWithMessage("Charset was different than expected")
513 .that(context.get("charset"))
514 .isEqualTo(encoding);
515 assertWithMessage("Severity is set to unexpected value")
516 .that(context.get("severity"))
517 .isEqualTo("error");
518 assertWithMessage("Basedir is set to unexpected value")
519 .that(context.get("basedir"))
520 .isEqualTo("testBaseDir");
521
522 final Locale locale =
523 TestUtil.getInternalStaticState(LocalizedMessage.class, "sLocale", Locale.class);
524 assertWithMessage("Locale is set to unexpected value")
525 .that(locale)
526 .isEqualTo(Locale.ITALY);
527 }
528
529 @Test
530 public void testSetupChildExceptions() {
531 final Checker checker = new Checker();
532 final PackageObjectFactory factory = new PackageObjectFactory(
533 new HashSet<>(), Thread.currentThread().getContextClassLoader());
534 checker.setModuleFactory(factory);
535
536 final Configuration config = new DefaultConfiguration("java.lang.String");
537 try {
538 checker.setupChild(config);
539 assertWithMessage("Exception is expected").fail();
540 }
541 catch (CheckstyleException exc) {
542 assertWithMessage("Error message is not expected")
543 .that(exc.getMessage())
544 .isEqualTo("java.lang.String is not allowed as a child in Checker");
545 }
546 }
547
548 @Test
549 public void testSetupChildInvalidProperty() throws Exception {
550 final DefaultConfiguration checkConfig = createModuleConfig(HiddenFieldCheck.class);
551 checkConfig.addProperty("$$No such property", null);
552 try {
553 createChecker(checkConfig);
554 assertWithMessage("Exception is expected").fail();
555 }
556 catch (CheckstyleException exc) {
557 assertWithMessage("Error message is not expected")
558 .that(exc.getMessage())
559 .isEqualTo("cannot initialize module com.puppycrawl.tools.checkstyle.TreeWalker"
560 + " - cannot initialize module " + checkConfig.getName()
561 + " - Property '$$No such property'"
562 + " does not exist, please check the documentation");
563 }
564 }
565
566 @Test
567 public void testSetupChildListener() throws Exception {
568 final Checker checker = new Checker();
569 final PackageObjectFactory factory = new PackageObjectFactory(
570 new HashSet<>(), Thread.currentThread().getContextClassLoader());
571 checker.setModuleFactory(factory);
572
573 final Configuration config = new DefaultConfiguration(
574 DebugAuditAdapter.class.getCanonicalName());
575 checker.setupChild(config);
576
577 final List<AuditListener> listeners = TestUtil.getInternalStateListAuditListener(checker,
578 "listeners");
579 assertWithMessage("Invalid child listener class")
580 .that(listeners.get(listeners.size() - 1) instanceof DebugAuditAdapter)
581 .isTrue();
582 }
583
584 @Test
585 public void testDestroyCheckerWithWrongCacheFileNameLength() throws Exception {
586 final Checker checker = new Checker();
587 final PackageObjectFactory factory = new PackageObjectFactory(
588 new HashSet<>(), Thread.currentThread().getContextClassLoader());
589 checker.setModuleFactory(factory);
590 checker.configure(new DefaultConfiguration("default config"));
591
592
593
594 checker.setCacheFile(String.format(Locale.ENGLISH, "%0300d", 0));
595 try {
596 checker.destroy();
597 assertWithMessage("Exception did not happen").fail();
598 }
599 catch (IllegalStateException exc) {
600 assertWithMessage("Cause of exception differs from IOException")
601 .that(exc.getCause())
602 .isInstanceOf(IOException.class);
603
604 assertWithMessage("Exception message differ")
605 .that(exc.getMessage())
606 .isEqualTo(getLocalizedMessage(
607 "Checker.cacheFilesException"));
608 }
609 }
610
611
612
613
614 @Test
615 public void testCacheAndCheckWhichDoesNotImplementExternalResourceHolderInterface()
616 throws Exception {
617 assertWithMessage("ExternalResourceHolder has changed his parent")
618 .that(ExternalResourceHolder.class.isAssignableFrom(HiddenFieldCheck.class))
619 .isFalse();
620 final DefaultConfiguration checkConfig = createModuleConfig(HiddenFieldCheck.class);
621
622 final DefaultConfiguration treeWalkerConfig = createModuleConfig(TreeWalker.class);
623 treeWalkerConfig.addChild(checkConfig);
624
625 final DefaultConfiguration checkerConfig = createRootConfig(treeWalkerConfig);
626 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
627
628 final File cacheFile = createTempFile("junit");
629 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
630
631 final File tmpFile = createTempFile("file", ".java");
632
633 execute(checkerConfig, tmpFile.getPath());
634 final Properties cacheAfterFirstRun = new Properties();
635 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
636 cacheAfterFirstRun.load(reader);
637 }
638
639
640 execute(checkerConfig, tmpFile.getPath());
641 final Properties cacheAfterSecondRun = new Properties();
642 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
643 cacheAfterSecondRun.load(reader);
644 }
645
646 assertWithMessage("Cache from first run differs from second run cache")
647 .that(cacheAfterSecondRun)
648 .isEqualTo(cacheAfterFirstRun);
649 }
650
651 @Test
652 public void testWithCacheWithNoViolation() throws Exception {
653 final Checker checker = new Checker();
654 final PackageObjectFactory factory = new PackageObjectFactory(
655 new HashSet<>(), Thread.currentThread().getContextClassLoader());
656 checker.setModuleFactory(factory);
657 checker.configure(createModuleConfig(TranslationCheck.class));
658
659 final File cacheFile = createTempFile("junit");
660 checker.setCacheFile(cacheFile.getPath());
661
662 checker.setupChild(createModuleConfig(TranslationCheck.class));
663 final File tmpFile = createTempFile("file", ".java");
664 final List<File> files = new ArrayList<>(1);
665 files.add(tmpFile);
666 checker.process(files);
667
668
669 checker.destroy();
670
671 final Properties cache = new Properties();
672 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
673 cache.load(reader);
674 }
675
676
677 final int expectedNumberOfObjectsInCache = 2;
678 assertWithMessage("Cache has unexpected size")
679 .that(cache)
680 .hasSize(expectedNumberOfObjectsInCache);
681
682 final String expectedConfigHash = "D581D4A2BD482D4E1EF1F82459356BA2D8A3B" + "FC3";
683 assertWithMessage("Cache has unexpected hash")
684 .that(cache.getProperty(PropertyCacheFile.CONFIG_HASH_KEY))
685 .isEqualTo(expectedConfigHash);
686
687 assertWithMessage("Cache file has null path")
688 .that(cache.getProperty(tmpFile.getPath()))
689 .isNotNull();
690 }
691
692 @Test
693 public void testClearExistingCache() throws Exception {
694 final DefaultConfiguration checkerConfig = createRootConfig(null);
695 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
696 final File cacheFile = createTempFile("junit");
697 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
698
699 final Checker checker = new Checker();
700 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
701 checker.configure(checkerConfig);
702 checker.addListener(getBriefUtLogger());
703
704 checker.clearCache();
705
706 checker.destroy();
707
708 final Properties cacheAfterClear = new Properties();
709 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
710 cacheAfterClear.load(reader);
711 }
712
713 assertWithMessage("Cache has unexpected size")
714 .that(cacheAfterClear)
715 .hasSize(1);
716 assertWithMessage("Cache has null hash")
717 .that(cacheAfterClear.getProperty(PropertyCacheFile.CONFIG_HASH_KEY))
718 .isNotNull();
719
720 final String pathToEmptyFile = createTempFile("file", ".java").getPath();
721
722
723 execute(checkerConfig, pathToEmptyFile);
724 final Properties cacheAfterSecondRun = new Properties();
725 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
726 cacheAfterSecondRun.load(reader);
727 }
728
729 assertWithMessage("Cache has null path")
730 .that(cacheAfterSecondRun.getProperty(pathToEmptyFile))
731 .isNotNull();
732 final String cacheHash = cacheAfterSecondRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY);
733 assertWithMessage("Cash have changed it hash")
734 .that(cacheHash)
735 .isEqualTo(cacheAfterClear.getProperty(PropertyCacheFile.CONFIG_HASH_KEY));
736 final int expectedNumberOfObjectsInCacheAfterSecondRun = 2;
737 assertWithMessage("Cache has changed number of items")
738 .that(cacheAfterSecondRun)
739 .hasSize(expectedNumberOfObjectsInCacheAfterSecondRun);
740 }
741
742 @Test
743 public void testClearCache() throws Exception {
744 final DefaultConfiguration violationCheck =
745 createModuleConfig(DummyFileSetViolationCheck.class);
746 final DefaultConfiguration checkerConfig = new DefaultConfiguration("myConfig");
747 checkerConfig.addProperty("charset", "UTF-8");
748 final File cacheFile = createTempFile("junit");
749 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
750 checkerConfig.addChild(violationCheck);
751 final Checker checker = new Checker();
752 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
753 checker.configure(checkerConfig);
754 checker.addListener(getBriefUtLogger());
755
756 checker.process(Collections.singletonList(new File("dummy.java")));
757 checker.clearCache();
758
759 final PropertyCacheFile cache = TestUtil.getInternalState(checker,
760 "cacheFile", PropertyCacheFile.class);
761 cache.persist();
762
763 final Properties cacheAfterClear = new Properties();
764 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
765 cacheAfterClear.load(reader);
766 }
767
768 assertWithMessage("Cache has unexpected size")
769 .that(cacheAfterClear)
770 .hasSize(1);
771 }
772
773 @Test
774 public void setFileExtension() {
775 final Checker checker = new Checker();
776 checker.setFileExtensions(".test1", "test2");
777 final String[] actual = TestUtil.getInternalState(checker,
778 "fileExtensions", String[].class);
779 assertWithMessage("Extensions are not expected")
780 .that(actual)
781 .isEqualTo(new String[] {".test1", ".test2"});
782 }
783
784 @Test
785 public void testClearCacheWhenCacheFileIsNotSet() {
786
787
788 final Checker checker = new Checker();
789 checker.clearCache();
790 final PropertyCacheFile cache = TestUtil.getInternalState(checker,
791 "cacheFile", PropertyCacheFile.class);
792 assertWithMessage("If cache file is not set the cache should default to null")
793 .that(cache)
794 .isNull();
795 }
796
797
798
799
800
801
802
803
804 @Test
805 public void testCatchErrorInProcessFilesMethod() throws Exception {
806
807 final String errorMessage = "Java Virtual Machine is broken"
808 + " or has run out of resources necessary for it to continue operating.";
809 final Error expectedError = new IOError(new InternalError(errorMessage));
810
811 final File mock = new File("testFile") {
812 @Serial
813 private static final long serialVersionUID = 1L;
814
815
816
817
818
819
820
821
822 @Override
823 public long lastModified() {
824 throw expectedError;
825 }
826 };
827
828 final Checker checker = new Checker();
829 final List<File> filesToProcess = new ArrayList<>();
830 filesToProcess.add(mock);
831 try {
832 checker.process(filesToProcess);
833 assertWithMessage("IOError is expected!").fail();
834 }
835
836 catch (Error error) {
837 assertWithMessage("Error cause differs from IOError")
838 .that(error.getCause())
839 .isInstanceOf(IOError.class);
840 assertWithMessage("Error cause is not InternalError")
841 .that(error.getCause().getCause())
842 .isInstanceOf(InternalError.class);
843 assertWithMessage("Error message is not expected")
844 .that(error)
845 .hasCauseThat()
846 .hasCauseThat()
847 .hasMessageThat()
848 .isEqualTo(errorMessage);
849 assertWithMessage("Error message differs")
850 .that(error.getMessage())
851 .isEqualTo(getLocalizedMessage(
852 "Checker.error", mock.getPath()));
853
854 }
855 }
856
857
858
859
860
861
862
863
864 @Test
865 public void testCatchErrorWithNoFileName() throws Exception {
866
867 final String errorMessage = "Java Virtual Machine is broken"
868 + " or has run out of resources necessary for it to continue operating.";
869 final Error expectedError = new IOError(new InternalError(errorMessage));
870
871 final File mock = new File("testFile") {
872 @Serial
873 private static final long serialVersionUID = 1L;
874
875
876
877
878
879
880
881 @Override
882 public long lastModified() {
883 throw expectedError;
884 }
885
886 @Override
887 public String getAbsolutePath() {
888 return null;
889 }
890 };
891
892 final Checker checker = new Checker();
893 final List<File> filesToProcess = new ArrayList<>();
894 filesToProcess.add(mock);
895 try {
896 checker.process(filesToProcess);
897 assertWithMessage("IOError is expected!").fail();
898 }
899
900 catch (Error error) {
901 assertWithMessage("Error cause differs from IOError")
902 .that(error)
903 .hasCauseThat()
904 .isInstanceOf(IOError.class);
905 assertWithMessage("Error cause is not InternalError")
906 .that(error)
907 .hasCauseThat()
908 .hasCauseThat()
909 .isInstanceOf(InternalError.class);
910 assertWithMessage("Error message is not expected")
911 .that(error)
912 .hasCauseThat()
913 .hasCauseThat()
914 .hasMessageThat()
915 .isEqualTo(errorMessage);
916 }
917 }
918
919
920
921
922 @Test
923 public void testCacheAndFilterWhichDoesNotImplementExternalResourceHolderInterface()
924 throws Exception {
925 assertWithMessage("ExternalResourceHolder has changed its parent")
926 .that(ExternalResourceHolder.class.isAssignableFrom(DummyFilter.class))
927 .isFalse();
928 final DefaultConfiguration filterConfig = createModuleConfig(DummyFilter.class);
929
930 final DefaultConfiguration checkerConfig = createRootConfig(filterConfig);
931 final File cacheFile = createTempFile("junit");
932 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
933
934 final String pathToEmptyFile = createTempFile("file", ".java").getPath();
935
936 execute(checkerConfig, pathToEmptyFile);
937 final Properties cacheAfterFirstRun = new Properties();
938 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
939 cacheAfterFirstRun.load(reader);
940 }
941
942
943 execute(checkerConfig, pathToEmptyFile);
944 final Properties cacheAfterSecondRun = new Properties();
945 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
946 cacheAfterSecondRun.load(reader);
947 }
948
949 final String cacheFilePath = cacheAfterSecondRun.getProperty(pathToEmptyFile);
950 assertWithMessage("Cache file has changed its path")
951 .that(cacheFilePath)
952 .isEqualTo(cacheAfterFirstRun.getProperty(pathToEmptyFile));
953 final String cacheHash = cacheAfterSecondRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY);
954 assertWithMessage("Cache has changed its hash")
955 .that(cacheHash)
956 .isEqualTo(cacheAfterFirstRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY));
957 final int expectedNumberOfObjectsInCache = 2;
958 assertWithMessage("Number of items in cache differs from expected")
959 .that(cacheAfterFirstRun)
960 .hasSize(expectedNumberOfObjectsInCache);
961 assertWithMessage("Number of items in cache differs from expected")
962 .that(cacheAfterSecondRun)
963 .hasSize(expectedNumberOfObjectsInCache);
964 }
965
966
967
968
969
970 @Test
971 public void testCacheAndCheckWhichAddsNewResourceLocationButKeepsSameCheckerInstance()
972 throws Exception {
973
974
975
976
977
978
979 final DynamicalResourceHolderCheck check = new DynamicalResourceHolderCheck();
980 final String firstExternalResourceLocation = getPath("InputCheckerImportControlOne.xml");
981 final String firstExternalResourceKey = PropertyCacheFile.EXTERNAL_RESOURCE_KEY_PREFIX
982 + firstExternalResourceLocation;
983 check.setFirstExternalResourceLocation(firstExternalResourceLocation);
984
985 final DefaultConfiguration checkerConfig = createRootConfig(null);
986 final File cacheFile = createTempFile("junit");
987 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
988
989 final Checker checker = new Checker();
990 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
991 checker.addFileSetCheck(check);
992 checker.addFilter(new DummyFilterSet());
993 checker.configure(checkerConfig);
994 checker.addListener(getBriefUtLogger());
995
996 final String pathToEmptyFile = createTempFile("file", ".java").getPath();
997
998 execute(checker, pathToEmptyFile);
999 final Properties cacheAfterFirstRun = new Properties();
1000 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1001 cacheAfterFirstRun.load(reader);
1002 }
1003
1004 final int expectedNumberOfObjectsInCacheAfterFirstRun = 4;
1005 assertWithMessage("Number of items in cache differs from expected")
1006 .that(cacheAfterFirstRun)
1007 .hasSize(expectedNumberOfObjectsInCacheAfterFirstRun);
1008
1009
1010 final String secondExternalResourceLocation = "InputCheckerImportControlTwo.xml";
1011 final String secondExternalResourceKey = PropertyCacheFile.EXTERNAL_RESOURCE_KEY_PREFIX
1012 + secondExternalResourceLocation;
1013 check.setSecondExternalResourceLocation(secondExternalResourceLocation);
1014
1015 checker.addFileSetCheck(check);
1016 checker.configure(checkerConfig);
1017
1018 execute(checker, pathToEmptyFile);
1019 final Properties cacheAfterSecondRun = new Properties();
1020 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1021 cacheAfterSecondRun.load(reader);
1022 }
1023
1024 final String cacheFilePath = cacheAfterSecondRun.getProperty(pathToEmptyFile);
1025 assertWithMessage("Cache file has changed its path")
1026 .that(cacheFilePath)
1027 .isEqualTo(cacheAfterFirstRun.getProperty(pathToEmptyFile));
1028 final String cacheHash = cacheAfterSecondRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY);
1029 assertWithMessage("Cache has changed its hash")
1030 .that(cacheHash)
1031 .isEqualTo(cacheAfterFirstRun.getProperty(PropertyCacheFile.CONFIG_HASH_KEY));
1032 final String resourceKey = cacheAfterSecondRun.getProperty(firstExternalResourceKey);
1033 assertWithMessage("Cache has changed its resource key")
1034 .that(resourceKey)
1035 .isEqualTo(cacheAfterFirstRun.getProperty(firstExternalResourceKey));
1036 assertWithMessage("Cache has null as a resource key")
1037 .that(cacheAfterFirstRun.getProperty(firstExternalResourceKey))
1038 .isNotNull();
1039 final int expectedNumberOfObjectsInCacheAfterSecondRun = 4;
1040 assertWithMessage("Number of items in cache differs from expected")
1041 .that(cacheAfterSecondRun)
1042 .hasSize(expectedNumberOfObjectsInCacheAfterSecondRun);
1043 assertWithMessage("Cache has not null as a resource key")
1044 .that(cacheAfterFirstRun.getProperty(secondExternalResourceKey))
1045 .isNull();
1046 assertWithMessage("Cache has null as a resource key")
1047 .that(cacheAfterSecondRun.getProperty(secondExternalResourceKey))
1048 .isNotNull();
1049 }
1050
1051 @Test
1052 public void testClearLazyLoadCacheInDetailAST() throws Exception {
1053
1054 final String filePath = getPath("InputCheckerClearDetailAstLazyLoadCache.java");
1055
1056 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
1057 verifyWithInlineConfigParser(filePath, expected);
1058 }
1059
1060 @Test
1061 public void testCacheOnViolationSuppression() throws Exception {
1062 final File cacheFile = createTempFile("junit");
1063 final DefaultConfiguration violationCheck =
1064 createModuleConfig(DummyFileSetViolationCheck.class);
1065
1066 final DefaultConfiguration filterConfig = createModuleConfig(SuppressionFilter.class);
1067 filterConfig.addProperty("file", getPath("InputCheckerSuppressAll.xml"));
1068
1069 final DefaultConfiguration checkerConfig = createRootConfig(violationCheck);
1070 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1071 checkerConfig.addChild(filterConfig);
1072
1073 final String fileViolationPath = createTempFile("ViolationFile", ".java").getPath();
1074
1075 execute(checkerConfig, fileViolationPath);
1076
1077 try (InputStream input = Files.newInputStream(cacheFile.toPath())) {
1078 final Properties details = new Properties();
1079 details.load(input);
1080
1081 assertWithMessage("suppressed violation file saved in cache")
1082 .that(details.getProperty(fileViolationPath))
1083 .isNotNull();
1084 }
1085 }
1086
1087 @Test
1088 public void testHaltOnException() throws Exception {
1089 final DefaultConfiguration checkConfig =
1090 createModuleConfig(CheckWhichThrowsError.class);
1091 final String filePath = getPath("InputChecker.java");
1092 try {
1093 execute(checkConfig, filePath);
1094 assertWithMessage("Exception is expected").fail();
1095 }
1096 catch (CheckstyleException exc) {
1097 assertWithMessage("Error message is not expected")
1098 .that(exc.getMessage())
1099 .isEqualTo("Exception was thrown while processing " + filePath);
1100 }
1101 }
1102
1103 @Test
1104 public void testExceptionWithCache() throws Exception {
1105 final File cacheFile = createTempFile("junit");
1106
1107 final DefaultConfiguration checkConfig =
1108 createModuleConfig(CheckWhichThrowsError.class);
1109
1110 final DefaultConfiguration treewalkerConfig =
1111 createModuleConfig(TreeWalker.class);
1112 treewalkerConfig.addChild(checkConfig);
1113
1114 final DefaultConfiguration checkerConfig = createRootConfig(treewalkerConfig);
1115 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1116 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1117 checkerConfig.addChild(treewalkerConfig);
1118
1119 final Checker checker = createChecker(checkerConfig);
1120
1121 final String filePath = getPath("InputChecker.java");
1122 try {
1123 checker.process(Collections.singletonList(new File(filePath)));
1124 assertWithMessage("Exception is expected").fail();
1125 }
1126 catch (CheckstyleException exc) {
1127 assertWithMessage("Error message is not expected")
1128 .that(exc.getMessage())
1129 .isEqualTo("Exception was thrown while processing " + filePath);
1130
1131
1132 checker.destroy();
1133
1134 final Properties cache = new Properties();
1135 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1136 cache.load(reader);
1137 }
1138
1139 assertWithMessage("Cache has unexpected size")
1140 .that(cache)
1141 .hasSize(1);
1142 assertWithMessage("testFile is not in cache")
1143 .that(cache.getProperty(filePath))
1144 .isNull();
1145 }
1146 }
1147
1148
1149
1150
1151
1152
1153
1154
1155 @Test
1156 public void testCatchErrorWithCache() throws Exception {
1157 final File cacheFile = createTempFile("junit");
1158
1159 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
1160 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1161 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1162
1163 final String errorMessage = "Java Virtual Machine is broken"
1164 + " or has run out of resources necessary for it to continue operating.";
1165 final Error expectedError = new IOError(new InternalError(errorMessage));
1166
1167 final File mock = new File("testFile") {
1168 @Serial
1169 private static final long serialVersionUID = 1L;
1170 @Override
1171 public String getAbsolutePath() {
1172 return "testFile";
1173 }
1174
1175
1176
1177
1178
1179
1180
1181
1182 @Override
1183 public File getAbsoluteFile() {
1184 throw expectedError;
1185 }
1186 };
1187
1188 final Checker checker = new Checker();
1189 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1190 checker.configure(checkerConfig);
1191 final List<File> filesToProcess = new ArrayList<>();
1192 filesToProcess.add(mock);
1193 try {
1194 checker.process(filesToProcess);
1195 assertWithMessage("IOError is expected!").fail();
1196 }
1197
1198 catch (Error error) {
1199 assertWithMessage("Error cause differs from IOError")
1200 .that(error.getCause())
1201 .isInstanceOf(IOError.class);
1202 assertWithMessage("Error message is not expected")
1203 .that(error)
1204 .hasCauseThat()
1205 .hasCauseThat()
1206 .hasMessageThat()
1207 .isEqualTo(errorMessage);
1208
1209
1210 checker.destroy();
1211
1212 final Properties cache = new Properties();
1213 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1214 cache.load(reader);
1215 }
1216
1217 assertWithMessage("Cache has unexpected size")
1218 .that(cache)
1219 .hasSize(1);
1220 assertWithMessage("testFile is not in cache")
1221 .that(cache.getProperty("testFile"))
1222 .isNull();
1223 }
1224 }
1225
1226
1227
1228
1229
1230
1231
1232
1233 @Test
1234 public void testCatchErrorWithCacheWithNoFileName() throws Exception {
1235 final File cacheFile = createTempFile("junit");
1236
1237 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
1238 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1239 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1240
1241 final String errorMessage = "Java Virtual Machine is broken"
1242 + " or has run out of resources necessary for it to continue operating.";
1243 final Error expectedError = new IOError(new InternalError(errorMessage));
1244
1245 final File mock = new File("testFile") {
1246 @Serial
1247 private static final long serialVersionUID = 1L;
1248
1249
1250
1251
1252
1253
1254
1255
1256 @Override
1257 public String getAbsolutePath() {
1258 throw expectedError;
1259 }
1260 };
1261
1262 final Checker checker = new Checker();
1263 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1264 checker.configure(checkerConfig);
1265 final List<File> filesToProcess = new ArrayList<>();
1266 filesToProcess.add(mock);
1267 try {
1268 checker.process(filesToProcess);
1269 assertWithMessage("IOError is expected!").fail();
1270 }
1271
1272 catch (Error error) {
1273 assertWithMessage("Error cause differs from IOError")
1274 .that(error)
1275 .hasCauseThat()
1276 .isInstanceOf(IOError.class);
1277 assertWithMessage("Error message is not expected")
1278 .that(error)
1279 .hasCauseThat()
1280 .hasCauseThat()
1281 .hasMessageThat()
1282 .isEqualTo(errorMessage);
1283
1284
1285 checker.destroy();
1286
1287 final Properties cache = new Properties();
1288 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1289 cache.load(reader);
1290 }
1291
1292 assertWithMessage("Cache has unexpected size")
1293 .that(cache)
1294 .hasSize(1);
1295 }
1296 }
1297
1298
1299
1300
1301
1302
1303
1304
1305 @Test
1306 public void testExceptionWithNoFileName() {
1307 final String errorMessage = "Security Exception";
1308 final RuntimeException expectedError = new SecurityException(errorMessage);
1309
1310 final File mock = new File("testFile") {
1311 @Serial
1312 private static final long serialVersionUID = 1L;
1313
1314
1315
1316
1317
1318
1319
1320
1321 @Override
1322 public String getAbsolutePath() {
1323 throw expectedError;
1324 }
1325 };
1326
1327 final Checker checker = new Checker();
1328 final List<File> filesToProcess = new ArrayList<>();
1329 filesToProcess.add(mock);
1330 try {
1331 checker.process(filesToProcess);
1332 assertWithMessage("SecurityException is expected!").fail();
1333 }
1334 catch (CheckstyleException exc) {
1335 assertWithMessage("Error cause differs from SecurityException")
1336 .that(exc)
1337 .hasCauseThat()
1338 .isInstanceOf(SecurityException.class);
1339 assertWithMessage("Error message is not expected")
1340 .that(exc)
1341 .hasCauseThat()
1342 .hasMessageThat()
1343 .isEqualTo(errorMessage);
1344 }
1345 }
1346
1347
1348
1349
1350
1351
1352
1353
1354 @Test
1355 public void testExceptionWithCacheAndNoFileName() throws Exception {
1356 final File cacheFile = createTempFile("junit");
1357
1358 final DefaultConfiguration checkerConfig = new DefaultConfiguration("configuration");
1359 checkerConfig.addProperty("charset", StandardCharsets.UTF_8.name());
1360 checkerConfig.addProperty("cacheFile", cacheFile.getPath());
1361
1362 final String errorMessage = "Security Exception";
1363 final RuntimeException expectedError = new SecurityException(errorMessage);
1364
1365 final File mock = new File("testFile") {
1366 @Serial
1367 private static final long serialVersionUID = 1L;
1368
1369
1370
1371
1372
1373
1374
1375
1376 @Override
1377 public String getAbsolutePath() {
1378 throw expectedError;
1379 }
1380 };
1381
1382 final Checker checker = new Checker();
1383 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1384 checker.configure(checkerConfig);
1385 final List<File> filesToProcess = new ArrayList<>();
1386 filesToProcess.add(mock);
1387 try {
1388 checker.process(filesToProcess);
1389 assertWithMessage("SecurityException is expected!").fail();
1390 }
1391 catch (CheckstyleException exc) {
1392 assertWithMessage("Error cause differs from SecurityException")
1393 .that(exc)
1394 .hasCauseThat()
1395 .isInstanceOf(SecurityException.class);
1396 assertWithMessage("Error message is not expected")
1397 .that(exc)
1398 .hasCauseThat()
1399 .hasMessageThat()
1400 .isEqualTo(errorMessage);
1401
1402
1403 checker.destroy();
1404
1405 final Properties cache = new Properties();
1406 try (BufferedReader reader = Files.newBufferedReader(cacheFile.toPath())) {
1407 cache.load(reader);
1408 }
1409
1410 assertWithMessage("Cache has unexpected size")
1411 .that(cache)
1412 .hasSize(1);
1413 }
1414 }
1415
1416 @Test
1417 public void testHaltOnExceptionOff() throws Exception {
1418 final String filePath = getPath("InputChecker.java");
1419 final String[] expected = {
1420 "1: " + getCheckMessage(EXCEPTION_MSG, "java.lang.IndexOutOfBoundsException: test"),
1421 };
1422
1423 verifyWithInlineXmlConfig(filePath, expected);
1424 }
1425
1426 @Test
1427 public void testTabViolationDefault() throws Exception {
1428 final String[] expected = {
1429 "17:17: violation",
1430 "21:49: violation",
1431 };
1432 verifyWithInlineConfigParser(getPath("InputCheckerTabCharacter.java"),
1433 expected);
1434 }
1435
1436 @Test
1437 public void testTabViolationCustomWidth() throws Exception {
1438 final String[] expected = {
1439 "18:17: violation",
1440 "22:37: violation",
1441 };
1442
1443 verifyWithInlineXmlConfig(getPath("InputCheckerTabCharacterCustomWidth.java"), expected);
1444 }
1445
1446 @Test
1447 public void testCheckerProcessCallAllNeededMethodsOfFileSets() throws Exception {
1448 final DummyFileSet fileSet = new DummyFileSet();
1449 final Checker checker = new Checker();
1450 checker.addFileSetCheck(fileSet);
1451 checker.process(Collections.singletonList(new File("dummy.java")));
1452 final List<String> expected =
1453 Arrays.asList("beginProcessing", "finishProcessing", "destroy");
1454 assertWithMessage("Method calls were not expected")
1455 .that(fileSet.getMethodCalls())
1456 .isEqualTo(expected);
1457 }
1458
1459 @Test
1460 public void testSetFileSetCheckSetsMessageDispatcher() {
1461 final DummyFileSet fileSet = new DummyFileSet();
1462 final Checker checker = new Checker();
1463 checker.addFileSetCheck(fileSet);
1464 assertWithMessage("Message dispatcher was not expected")
1465 .that(fileSet.getInternalMessageDispatcher())
1466 .isEqualTo(checker);
1467 }
1468
1469 @Test
1470 public void testAddAuditListenerAsChild() throws Exception {
1471 final Checker checker = new Checker();
1472 final DebugAuditAdapter auditAdapter = new DebugAuditAdapter();
1473 final PackageObjectFactory factory = new PackageObjectFactory(
1474 new HashSet<>(), Thread.currentThread().getContextClassLoader()) {
1475 @Override
1476 public Object createModule(String name) throws CheckstyleException {
1477 Object adapter = auditAdapter;
1478 if (!name.equals(DebugAuditAdapter.class.getName())) {
1479 adapter = super.createModule(name);
1480 }
1481 return adapter;
1482 }
1483 };
1484 checker.setModuleFactory(factory);
1485 checker.setupChild(createModuleConfig(DebugAuditAdapter.class));
1486
1487 checker.process(Collections.singletonList(new File("dummy.java")));
1488 assertWithMessage("Checker.fireAuditStarted() doesn't call listener")
1489 .that(auditAdapter.wasCalled())
1490 .isTrue();
1491 }
1492
1493 @Test
1494 public void testAddBeforeExecutionFileFilterAsChild() throws Exception {
1495 final Checker checker = new Checker();
1496 final TestBeforeExecutionFileFilter fileFilter = new TestBeforeExecutionFileFilter();
1497 final PackageObjectFactory factory = new PackageObjectFactory(
1498 new HashSet<>(), Thread.currentThread().getContextClassLoader()) {
1499 @Override
1500 public Object createModule(String name) throws CheckstyleException {
1501 Object filter = fileFilter;
1502 if (!name.equals(TestBeforeExecutionFileFilter.class.getName())) {
1503 filter = super.createModule(name);
1504 }
1505 return filter;
1506 }
1507 };
1508 checker.setModuleFactory(factory);
1509 checker.setupChild(createModuleConfig(TestBeforeExecutionFileFilter.class));
1510 checker.process(Collections.singletonList(new File("dummy.java")));
1511 assertWithMessage("Checker.acceptFileStarted() doesn't call listener")
1512 .that(fileFilter.wasCalled())
1513 .isTrue();
1514 }
1515
1516 @Test
1517 public void testFileSetCheckInitWhenAddedAsChild() throws Exception {
1518 final Checker checker = new Checker();
1519 final DummyFileSet fileSet = new DummyFileSet();
1520 final PackageObjectFactory factory = new PackageObjectFactory(
1521 new HashSet<>(), Thread.currentThread().getContextClassLoader()) {
1522 @Override
1523 public Object createModule(String name) throws CheckstyleException {
1524 Object check = fileSet;
1525 if (!name.equals(DummyFileSet.class.getName())) {
1526 check = super.createModule(name);
1527 }
1528 return check;
1529 }
1530 };
1531 checker.setModuleFactory(factory);
1532 checker.finishLocalSetup();
1533 checker.setupChild(createModuleConfig(DummyFileSet.class));
1534 assertWithMessage("FileSetCheck.init() wasn't called")
1535 .that(fileSet.isInitCalled())
1536 .isTrue();
1537 }
1538
1539
1540 @Test
1541 public void testDefaultLoggerClosesItStreams() throws Exception {
1542 final Checker checker = new Checker();
1543 try (CloseAndFlushTestByteArrayOutputStream testInfoOutputStream =
1544 new CloseAndFlushTestByteArrayOutputStream();
1545 CloseAndFlushTestByteArrayOutputStream testErrorOutputStream =
1546 new CloseAndFlushTestByteArrayOutputStream()) {
1547 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1548 checker.addListener(new DefaultLogger(testInfoOutputStream,
1549 OutputStreamOptions.CLOSE, testErrorOutputStream, OutputStreamOptions.CLOSE));
1550
1551 final File tmpFile = createTempFile("file", ".java");
1552
1553 execute(checker, tmpFile.getPath());
1554
1555 assertWithMessage("Output stream close count")
1556 .that(testInfoOutputStream.getCloseCount())
1557 .isEqualTo(1);
1558 assertWithMessage("Output stream flush count")
1559 .that(testInfoOutputStream.getFlushCount())
1560 .isEqualTo(TestUtil.adjustFlushCountForOutputStreamClose(3));
1561 assertWithMessage("Error stream close count")
1562 .that(testErrorOutputStream.getCloseCount())
1563 .isEqualTo(1);
1564 assertWithMessage("Error stream flush count")
1565 .that(testErrorOutputStream.getFlushCount())
1566 .isEqualTo(TestUtil.adjustFlushCountForOutputStreamClose(1));
1567 }
1568 }
1569
1570
1571 @Test
1572 public void testXmlLoggerClosesItStreams() throws Exception {
1573 final Checker checker = new Checker();
1574 try (CloseAndFlushTestByteArrayOutputStream testInfoOutputStream =
1575 new CloseAndFlushTestByteArrayOutputStream()) {
1576 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1577 checker.addListener(new XMLLogger(testInfoOutputStream, OutputStreamOptions.CLOSE));
1578
1579 final File tmpFile = createTempFile("file", ".java");
1580
1581 execute(checker, tmpFile.getPath(), tmpFile.getPath());
1582
1583 assertWithMessage("Output stream close count")
1584 .that(testInfoOutputStream.getCloseCount())
1585 .isEqualTo(1);
1586 assertWithMessage("Output stream flush count")
1587 .that(testInfoOutputStream.getFlushCount())
1588 .isEqualTo(TestUtil.adjustFlushCountForOutputStreamClose(0));
1589 }
1590 }
1591
1592 @Test
1593 public void testDuplicatedModule() throws Exception {
1594
1595 final DefaultConfiguration moduleConfig1 =
1596 createModuleConfig(NewlineAtEndOfFileCheck.class);
1597 final DefaultConfiguration moduleConfig2 =
1598 createModuleConfig(NewlineAtEndOfFileCheck.class);
1599 moduleConfig2.addProperty("id", "ModuleId");
1600 final DefaultConfiguration root = new DefaultConfiguration("root");
1601 root.addChild(moduleConfig1);
1602 root.addChild(moduleConfig2);
1603 final Checker checker = new Checker();
1604 checker.setModuleClassLoader(Thread.currentThread().getContextClassLoader());
1605 checker.configure(root);
1606
1607
1608 final ByteArrayOutputStream out = TestUtil.getInternalState(this,
1609 "stream", ByteArrayOutputStream.class);
1610 final DefaultLogger logger = new DefaultLogger(out, OutputStreamOptions.CLOSE, out,
1611 OutputStreamOptions.NONE, new AuditEventDefaultFormatter());
1612 checker.addListener(logger);
1613
1614 final File tempFile = createTempFile("file", ".java");
1615 try (BufferedWriter bufferedWriter = Files.newBufferedWriter(tempFile.toPath())) {
1616 bufferedWriter.write(';');
1617 }
1618 final String path = tempFile.getPath();
1619 final String violationMessage =
1620 getCheckMessage(NewlineAtEndOfFileCheck.class, MSG_KEY_NO_NEWLINE_EOF);
1621 final String[] expected = {
1622 "1: " + violationMessage + " [NewlineAtEndOfFile]",
1623 "1: " + violationMessage + " [ModuleId]",
1624 };
1625
1626
1627 out.flush();
1628 final int errs = checker.process(Collections.singletonList(new File(path)));
1629 try (ByteArrayInputStream inputStream =
1630 new ByteArrayInputStream(out.toByteArray());
1631 LineNumberReader lnr = new LineNumberReader(
1632 new InputStreamReader(inputStream, StandardCharsets.UTF_8))) {
1633
1634 final List<String> actual = lnr.lines()
1635 .filter(line -> !getCheckMessage(AUDIT_STARTED_MESSAGE).equals(line))
1636 .filter(line -> !getCheckMessage(AUDIT_FINISHED_MESSAGE).equals(line))
1637 .limit(expected.length)
1638 .sorted()
1639 .toList();
1640 Arrays.sort(expected);
1641
1642 for (int i = 0; i < expected.length; i++) {
1643 final String expectedResult = "[ERROR] " + path + ":" + expected[i];
1644 assertWithMessage("error message " + i)
1645 .that(actual.get(i))
1646 .isEqualTo(expectedResult);
1647 }
1648
1649 assertWithMessage("unexpected output: " + lnr.readLine())
1650 .that(errs)
1651 .isEqualTo(expected.length);
1652 }
1653
1654 checker.destroy();
1655 }
1656
1657 @Test
1658 public void testCachedFile() throws Exception {
1659 final Checker checker = createChecker(createModuleConfig(TranslationCheck.class));
1660 final OutputStream infoStream = new ByteArrayOutputStream();
1661 final OutputStream errorStream = new ByteArrayOutputStream();
1662 final DefaultLoggerWithCounter loggerWithCounter =
1663 new DefaultLoggerWithCounter(infoStream, OutputStreamOptions.CLOSE,
1664 errorStream, OutputStreamOptions.CLOSE);
1665 checker.addListener(loggerWithCounter);
1666 final File cacheFile = createTempFile("cacheFile", ".txt");
1667 checker.setCacheFile(cacheFile.getAbsolutePath());
1668
1669 final File testFile = createTempFile("testFile", ".java");
1670 final List<File> files = List.of(testFile, testFile);
1671 checker.process(files);
1672
1673 assertWithMessage("Cached file should not be processed twice")
1674 .that(loggerWithCounter.fileStartedCount)
1675 .isEqualTo(1);
1676
1677 checker.destroy();
1678 }
1679
1680 @Test
1681 public void testUnmappableCharacters() throws Exception {
1682 final String[] expected = {
1683 "14: " + getCheckMessage(LineLengthCheck.class, MSG_KEY, 80, 225),
1684 };
1685
1686 verifyWithInlineXmlConfig(getPath("InputCheckerTestCharset.java"),
1687 expected);
1688 }
1689
1690
1691
1692
1693
1694
1695
1696
1697 @SuppressForbidden
1698 @Test
1699 public void testViolationMessageOnIoException() throws Exception {
1700 final DefaultConfiguration checkConfig =
1701 createModuleConfig(CheckWhichThrowsError.class);
1702
1703 final DefaultConfiguration treeWalkerConfig = createModuleConfig(TreeWalker.class);
1704 treeWalkerConfig.addChild(checkConfig);
1705
1706 final DefaultConfiguration checkerConfig = createRootConfig(treeWalkerConfig);
1707 checkerConfig.addChild(treeWalkerConfig);
1708
1709 checkerConfig.addProperty("haltOnException", "false");
1710 final File file = new File("InputNonChecker.java");
1711 final String filePath = file.getAbsolutePath();
1712 final String[] expected = {
1713 "1: " + getCheckMessage(EXCEPTION_MSG, filePath
1714 + " (No such file or directory)"),
1715 };
1716
1717 verify(checkerConfig, filePath, expected);
1718 }
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728 @Test
1729 public void testRelativizedFileExclusion() throws Exception {
1730 final DefaultConfiguration newLineAtEndOfFileConfig =
1731 createModuleConfig(NewlineAtEndOfFileCheck.class);
1732
1733 final DefaultConfiguration beforeExecutionExclusionFileFilterConfig =
1734 createModuleConfig(BeforeExecutionExclusionFileFilter.class);
1735
1736 beforeExecutionExclusionFileFilterConfig.addProperty("fileNamePattern",
1737 "^(?!InputCheckerTestExcludeRelativizedFile.*\\.java).*");
1738
1739 final DefaultConfiguration checkerConfig = createRootConfig(null);
1740 checkerConfig.addChild(newLineAtEndOfFileConfig);
1741 checkerConfig.addChild(beforeExecutionExclusionFileFilterConfig);
1742
1743
1744 checkerConfig.addProperty("basedir",
1745 temporaryFolder.getPath());
1746
1747 final String violationMessage =
1748 getCheckMessage(NewlineAtEndOfFileCheck.class, MSG_KEY_NO_NEWLINE_EOF);
1749
1750 final String[] expected = {
1751 "1: " + violationMessage,
1752 };
1753
1754 final File tempFile = createTempFile("InputCheckerTestExcludeRelativizedFile", ".java");
1755 try (BufferedWriter bufferedWriter = Files.newBufferedWriter(tempFile.toPath())) {
1756 bufferedWriter.write(';');
1757 }
1758
1759 final File[] processedFiles = {tempFile};
1760
1761 verify(createChecker(checkerConfig), processedFiles,
1762 tempFile.getName(), expected);
1763 }
1764
1765 public static class DefaultLoggerWithCounter extends DefaultLogger {
1766
1767 private int fileStartedCount;
1768
1769 public DefaultLoggerWithCounter(OutputStream infoStream,
1770 OutputStreamOptions infoStreamOptions,
1771 OutputStream errorStream,
1772 OutputStreamOptions errorStreamOptions) {
1773 super(infoStream, infoStreamOptions, errorStream, errorStreamOptions);
1774 }
1775
1776 @Override
1777 public void fileStarted(AuditEvent event) {
1778 fileStartedCount++;
1779 }
1780 }
1781
1782 public static class DummyFilter implements Filter {
1783
1784 @Override
1785 public boolean accept(AuditEvent event) {
1786 return false;
1787 }
1788
1789 }
1790
1791 public static class DummyFileSetViolationCheck extends AbstractFileSetCheck
1792 implements ExternalResourceHolder {
1793
1794 @Override
1795 protected void processFiltered(File file, FileText fileText) {
1796 log(1, "test");
1797 }
1798
1799 @Override
1800 public Set<String> getExternalResourceLocations() {
1801 final Set<String> externalResourceLocation = new HashSet<>(1);
1802 externalResourceLocation.add("non_existent_external_resource.xml");
1803 return externalResourceLocation;
1804 }
1805
1806 }
1807
1808 public static class DummyFilterSet extends FilterSet implements ExternalResourceHolder {
1809
1810 @Override
1811 public Set<String> getExternalResourceLocations() {
1812 final Set<String> strings = new HashSet<>();
1813 strings.add("test");
1814 return strings;
1815 }
1816
1817 }
1818
1819 public static final class DynamicalResourceHolderCheck extends AbstractFileSetCheck
1820 implements ExternalResourceHolder {
1821
1822 private String firstExternalResourceLocation;
1823 private String secondExternalResourceLocation;
1824
1825 public void setFirstExternalResourceLocation(String firstExternalResourceLocation) {
1826 this.firstExternalResourceLocation = firstExternalResourceLocation;
1827 }
1828
1829 public void setSecondExternalResourceLocation(String secondExternalResourceLocation) {
1830 this.secondExternalResourceLocation = secondExternalResourceLocation;
1831 }
1832
1833 @Override
1834 protected void processFiltered(File file, FileText fileText) {
1835
1836 }
1837
1838 @Override
1839 public Set<String> getExternalResourceLocations() {
1840 final Set<String> locations = new HashSet<>();
1841 locations.add(firstExternalResourceLocation);
1842
1843 if (secondExternalResourceLocation != null) {
1844 locations.add(secondExternalResourceLocation);
1845 }
1846 return locations;
1847 }
1848
1849 }
1850
1851 public static class CheckWhichDoesNotRequireCommentNodes extends AbstractCheck {
1852
1853
1854 private static final int METHOD_DEF_CHILD_COUNT = 7;
1855
1856 @Override
1857 public int[] getDefaultTokens() {
1858 return new int[] {TokenTypes.METHOD_DEF};
1859 }
1860
1861 @Override
1862 public int[] getAcceptableTokens() {
1863 return new int[] {TokenTypes.METHOD_DEF};
1864 }
1865
1866 @Override
1867 public int[] getRequiredTokens() {
1868 return new int[] {TokenTypes.METHOD_DEF};
1869 }
1870
1871 @Override
1872 public void visitToken(DetailAST ast) {
1873 if (ast.findFirstToken(TokenTypes.MODIFIERS).findFirstToken(
1874 TokenTypes.BLOCK_COMMENT_BEGIN) != null) {
1875 log(ast, "AST has incorrect structure structure."
1876 + " The check does not require comment nodes but there were comment nodes"
1877 + " in the AST.");
1878 }
1879 final int childCount = ast.getChildCount();
1880 if (childCount != METHOD_DEF_CHILD_COUNT) {
1881 final String msg = String.format(Locale.ENGLISH,
1882 "AST node in no comment tree has wrong number of children. "
1883 + "Expected is %d but was %d",
1884 METHOD_DEF_CHILD_COUNT, childCount);
1885 log(ast, msg);
1886 }
1887
1888 int actualChildCount = 0;
1889 for (DetailAST child = ast.getFirstChild().getFirstChild(); child != null; child =
1890 child.getNextSibling()) {
1891 actualChildCount++;
1892 }
1893 final int cacheChildCount = ast.getFirstChild().getChildCount();
1894 if (cacheChildCount != actualChildCount) {
1895 final String msg = String.format(Locale.ENGLISH,
1896 "AST node with no comment has wrong number of children. "
1897 + "Expected is %d but was %d",
1898 cacheChildCount, actualChildCount);
1899 log(ast, msg);
1900 }
1901 }
1902
1903 }
1904
1905 public static class CheckWhichRequiresCommentNodes extends AbstractCheck {
1906
1907
1908 private static final int METHOD_DEF_CHILD_COUNT = 7;
1909
1910 @Override
1911 public boolean isCommentNodesRequired() {
1912 return true;
1913 }
1914
1915 @Override
1916 public int[] getDefaultTokens() {
1917 return new int[] {TokenTypes.METHOD_DEF};
1918 }
1919
1920 @Override
1921 public int[] getAcceptableTokens() {
1922 return new int[] {TokenTypes.METHOD_DEF};
1923 }
1924
1925 @Override
1926 public int[] getRequiredTokens() {
1927 return new int[] {TokenTypes.METHOD_DEF};
1928 }
1929
1930
1931 @Override
1932 public void visitToken(DetailAST ast) {
1933 if (ast.findFirstToken(TokenTypes.MODIFIERS).findFirstToken(
1934 TokenTypes.BLOCK_COMMENT_BEGIN) == null) {
1935 log(ast, "Incorrect AST structure.");
1936 }
1937 final int childCount = ast.getChildCount();
1938 if (childCount != METHOD_DEF_CHILD_COUNT) {
1939 final String msg = String.format(Locale.ENGLISH,
1940 "AST node in comment tree has wrong number of children. "
1941 + "Expected is %d but was %d",
1942 METHOD_DEF_CHILD_COUNT, childCount);
1943 log(ast, msg);
1944 }
1945
1946 int actualChildCount = 0;
1947 for (DetailAST child = ast.getFirstChild().getFirstChild(); child != null; child =
1948 child.getNextSibling()) {
1949 actualChildCount++;
1950 }
1951 final int cacheChildCount = ast.getFirstChild().getChildCount();
1952 if (cacheChildCount != actualChildCount) {
1953 final String msg = String.format(Locale.ENGLISH,
1954 "AST node with comment has wrong number of children. "
1955 + "Expected is %d but was %d",
1956 cacheChildCount, actualChildCount);
1957 log(ast, msg);
1958 }
1959 }
1960
1961 }
1962
1963 public static final class DummyFileSet extends AbstractFileSetCheck {
1964
1965 private final List<String> methodCalls = new ArrayList<>();
1966
1967 private boolean initCalled;
1968
1969 @Override
1970 public void init() {
1971 super.init();
1972 initCalled = true;
1973 }
1974
1975 @Override
1976 public void beginProcessing(String charset) {
1977 methodCalls.add("beginProcessing");
1978 super.beginProcessing(charset);
1979 }
1980
1981 @Override
1982 public void finishProcessing() {
1983 methodCalls.add("finishProcessing");
1984 super.finishProcessing();
1985 }
1986
1987 @Override
1988 protected void processFiltered(File file, FileText fileText) {
1989 methodCalls.add("processFiltered");
1990 }
1991
1992 @Override
1993 public void destroy() {
1994 methodCalls.add("destroy");
1995 super.destroy();
1996 }
1997
1998 public List<String> getMethodCalls() {
1999 return Collections.unmodifiableList(methodCalls);
2000 }
2001
2002 public boolean isInitCalled() {
2003 return initCalled;
2004 }
2005
2006 public MessageDispatcher getInternalMessageDispatcher() {
2007 return getMessageDispatcher();
2008 }
2009
2010 }
2011
2012 }