View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  ///////////////////////////////////////////////////////////////////////////////////////////////
19  
20  package org.checkstyle.suppressionxpathfilter;
21  
22  import java.io.File;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.List;
26  
27  import org.junit.jupiter.api.Test;
28  
29  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
30  import com.puppycrawl.tools.checkstyle.checks.coding.IllegalTokenCheck;
31  import com.puppycrawl.tools.checkstyle.checks.coding.MatchXpathCheck;
32  
33  public class XpathRegressionMatchXpathTest extends AbstractXpathTestSupport {
34  
35      private final String checkName = MatchXpathCheck.class.getSimpleName();
36  
37      @Override
38      protected String getCheckName() {
39          return checkName;
40      }
41  
42      @Test
43      public void testOne() throws Exception {
44          final File fileToProcess =
45                  new File(getPath("InputXpathMatchXpathOne.java"));
46  
47          final DefaultConfiguration moduleConfig =
48                  createModuleConfig(MatchXpathCheck.class);
49          moduleConfig.addProperty("query", "//METHOD_DEF[./IDENT[@text='test']]");
50  
51          final String[] expectedViolation = {
52              "4:5: " + getCheckMessage(MatchXpathCheck.class, MatchXpathCheck.MSG_KEY),
53          };
54  
55          final List<String> expectedXpathQueries = Arrays.asList(
56              "/COMPILATION_UNIT/CLASS_DEF[./IDENT[@text='InputXpathMatchXpathOne']]"
57                      + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]",
58              "/COMPILATION_UNIT/CLASS_DEF[./IDENT[@text='InputXpathMatchXpathOne']]"
59                      + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/MODIFIERS",
60              "/COMPILATION_UNIT/CLASS_DEF[./IDENT[@text='InputXpathMatchXpathOne']]"
61                      + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='test']]/MODIFIERS/LITERAL_PUBLIC"
62          );
63  
64          runVerifications(moduleConfig, fileToProcess, expectedViolation,
65                  expectedXpathQueries);
66      }
67  
68      @Test
69      public void testTwo() throws Exception {
70          final File fileToProcess =
71                  new File(getPath("InputXpathMatchXpathTwo.java"));
72  
73          final DefaultConfiguration moduleConfig =
74                  createModuleConfig(MatchXpathCheck.class);
75          moduleConfig.addProperty("query", "//LITERAL_THROWS[./IDENT[@text='Throwable' or "
76                  + "@text='RuntimeException' or ends-with(@text, 'Error')]]");
77  
78          final String[] expectedViolation = {
79              "4:25: " + getCheckMessage(MatchXpathCheck.class, MatchXpathCheck.MSG_KEY),
80          };
81  
82          final List<String> expectedXpathQueries = Collections.singletonList(
83                  "/COMPILATION_UNIT/CLASS_DEF"
84                          + "[./IDENT[@text='InputXpathMatchXpathTwo']]"
85                          + "/OBJBLOCK/METHOD_DEF[./IDENT[@text='func1']]"
86                          + "/LITERAL_THROWS[./IDENT[@text='RuntimeException']]"
87          );
88  
89          runVerifications(moduleConfig, fileToProcess, expectedViolation,
90                  expectedXpathQueries);
91      }
92  
93      @Test
94      public void testEncodedQuoteString() throws Exception {
95          final File fileToProcess =
96                  new File(getPath("InputXpathMatchXpathEncodedQuoteString.java"));
97  
98          final DefaultConfiguration moduleConfig =
99                  createModuleConfig(IllegalTokenCheck.class);
100         moduleConfig.addProperty("tokens", "STRING_LITERAL");
101 
102         final String[] expectedViolation = {
103             "4:24: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
104                     "\"\\\"testOne\\\"\""),
105         };
106 
107         final List<String> expectedXpathQueries = Arrays.asList(
108             "/COMPILATION_UNIT/CLASS_DEF"
109                     + "[./IDENT[@text='InputXpathMatchXpathEncodedQuoteString']]/"
110                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='quoteChar']]/ASSIGN/EXPR"
111                     + "[./STRING_LITERAL[@text='\\&quot;testOne\\&quot;']]",
112             "/COMPILATION_UNIT/CLASS_DEF"
113                     + "[./IDENT[@text='InputXpathMatchXpathEncodedQuoteString']]/"
114                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='quoteChar']]/ASSIGN/EXPR"
115                     + "/STRING_LITERAL[@text='\\&quot;testOne\\&quot;']"
116         );
117 
118         runVerifications(moduleConfig, fileToProcess, expectedViolation,
119                 expectedXpathQueries);
120     }
121 
122     @Test
123     public void testEncodedLessString() throws Exception {
124         final File fileToProcess =
125                 new File(getPath("InputXpathMatchXpathEncodedLessString.java"));
126 
127         final DefaultConfiguration moduleConfig =
128                 createModuleConfig(IllegalTokenCheck.class);
129         moduleConfig.addProperty("tokens", "STRING_LITERAL");
130 
131         final String[] expectedViolation = {
132             "4:23: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
133                     "\"<testTwo\""),
134         };
135 
136         final List<String> expectedXpathQueries = Arrays.asList(
137             "/COMPILATION_UNIT/CLASS_DEF"
138                     + "[./IDENT[@text='InputXpathMatchXpathEncodedLessString']]/"
139                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='lessChar']]/ASSIGN/EXPR"
140                     + "[./STRING_LITERAL[@text='&lt;testTwo']]",
141             "/COMPILATION_UNIT/CLASS_DEF"
142                     + "[./IDENT[@text='InputXpathMatchXpathEncodedLessString']]/"
143                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='lessChar']]/ASSIGN/EXPR/"
144                     + "STRING_LITERAL[@text='&lt;testTwo']"
145         );
146 
147         runVerifications(moduleConfig, fileToProcess, expectedViolation,
148                 expectedXpathQueries);
149     }
150 
151     @Test
152     public void testEncodedNewLineString() throws Exception {
153         final File fileToProcess =
154                 new File(getPath("InputXpathMatchXpathEncodedNewLineString.java"));
155 
156         final DefaultConfiguration moduleConfig =
157                 createModuleConfig(IllegalTokenCheck.class);
158         moduleConfig.addProperty("tokens", "STRING_LITERAL");
159 
160         final String[] expectedViolation = {
161             "4:26: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
162                     "\"testFive\\n\""),
163         };
164 
165         final List<String> expectedXpathQueries = Arrays.asList(
166             "/COMPILATION_UNIT/CLASS_DEF"
167                     + "[./IDENT[@text='InputXpathMatchXpathEncodedNewLineString']]/"
168                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='newLineChar']]/ASSIGN/EXPR"
169                     + "[./STRING_LITERAL[@text='testFive\\n']]",
170             "/COMPILATION_UNIT/CLASS_DEF"
171                     + "[./IDENT[@text='InputXpathMatchXpathEncodedNewLineString']]/"
172                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='newLineChar']]/ASSIGN/EXPR"
173                     + "/STRING_LITERAL[@text='testFive\\n']"
174         );
175 
176         runVerifications(moduleConfig, fileToProcess, expectedViolation,
177                 expectedXpathQueries);
178     }
179 
180     @Test
181     public void testGreaterString() throws Exception {
182         final File fileToProcess =
183                 new File(getPath("InputXpathMatchXpathEncodedGreaterString.java"));
184 
185         final DefaultConfiguration moduleConfig =
186                 createModuleConfig(IllegalTokenCheck.class);
187         moduleConfig.addProperty("tokens", "STRING_LITERAL");
188 
189         final String[] expectedViolation = {
190             "4:26: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
191                     "\">testFour\""),
192         };
193 
194         final List<String> expectedXpathQueries = Arrays.asList(
195             "/COMPILATION_UNIT/CLASS_DEF"
196                     + "[./IDENT[@text='InputXpathMatchXpathEncodedGreaterString']]/"
197                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='greaterChar']]/ASSIGN/EXPR"
198                     + "[./STRING_LITERAL[@text='&gt;testFour']]",
199             "/COMPILATION_UNIT/CLASS_DEF"
200                     + "[./IDENT[@text='InputXpathMatchXpathEncodedGreaterString']]/"
201                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='greaterChar']]/ASSIGN/EXPR"
202                     + "/STRING_LITERAL[@text='&gt;testFour']"
203         );
204 
205         runVerifications(moduleConfig, fileToProcess, expectedViolation,
206                 expectedXpathQueries);
207     }
208 
209     @Test
210     public void testEncodedAmpString() throws Exception {
211         final File fileToProcess =
212                 new File(getPath("InputXpathMatchXpathEncodedAmpString.java"));
213 
214         final DefaultConfiguration moduleConfig =
215                 createModuleConfig(IllegalTokenCheck.class);
216         moduleConfig.addProperty("tokens", "STRING_LITERAL");
217 
218         final String[] expectedViolation = {
219             "4:28: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
220                     "\"&testThree\""),
221         };
222 
223         final List<String> expectedXpathQueries = Arrays.asList(
224             "/COMPILATION_UNIT/CLASS_DEF"
225                     + "[./IDENT[@text='InputXpathMatchXpathEncodedAmpString']]/"
226                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='ampersandChar']]/ASSIGN/EXPR"
227                     + "[./STRING_LITERAL[@text='&amp;testThree']]",
228             "/COMPILATION_UNIT/CLASS_DEF"
229                     + "[./IDENT[@text='InputXpathMatchXpathEncodedAmpString']]/"
230                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='ampersandChar']]/ASSIGN/EXPR"
231                     + "/STRING_LITERAL[@text='&amp;testThree']"
232         );
233 
234         runVerifications(moduleConfig, fileToProcess, expectedViolation,
235                 expectedXpathQueries);
236     }
237 
238     @Test
239     public void testEncodedAposString() throws Exception {
240         final File fileToProcess =
241                 new File(getPath("InputXpathMatchXpathEncodedAposString.java"));
242 
243         final DefaultConfiguration moduleConfig =
244                 createModuleConfig(IllegalTokenCheck.class);
245         moduleConfig.addProperty("tokens", "STRING_LITERAL");
246 
247         final String[] expectedViolation = {
248             "4:23: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
249                     "\"'SingleQuoteOnBothSide'\""),
250         };
251 
252         final List<String> expectedXpathQueries = Arrays.asList(
253             "/COMPILATION_UNIT/CLASS_DEF"
254                     + "[./IDENT[@text='InputXpathMatchXpathEncodedAposString']]/"
255                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='aposChar']]/ASSIGN/EXPR"
256                     + "[./STRING_LITERAL[@text='&apos;&apos;SingleQuoteOnBothSide&apos;&apos;']]",
257             "/COMPILATION_UNIT/CLASS_DEF"
258                     + "[./IDENT[@text='InputXpathMatchXpathEncodedAposString']]/"
259                     + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='aposChar']]/ASSIGN/EXPR"
260                     + "/STRING_LITERAL[@text='&apos;&apos;SingleQuoteOnBothSide&apos;&apos;']"
261         );
262 
263         runVerifications(moduleConfig, fileToProcess, expectedViolation,
264                 expectedXpathQueries);
265     }
266 
267     @Test
268     public void testEncodedCarriageString() throws Exception {
269         final File fileToProcess =
270             new File(getPath("InputXpathMatchXpathEncodedCarriageString.java"));
271 
272         final DefaultConfiguration moduleConfig =
273                 createModuleConfig(IllegalTokenCheck.class);
274         moduleConfig.addProperty("tokens", "STRING_LITERAL");
275 
276         final String[] expectedViolation = {
277             "4:27: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
278                     "\"carriageCharAtEnd\\r\""),
279         };
280 
281         final List<String> expectedXpathQueries = Arrays.asList(
282                 "/COMPILATION_UNIT/CLASS_DEF"
283                         + "[./IDENT[@text='InputXpathMatchXpathEncodedCarriageString"
284                         + "']]/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='carriageChar']]/ASSIGN"
285                         + "/EXPR[./STRING_LITERAL[@text='carriageCharAtEnd\\r']]",
286                 "/COMPILATION_UNIT/CLASS_DEF"
287                         + "[./IDENT[@text='InputXpathMatchXpathEncodedCarriageString"
288                         + "']]/OBJBLOCK/VARIABLE_DEF[./IDENT[@text='carriageChar']]/ASSIGN"
289                         + "/EXPR/STRING_LITERAL[@text='carriageCharAtEnd\\r']"
290         );
291 
292         runVerifications(moduleConfig, fileToProcess, expectedViolation,
293                 expectedXpathQueries);
294     }
295 
296     @Test
297     public void testEncodedAmpersandChars() throws Exception {
298         final File fileToProcess =
299                 new File(getPath("InputXpathMatchXpathEncodedAmpChar.java"));
300 
301         final DefaultConfiguration moduleConfig =
302                 createModuleConfig(IllegalTokenCheck.class);
303         moduleConfig.addProperty("tokens", "CHAR_LITERAL");
304 
305         final String[] expectedViolationForAmpersand = {
306             "4:20: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
307                     "'&'"),
308         };
309 
310         final List<String> expectedXpathQueriesForAmpersand = Arrays.asList(
311                 "/COMPILATION_UNIT/CLASS_DEF"
312                         + "[./IDENT[@text='InputXpathMatchXpathEncodedAmpChar']]/"
313                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='ampChar']]/ASSIGN/EXPR"
314                         + "[./CHAR_LITERAL[@text='&apos;&apos;&amp;&apos;&apos;']]",
315                 "/COMPILATION_UNIT/CLASS_DEF"
316                         + "[./IDENT[@text='InputXpathMatchXpathEncodedAmpChar']]/"
317                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='ampChar']]/ASSIGN/EXPR"
318                         + "/CHAR_LITERAL[@text='&apos;&apos;&amp;&apos;&apos;']"
319         );
320 
321         runVerifications(moduleConfig, fileToProcess, expectedViolationForAmpersand,
322                 expectedXpathQueriesForAmpersand);
323     }
324 
325     @Test
326     public void testEncodedQuoteChar() throws Exception {
327         final File fileToProcess =
328                 new File(getPath("InputXpathMatchXpathEncodedQuoteChar.java"));
329 
330         final DefaultConfiguration moduleConfig =
331                 createModuleConfig(IllegalTokenCheck.class);
332         moduleConfig.addProperty("tokens", "CHAR_LITERAL");
333 
334         final String[] expectedViolationsForQuote = {
335             "4:21: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
336                     "'\\\"'"),
337         };
338 
339         final List<String> expectedXpathQueriesForQuote = Arrays.asList(
340                 "/COMPILATION_UNIT/CLASS_DEF"
341                         + "[./IDENT[@text='InputXpathMatchXpathEncodedQuoteChar']]/"
342                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='quotChar']]/ASSIGN/EXPR"
343                         + "[./CHAR_LITERAL[@text='&apos;&apos;\\&quot;&apos;&apos;']]",
344                 "/COMPILATION_UNIT/CLASS_DEF"
345                         + "[./IDENT[@text='InputXpathMatchXpathEncodedQuoteChar']]/"
346                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='quotChar']]/ASSIGN/EXPR/"
347                         + "CHAR_LITERAL[@text='&apos;&apos;\\&quot;&apos;&apos;']"
348         );
349 
350         runVerifications(moduleConfig, fileToProcess, expectedViolationsForQuote,
351                 expectedXpathQueriesForQuote);
352     }
353 
354     @Test
355     public void testEncodedLessChar() throws Exception {
356         final File fileToProcess =
357                 new File(getPath("InputXpathMatchXpathEncodedLessChar.java"));
358 
359         final DefaultConfiguration moduleConfig =
360                 createModuleConfig(IllegalTokenCheck.class);
361         moduleConfig.addProperty("tokens", "CHAR_LITERAL");
362 
363         final String[] expectedViolationsForLess = {
364             "4:21: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
365                     "'<'"),
366         };
367 
368         final List<String> expectedXpathQueriesForLess = Arrays.asList(
369                 "/COMPILATION_UNIT/CLASS_DEF"
370                         + "[./IDENT[@text='InputXpathMatchXpathEncodedLessChar']]/"
371                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='lessChar']]/ASSIGN/EXPR"
372                         + "[./CHAR_LITERAL[@text='&apos;&apos;&lt;&apos;&apos;']]",
373                 "/COMPILATION_UNIT/CLASS_DEF"
374                         + "[./IDENT[@text='InputXpathMatchXpathEncodedLessChar']]/"
375                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='lessChar']]/ASSIGN/EXPR/"
376                         + "CHAR_LITERAL[@text='&apos;&apos;&lt;&apos;&apos;']"
377         );
378 
379         runVerifications(moduleConfig, fileToProcess, expectedViolationsForLess,
380                 expectedXpathQueriesForLess);
381     }
382 
383     @Test
384     public void testEncodedAposChar() throws Exception {
385         final File fileToProcess =
386                 new File(getPath("InputXpathMatchXpathEncodedAposChar.java"));
387 
388         final DefaultConfiguration moduleConfig =
389                 createModuleConfig(IllegalTokenCheck.class);
390         moduleConfig.addProperty("tokens", "CHAR_LITERAL");
391 
392         final String[] expectedViolationsForApos = {
393             "4:21: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
394                     "'\\''"),
395         };
396 
397         final List<String> expectedXpathQueriesForApos = Arrays.asList(
398                 "/COMPILATION_UNIT/CLASS_DEF"
399                         + "[./IDENT[@text='InputXpathMatchXpathEncodedAposChar']]/"
400                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='aposChar']]/ASSIGN/EXPR"
401                         + "[./CHAR_LITERAL[@text='&apos;&apos;\\&apos;&apos;&apos;&apos;']]",
402                 "/COMPILATION_UNIT/CLASS_DEF"
403                         + "[./IDENT[@text='InputXpathMatchXpathEncodedAposChar']]/"
404                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='aposChar']]/ASSIGN/EXPR/"
405                         + "CHAR_LITERAL[@text='&apos;&apos;\\&apos;&apos;&apos;&apos;']"
406         );
407 
408         runVerifications(moduleConfig, fileToProcess, expectedViolationsForApos,
409                 expectedXpathQueriesForApos);
410     }
411 
412     @Test
413     public void testEncodedGreaterChar() throws Exception {
414         final File fileToProcess =
415                 new File(getPath("InputXpathMatchXpathEncodedGreaterChar.java"));
416 
417         final DefaultConfiguration moduleConfig =
418                 createModuleConfig(IllegalTokenCheck.class);
419         moduleConfig.addProperty("tokens", "CHAR_LITERAL");
420 
421         final String[] expectedViolationsForGreater = {
422             "4:24: " + getCheckMessage(IllegalTokenCheck.class, IllegalTokenCheck.MSG_KEY,
423                     "'>'"),
424         };
425 
426         final List<String> expectedXpathQueriesForGreater = Arrays.asList(
427                 "/COMPILATION_UNIT/CLASS_DEF"
428                         + "[./IDENT[@text='"
429                         + "InputXpathMatchXpathEncodedGreaterChar']]/"
430                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='greaterChar']]/ASSIGN/EXPR"
431                         + "[./CHAR_LITERAL[@text='&apos;&apos;&gt;&apos;&apos;']]",
432                 "/COMPILATION_UNIT/CLASS_DEF"
433                         + "[./IDENT[@text='"
434                         + "InputXpathMatchXpathEncodedGreaterChar']]/"
435                         + "OBJBLOCK/VARIABLE_DEF[./IDENT[@text='greaterChar']]/ASSIGN/EXPR/"
436                         + "CHAR_LITERAL[@text='&apos;&apos;&gt;&apos;&apos;']"
437         );
438 
439         runVerifications(moduleConfig, fileToProcess, expectedViolationsForGreater,
440                 expectedXpathQueriesForGreater);
441     }
442 
443     @Test
444     public void testFollowing() throws Exception {
445         final File fileToProcess =
446                 new File(getPath("InputXpathMatchXpathThree.java"));
447 
448         final DefaultConfiguration moduleConfig =
449                 createModuleConfig(MatchXpathCheck.class);
450         moduleConfig.addProperty("query",
451                 "//METHOD_DEF/following::*[1]");
452 
453         final String[] expectedViolation = {
454             "5:1: " + getCheckMessage(MatchXpathCheck.class, MatchXpathCheck.MSG_KEY),
455         };
456 
457         final List<String> expectedXpathQueries = Collections.singletonList(
458                 "/COMPILATION_UNIT"
459                         + "/CLASS_DEF[./IDENT[@text='InputXpathMatchXpathThree']]"
460                         + "/OBJBLOCK/RCURLY"
461         );
462 
463         runVerifications(moduleConfig, fileToProcess, expectedViolation,
464                 expectedXpathQueries);
465     }
466 }