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