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.naming.AbstractNameCheck.MSG_INVALID_PATTERN;
24 import static com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck.MSG_KEY;
25
26 import java.io.FileNotFoundException;
27 import java.io.IOException;
28 import java.util.List;
29
30 import org.junit.jupiter.api.Test;
31
32 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
33 import com.puppycrawl.tools.checkstyle.api.AuditEvent;
34 import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
35 import com.puppycrawl.tools.checkstyle.api.SeverityLevel;
36 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
37 import com.puppycrawl.tools.checkstyle.api.Violation;
38 import com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck;
39 import com.puppycrawl.tools.checkstyle.checks.naming.ConstantNameCheck;
40 import com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineCheck;
41 import com.puppycrawl.tools.checkstyle.checks.sizes.LineLengthCheck;
42 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
43
44 public class SuppressWithNearbyTextFilterTest extends AbstractModuleTestSupport {
45
46 private static final String REGEXP_SINGLELINE_CHECK_FORMAT = "this should not appear";
47
48 @Override
49 protected String getPackageLocation() {
50 return "com/puppycrawl/tools/checkstyle/filters/suppresswithnearbytextfilter";
51 }
52
53 @Test
54 public void testDefaultConfig() throws Exception {
55 final int expectedLineLength = 90;
56 final String pattern = "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$";
57
58 final String[] violationMessages = {
59 "29: " + getLineLengthCheckMessage(expectedLineLength, 94),
60 "31: " + getLineLengthCheckMessage(expectedLineLength, 97),
61 "41: " + getLineLengthCheckMessage(expectedLineLength, 94),
62 "44:22: " + getCheckMessage(ConstantNameCheck.class,
63 MSG_INVALID_PATTERN, "badConstant", pattern),
64 "47:22: " + getCheckMessage(ConstantNameCheck.class,
65 MSG_INVALID_PATTERN, "badConstant1", pattern),
66 };
67
68 final String[] suppressedMessages = {
69 "31: " + getLineLengthCheckMessage(expectedLineLength, 97),
70 "41: " + getLineLengthCheckMessage(expectedLineLength, 94),
71 "47:22: " + getCheckMessage(ConstantNameCheck.class,
72 MSG_INVALID_PATTERN, "badConstant1", pattern),
73 };
74
75 verifyFilterWithInlineConfigParser(
76 getPath("InputSuppressWithNearbyTextFilterDefaultConfig.java"),
77 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
78 );
79 }
80
81 @Test
82 public void testNearbyTextPattern() throws Exception {
83 final int expectedLineLength = 90;
84
85 final String[] violationMessages = {
86 "15: " + getRegexpSinglelineCheckMessage(),
87 "28: " + getLineLengthCheckMessage(expectedLineLength, 94),
88 "33: " + getLineLengthCheckMessage(expectedLineLength, 93),
89 "33: " + getRegexpSinglelineCheckMessage(),
90 "39: " + getLineLengthCheckMessage(expectedLineLength, 93),
91 "44: " + getRegexpSinglelineCheckMessage(),
92 "49: " + getLineLengthCheckMessage(expectedLineLength, 95),
93 "54: " + getRegexpSinglelineCheckMessage(),
94 "58: " + getLineLengthCheckMessage(expectedLineLength, 97),
95 };
96
97 final String[] suppressedMessages = {
98 "33: " + getLineLengthCheckMessage(expectedLineLength, 93),
99 "33: " + getRegexpSinglelineCheckMessage(),
100 "39: " + getLineLengthCheckMessage(expectedLineLength, 93),
101 "49: " + getLineLengthCheckMessage(expectedLineLength, 95),
102 "54: " + getRegexpSinglelineCheckMessage(),
103 "58: " + getLineLengthCheckMessage(expectedLineLength, 97),
104 };
105
106 verifyFilterWithInlineConfigParser(
107 getPath("InputSuppressWithNearbyTextFilterNearbyTextPattern.css"),
108 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
109 );
110 }
111
112 @Test
113 public void testCheckPattern() throws Exception {
114 final int expectedLineLength = 80;
115
116 final String[] violationMessages = {
117 "15: " + getRegexpSinglelineCheckMessage(),
118 "28: " + getLineLengthCheckMessage(expectedLineLength, 89),
119 "29: " + getRegexpSinglelineCheckMessage(),
120 "35: " + getLineLengthCheckMessage(expectedLineLength, 87),
121 };
122
123 final String[] suppressedMessages = {
124 "28: " + getLineLengthCheckMessage(expectedLineLength, 89),
125 "35: " + getLineLengthCheckMessage(expectedLineLength, 87),
126 };
127
128 verifyFilterWithInlineConfigParser(
129 getPath("InputSuppressWithNearbyTextFilterCheckPattern.bash"),
130 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
131 );
132 }
133
134 @Test
135 public void testMessagePattern() throws Exception {
136 final int expectedLineLength = 90;
137
138 final String[] violationMessages = {
139 "15: " + getRegexpSinglelineCheckMessage(),
140 "33: " + getRegexpSinglelineCheckMessage(),
141 "38: " + getLineLengthCheckMessage(expectedLineLength, 98),
142 "42: " + getLineLengthCheckMessage(expectedLineLength, 96),
143 };
144
145 final String[] suppressedMessages = {
146 "38: " + getLineLengthCheckMessage(expectedLineLength, 98),
147 "42: " + getLineLengthCheckMessage(expectedLineLength, 96),
148 };
149
150 verifyFilterWithInlineConfigParser(
151 getPath("InputSuppressWithNearbyTextFilterMessagePattern.xml"),
152 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
153 );
154 }
155
156 @Test
157 public void testIdPattern() throws Exception {
158 final int expectedLineLength = 80;
159
160 final String[] violationMessages = {
161 "16: " + getRegexpSinglelineCheckMessage(),
162 "29: " + getRegexpSinglelineCheckMessage(),
163 "34: " + getLineLengthCheckMessage(expectedLineLength, 83),
164 "38: " + getLineLengthCheckMessage(expectedLineLength, 84),
165 };
166
167 final String[] suppressedMessages = {
168 "34: " + getLineLengthCheckMessage(expectedLineLength, 83),
169 "38: " + getLineLengthCheckMessage(expectedLineLength, 84),
170 };
171
172 verifyFilterWithInlineConfigParser(
173 getPath("InputSuppressWithNearbyTextFilterIdPattern.html"),
174 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
175 );
176 }
177
178 @Test
179 public void testLineRangePositive3() throws Exception {
180 final int expectedLineLength = 92;
181
182 final String[] violationMessages = {
183 "15: " + getRegexpSinglelineCheckMessage(),
184 "27: " + getLineLengthCheckMessage(expectedLineLength, 98),
185 "28: " + getLineLengthCheckMessage(expectedLineLength, 98),
186 "29: " + getLineLengthCheckMessage(expectedLineLength, 98),
187 "30: " + getLineLengthCheckMessage(expectedLineLength, 93),
188 "33: " + getRegexpSinglelineCheckMessage(),
189 "34: " + getRegexpSinglelineCheckMessage(),
190 "35: " + getRegexpSinglelineCheckMessage(),
191 "36: " + getRegexpSinglelineCheckMessage(),
192 };
193
194 final String[] suppressedMessages = {
195 "27: " + getLineLengthCheckMessage(expectedLineLength, 98),
196 "28: " + getLineLengthCheckMessage(expectedLineLength, 98),
197 "29: " + getLineLengthCheckMessage(expectedLineLength, 98),
198 "33: " + getRegexpSinglelineCheckMessage(),
199 "34: " + getRegexpSinglelineCheckMessage(),
200 "35: " + getRegexpSinglelineCheckMessage(),
201 "36: " + getRegexpSinglelineCheckMessage(),
202 };
203
204 verifyFilterWithInlineConfigParser(
205 getPath("InputSuppressWithNearbyTextFilterLineRangePositive3.sql"),
206 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
207 );
208 }
209
210 @Test
211 public void testLineRangeNegative2() throws Exception {
212 final int expectedLineLength = 91;
213
214 final String[] violationMessages = {
215 "15: " + getRegexpSinglelineCheckMessage(),
216 "27: " + getLineLengthCheckMessage(expectedLineLength, 96),
217 "28: " + getLineLengthCheckMessage(expectedLineLength, 94),
218 "29: " + getLineLengthCheckMessage(expectedLineLength, 94),
219 "30: " + getLineLengthCheckMessage(expectedLineLength, 98),
220 "33: " + getRegexpSinglelineCheckMessage(),
221 "34: " + getRegexpSinglelineCheckMessage(),
222 "35: " + getRegexpSinglelineCheckMessage(),
223 "36: " + getRegexpSinglelineCheckMessage(),
224 };
225
226 final String[] suppressedMessages = {
227 "28: " + getLineLengthCheckMessage(expectedLineLength, 94),
228 "29: " + getLineLengthCheckMessage(expectedLineLength, 94),
229 "30: " + getLineLengthCheckMessage(expectedLineLength, 98),
230 "34: " + getRegexpSinglelineCheckMessage(),
231 "35: " + getRegexpSinglelineCheckMessage(),
232 "36: " + getRegexpSinglelineCheckMessage(),
233 };
234
235 verifyFilterWithInlineConfigParser(
236 getPath("InputSuppressWithNearbyTextFilterLineRangeNegative2.txt"),
237 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
238 );
239 }
240
241 @Test
242 public void testVariableCheckPatternAndLineRange() throws Exception {
243 final int expectedLineLength = 85;
244
245 final String[] violationMessages = {
246 "19: " + getLineLengthCheckMessage(expectedLineLength, 89),
247 "20: " + getLineLengthCheckMessage(expectedLineLength, 89),
248 "21: " + getLineLengthCheckMessage(expectedLineLength, 89),
249 "22: " + getLineLengthCheckMessage(expectedLineLength, 87),
250 "24: " + getLineLengthCheckMessage(expectedLineLength, 87),
251 "25: " + getLineLengthCheckMessage(expectedLineLength, 89),
252 "26: " + getLineLengthCheckMessage(expectedLineLength, 89),
253 };
254
255 final String[] suppressedMessages = {
256 "19: " + getLineLengthCheckMessage(expectedLineLength, 89),
257 "20: " + getLineLengthCheckMessage(expectedLineLength, 89),
258 "21: " + getLineLengthCheckMessage(expectedLineLength, 89),
259 "25: " + getLineLengthCheckMessage(expectedLineLength, 89),
260 "26: " + getLineLengthCheckMessage(expectedLineLength, 89),
261 };
262
263 verifyFilterWithInlineConfigParser(
264 getPath("InputSuppressWithNearbyTextFilter"
265 + "VariableNearbyTextPatternAndLineRange.xml"),
266 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
267 );
268 }
269
270 @Test
271 public void testNearbyTextPatternAny() throws Exception {
272 final int expectedLineLength = 76;
273
274 final String[] violationMessages = {
275 "18: " + getLineLengthCheckMessage(expectedLineLength, 80),
276 };
277
278 final String[] suppressedMessages = {
279 "18: " + getLineLengthCheckMessage(expectedLineLength, 80),
280 };
281
282 verifyFilterWithInlineConfigParser(
283 getPath("InputSuppressWithNearbyTextFilterNearbyTextPatternAny.txt"),
284 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
285 );
286 }
287
288 @Test
289 public void testNearbyTextPatternCompactVariableCheckPattern() throws Exception {
290 final String[] violationMessages = {
291 "26:13: " + getCheckMessage(MagicNumberCheck.class, MagicNumberCheck.MSG_KEY, "42"),
292 "27:13: " + getCheckMessage(MagicNumberCheck.class, MagicNumberCheck.MSG_KEY, "43"),
293 };
294
295 final String[] suppressedMessages = {
296 "26:13: " + getCheckMessage(MagicNumberCheck.class, MagicNumberCheck.MSG_KEY, "42"),
297 };
298
299 verifyFilterWithInlineConfigParser(
300 getPath("InputSuppressWithNearbyTextFilterNearbyTextPattern"
301 + "CompactVariableCheckPattern.java"),
302 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
303 );
304 }
305
306 @Test
307 public void testNearbyTextPatternUrlLineLengthSuppression() throws Exception {
308 final int expectedLineLength = 90;
309
310 final String[] violationMessages = {
311 "32: " + getLineLengthCheckMessage(expectedLineLength, 98),
312 "39: " + getLineLengthCheckMessage(expectedLineLength, 97),
313 };
314
315 final String[] suppressedMessages = {
316 "32: " + getLineLengthCheckMessage(expectedLineLength, 98),
317 "39: " + getLineLengthCheckMessage(expectedLineLength, 97),
318 };
319
320 verifyFilterWithInlineConfigParser(
321 getPath("InputSuppressWithNearbyTextFilterNearbyTextPatternUrlLineLengthSuppression"
322 + ".java"),
323 violationMessages, removeSuppressed(violationMessages, suppressedMessages)
324 );
325 }
326
327 @Test
328 public void testInvalidCheckPattern() throws Exception {
329 final String[] violationAndSuppressedMessages = {
330 "18: " + getLineLengthCheckMessage(80, 93),
331 };
332
333 try {
334 verifyFilterWithInlineConfigParser(
335 getPath("InputSuppressWithNearbyTextFilterInvalidCheckPattern.txt"),
336 violationAndSuppressedMessages
337 );
338 assertWithMessage("CheckstyleException is expected").fail();
339 }
340 catch (CheckstyleException ex) {
341 final IllegalArgumentException cause = (IllegalArgumentException) ex.getCause();
342 assertWithMessage("Invalid exception message")
343 .that(cause)
344 .hasMessageThat()
345 .isEqualTo("unable to parse expanded comment a![b");
346 }
347 }
348
349 @Test
350 public void testInvalidIdPattern() throws Exception {
351 final String[] violationAndSuppressedMessages = {
352 "18: " + getLineLengthCheckMessage(80, 93),
353 };
354
355 try {
356 verifyFilterWithInlineConfigParser(
357 getPath("InputSuppressWithNearbyTextFilterInvalidIdPattern.txt"),
358 violationAndSuppressedMessages
359 );
360 assertWithMessage("CheckstyleException is expected").fail();
361 }
362 catch (CheckstyleException ex) {
363 final IllegalArgumentException cause = (IllegalArgumentException) ex.getCause();
364 assertWithMessage("Invalid exception message")
365 .that(cause)
366 .hasMessageThat()
367 .isEqualTo("unable to parse expanded comment a![b");
368 }
369 }
370
371 @Test
372 public void testInvalidMessagePattern() throws Exception {
373 final String[] violationAndSuppressedMessages = {
374 "18: " + getLineLengthCheckMessage(80, 93),
375 };
376
377 try {
378 verifyFilterWithInlineConfigParser(
379 getPath("InputSuppressWithNearbyTextFilterInvalidMessagePattern.txt"),
380 violationAndSuppressedMessages
381 );
382 assertWithMessage("CheckstyleException is expected").fail();
383 }
384 catch (CheckstyleException ex) {
385 final IllegalArgumentException cause = (IllegalArgumentException) ex.getCause();
386 assertWithMessage("Invalid exception message")
387 .that(cause)
388 .hasMessageThat()
389 .isEqualTo("unable to parse expanded comment a![b");
390 }
391 }
392
393 @Test
394 public void testInvalidLineRange() throws Exception {
395 final String[] violationAndSuppressedMessages = {
396 "18: " + getLineLengthCheckMessage(80, 93),
397 };
398
399 try {
400 verifyFilterWithInlineConfigParser(
401 getPath("InputSuppressWithNearbyTextFilterInvalidLineRange.txt"),
402 violationAndSuppressedMessages
403 );
404 assertWithMessage("CheckstyleException is expected").fail();
405 }
406 catch (CheckstyleException ex) {
407 assertWithMessage("Invalid exception message")
408 .that(ex)
409 .hasCauseThat()
410 .hasMessageThat()
411 .isEqualTo("unable to parse line range"
412 + " from 'SUPPRESS CHECKSTYLE LineLengthCheck' using a!b");
413 }
414 }
415
416
417
418
419
420
421 @Test
422 public void testAcceptNullViolation() {
423 final SuppressWithNearbyTextFilter filter = new SuppressWithNearbyTextFilter();
424 final AuditEvent auditEvent = new AuditEvent(this);
425 assertWithMessage("Filter should accept audit event")
426 .that(filter.accept(auditEvent))
427 .isTrue();
428 assertWithMessage("File name should not be null")
429 .that(auditEvent.getFileName())
430 .isNull();
431 }
432
433
434
435
436
437
438
439 @Test
440 public void testThrowsIllegalStateExceptionWhenFileNotFound() {
441 final Violation message = new Violation(1, 1, 1, TokenTypes.CLASS_DEF,
442 "messages.properties", "key", null, SeverityLevel.ERROR, null, getClass(), null);
443 final String fileName = "nonexisting_file";
444 final AuditEvent auditEvent = new AuditEvent(this, fileName, message);
445 final SuppressWithNearbyTextFilter filter = new SuppressWithNearbyTextFilter();
446
447 try {
448 filter.accept(auditEvent);
449 assertWithMessage(IllegalStateException.class.getSimpleName() + " is expected").fail();
450 }
451 catch (IllegalStateException ex) {
452 assertWithMessage("Invalid exception message")
453 .that(ex.getMessage())
454 .isEqualTo("Cannot read source file: " + fileName);
455
456 final Throwable cause = ex.getCause();
457 assertWithMessage("Exception cause has invalid type")
458 .that(cause)
459 .isInstanceOf(FileNotFoundException.class);
460 assertWithMessage("Invalid exception message")
461 .that(cause)
462 .hasMessageThat()
463 .isEqualTo(fileName + " (No such file or directory)");
464 }
465 }
466
467
468
469
470
471
472
473
474
475
476 @Test
477 public void testFilterWithDirectory() throws IOException {
478 final SuppressWithNearbyTextFilter filter = new SuppressWithNearbyTextFilter();
479 final AuditEvent event = new AuditEvent(this, getPath(""), new Violation(1, 1,
480 "bundle", "key", null, SeverityLevel.ERROR, "moduleId", getClass(),
481 "customMessage"));
482
483 assertWithMessage("filter should accept directory")
484 .that(filter.accept(event))
485 .isTrue();
486 }
487
488
489
490
491
492
493
494
495
496 @Test
497 public void testSuppressionsAreClearedEachRun() throws IOException {
498 final SuppressWithNearbyTextFilter filter = new SuppressWithNearbyTextFilter();
499
500 final List<?> suppressions1 = getSuppressionsAfterExecution(filter,
501 getPath("InputSuppressWithNearbyTextFilterDefaultConfig.java"));
502 assertWithMessage("Invalid suppressions size")
503 .that(suppressions1)
504 .hasSize(3);
505
506 final List<?> suppressions2 = getSuppressionsAfterExecution(filter,
507 getPath("InputSuppressWithNearbyTextFilterOneLineText.txt"));
508 assertWithMessage("Invalid suppressions size")
509 .that(suppressions2)
510 .isEmpty();
511 }
512
513
514
515
516
517
518
519
520
521 @Test
522 public void testCachedFileAbsolutePathHasChangedEachRun() throws IOException {
523 final SuppressWithNearbyTextFilter filter = new SuppressWithNearbyTextFilter();
524
525 final String cachedFileAbsolutePath1 = getCachedFileAbsolutePathAfterExecution(filter,
526 getPath("InputSuppressWithNearbyTextFilterDefaultConfig.java"));
527 final String cachedFileAbsolutePath2 = getCachedFileAbsolutePathAfterExecution(filter,
528 getPath("InputSuppressWithNearbyTextFilterOneLineText.txt"));
529
530 assertWithMessage("cachedFileAbsolutePath has not changed")
531 .that(cachedFileAbsolutePath1)
532 .isNotEqualTo(cachedFileAbsolutePath2);
533 }
534
535
536
537
538
539
540 private static List<?> getSuppressionsAfterExecution(SuppressWithNearbyTextFilter filter,
541 String filename) {
542 final AuditEvent dummyEvent = buildDummyAuditEvent(filename);
543 filter.accept(dummyEvent);
544 return TestUtil.getInternalState(filter, "suppressions");
545 }
546
547
548
549
550
551
552
553 private static String getCachedFileAbsolutePathAfterExecution(SuppressWithNearbyTextFilter
554 filter,
555 String filename) {
556 final AuditEvent dummyEvent = buildDummyAuditEvent(filename);
557 filter.accept(dummyEvent);
558 return TestUtil.getInternalState(filter, "cachedFileAbsolutePath");
559 }
560
561
562
563
564
565
566
567 private static AuditEvent buildDummyAuditEvent(String filename) {
568 final Violation violation = new Violation(1, null, null,
569 null, null, Object.class, null);
570 return new AuditEvent("", filename, violation);
571 }
572
573 private static String getLineLengthCheckMessage(int expectedLength, int actualLength) {
574 return getCheckMessage(LineLengthCheck.class, MSG_KEY, expectedLength, actualLength);
575 }
576
577 private static String getRegexpSinglelineCheckMessage() {
578 final String msgRegexExceeded = "regexp.exceeded";
579 return getCheckMessage(RegexpSinglelineCheck.class,
580 msgRegexExceeded, REGEXP_SINGLELINE_CHECK_FORMAT);
581 }
582 }