View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 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 org.junit.Assert.assertFalse;
23  import static org.junit.Assert.assertTrue;
24  import static org.junit.Assert.fail;
25  
26  import java.io.File;
27  import java.nio.charset.StandardCharsets;
28  
29  import org.junit.Before;
30  import org.junit.Test;
31  
32  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
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.LocalizedMessage;
37  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
38  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
39  import net.sf.saxon.sxpath.XPathEvaluator;
40  import net.sf.saxon.sxpath.XPathExpression;
41  import nl.jqno.equalsverifier.EqualsVerifier;
42  
43  public class XpathFilterTest extends AbstractModuleTestSupport {
44  
45      private File file;
46      private FileContents fileContents;
47  
48      @Before
49      public void setUp() throws Exception {
50          file = new File(getPath("InputXpathFilterSuppressByXpath.java"));
51          fileContents = new FileContents(new FileText(file,
52                  StandardCharsets.UTF_8.name()));
53      }
54  
55      @Override
56      protected String getPackageLocation() {
57          return "com/puppycrawl/tools/checkstyle/filters/xpathfilter";
58      }
59  
60      @Test
61      public void testMatching() throws Exception {
62          final String xpath = "/CLASS_DEF[@text='InputXpathFilterSuppressByXpath']";
63          final XpathFilter filter =
64                  new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
65          final TreeWalkerAuditEvent ev = getEvent(3, 0,
66                  TokenTypes.CLASS_DEF);
67          assertFalse("Event should be rejected", filter.accept(ev));
68      }
69  
70      @Test
71      public void testNonMatchingTokenType() throws Exception {
72          final String xpath = "//METHOD_DEF[@text='countTokens']";
73          final XpathFilter filter =
74                  new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
75          final TreeWalkerAuditEvent ev = getEvent(3, 0,
76                  TokenTypes.CLASS_DEF);
77          assertTrue("Event should be accepted", filter.accept(ev));
78      }
79  
80      @Test
81      public void testNonMatchingLineNumber() throws Exception {
82          final String xpath = "/CLASS_DEF[@text='InputXpathFilterSuppressByXpath']";
83          final XpathFilter filter =
84                  new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
85          final TreeWalkerAuditEvent ev = getEvent(100, 0,
86                  TokenTypes.CLASS_DEF);
87          assertTrue("Event should be accepted", filter.accept(ev));
88      }
89  
90      @Test
91      public void testNonMatchingColumnNumber() throws Exception {
92          final String xpath = "/CLASS_DEF[@text='InputXpathFilterSuppressByXpath']";
93          final XpathFilter filter =
94                  new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
95          final TreeWalkerAuditEvent ev = getEvent(3, 100,
96                  TokenTypes.CLASS_DEF);
97          assertTrue("Event should be accepted", filter.accept(ev));
98      }
99  
100     @Test
101     public void testComplexQuery() throws Exception {
102         final String xpath = "//VARIABLE_DEF[@text='pi' and "
103                 + "../..[@text='countTokens']] "
104                 + "| //VARIABLE_DEF[@text='someVariable' and ../..[@text='sum']]";
105         final XpathFilter filter =
106                 new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
107         final TreeWalkerAuditEvent eventOne = getEvent(5, 8,
108                 TokenTypes.VARIABLE_DEF);
109         final TreeWalkerAuditEvent eventTwo = getEvent(10, 4,
110                 TokenTypes.VARIABLE_DEF);
111         final TreeWalkerAuditEvent eventThree = getEvent(15, 8,
112                 TokenTypes.VARIABLE_DEF);
113         assertFalse("Event should be rejected", filter.accept(eventOne));
114         assertTrue("Event should be accepted", filter.accept(eventTwo));
115         assertFalse("Event should be rejected", filter.accept(eventThree));
116     }
117 
118     @Test
119     public void testIncorrectQuery() {
120         final String xpath = "1@#";
121         try {
122             final Object test = new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null,
123                     null, xpath);
124             fail("Exception was expected but got " + test);
125         }
126         catch (IllegalStateException ex) {
127             assertTrue("Message should be: Unexpected xpath query",
128                     ex.getMessage().contains("Unexpected xpath query"));
129         }
130     }
131 
132     @Test
133     public void testNoQuery() throws Exception {
134         final TreeWalkerAuditEvent event = getEvent(15, 8,
135                 TokenTypes.VARIABLE_DEF);
136         final XpathFilter filter =
137                 new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, null);
138         assertFalse("Event should be accepted", filter.accept(event));
139     }
140 
141     @Test
142     public void testNullFileName() {
143         final String xpath = "NON_MATCHING_QUERY";
144         final XpathFilter filter =
145                 new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
146         final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(null,
147                 null, null, null);
148         assertTrue("Event should be accepted", filter.accept(ev));
149     }
150 
151     @Test
152     public void testNonMatchingFileRegexp() throws Exception {
153         final String xpath = "NON_MATCHING_QUERY";
154         final XpathFilter filter =
155                 new XpathFilter("NonMatchingRegexp", "Test", null, null, xpath);
156         final TreeWalkerAuditEvent ev = getEvent(3, 0,
157                 TokenTypes.CLASS_DEF);
158         assertTrue("Event should be accepted", filter.accept(ev));
159     }
160 
161     @Test
162     public void testNullLocalizedMessage() {
163         final String xpath = "NON_MATCHING_QUERY";
164         final XpathFilter filter =
165                 new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
166         final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(null,
167                 file.getName(), null, null);
168         assertTrue("Event should be accepted", filter.accept(ev));
169     }
170 
171     @Test
172     public void testNonMatchingModuleId() throws Exception {
173         final String xpath = "NON_MATCHING_QUERY";
174         final XpathFilter filter =
175                 new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, "id19", xpath);
176         final LocalizedMessage message =
177                 new LocalizedMessage(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id20",
178                         getClass(), null);
179         final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents,
180                 file.getName(), message, TestUtil.parseFile(file));
181         assertTrue("Event should be accepted", filter.accept(ev));
182     }
183 
184     @Test
185     public void testMatchingModuleId() throws Exception {
186         final String xpath = "/CLASS_DEF[@text='InputXpathFilterSuppressByXpath']";
187         final XpathFilter filter =
188                 new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, "id19", xpath);
189         final LocalizedMessage message =
190                 new LocalizedMessage(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id19",
191                         getClass(), null);
192         final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents,
193                 file.getName(), message, TestUtil.parseFile(file));
194         assertFalse("Event should be rejected", filter.accept(ev));
195     }
196 
197     @Test
198     public void testNonMatchingChecks() throws Exception {
199         final String xpath = "NON_MATCHING_QUERY";
200         final XpathFilter filter = new XpathFilter("InputXpathFilterSuppressByXpath",
201                 "NonMatchingRegexp", null, "id19", xpath);
202         final LocalizedMessage message =
203                 new LocalizedMessage(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id19",
204                         getClass(), null);
205         final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents,
206                 file.getName(), message, TestUtil.parseFile(file));
207         assertTrue("Event should be accepted", filter.accept(ev));
208     }
209 
210     @Test
211     public void testNonMatchingFileNameModuleIdAndCheck() throws Exception {
212         final String xpath = "NON_MATCHING_QUERY";
213         final XpathFilter filter =
214                 new XpathFilter("InputXpathFilterSuppressByXpath", null, null, null, xpath);
215         final TreeWalkerAuditEvent ev = getEvent(3, 0,
216                 TokenTypes.CLASS_DEF);
217         assertTrue("Event should be accepted", filter.accept(ev));
218     }
219 
220     @Test
221     public void testNullModuleIdAndNonMatchingChecks() throws Exception {
222         final String xpath = "NON_MATCHING_QUERY";
223         final XpathFilter filter = new XpathFilter("InputXpathFilterSuppressByXpath",
224                 "NonMatchingRegexp", null, null, xpath);
225         final TreeWalkerAuditEvent ev = getEvent(3, 0,
226                 TokenTypes.CLASS_DEF);
227         assertTrue("Event should be accepted", filter.accept(ev));
228     }
229 
230     @Test
231     public void testDecideByMessage() throws Exception {
232         final LocalizedMessage message = new LocalizedMessage(0, 0, TokenTypes.CLASS_DEF, "", "",
233                 null, null, null, getClass(), "Test");
234         final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents, file.getName(),
235                 message, TestUtil.parseFile(file));
236         final XpathFilter filter1 = new XpathFilter(null, null, "Test", null, null);
237         final XpathFilter filter2 = new XpathFilter(null, null, "Bad", null, null);
238         assertFalse("Message match", filter1.accept(ev));
239         assertTrue("Message not match", filter2.accept(ev));
240     }
241 
242     @Test
243     public void testThrowException() {
244         final String xpath = "/CLASS_DEF[@text='InputXpathFilterSuppressByXpath']";
245         final XpathFilter filter =
246                 new XpathFilter("InputXpathFilterSuppressByXpath", "Test", null, null, xpath);
247         final LocalizedMessage message =
248                 new LocalizedMessage(3, 0, TokenTypes.CLASS_DEF, "", "", null, null, "id19",
249                         getClass(), null);
250         final TreeWalkerAuditEvent ev = new TreeWalkerAuditEvent(fileContents,
251                 file.getName(), message, null);
252         try {
253             filter.accept(ev);
254             fail("Exception is expected");
255         }
256         catch (IllegalStateException ex) {
257             assertTrue("Exception message does not match expected one",
258                     ex.getMessage().contains("Cannot initialize context and evaluate query"));
259         }
260     }
261 
262     @Test
263     public void testEqualsAndHashCode() throws Exception {
264         final XPathEvaluator xpathEvaluator = new XPathEvaluator();
265         EqualsVerifier.forClass(XpathFilter.class).withPrefabValues(XPathExpression.class,
266                 xpathEvaluator.createExpression("//METHOD_DEF"),
267                 xpathEvaluator.createExpression("//VARIABLE_DEF"))
268                 .usingGetClass()
269                 .withIgnoredFields("fileRegexp", "checkRegexp", "messageRegexp", "xpathExpression")
270                 .verify();
271     }
272 
273     private TreeWalkerAuditEvent getEvent(int line, int column, int tokenType)
274             throws Exception {
275         final LocalizedMessage message =
276                 new LocalizedMessage(line, column, tokenType, "", "", null, null, null,
277                         getClass(), null);
278         return new TreeWalkerAuditEvent(fileContents, file.getName(), message,
279                 TestUtil.parseFile(file));
280     }
281 }