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