View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2026 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 com.puppycrawl.tools.checkstyle.filters;
21  
22  import static com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck.MSG_KEY_LINE_PREVIOUS;
23  import static com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck.MSG_VARIABLE;
24  import static com.puppycrawl.tools.checkstyle.checks.naming.AbstractNameCheck.MSG_INVALID_PATTERN;
25  
26  import java.io.File;
27  import java.io.IOException;
28  import java.nio.file.Files;
29  import java.nio.file.Path;
30  import java.nio.file.Paths;
31  import java.util.HashMap;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.stream.Stream;
35  
36  import org.junit.jupiter.api.Test;
37  
38  import com.puppycrawl.tools.checkstyle.AbstractExamplesModuleTestSupport;
39  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
40  import com.puppycrawl.tools.checkstyle.bdd.InlineConfigParser;
41  import com.puppycrawl.tools.checkstyle.bdd.TestInputConfiguration;
42  import com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck;
43  import com.puppycrawl.tools.checkstyle.checks.coding.IllegalThrowsCheck;
44  import com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck;
45  import com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck;
46  import com.puppycrawl.tools.checkstyle.checks.modifier.RedundantModifierCheck;
47  import com.puppycrawl.tools.checkstyle.checks.naming.AbstractNameCheck;
48  
49  public class SuppressionXpathSingleFilterExamplesTest extends AbstractExamplesModuleTestSupport {
50  
51      @Override
52      public String getPackageLocation() {
53          return "com/puppycrawl/tools/checkstyle/filters/suppressionxpathsinglefilter";
54      }
55  
56      @Test
57      public void testExample1() throws Exception {
58          final String[] expected = {
59              "15:15: " + getCheckMessage(AbstractNameCheck.class,
60                      MSG_INVALID_PATTERN, "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
61              "17:15: " + getCheckMessage(AbstractNameCheck.class,
62                      MSG_INVALID_PATTERN, "MyMethod2", "^[a-z][a-zA-Z0-9]*$"),
63              "19:15: " + getCheckMessage(AbstractNameCheck.class,
64                      MSG_INVALID_PATTERN, "MyMethodA", "^[a-z][a-zA-Z0-9]*$"),
65          };
66  
67          verifyFilterWithInlineConfigParser(getPath("Example1.java"),
68                  expected, expected);
69      }
70  
71      @Test
72      public void testExample2() throws Exception {
73          final String[] expectedWithoutFilter = {
74              "17:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
75              "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
76              "19:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
77              "MyMethod2", "^[a-z][a-zA-Z0-9]*$"),
78              "21:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
79              "MyMethodA", "^[a-z][a-zA-Z0-9]*$"),
80          };
81          final String[] expectedWithFilter = {
82              "17:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
83              "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
84              "21:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
85              "MyMethodA", "^[a-z][a-zA-Z0-9]*$"),
86          };
87  
88          verifyFilterWithInlineConfigParser(getPath("Example2.java"),
89                  expectedWithoutFilter, expectedWithFilter);
90      }
91  
92      @Test
93      public void testExample3() throws Exception {
94          final String[] expectedWithoutFilter = {
95              "20:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
96              "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
97              "22:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
98              "MyMethod2", "^[a-z][a-zA-Z0-9]*$"),
99              "24:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
100             "MyMethodA", "^[a-z][a-zA-Z0-9]*$"),
101         };
102         final String[] expectedWithFilter = {};
103 
104         verifyFilterWithInlineConfigParser(getPath("Example3.java"),
105                 expectedWithoutFilter, expectedWithFilter);
106     }
107 
108     @Test
109     public void testExample4() throws Exception {
110         final String[] expectedWithoutFilter = {
111             "19:9: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
112             "com.puppycrawl.tools.checkstyle.filters.suppressionxpathsinglefilter",
113                     "^[A-Z]+(\\.[A-Z]*)*$"),
114         };
115         final String[] expectedWithFilter = {};
116 
117         verifyFilterWithInlineConfigParser(getPath("Example4.java"),
118                 expectedWithoutFilter, expectedWithFilter);
119     }
120 
121     @Test
122     public void testExample5() throws Exception {
123         final String[] expectedWithoutFilter = {
124             "17:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
125                     "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
126             "19:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
127                     "MyMethod2", "^[a-z][a-zA-Z0-9]*$"),
128             "21:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
129                     "MyMethodA", "^[a-z][a-zA-Z0-9]*$"),
130         };
131         final String[] expectedWithFilter = {};
132 
133         verifyFilterWithInlineConfigParser(getPath("Example5.java"),
134                 expectedWithoutFilter, expectedWithFilter);
135     }
136 
137     @Test
138     public void testUseCase5() throws Exception {
139         final String[] expectedWithoutFilter = {
140             "17:3: " + getCheckMessage(RedundantModifierCheck.class,
141                     RedundantModifierCheck.MSG_KEY, "public"),
142         };
143         final String[] expectedWithFilter = {};
144 
145         verifyFilterWithInlineConfigParser(getPath("UseCase5.java"),
146                 expectedWithoutFilter, expectedWithFilter);
147     }
148 
149     @Test
150     public void testExample6() throws Exception {
151         final String[] expectedWithoutFilter = {
152             "23:23: " + getCheckMessage(MagicNumberCheck.class, MagicNumberCheck.MSG_KEY,
153                 "177"),
154         };
155         final String[] expectedWithFilter = {};
156 
157         verifyFilterWithInlineConfigParser(getPath("Example6.java"),
158                 expectedWithoutFilter, expectedWithFilter);
159     }
160 
161     @Test
162     public void testUseCase6() throws Exception {
163         final String[] expectedWithoutFilter = {
164             "21:1: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
165             "UseCase6", "^Abstract.+$"),
166             "22:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
167             "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
168             "27:1: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
169             "AnotherClass", "^Abstract.+$"),
170             "28:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
171             "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
172         };
173         final String[] expectedWithFilter = {
174             "27:1: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
175             "AnotherClass", "^Abstract.+$"),
176             "28:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
177             "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
178         };
179 
180         verifyFilterWithInlineConfigParser(getPath("UseCase6.java"),
181                 expectedWithoutFilter, expectedWithFilter);
182     }
183 
184     @Test
185     public void testUseCase7() throws Exception {
186         final String[] expectedWithoutFilter = {
187             "19:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
188             "MyMethod1", "^[a-z][a-zA-Z0-9]*$"),
189             "21:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
190             "MyMethod2", "^[a-z][a-zA-Z0-9]*$"),
191             "23:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
192             "MyMethod3", "^[a-z][a-zA-Z0-9]*$"),
193         };
194         final String[] expectedWithFilter = {
195             "23:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
196             "MyMethod3", "^[a-z][a-zA-Z0-9]*$"),
197         };
198 
199         verifyFilterWithInlineConfigParser(getPath("UseCase7.java"),
200                 expectedWithoutFilter, expectedWithFilter);
201     }
202 
203     @Test
204     public void testUseCase8() throws Exception {
205         final String[] expectedWithoutFilter = {
206             "23:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
207             "testVariable1", "^[A-Z][A-Z0-9]*$"),
208             "25:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
209             "testVariable2", "^[A-Z][A-Z0-9]*$"),
210         };
211         final String[] expectedWithFilter = {
212             "25:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
213             "testVariable2", "^[A-Z][A-Z0-9]*$"),
214         };
215 
216         verifyFilterWithInlineConfigParser(getPath("UseCase8.java"),
217                 expectedWithoutFilter, expectedWithFilter);
218     }
219 
220     @Test
221     public void testUseCase1() throws Exception {
222         final String[] expectedWithoutFilter = {
223             "19:3: " + getCheckMessage(LeftCurlyCheck.class, MSG_KEY_LINE_PREVIOUS,
224             "{", 3),
225             "23:3: " + getCheckMessage(LeftCurlyCheck.class, MSG_KEY_LINE_PREVIOUS,
226             "{", 3),
227         };
228         final String[] expectedWithFilter = {
229             "23:3: " + getCheckMessage(LeftCurlyCheck.class, MSG_KEY_LINE_PREVIOUS,
230             "{", 3),
231         };
232 
233         verifyFilterWithInlineConfigParser(getPath("UseCase1.java"),
234                 expectedWithoutFilter, expectedWithFilter);
235     }
236 
237     @Test
238     public void testUseCase2() throws Exception {
239         final String[] expectedWithoutFilter = {
240             "25:5: " + getCheckMessage(RequireThisCheck.class, MSG_VARIABLE,
241                     "age", ""),
242             "29:5: " + getCheckMessage(RequireThisCheck.class, MSG_VARIABLE,
243                     "number", ""),
244         };
245         final String[] expectedWithFilter = {
246             "29:5: " + getCheckMessage(RequireThisCheck.class, MSG_VARIABLE,
247                     "number", ""),
248         };
249 
250         verifyFilterWithInlineConfigParser(getPath("UseCase2.java"),
251                 expectedWithoutFilter, expectedWithFilter);
252     }
253 
254     @Test
255     public void testUseCase3() throws Exception {
256         final String[] expectedWithoutFilter = {
257             "19:37: " + getCheckMessage(IllegalThrowsCheck.class, IllegalThrowsCheck.MSG_KEY,
258                     "RuntimeException"),
259             "23:37: " + getCheckMessage(IllegalThrowsCheck.class, IllegalThrowsCheck.MSG_KEY,
260                     "RuntimeException"),
261         };
262         final String[] expectedWithFilter = {
263             "23:37: " + getCheckMessage(IllegalThrowsCheck.class, IllegalThrowsCheck.MSG_KEY,
264                     "RuntimeException"),
265         };
266 
267         verifyFilterWithInlineConfigParser(getPath("UseCase3.java"),
268                 expectedWithoutFilter, expectedWithFilter);
269     }
270 
271     @Test
272     public void testUseCase4() throws Exception {
273         final String[] expectedWithoutFilter = {
274             "24:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
275                     "TestMethod1", "^[a-z](_?[a-zA-Z0-9]+)*$"),
276             "26:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
277                     "num", "^[A-Z][A-Z0-9]*$"),
278             "30:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
279                     "TestMethod2", "^[a-z](_?[a-zA-Z0-9]+)*$"),
280             "32:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
281                     "num", "^[A-Z][A-Z0-9]*$"),
282         };
283         final String[] expectedWithFilter = {
284             "30:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
285                     "TestMethod2", "^[a-z](_?[a-zA-Z0-9]+)*$"),
286             "32:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
287                     "num", "^[A-Z][A-Z0-9]*$"),
288         };
289 
290         verifyFilterWithInlineConfigParser(getPath("UseCase4.java"),
291                 expectedWithoutFilter, expectedWithFilter);
292     }
293 
294     @Test
295     public void testExample7() throws Exception {
296         final Map<String, List<String>> expected = new HashMap<>();
297         final List<String> messages =
298                 List.of("3:14: " + getCheckMessage(AbstractNameCheck.class,
299                             MSG_INVALID_PATTERN, "myApplication",
300                             "^[A-Z][a-zA-Z0-9]*$"));
301         expected.put(getPath("src/myApplication.java"), messages);
302 
303         final Path path = Paths.get("src/xdocs-examples/resources/" + getPackageLocation() + "/");
304 
305         final String fileWithConfig = getPath("Example7.java");
306         final TestInputConfiguration testInputConfiguration =
307                 InlineConfigParser.parse(fileWithConfig);
308         final DefaultConfiguration parsedConfig =
309                 testInputConfiguration.createConfiguration();
310         verify(createChecker(parsedConfig), getFilesInFolder(path), expected);
311     }
312 
313     @Test
314     public void testExample8() throws Exception {
315         final String[] expectedWithoutFilter = {
316             "22:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
317             "MyMethod", "^[a-z][a-zA-Z0-9]*$"),
318             "24:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
319             "MyMethod2", "^[a-z][a-zA-Z0-9]*$"),
320             "26:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
321             "MyMethodA", "^[a-z][a-zA-Z0-9]*$"),
322         };
323         final String[] expectedWithFilter = {
324             "24:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
325             "MyMethod2", "^[a-z][a-zA-Z0-9]*$"),
326             "26:15: " + getCheckMessage(AbstractNameCheck.class, MSG_INVALID_PATTERN,
327             "MyMethodA", "^[a-z][a-zA-Z0-9]*$"),
328         };
329 
330         verifyFilterWithInlineConfigParser(getPath("Example8.java"),
331                 expectedWithoutFilter, expectedWithFilter);
332     }
333 
334     private static File[] getFilesInFolder(Path path) throws IOException {
335         try (Stream<Path> stream = Files.walk(path.toAbsolutePath())) {
336             return stream.filter(Files::isRegularFile)
337                     .map(Path::toFile)
338                     .toArray(File[]::new);
339         }
340     }
341 
342 }