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.filters;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck.MSG_KEY_SINGLE;
24 import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck.MSG_EXPECTED_TAG;
25 import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck.MSG_RETURN_EXPECTED;
26 import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck.MSG_UNUSED_TAG;
27 import static com.puppycrawl.tools.checkstyle.checks.whitespace.FileTabCharacterCheck.MSG_CONTAINS_TAB;
28 import static com.puppycrawl.tools.checkstyle.checks.whitespace.FileTabCharacterCheck.MSG_FILE_CONTAINS_TAB;
29 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
30
31 import java.io.File;
32 import java.io.FileNotFoundException;
33 import java.io.IOException;
34 import java.nio.file.Files;
35 import java.nio.file.StandardCopyOption;
36 import java.util.Arrays;
37 import java.util.List;
38
39 import org.junit.jupiter.api.Test;
40 import org.junit.jupiter.api.io.TempDir;
41
42 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
43 import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
44 import com.puppycrawl.tools.checkstyle.TreeWalker;
45 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
46 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
47 import com.puppycrawl.tools.checkstyle.api.Configuration;
48 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
49 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
50 import com.puppycrawl.tools.checkstyle.api.Violation;
51 import com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck;
52 import com.puppycrawl.tools.checkstyle.checks.indentation.IndentationCheck;
53 import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck;
54 import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineCheck;
55 import com.puppycrawl.tools.checkstyle.checks.whitespace.FileTabCharacterCheck;
56 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
57 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
58 import nl.jqno.equalsverifier.EqualsVerifier;
59 import nl.jqno.equalsverifier.EqualsVerifierReport;
60
61 public class SuppressWithPlainTextCommentFilterTest extends AbstractModuleTestSupport {
62
63 private static final String MSG_REGEXP_EXCEEDED = "regexp.exceeded";
64
65 @TempDir
66 public File temporaryFolder;
67
68 @Override
69 public String getPackageLocation() {
70 return "com/puppycrawl/tools/checkstyle/filters/suppresswithplaintextcommentfilter";
71 }
72
73 @Test
74 public void testFilterWithDefaultConfig() throws Exception {
75 final String[] suppressed = {
76 "20:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
77 "28:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
78 };
79
80 final String[] violationMessages = {
81 "20:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
82 "24:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
83 "28:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
84 };
85
86 verifyFilterWithInlineConfigParser(
87 getPath("InputSuppressWithPlainTextCommentFilterWithDefaultCfg.java"),
88 violationMessages, removeSuppressed(violationMessages, suppressed));
89 }
90
91 @Test
92 public void testChangeOffAndOnFormat() throws Exception {
93 final String[] suppressed = {
94 "20:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
95 "27:30: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
96 };
97
98 final String[] violationMessage = {
99 "20:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
100 "24:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
101 "27:30: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
102 "30:13: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
103 };
104
105 verifyFilterWithInlineConfigParser(
106 getPath("InputSuppressWithPlainTextCommentFilterWithCustomOnAndOffComments.java"),
107 violationMessage, removeSuppressed(violationMessage, suppressed));
108 }
109
110 @Test
111 public void testSuppressionCommentsInXmlFile() throws Exception {
112 final DefaultConfiguration filterCfg =
113 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
114 filterCfg.addProperty("offCommentFormat", "CS-OFF");
115 filterCfg.addProperty("onCommentFormat", "CS-ON");
116
117 final DefaultConfiguration checkCfg = createModuleConfig(FileTabCharacterCheck.class);
118 checkCfg.addProperty("eachLine", "true");
119
120 final String[] suppressed = {
121 "7:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
122 };
123
124 final String[] violationMessages = {
125 "7:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
126 "10:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
127 };
128
129 verifySuppressed(
130 "InputSuppressWithPlainTextCommentFilter.xml",
131 removeSuppressed(violationMessages, suppressed),
132 filterCfg, checkCfg
133 );
134 }
135
136 @Test
137 public void testSuppressionCommentsInPropertiesFile() throws Exception {
138 final DefaultConfiguration filterCfg =
139 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
140 filterCfg.addProperty("offCommentFormat", "# CHECKSTYLE:OFF");
141 filterCfg.addProperty("onCommentFormat", "# CHECKSTYLE:ON");
142
143 final DefaultConfiguration checkCfg = createModuleConfig(RegexpSinglelineCheck.class);
144 checkCfg.addProperty("format", "^key[0-9]=$");
145
146 final String[] suppressed = {
147 "2: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
148 "^key[0-9]=$"),
149 };
150
151 final String[] violationMessages = {
152 "2: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
153 "^key[0-9]=$"),
154 "4: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
155 "^key[0-9]=$"),
156 };
157
158 verifySuppressed(
159 "InputSuppressWithPlainTextCommentFilter.properties",
160 removeSuppressed(violationMessages, suppressed),
161 filterCfg, checkCfg
162 );
163 }
164
165 @Test
166 public void testSuppressionCommentsInSqlFile() throws Exception {
167 final DefaultConfiguration filterCfg =
168 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
169 filterCfg.addProperty("offCommentFormat", "-- CHECKSTYLE OFF");
170 filterCfg.addProperty("onCommentFormat", "-- CHECKSTYLE ON");
171
172 final DefaultConfiguration checkCfg = createModuleConfig(FileTabCharacterCheck.class);
173 checkCfg.addProperty("eachLine", "true");
174
175 final String[] suppressed = {
176 "2:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
177 };
178
179 final String[] violationMessages = {
180 "2:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
181 "5:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
182 };
183
184 verifySuppressed(
185 "InputSuppressWithPlainTextCommentFilter.sql",
186 removeSuppressed(violationMessages, suppressed),
187 filterCfg, checkCfg
188 );
189 }
190
191 @Test
192 public void testSuppressionCommentsInJavaScriptFile() throws Exception {
193 final String[] suppressed = {
194 "22: " + getCheckMessage(RegexpSinglelineCheck.class,
195 MSG_REGEXP_EXCEEDED, ".*\\s===.*"),
196 };
197
198 final String[] violationMessages = {
199 "22: " + getCheckMessage(RegexpSinglelineCheck.class,
200 MSG_REGEXP_EXCEEDED, ".*\\s===.*"),
201 "25: " + getCheckMessage(RegexpSinglelineCheck.class,
202 MSG_REGEXP_EXCEEDED, ".*\\s===.*"),
203 };
204
205 verifyFilterWithInlineConfigParser(
206 getPath("InputSuppressWithPlainTextCommentFilter.js"),
207 violationMessages,
208 removeSuppressed(violationMessages, suppressed)
209 );
210 }
211
212 @Test
213 public void testInvalidCheckFormat() {
214 final DefaultConfiguration filterCfg =
215 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
216 filterCfg.addProperty("checkFormat", "e[l");
217 filterCfg.addProperty("onCommentFormat", "// cs-on");
218 filterCfg.addProperty("offCommentFormat", "// cs-off");
219
220 final DefaultConfiguration checkCfg = createModuleConfig(FileTabCharacterCheck.class);
221 checkCfg.addProperty("eachLine", "true");
222
223 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
224
225 final String[] violationMessages = {
226 "5:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_FILE_CONTAINS_TAB),
227 "8:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
228 "10:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
229 };
230
231 final CheckstyleException exc = getExpectedThrowable(
232 CheckstyleException.class,
233 () -> {
234 verifySuppressed(
235 "InputSuppressWithPlainTextCommentFilterWithCustomOnAndOffComments.java",
236 removeSuppressed(violationMessages, suppressed),
237 filterCfg, checkCfg
238 );
239 });
240 final IllegalArgumentException cause = (IllegalArgumentException) exc.getCause();
241 assertWithMessage("Invalid exception message")
242 .that(cause)
243 .hasMessageThat()
244 .isEqualTo("unable to parse expanded comment e[l");
245 }
246
247 @Test
248 public void testInvalidIdFormat() {
249 final DefaultConfiguration filterCfg =
250 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
251 filterCfg.addProperty("idFormat", "e[l");
252 filterCfg.addProperty("onCommentFormat", "// cs-on");
253 filterCfg.addProperty("offCommentFormat", "// cs-off");
254
255 final DefaultConfiguration checkCfg = createModuleConfig(FileTabCharacterCheck.class);
256 checkCfg.addProperty("eachLine", "true");
257
258 final CheckstyleException exc = getExpectedThrowable(
259 CheckstyleException.class,
260 () -> {
261 verifySuppressed(
262 "InputSuppressWithPlainTextCommentFilterWithCustomOnAndOffComments.java",
263 CommonUtil.EMPTY_STRING_ARRAY, filterCfg, checkCfg
264 );
265 });
266 final IllegalArgumentException cause = (IllegalArgumentException) exc.getCause();
267 assertWithMessage("Invalid exception message")
268 .that(cause)
269 .hasMessageThat()
270 .isEqualTo("unable to parse expanded comment e[l");
271 }
272
273 @Test
274 public void testInvalidMessageFormat() {
275 final DefaultConfiguration filterCfg =
276 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
277 filterCfg.addProperty("messageFormat", "e[l");
278 filterCfg.addProperty("onCommentFormat", "// cs-on");
279 filterCfg.addProperty("offCommentFormat", "// cs-off");
280
281 final DefaultConfiguration checkCfg = createModuleConfig(FileTabCharacterCheck.class);
282 checkCfg.addProperty("eachLine", "true");
283
284 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
285
286 final String[] violationMessages = {
287 "5:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_FILE_CONTAINS_TAB),
288 "8:7: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
289 "10:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
290 };
291
292 final CheckstyleException exc = getExpectedThrowable(
293 CheckstyleException.class,
294 () -> {
295 verifySuppressed(
296 "InputSuppressWithPlainTextCommentFilterWithCustomOnAndOffComments.java",
297 removeSuppressed(violationMessages, suppressed),
298 filterCfg, checkCfg
299 );
300 });
301 final IllegalArgumentException cause = (IllegalArgumentException) exc.getCause();
302 assertWithMessage("Invalid exception message")
303 .that(cause)
304 .hasMessageThat()
305 .isEqualTo("unable to parse expanded comment e[l");
306 }
307
308 @Test
309 public void testInvalidMessageFormatInSqlFile() {
310 final DefaultConfiguration filterCfg =
311 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
312 filterCfg.addProperty("onCommentFormat", "CSON (\\w+)");
313 filterCfg.addProperty("messageFormat", "e[l");
314
315 final DefaultConfiguration checkCfg = createModuleConfig(RegexpSinglelineCheck.class);
316 checkCfg.addProperty("format", "^.*COUNT\\(\\*\\).*$");
317
318 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
319
320 final String[] violationMessages = {
321 "2: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
322 "^.*COUNT\\(\\*\\).*$"),
323 };
324
325 final CheckstyleException exc = getExpectedThrowable(
326 CheckstyleException.class,
327 () -> {
328 verifySuppressed(
329 "InputSuppressWithPlainTextCommentFilterWithCustomOnComment.sql",
330 removeSuppressed(violationMessages, suppressed),
331 filterCfg, checkCfg
332 );
333 });
334 final IllegalArgumentException cause = (IllegalArgumentException) exc.getCause();
335 assertWithMessage("Invalid exception message")
336 .that(cause)
337 .hasMessageThat()
338 .isEqualTo("unable to parse expanded comment e[l");
339 }
340
341 @Test
342 public void testAcceptNullViolation() {
343 final SuppressWithPlainTextCommentFilter filter = new SuppressWithPlainTextCommentFilter();
344 final AuditEvent auditEvent = new AuditEvent(this);
345 assertWithMessage("Filter should accept audit event")
346 .that(filter.accept(auditEvent))
347 .isTrue();
348 assertWithMessage("File name should not be null")
349 .that(auditEvent.getFileName())
350 .isNull();
351 }
352
353
354
355
356
357
358 @Test
359 public void testEqualsAndHashCodeOfSuppressionClass() throws ClassNotFoundException {
360 final Class<?> suppressionClass = TestUtil.getInnerClassType(
361 SuppressWithPlainTextCommentFilter.class, "Suppression");
362 final EqualsVerifierReport ev = EqualsVerifier
363 .forClass(suppressionClass).usingGetClass()
364 .report();
365 assertWithMessage("Error: %s", ev.getMessage())
366 .that(ev.isSuccessful())
367 .isTrue();
368 }
369
370
371
372
373
374
375
376
377 @Test
378 public void testCachingExecution() throws Exception {
379 final SuppressWithPlainTextCommentFilter filter = new SuppressWithPlainTextCommentFilter();
380 final String inputPath =
381 getPath("InputSuppressWithPlainTextCommentFilterCustomMessageFormat.java");
382 final File tempFile = new File(temporaryFolder,
383 "InputSuppressWithPlainTextCommentFilterCustomMessageFormat.java");
384 Files.copy(new File(inputPath).toPath(), tempFile.toPath(),
385 StandardCopyOption.REPLACE_EXISTING);
386
387 final AuditEvent auditEvent1 = new AuditEvent(
388 tempFile.getPath(), tempFile.getPath(),
389 new Violation(1, null, null, null, null,
390 Object.class, null)
391 );
392 filter.accept(auditEvent1);
393 final boolean deleted = tempFile.delete();
394 assertWithMessage("Temporary file should be deleted.")
395 .that(deleted).isTrue();
396 final AuditEvent auditEvent2 = new AuditEvent(
397 tempFile.getPath(), tempFile.getPath(),
398 new Violation(2, null, null, null, null,
399 Object.class, null)
400 );
401 filter.accept(auditEvent2);
402
403 assertWithMessage("Cache should handle missing file.")
404 .that(tempFile.exists()).isFalse();
405 }
406
407
408
409
410
411
412
413
414
415 @Test
416 public void testSuppressionsAreClearedEachRun() throws IOException {
417 final SuppressWithPlainTextCommentFilter filter = new SuppressWithPlainTextCommentFilter();
418 final Violation violation = new Violation(1, null, null,
419 null, null, Object.class, null);
420
421 final String fileName1 = getPath(
422 "InputSuppressWithPlainTextCommentFilterCustomMessageFormat.java");
423 final AuditEvent event1 = new AuditEvent("", fileName1, violation);
424 filter.accept(event1);
425
426 final List<?> suppressions1 = getSuppressionsAfterExecution(filter);
427 assertWithMessage("Invalid suppressions size")
428 .that(suppressions1)
429 .hasSize(4);
430
431 final String fileName2 = getPath(
432 "InputSuppressWithPlainTextCommentFilterWithDefaultCfg.java");
433 final AuditEvent event2 = new AuditEvent("", fileName2, violation);
434 filter.accept(event2);
435
436 final List<?> suppressions2 = getSuppressionsAfterExecution(filter);
437 assertWithMessage("Invalid suppressions size")
438 .that(suppressions2)
439 .hasSize(6);
440 }
441
442 @Test
443 public void testSuppressByCheck() throws Exception {
444 final String[] suppressedViolationMessages = {
445 "36:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
446 };
447
448 final String[] expectedViolationMessages = {
449 "33: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
450 ".*[a-zA-Z][0-9].*"),
451 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
452 ".*[a-zA-Z][0-9].*"),
453 "36:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
454 "38: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
455 ".*[a-zA-Z][0-9].*"),
456 "41: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
457 ".*[a-zA-Z][0-9].*"),
458 };
459
460 verifyFilterWithInlineConfigParser(
461 getPath("InputSuppressWithPlainTextCommentFilterSuppressById.java"),
462 expectedViolationMessages,
463 removeSuppressed(expectedViolationMessages, suppressedViolationMessages)
464 );
465 }
466
467 @Test
468 public void testSuppressByModuleId() throws Exception {
469 final String[] suppressedViolationMessages = {
470 "33: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
471 ".*[a-zA-Z][0-9].*"),
472 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
473 ".*[a-zA-Z][0-9].*"),
474 "38: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
475 ".*[a-zA-Z][0-9].*"),
476 };
477
478 final String[] expectedViolationMessages = {
479 "30: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
480 ".*[a-zA-Z][0-9].*"),
481 "33: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
482 ".*[a-zA-Z][0-9].*"),
483 "36:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
484 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
485 ".*[a-zA-Z][0-9].*"),
486 "38: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
487 ".*[a-zA-Z][0-9].*"),
488 "41: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
489 ".*[a-zA-Z][0-9].*"),
490 };
491
492 verifyFilterWithInlineConfigParser(
493 getPath("InputSuppressWithPlainTextCommentFilterSuppressById2.java"),
494 expectedViolationMessages,
495 removeSuppressed(expectedViolationMessages, suppressedViolationMessages)
496 );
497 }
498
499 @Test
500 public void testSuppressByCheckAndModuleId() throws Exception {
501 final String[] suppressedViolationMessages = {
502 "36:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
503 };
504
505 final String[] expectedViolationMessages = {
506 "30: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
507 ".*[a-zA-Z][0-9].*"),
508 "33: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
509 ".*[a-zA-Z][0-9].*"),
510 "36:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
511 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
512 ".*[a-zA-Z][0-9].*"),
513 "38: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
514 ".*[a-zA-Z][0-9].*"),
515 "41: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
516 ".*[a-zA-Z][0-9].*"),
517 };
518
519 verifyFilterWithInlineConfigParser(
520 getPath("InputSuppressWithPlainTextCommentFilterSuppressById3.java"),
521 expectedViolationMessages,
522 removeSuppressed(expectedViolationMessages, suppressedViolationMessages)
523 );
524 }
525
526 @Test
527 public void testSuppressByCheckAndNonMatchingModuleId() throws Exception {
528 final String[] suppressedViolationMessages = CommonUtil.EMPTY_STRING_ARRAY;
529
530 final String[] expectedViolationMessages = {
531 "30: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
532 ".*[a-zA-Z][0-9].*"),
533 "33: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
534 ".*[a-zA-Z][0-9].*"),
535 "36:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
536 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
537 ".*[a-zA-Z][0-9].*"),
538 "38: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
539 ".*[a-zA-Z][0-9].*"),
540 "41: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
541 ".*[a-zA-Z][0-9].*"),
542 };
543
544 verifyFilterWithInlineConfigParser(
545 getPath("InputSuppressWithPlainTextCommentFilterSuppressById4.java"),
546 expectedViolationMessages,
547 removeSuppressed(expectedViolationMessages, suppressedViolationMessages)
548 );
549 }
550
551 @Test
552 public void testSuppressByModuleIdWithNullModuleId() throws Exception {
553 final String[] suppressedViolationMessages = {
554 "33: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
555 ".*[a-zA-Z][0-9].*"),
556 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
557 ".*[a-zA-Z][0-9].*"),
558 "38: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
559 ".*[a-zA-Z][0-9].*"),
560 };
561
562 final String[] expectedViolationMessages = {
563 "30: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
564 ".*[a-zA-Z][0-9].*"),
565 "33: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
566 ".*[a-zA-Z][0-9].*"),
567 "36:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
568 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
569 ".*[a-zA-Z][0-9].*"),
570 "38: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
571 ".*[a-zA-Z][0-9].*"),
572 "41: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
573 ".*[a-zA-Z][0-9].*"),
574 };
575
576 verifyFilterWithInlineConfigParser(
577 getPath("InputSuppressWithPlainTextCommentFilterSuppressById5.java"),
578 expectedViolationMessages,
579 removeSuppressed(expectedViolationMessages, suppressedViolationMessages)
580 );
581 }
582
583 @Test
584 public void testSuppressedByIdJavadocCheck() throws Exception {
585 final String[] suppressedViolationMessages = {
586 "29: " + getCheckMessage(JavadocMethodCheck.class, MSG_RETURN_EXPECTED),
587 "33:9: " + getCheckMessage(JavadocMethodCheck.class,
588 MSG_UNUSED_TAG, "@param", "unused"),
589 "40:22: " + getCheckMessage(JavadocMethodCheck.class,
590 MSG_EXPECTED_TAG, "@param", "a"),
591 };
592
593 final String[] expectedViolationMessages = {
594 "29: " + getCheckMessage(JavadocMethodCheck.class, MSG_RETURN_EXPECTED),
595 "33:9: " + getCheckMessage(JavadocMethodCheck.class,
596 MSG_UNUSED_TAG, "@param", "unused"),
597 "40:22: " + getCheckMessage(JavadocMethodCheck.class,
598 MSG_EXPECTED_TAG, "@param", "a"),
599 };
600
601 verifyFilterWithInlineConfigParser(
602 getPath("InputSuppressWithPlainTextCommentFilterSuppressByIdJavadocCheck.java"),
603 expectedViolationMessages,
604 removeSuppressed(expectedViolationMessages, suppressedViolationMessages)
605 );
606 }
607
608 @Test
609 public void testAcceptThrowsIllegalStateExceptionAsFileNotFound() {
610 final Violation message = new Violation(1, 1, 1, TokenTypes.CLASS_DEF,
611 "messages.properties", "key", null, SeverityLevel.ERROR, null, getClass(), null);
612 final String fileName = "nonexisting_file";
613 final AuditEvent auditEvent = new AuditEvent(this, fileName, message);
614
615 final SuppressWithPlainTextCommentFilter filter = new SuppressWithPlainTextCommentFilter();
616
617 final IllegalStateException exc = getExpectedThrowable(
618 IllegalStateException.class,
619 () -> {
620 filter.accept(auditEvent);
621 });
622 assertWithMessage("Invalid exception message")
623 .that(exc.getMessage())
624 .isEqualTo("Cannot read source file: " + fileName);
625
626 final Throwable cause = exc.getCause();
627 assertWithMessage("Exception cause has invalid type")
628 .that(cause)
629 .isInstanceOf(FileNotFoundException.class);
630 assertWithMessage("Invalid exception message")
631 .that(cause)
632 .hasMessageThat()
633 .isEqualTo(fileName + " (No such file or directory)");
634 }
635
636 @Test
637 public void testFilterWithCustomMessageFormat() throws Exception {
638 final String[] suppressed = {
639 "34:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
640 };
641
642 final String[] violationMessages = {
643 "32: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
644 ".*[a-zA-Z][0-9].*"),
645 "34:1: " + getCheckMessage(FileTabCharacterCheck.class, MSG_CONTAINS_TAB),
646 "34: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
647 ".*[a-zA-Z][0-9].*"),
648 "36: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
649 ".*[a-zA-Z][0-9].*"),
650 "39: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
651 ".*[a-zA-Z][0-9].*"),
652 };
653
654 verifyFilterWithInlineConfigParser(
655 getPath("InputSuppressWithPlainTextCommentFilterCustomMessageFormat.java"),
656 violationMessages, removeSuppressed(violationMessages, suppressed)
657 );
658 }
659
660 @Test
661 public void testFilterWithIdAndCustomMessageFormat() throws Exception {
662 final DefaultConfiguration filterCfg =
663 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
664 filterCfg.addProperty("offCommentFormat", "CHECKSTYLE stop (\\w+) (\\w+)");
665 filterCfg.addProperty("onCommentFormat", "CHECKSTYLE resume (\\w+) (\\w+)");
666 filterCfg.addProperty("idFormat", "$1");
667 filterCfg.addProperty("messageFormat", "$2");
668
669 final DefaultConfiguration regexpCheckCfg = createModuleConfig(RegexpSinglelineCheck.class);
670 regexpCheckCfg.addProperty("id", "warning");
671 regexpCheckCfg.addProperty("format", "^.*COUNT\\(\\*\\).*$");
672
673 final String[] suppressedViolationMessages = {
674 "2: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
675 "^.*COUNT\\(\\*\\).*$"),
676 };
677
678 final String[] expectedViolationMessages = {
679 "2: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
680 "^.*COUNT\\(\\*\\).*$"),
681 "5: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
682 "^.*COUNT\\(\\*\\).*$"),
683 "8: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
684 "^.*COUNT\\(\\*\\).*$"),
685 };
686
687 verifySuppressed(
688 "InputSuppressWithPlainTextCommentFilterCustomMessageFormat.sql",
689 removeSuppressed(expectedViolationMessages, suppressedViolationMessages),
690 filterCfg, regexpCheckCfg
691 );
692 }
693
694 @Test
695 public void testFilterWithCheckAndCustomMessageFormat() throws Exception {
696 final DefaultConfiguration filterCfg =
697 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
698 filterCfg.addProperty("offCommentFormat", "CHECKSTYLE stop (\\w+) (\\w+)");
699 filterCfg.addProperty("onCommentFormat", "CHECKSTYLE resume (\\w+) (\\w+)");
700 filterCfg.addProperty("checkFormat", "RegexpSinglelineCheck");
701 filterCfg.addProperty("messageFormat", "$2");
702
703 final DefaultConfiguration regexpCheckCfg = createModuleConfig(RegexpSinglelineCheck.class);
704 regexpCheckCfg.addProperty("id", "warning");
705 regexpCheckCfg.addProperty("format", "^.*COUNT\\(\\*\\).*$");
706
707 final String[] suppressedViolationMessages = {
708 "2: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
709 "^.*COUNT\\(\\*\\).*$"),
710 };
711
712 final String[] expectedViolationMessages = {
713 "2: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
714 "^.*COUNT\\(\\*\\).*$"),
715 "5: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
716 "^.*COUNT\\(\\*\\).*$"),
717 "8: " + getCheckMessage(RegexpSinglelineCheck.class, MSG_REGEXP_EXCEEDED,
718 "^.*COUNT\\(\\*\\).*$"),
719 };
720
721 verifySuppressed(
722 "InputSuppressWithPlainTextCommentFilterCustomMessageFormat.sql",
723 removeSuppressed(expectedViolationMessages, suppressedViolationMessages),
724 filterCfg, regexpCheckCfg
725 );
726 }
727
728 @Test
729 public void testCheckFormatAnchoredToIndentationCheckFqcn() throws Exception {
730 final DefaultConfiguration filterCfg =
731 createModuleConfig(SuppressWithPlainTextCommentFilter.class);
732 filterCfg.addProperty("checkFormat", "\\.IndentationCheck$");
733 filterCfg.addProperty("offCommentFormat", "CSOFF");
734 filterCfg.addProperty("onCommentFormat", "CSON");
735
736 final DefaultConfiguration twCfg =
737 createModuleConfig(TreeWalker.class);
738 twCfg.addChild(createModuleConfig(IndentationCheck.class));
739 twCfg.addChild(createModuleConfig(CommentsIndentationCheck.class));
740
741 final DefaultConfiguration checkerConfig = createRootConfig(null);
742 checkerConfig.addProperty("fileExtensions", "java");
743 checkerConfig.addChild(filterCfg);
744 checkerConfig.addChild(twCfg);
745
746 final String[] expected = {
747 "5:5: " + getCheckMessage(CommentsIndentationCheck.class, MSG_KEY_SINGLE, 6, 4, 0),
748 };
749
750 verify(checkerConfig,
751 getPath("InputSuppressWithPlainTextCommentFilterIndentationAnchored.java"),
752 expected);
753 }
754
755 @Test
756 public void testFilterWithDirectory() throws IOException {
757 final SuppressWithPlainTextCommentFilter filter = new SuppressWithPlainTextCommentFilter();
758 final AuditEvent event = new AuditEvent(this, getPath(""), new Violation(1, 1,
759 "bundle", "key", null, SeverityLevel.ERROR, "moduleId", getClass(),
760 "customMessage"));
761
762 assertWithMessage("filter should accept directory")
763 .that(filter.accept(event))
764 .isTrue();
765 }
766
767 private static List<?> getSuppressionsAfterExecution(
768 SuppressWithPlainTextCommentFilter filter) {
769 return TestUtil.getInternalState(filter, "currentFileSuppressionCache", List.class);
770 }
771
772 private void verifySuppressed(String fileNameWithExtension, String[] violationMessages,
773 Configuration... childConfigs) throws Exception {
774 final DefaultConfiguration checkerConfig = createRootConfig(null);
775
776 Arrays.stream(childConfigs).forEach(checkerConfig::addChild);
777
778 final String fileExtension = CommonUtil.getFileExtension(fileNameWithExtension);
779 checkerConfig.addProperty("fileExtensions", fileExtension);
780
781 verify(checkerConfig, getPath(fileNameWithExtension), violationMessages);
782 }
783
784 }