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 com.puppycrawl.tools.checkstyle.filters;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.coding.IllegalTokenTextCheck.MSG_KEY;
24  import static com.puppycrawl.tools.checkstyle.checks.naming.AbstractNameCheck.MSG_INVALID_PATTERN;
25  
26  import java.util.Collections;
27  import java.util.Set;
28  
29  import org.junit.jupiter.api.Test;
30  
31  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
32  import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
33  import com.puppycrawl.tools.checkstyle.checks.coding.IllegalTokenTextCheck;
34  import com.puppycrawl.tools.checkstyle.checks.naming.ConstantNameCheck;
35  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
36  import nl.jqno.equalsverifier.EqualsVerifier;
37  import nl.jqno.equalsverifier.EqualsVerifierReport;
38  import nl.jqno.equalsverifier.Warning;
39  
40  public class SuppressionXpathFilterTest extends AbstractModuleTestSupport {
41  
42      private static final String PATTERN = "^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$";
43  
44      private static final String[] ALL_MESSAGES = {
45          "20:29: " + getCheckMessage(ConstantNameCheck.class,
46                                      MSG_INVALID_PATTERN, "bad_name", PATTERN),
47      };
48  
49      @Override
50      protected String getPackageLocation() {
51          return "com/puppycrawl/tools/checkstyle/filters/suppressionxpathfilter";
52      }
53  
54      @Test
55      public void testAcceptOne() throws Exception {
56          final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
57          verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilterAcceptOne.java"),
58                                             ALL_MESSAGES,
59                                             removeSuppressed(ALL_MESSAGES, suppressed));
60      }
61  
62      @Test
63      public void testAcceptTwo() throws Exception {
64          final String[] expected = {
65              "20:29: " + getCheckMessage(ConstantNameCheck.class, MSG_INVALID_PATTERN,
66                                          "different_name_than_suppression", PATTERN),
67          };
68          final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
69          verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilterAcceptTwo.java"),
70                                             expected, removeSuppressed(expected, suppressed));
71      }
72  
73      @Test
74      public void testAcceptOnNullFile() throws Exception {
75          final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
76          verifyFilterWithInlineConfigParser(
77              getPath("InputSuppressionXpathFilterAcceptOnNullFile.java"), ALL_MESSAGES,
78              removeSuppressed(ALL_MESSAGES, suppressed));
79      }
80  
81      @Test
82      public void testNonExistentSuppressionFileWithFalseOptional() throws Exception {
83          final String fileName = getPath("non_existent_suppression_file.xml");
84          try {
85              final boolean optional = false;
86              createSuppressionXpathFilter(fileName, optional);
87              assertWithMessage("Exception is expected").fail();
88          }
89          catch (CheckstyleException ex) {
90              assertWithMessage("Invalid error message")
91                  .that(ex.getMessage())
92                  .isEqualTo("Unable to find: " + fileName);
93          }
94      }
95  
96      @Test
97      public void testExistingInvalidSuppressionFileWithTrueOptional() throws Exception {
98          final String fileName = getPath("InputSuppressionXpathFilterInvalidFile.xml");
99          try {
100             final boolean optional = true;
101             createSuppressionXpathFilter(fileName, optional);
102             assertWithMessage("Exception is expected").fail();
103         }
104         catch (CheckstyleException ex) {
105             assertWithMessage("Invalid error message")
106                 .that(ex.getMessage())
107                 .isEqualTo("Unable to parse " + fileName
108                     + " - invalid files or checks or message format for suppress-xpath");
109         }
110     }
111 
112     @Test
113     public void testExistingSuppressionFileWithTrueOptional() throws Exception {
114         final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
115         verifyFilterWithInlineConfigParser(
116             getPath("InputSuppressionXpathFilterAcceptWithOptionalTrue.java"), ALL_MESSAGES,
117             removeSuppressed(ALL_MESSAGES, suppressed));
118     }
119 
120     @Test
121     public void testNonExistentSuppressionFileWithTrueOptional() throws Exception {
122         final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
123         verifyFilterWithInlineConfigParser(
124             getPath("InputSuppressionXpathFilterNonExistentFileWithTrueOptional.java"),
125             ALL_MESSAGES, removeSuppressed(ALL_MESSAGES, suppressed));
126     }
127 
128     @Test
129     public void testReject() throws Exception {
130         final String[] suppressed = {
131             "20:29: " + getCheckMessage(ConstantNameCheck.class,
132                                         MSG_INVALID_PATTERN, "bad_name", PATTERN),
133         };
134         verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilterReject.java"),
135                                            ALL_MESSAGES,
136                                            removeSuppressed(ALL_MESSAGES, suppressed));
137     }
138 
139     @Test
140     public void testEqualsAndHashCode() {
141         final EqualsVerifierReport ev = EqualsVerifier.forClass(SuppressionXpathFilter.class)
142                 .usingGetClass()
143                 .withIgnoredFields("file", "optional", "configuration")
144                 .suppress(Warning.NONFINAL_FIELDS).report();
145         assertWithMessage("Error: " + ev.getMessage())
146                 .that(ev.isSuccessful())
147                 .isTrue();
148     }
149 
150     @Test
151     public void testExternalResource() throws Exception {
152         final boolean optional = false;
153         final String fileName = getPath("InputSuppressionXpathFilterIdAndQuery.xml");
154         final SuppressionXpathFilter filter = createSuppressionXpathFilter(fileName, optional);
155         final Set<String> expected = Collections.singleton(fileName);
156         final Set<String> actual = filter.getExternalResourceLocations();
157         assertWithMessage("Invalid external resource")
158             .that(actual)
159             .isEqualTo(expected);
160     }
161 
162     private static SuppressionXpathFilter createSuppressionXpathFilter(String fileName,
163                                                                        boolean optional)
164             throws CheckstyleException {
165         final SuppressionXpathFilter suppressionXpathFilter = new SuppressionXpathFilter();
166         suppressionXpathFilter.setFile(fileName);
167         suppressionXpathFilter.setOptional(optional);
168         suppressionXpathFilter.finishLocalSetup();
169         return suppressionXpathFilter;
170     }
171 
172     @Test
173     public void testFalseEncodeString() throws Exception {
174         final String pattern = "[^a-zA-z0-9]*";
175         final String[] expected = {
176             "17:24: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
177             "19:23: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
178             "21:28: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
179             "23:26: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
180             "25:26: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
181             "27:26: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
182             "29:23: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
183             "31:29: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
184             "33:29: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
185         };
186 
187         final String[] suppressed = {
188             "17:24: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
189             "19:23: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
190             "21:28: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
191             "23:26: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
192             "25:26: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
193             "27:26: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
194             "29:23: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
195         };
196 
197         verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilterEscapeString.java"),
198                                            expected, removeSuppressed(expected, suppressed));
199     }
200 
201     @Test
202     public void testFalseEncodeChar() throws Exception {
203         final String pattern = "[^a-zA-z0-9]*";
204         final String[] expected = {
205             "17:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
206             "19:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
207             "21:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
208             "23:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
209             "25:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
210         };
211 
212         final String[] suppressed = {
213             "21:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
214             "23:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
215             "25:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
216         };
217 
218         verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilterEscapeChar.java"),
219                                            expected, removeSuppressed(expected, suppressed));
220     }
221 
222     @Test
223     public void testXpathSuppression() throws Exception {
224         for (int test = 1; test <= 4; test++) {
225 
226             final String[] expected = {
227                 "20:29: " + getCheckMessage(ConstantNameCheck.class, MSG_INVALID_PATTERN,
228                         "different_name_than_suppression", PATTERN),
229             };
230             final String[] suppressed = CommonUtil.EMPTY_STRING_ARRAY;
231             final String path = "InputSuppressionXpathFilter" + test + ".java";
232             verifyFilterWithInlineConfigParser(getPath(path),
233                     expected, removeSuppressed(expected, suppressed));
234         }
235     }
236 
237     @Test
238     public void testXpathSuppression2() throws Exception {
239         final String pattern = "[^a-zA-z0-9]*";
240         final String[] expected = {
241             "18:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
242         };
243 
244         final String[] suppressed = {
245             "18:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
246         };
247 
248         verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilter5.java"),
249                                            expected, removeSuppressed(expected, suppressed));
250     }
251 
252     @Test
253     public void testXpathSuppression3() throws Exception {
254         final String pattern = "[^a-zA-z0-9]*";
255         final String[] expected = {
256             "18:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
257         };
258 
259         final String[] suppressed = {
260             "18:14: " + getCheckMessage(IllegalTokenTextCheck.class, MSG_KEY, pattern),
261         };
262 
263         verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilter6.java"),
264                                            expected, removeSuppressed(expected, suppressed));
265     }
266 
267     @Test
268     public void testXpathSuppression4() throws Exception {
269         final String[] suppressed = {
270             "20:29: " + getCheckMessage(ConstantNameCheck.class,
271                                         MSG_INVALID_PATTERN, "bad_name", PATTERN),
272         };
273         verifyFilterWithInlineConfigParser(getPath("InputSuppressionXpathFilter7.java"),
274                                            ALL_MESSAGES,
275                                            removeSuppressed(ALL_MESSAGES, suppressed));
276     }
277 }