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
24 import java.io.File;
25 import java.nio.charset.StandardCharsets;
26 import java.util.regex.Pattern;
27
28 import org.junit.jupiter.api.BeforeEach;
29 import org.junit.jupiter.api.Test;
30
31 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
32 import com.puppycrawl.tools.checkstyle.JavaParser;
33 import com.puppycrawl.tools.checkstyle.TreeWalkerAuditEvent;
34 import com.puppycrawl.tools.checkstyle.api.FileContents;
35 import com.puppycrawl.tools.checkstyle.api.FileText;
36 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
37 import com.puppycrawl.tools.checkstyle.api.Violation;
38 import net.sf.saxon.Configuration;
39 import net.sf.saxon.sxpath.XPathEvaluator;
40 import net.sf.saxon.sxpath.XPathExpression;
41 import nl.jqno.equalsverifier.EqualsVerifier;
42 import nl.jqno.equalsverifier.EqualsVerifierReport;
43
44 public class XpathFilterElementTest extends AbstractModuleTestSupport {
45
46 private File file;
47 private FileContents fileContents;
48
49 @BeforeEach
50 public void setUp() throws Exception {
51 file = new File(getPath("InputXpathFilterElementSuppressByXpath.java"));
52 fileContents = new FileContents(new FileText(file,
53 StandardCharsets.UTF_8.name()));
54 }
55
56 @Override
57 public String getPackageLocation() {
58 return "com/puppycrawl/tools/checkstyle/filters/xpathfilterelement";
59 }
60
61 @Test
62 public void testMatching() throws Exception {
63 final String xpath = "//CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]";
64 final XpathFilterElement filter = new XpathFilterElement(
65 "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath);
66 final TreeWalkerAuditEvent ev = getEvent(3, 0,
67 TokenTypes.CLASS_DEF);
68 assertWithMessage("Event should be rejected")
69 .that(filter.accept(ev))
70 .isFalse();
71 }
72
73 @Test
74 public void testNonMatchingTokenType() throws Exception {
75 final String xpath = "//METHOD_DEF[./IDENT[@text='countTokens']]";
76 final XpathFilterElement filter = new XpathFilterElement(
77 "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath);
78 final TreeWalkerAuditEvent ev = getEvent(4, 4,
79 TokenTypes.CLASS_DEF);
80 assertWithMessage("Event should be accepted")
81 .that(filter.accept(ev))
82 .isTrue();
83 }
84
85 @Test
86 public void testNonMatchingLineNumber() throws Exception {
87 final String xpath = "//CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]";
88 final XpathFilterElement filter = new XpathFilterElement(
89 "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath);
90 final TreeWalkerAuditEvent ev = getEvent(100, 0,
91 TokenTypes.CLASS_DEF);
92 assertWithMessage("Event should be accepted")
93 .that(filter.accept(ev))
94 .isTrue();
95 }
96
97 @Test
98 public void testNonMatchingColumnNumber() throws Exception {
99 final String xpath = "//CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]";
100 final XpathFilterElement filter = new XpathFilterElement(
101 "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath);
102 final TreeWalkerAuditEvent ev = getEvent(3, 100,
103 TokenTypes.CLASS_DEF);
104 assertWithMessage("Event should be accepted")
105 .that(filter.accept(ev))
106 .isTrue();
107 }
108
109 @Test
110 public void testComplexQuery() throws Exception {
111 final String xpath = "//VARIABLE_DEF[./IDENT[@text='pi'] and "
112 + "../../IDENT[@text='countTokens']] "
113 + "| //VARIABLE_DEF[./IDENT[@text='someVariable'] and ../../IDENT[@text='sum']]";
114 final XpathFilterElement filter = new XpathFilterElement(
115 "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath);
116 final TreeWalkerAuditEvent eventOne = getEvent(5, 8,
117 TokenTypes.VARIABLE_DEF);
118 final TreeWalkerAuditEvent eventTwo = getEvent(10, 4,
119 TokenTypes.VARIABLE_DEF);
120 final TreeWalkerAuditEvent eventThree = getEvent(15, 8,
121 TokenTypes.VARIABLE_DEF);
122 assertWithMessage("Event should be rejected")
123 .that(filter.accept(eventOne))
124 .isFalse();
125 assertWithMessage("Event should be accepted")
126 .that(filter.accept(eventTwo))
127 .isTrue();
128 assertWithMessage("Event should be rejected")
129 .that(filter.accept(eventThree))
130 .isFalse();
131 }
132
133 @Test
134 public void testInvalidCheckRegexp() {
135 try {
136 final Object test = new XpathFilterElement(
137 ".*", "e[l", ".*", "moduleId", "query");
138 assertWithMessage("Exception is expected but got %s", test).fail();
139 }
140 catch (IllegalArgumentException exc) {
141 assertWithMessage("Message should be: Failed to initialise regular expression")
142 .that(exc.getMessage())
143 .contains("Failed to initialise regular expression");
144 }
145 }
146
147 @Test
148 public void testIncorrectQuery() {
149 final String xpath = "1@#";
150 try {
151 final Object test = new XpathFilterElement("InputXpathFilterElementSuppressByXpath",
152 "Test", null, null, xpath);
153 assertWithMessage("Exception is expected but got %s", test).fail();
154 }
155 catch (IllegalArgumentException exc) {
156 assertWithMessage("Message should be: Incorrect xpath query")
157 .that(exc.getMessage())
158 .contains("Incorrect xpath query");
159 }
160 }
161
162 @Test
163 public void testNoQuery() throws Exception {
164 final TreeWalkerAuditEvent event = getEvent(15, 8,
165 TokenTypes.VARIABLE_DEF);
166 final XpathFilterElement filter = new XpathFilterElement(
167 "InputXpathFilterElementSuppressByXpath", "Test", null, null, null);
168 assertWithMessage("Event should be accepted")
169 .that(filter.accept(event))
170 .isFalse();
171 }
172
173 @Test
174 public void testNullFileName() {
175 final XpathFilterElement filter = new XpathFilterElement(
176 "InputXpathFilterElementSuppressByXpath", "Test", null, null, null);
177 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(null,
178 null, null, null);
179 assertWithMessage("Event should be accepted")
180 .that(filter.accept(ev))
181 .isTrue();
182 }
183
184 @Test
185 public void testNonMatchingFileRegexp() throws Exception {
186 final XpathFilterElement filter =
187 new XpathFilterElement("NonMatchingRegexp", "Test", null, null, null);
188 final TreeWalkerAuditEvent ev = getEvent(3, 0,
189 TokenTypes.CLASS_DEF);
190 assertWithMessage("Event should be accepted")
191 .that(filter.accept(ev))
192 .isTrue();
193 }
194
195 @Test
196 public void testNonMatchingFilePattern() throws Exception {
197 final Pattern pattern = Pattern.compile("NonMatchingRegexp");
198 final XpathFilterElement filter =
199 new XpathFilterElement(pattern, null, null, null, null);
200 final TreeWalkerAuditEvent ev = getEvent(3, 0,
201 TokenTypes.CLASS_DEF);
202 assertWithMessage("Event should be accepted")
203 .that(filter.accept(ev))
204 .isTrue();
205 }
206
207 @Test
208 public void testNonMatchingCheckPattern() throws Exception {
209 final Pattern pattern = Pattern.compile("NonMatchingRegexp");
210 final XpathFilterElement filter =
211 new XpathFilterElement(null, pattern, null, null, null);
212 final TreeWalkerAuditEvent ev = getEvent(3, 0,
213 TokenTypes.CLASS_DEF);
214 assertWithMessage("Event should be accepted")
215 .that(filter.accept(ev))
216 .isTrue();
217 }
218
219 @Test
220 public void testNullViolation() {
221 final XpathFilterElement filter = new XpathFilterElement(
222 "InputXpathFilterElementSuppressByXpath", "Test", null, null, null);
223 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(null,
224 file.getName(), null, null);
225 assertWithMessage("Event should be accepted")
226 .that(filter.accept(ev))
227 .isTrue();
228 }
229
230 @Test
231 public void testNonMatchingModuleId() throws Exception {
232 final XpathFilterElement filter = new XpathFilterElement(
233 "InputXpathFilterElementSuppressByXpath", "Test", null, "id19", null);
234 final Violation message =
235 new Violation(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id20",
236 getClass(), null);
237 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
238 message, JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
239 assertWithMessage("Event should be accepted")
240 .that(filter.accept(ev))
241 .isTrue();
242 }
243
244 @Test
245 public void testMatchingModuleId() throws Exception {
246 final String xpath = "//CLASS_DEF[./IDENT[@text='InputXpathFilterElementSuppressByXpath']]";
247 final XpathFilterElement filter = new XpathFilterElement(
248 "InputXpathFilterElementSuppressByXpath", "Test", null, "id19", xpath);
249 final Violation message =
250 new Violation(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id19",
251 getClass(), null);
252 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
253 message, JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
254 assertWithMessage("Event should be rejected")
255 .that(filter.accept(ev))
256 .isFalse();
257 }
258
259 @Test
260 public void testNonMatchingChecks() throws Exception {
261 final String xpath = "NON_MATCHING_QUERY";
262 final XpathFilterElement filter = new XpathFilterElement(
263 "InputXpathFilterElementSuppressByXpath", "NonMatchingRegexp", null, "id19", xpath);
264 final Violation message =
265 new Violation(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id19",
266 getClass(), null);
267 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
268 message, JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
269 assertWithMessage("Event should be accepted")
270 .that(filter.accept(ev))
271 .isTrue();
272 }
273
274 @Test
275 public void testNonMatchingFileNameModuleIdAndCheck() throws Exception {
276 final String xpath = "NON_MATCHING_QUERY";
277 final XpathFilterElement filter = new XpathFilterElement(
278 "InputXpathFilterElementSuppressByXpath", null, null, null, xpath);
279 final TreeWalkerAuditEvent ev = getEvent(3, 0,
280 TokenTypes.CLASS_DEF);
281 assertWithMessage("Event should be accepted")
282 .that(filter.accept(ev))
283 .isTrue();
284 }
285
286 @Test
287 public void testNullModuleIdAndNonMatchingChecks() throws Exception {
288 final String xpath = "NON_MATCHING_QUERY";
289 final XpathFilterElement filter = new XpathFilterElement(
290 "InputXpathFilterElementSuppressByXpath", "NonMatchingRegexp", null, null, xpath);
291 final TreeWalkerAuditEvent ev = getEvent(3, 0,
292 TokenTypes.CLASS_DEF);
293 assertWithMessage("Event should be accepted")
294 .that(filter.accept(ev))
295 .isTrue();
296 }
297
298 @Test
299 public void testDecideByMessage() throws Exception {
300 final Violation message = new Violation(1, 0, TokenTypes.CLASS_DEF, "", "",
301 null, null, null, getClass(), "Test");
302 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
303 message, JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
304 final XpathFilterElement filter1 = new XpathFilterElement(null, null, "Test", null, null);
305 final XpathFilterElement filter2 = new XpathFilterElement(null, null, "Bad", null, null);
306 assertWithMessage("Message match")
307 .that(filter1.accept(ev))
308 .isFalse();
309 assertWithMessage("Message not match")
310 .that(filter2.accept(ev))
311 .isTrue();
312 }
313
314 @Test
315 public void testThrowException() {
316 final String xpath = "//CLASS_DEF[@text='InputXpathFilterElementSuppressByXpath']";
317 final XpathFilterElement filter = new XpathFilterElement(
318 "InputXpathFilterElementSuppressByXpath", "Test", null, null, xpath);
319 final Violation message =
320 new Violation(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id19",
321 getClass(), null);
322 final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents,
323 file.getName(), message, null);
324 try {
325 filter.accept(ev);
326 assertWithMessage("Exception is expected").fail();
327 }
328 catch (IllegalStateException exc) {
329 assertWithMessage("Exception message does not match expected one")
330 .that(exc.getMessage())
331 .contains("Cannot initialize context and evaluate query");
332 }
333 }
334
335 @Test
336 public void testEqualsAndHashCode() throws Exception {
337 final XPathEvaluator xpathEvaluator = new XPathEvaluator(Configuration.newConfiguration());
338 final EqualsVerifierReport ev = EqualsVerifier.forClass(XpathFilterElement.class)
339 .withPrefabValues(XPathExpression.class,
340 xpathEvaluator.createExpression("//METHOD_DEF"),
341 xpathEvaluator.createExpression("//VARIABLE_DEF"))
342 .usingGetClass()
343 .withIgnoredFields("xpathExpression", "isEmptyConfig")
344 .report();
345 assertWithMessage("Error: %s", ev.getMessage())
346 .that(ev.isSuccessful())
347 .isTrue();
348 }
349
350 private TreeWalkerAuditEvent getEvent(int line, int column, int tokenType)
351 throws Exception {
352 final Violation message =
353 new Violation(line, column, tokenType, "", "", null, null, null,
354 getClass(), null);
355 return new TreeWalkerAuditEvent(fileContents, file.getName(), message,
356 JavaParser.parseFile(file, JavaParser.Options.WITHOUT_COMMENTS));
357 }
358
359 }