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.coding.MagicNumberCheck.MSG_KEY;
24 import static com.puppycrawl.tools.checkstyle.checks.javadoc.MissingJavadocMethodCheck.MSG_JAVADOC_MISSING;
25 import static com.puppycrawl.tools.checkstyle.checks.naming.AbstractNameCheck.MSG_INVALID_PATTERN;
26 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
27
28 import java.io.File;
29 import java.nio.charset.StandardCharsets;
30 import java.util.regex.Pattern;
31 import java.util.regex.PatternSyntaxException;
32
33 import org.junit.jupiter.api.Test;
34
35 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
36 import com.puppycrawl.tools.checkstyle.JavaParser;
37 import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent;
38 import com.puppycrawl.tools.checkstyle.api.FileContents;
39 import com.puppycrawl.tools.checkstyle.api.FileText;
40 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
41 import com.puppycrawl.tools.checkstyle.api.Violation;
42 import com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck;
43 import com.puppycrawl.tools.checkstyle.checks.javadoc.MissingJavadocTypeCheck;
44 import com.puppycrawl.tools.checkstyle.checks.naming.TypeNameCheck;
45 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
46
47 public class SuppressionXpathSingleFilterTest
48 extends AbstractModuleTestSupport {
49
50 @Override
51 public String getPackageLocation() {
52 return "com/puppycrawl/tools/checkstyle/filters/suppressionxpathsinglefilter";
53 }
54
55 @Test
56 public void testMatching() throws Exception {
57 final String[] expected = {
58 "20:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
59 };
60
61 final String[] suppressed = {
62 "20:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
63 };
64
65 verifyFilterWithInlineConfigParser(
66 getPath("InputSuppressionXpathSingleFilterMatchingTokenType.java"), expected,
67 removeSuppressed(expected, suppressed));
68 }
69
70 @Test
71 public void testNonMatchingTokenType() throws Exception {
72 final String[] expected = {
73 "20:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
74 };
75
76 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
77
78 verifyFilterWithInlineConfigParser(
79 getPath("InputSuppressionXpathSingleFilterNonMatchingTokenType.java"), expected,
80 removeSuppressed(expected, suppressed));
81 }
82
83 @Test
84 public void testNonMatchingLineNumber() throws Exception {
85 final String[] expected = {
86 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
87 "22:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
88 };
89
90 final String[] suppressed = {
91 "22:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
92 };
93
94 verifyFilterWithInlineConfigParser(
95 getPath("InputSuppressionXpathSingleFilterNonMatchingLineNumber.java"), expected,
96 removeSuppressed(expected, suppressed));
97 }
98
99 @Test
100 public void testNonMatchingColumnNumber() throws Exception {
101 final String[] expected = {
102 "23:11: " + getCheckMessage(TypeNameCheck.class, MSG_INVALID_PATTERN,
103 "testClass", "^[A-Z][a-zA-Z0-9]*$"),
104 "26:11: " + getCheckMessage(TypeNameCheck.class, MSG_INVALID_PATTERN,
105 "anotherTestClass", "^[A-Z][a-zA-Z0-9]*$"),
106 };
107 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
108
109 verifyFilterWithInlineConfigParser(
110 getPath("InputSuppressionXpathSingleFilterNonMatchingColumnNumber.java"), expected,
111 removeSuppressed(expected, suppressed));
112 }
113
114 @Test
115 public void testComplexQuery() throws Exception {
116 final String[] expected = {
117 "27:21: " + getCheckMessage(MagicNumberCheck.class, MSG_KEY, "3.14"),
118 "28:16: " + getCheckMessage(MagicNumberCheck.class, MSG_KEY, "123"),
119 "32:28: " + getCheckMessage(MagicNumberCheck.class, MSG_KEY, "123"),
120 };
121 final String[] suppressed = {
122 "27:21: " + getCheckMessage(MagicNumberCheck.class, MSG_KEY, "3.14"),
123 };
124 verifyFilterWithInlineConfigParser(
125 getPath("InputSuppressionXpathSingleFilterComplexQuery.java"), expected,
126 removeSuppressed(expected, suppressed));
127 }
128
129 @Test
130 public void testIncorrectQuery() {
131 final String xpath = "1@#";
132 final IllegalArgumentException exc = getExpectedThrowable(
133 IllegalArgumentException.class,
134 () -> {
135 createSuppressionXpathSingleFilter(
136 "InputSuppressionXpathSingleFilterComplexQuery", "Test",
137 null, null, xpath);
138 });
139 assertWithMessage("Message should be: Unexpected xpath query")
140 .that(exc.getMessage())
141 .contains("Incorrect xpath query");
142 }
143
144 @Test
145 public void testNoQuery() throws Exception {
146 final String[] expected = {
147 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
148 };
149
150 final String[] suppressed = {
151 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
152 };
153
154 verifyFilterWithInlineConfigParser(
155 getPath("InputSuppressionXpathSingleFilterNoQuery.java"), expected,
156 removeSuppressed(expected, suppressed));
157 }
158
159 @Test
160 public void testNullFileName() throws Exception {
161 final String[] expected = {
162 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
163 };
164
165 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
166
167 verifyFilterWithInlineConfigParser(
168 getPath("InputSuppressionXpathSingleFilterNullFileName.java"), expected,
169 removeSuppressed(expected, suppressed));
170 }
171
172 @Test
173 public void testNonMatchingFileRegexp() throws Exception {
174 final String[] expected = {
175 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
176 };
177
178 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
179
180 verifyFilterWithInlineConfigParser(
181 getPath("InputSuppressionXpathSingleFilterNonMatchingFileRegexp.java"), expected,
182 removeSuppressed(expected, suppressed));
183 }
184
185 @Test
186 public void testInvalidFileRegexp() {
187 final SuppressionXpathSingleFilter filter = new SuppressionXpathSingleFilter();
188 final PatternSyntaxException exc = getExpectedThrowable(
189 PatternSyntaxException.class,
190 () -> {
191 filter.setFiles("e[l");
192 });
193 assertWithMessage("Message should be: Unclosed character class")
194 .that(exc.getMessage())
195 .contains("Unclosed character class");
196 }
197
198 @Test
199 public void testInvalidCheckRegexp() {
200 final SuppressionXpathSingleFilter filter = new SuppressionXpathSingleFilter();
201 final PatternSyntaxException exc = getExpectedThrowable(
202 PatternSyntaxException.class,
203 () -> {
204 filter.setChecks("e[l");
205 });
206 assertWithMessage("Message should be: Unclosed character class")
207 .that(exc.getMessage())
208 .contains("Unclosed character class");
209 }
210
211 @Test
212 public void testNullViolation() throws Exception {
213 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
214 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
215
216 verifyFilterWithInlineConfigParser(
217 getPath("InputSuppressionXpathSingleFilterNullViolation.java"), expected,
218 removeSuppressed(expected, suppressed));
219 }
220
221 @Test
222 public void testNonMatchingModuleId() throws Exception {
223 final String[] expected = {
224 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
225 };
226
227 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
228
229 verifyFilterWithInlineConfigParser(
230 getPath("InputSuppressionXpathSingleFilterNonMatchingModuleId.java"), expected,
231 removeSuppressed(expected, suppressed));
232 }
233
234 @Test
235 public void testMatchingModuleId() throws Exception {
236 final String[] expected = {
237 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
238 };
239
240 final String[] suppressed = {
241 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
242 };
243
244 verifyFilterWithInlineConfigParser(
245 getPath("InputSuppressionXpathSingleFilterMatchingModuleId.java"), expected,
246 removeSuppressed(expected, suppressed));
247 }
248
249 @Test
250 public void testNonMatchingChecks() throws Exception {
251 final String[] expected = {
252 "20:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
253 };
254
255 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
256
257 verifyFilterWithInlineConfigParser(
258 getPath("InputSuppressionXpathSingleFilterNonMatchingCheck.java"), expected,
259 removeSuppressed(expected, suppressed));
260 }
261
262 @Test
263 public void testNonMatchingFileNameModuleIdAndCheck() throws Exception {
264 final String[] expected = {
265 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
266 };
267 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
268
269 verifyFilterWithInlineConfigParser(
270 getPath("InputSuppressionXpathSingleFilterNonMatchingFileNameModuleIdAndCheck.java"),
271 expected, removeSuppressed(expected, suppressed));
272 }
273
274 @Test
275 public void testNullModuleIdAndNonMatchingChecks() throws Exception {
276 final String[] expected = {
277 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
278 };
279 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
280
281 verifyFilterWithInlineConfigParser(
282 getPath("InputSuppressionXpathSingleFilterNullModuleIdAndNonMatchingCheck.java"),
283 expected, removeSuppressed(expected, suppressed));
284 }
285
286 @Test
287 public void testDecideByMessage() throws Exception {
288 final String[] expected = {
289 "29:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
290 "32:21: " + getCheckMessage(MagicNumberCheck.class, MSG_KEY, "3.14"),
291 "33:16: " + getCheckMessage(MagicNumberCheck.class, MSG_KEY, "123"),
292 "37:28: " + getCheckMessage(MagicNumberCheck.class, MSG_KEY, "123"),
293 };
294
295 final String[] suppressed = {
296 "29:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
297 };
298
299 verifyFilterWithInlineConfigParser(
300 getPath("InputSuppressionXpathSingleFilterDecideByMessage.java"),
301 expected, removeSuppressed(expected, suppressed));
302 }
303
304 @Test
305 public void testThrowException() throws Exception {
306 final String xpath = "//CLASS_DEF[@text='InputSuppressionXpathSingleFilterComplexQuery']";
307 final SuppressionXpathSingleFilter filter =
308 createSuppressionXpathSingleFilter("InputSuppressionXpathSingleFilterComplexQuery",
309 "Test", null, null, xpath);
310 final Violation message =
311 new Violation(3, 0, TokenTypes.CLASS_DEF, "",
312 "", null, null, "id19",
313 getClass(), null);
314 final FileContents fileContents = new FileContents(new FileText(
315 new File(getPath("InputSuppressionXpathSingleFilterComplexQuery.java")),
316 StandardCharsets.UTF_8.name()));
317 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents,
318 "InputSuppressionXpathSingleFilterComplexQuery.java", message, null);
319 final IllegalStateException exc = getExpectedThrowable(
320 IllegalStateException.class,
321 () -> {
322 filter.accept(ev);
323 });
324 assertWithMessage("Exception message does not match expected one")
325 .that(exc.getMessage())
326 .contains("Cannot initialize context and evaluate query");
327 }
328
329 @Test
330 public void testAllNullConfiguration() throws Exception {
331 final String[] expected = {
332 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
333 };
334
335 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
336
337 verifyFilterWithInlineConfigParser(
338 getPath("InputSuppressionXpathSingleFilterAllNullConfiguration.java"),
339 expected, removeSuppressed(expected, suppressed));
340 }
341
342 @Test
343 public void testDecideByIdAndExpression() throws Exception {
344 final String[] expected = {
345 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
346 };
347
348 final String[] suppressed = {
349 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
350 };
351
352 verifyFilterWithInlineConfigParser(
353 getPath("InputSuppressionXpathSingleFilterDecideByIdAndExpression.java"),
354 expected, removeSuppressed(expected, suppressed));
355 }
356
357 @Test
358 public void testDefaultFileProperty() throws Exception {
359 final String[] expected = {
360 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
361 };
362
363 final String[] suppressed = {
364 "21:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
365 };
366
367 verifyFilterWithInlineConfigParser(
368 getPath("InputSuppressionXpathSingleFilterDefaultFileProperty.java"),
369 expected, removeSuppressed(expected, suppressed));
370 }
371
372 @Test
373 public void testDecideByCheck() throws Exception {
374 final String[] expected = {
375 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
376 };
377
378 final String[] suppressed = {
379 "19:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
380 };
381
382 verifyFilterWithInlineConfigParser(
383 getPath("InputSuppressionXpathSingleFilterDecideByCheck.java"),
384 expected, removeSuppressed(expected, suppressed));
385 }
386
387 @Test
388 public void testDecideById() throws Exception {
389 final String[] expected = {
390 "20:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
391 };
392
393 final String[] suppressed = {
394 "20:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
395 };
396
397 verifyFilterWithInlineConfigParser(
398 getPath("InputSuppressionXpathSingleFilterDecideById.java"),
399 expected, removeSuppressed(expected, suppressed));
400 }
401
402 @Test
403 public void testNonMatchingCheckRegexp() throws Exception {
404 final String[] expected = {
405 "20:1: " + getCheckMessage(MissingJavadocTypeCheck.class, MSG_JAVADOC_MISSING),
406 };
407
408 final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
409
410 verifyFilterWithInlineConfigParser(
411 getPath("InputSuppressionXpathSingleFilterNonMatchingCheckRegexp.java"), expected,
412 removeSuppressed(expected, suppressed));
413 }
414
415
416
417
418
419
420
421
422
423
424
425 @Test
426 public void testUpdateFilterFileSettingInRunTime() throws Exception {
427 final File file = new File(getPath("InputSuppressionXpathSingleFilterComplexQuery.java"));
428
429 final SuppressionXpathSingleFilter filter = new SuppressionXpathSingleFilter();
430 filter.setChecks("MagicNumber");
431 filter.finishLocalSetup();
432
433 final Violation violation = new Violation(27, 21, TokenTypes.NUM_DOUBLE, "",
434 "", null, null, null,
435 MagicNumberCheck.class, null);
436
437 final FileContents fileContents =
438 new FileContents(new FileText(file, StandardCharsets.UTF_8.name()));
439
440 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
441 violation, JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
442
443 assertWithMessage("match ia expected as 'files' is defaulted")
444 .that(filter.accept(ev))
445 .isFalse();
446
447
448 filter.setFiles(Pattern.quote(file.getPath() + ".never.match"));
449 filter.finishLocalSetup();
450
451 assertWithMessage("no match is expected due to weird value in 'files'")
452 .that(filter.accept(ev))
453 .isTrue();
454
455
456 filter.setFiles(null);
457 filter.finishLocalSetup();
458
459 assertWithMessage("match is expected as 'files' is defaulted")
460 .that(filter.accept(ev))
461 .isFalse();
462 }
463
464
465
466
467
468
469
470
471
472
473
474 @Test
475 public void testUpdateFilterChecksSettingInRunTime() throws Exception {
476 final File file = new File(getPath("InputSuppressionXpathSingleFilterComplexQuery.java"));
477
478 final SuppressionXpathSingleFilter filter = new SuppressionXpathSingleFilter();
479 filter.setChecks("MagicNumber");
480 filter.finishLocalSetup();
481
482 final Violation violation = new Violation(27, 21, TokenTypes.NUM_DOUBLE, "",
483 "", null, null, null,
484 MagicNumberCheck.class, null);
485
486 final FileContents fileContents =
487 new FileContents(new FileText(file, StandardCharsets.UTF_8.name()));
488
489 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
490 violation, JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
491
492 assertWithMessage("match is expected as 'checks' is set")
493 .that(filter.accept(ev))
494 .isFalse();
495
496
497 filter.setChecks(null);
498 filter.finishLocalSetup();
499
500 assertWithMessage("no match is expected as whole filter is defaulted (empty)")
501 .that(filter.accept(ev))
502 .isTrue();
503 }
504
505
506
507
508
509
510
511
512
513
514
515
516 @Test
517 public void testSetMessageHandlesNullCorrectly() throws Exception {
518 final File file = new File(getPath("InputSuppressionXpathSingleFilterComplexQuery.java"));
519
520 final SuppressionXpathSingleFilter filter = new SuppressionXpathSingleFilter();
521 filter.setMessage("MagicNumber");
522 filter.finishLocalSetup();
523
524 final Violation violation = new Violation(27, 21, TokenTypes.NUM_DOUBLE, "",
525 "", null, null, null,
526 MagicNumberCheck.class, "MagicNumber");
527
528 final FileContents fileContents =
529 new FileContents(new FileText(file, StandardCharsets.UTF_8.name()));
530
531 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
532 violation, JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
533
534 assertWithMessage("match is expected as 'message' is set")
535 .that(filter.accept(ev))
536 .isFalse();
537
538 filter.setMessage(null);
539 filter.finishLocalSetup();
540
541 assertWithMessage("no match is expected as whole filter is defaulted (empty)")
542 .that(filter.accept(ev))
543 .isTrue();
544 }
545
546 private static SuppressionXpathSingleFilter createSuppressionXpathSingleFilter(
547 String files, String checks, String message, String moduleId, String query) {
548 final SuppressionXpathSingleFilter filter = new SuppressionXpathSingleFilter();
549 filter.setFiles(files);
550 filter.setChecks(checks);
551 filter.setMessage(message);
552 filter.setId(moduleId);
553 filter.setQuery(query);
554 filter.finishLocalSetup();
555 return filter;
556 }
557
558 }