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.checks.coding;
21  
22  import static com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck.MSG_METHOD;
23  import static com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck.MSG_VARIABLE;
24  
25  import java.lang.reflect.Constructor;
26  import java.util.SortedSet;
27  
28  import org.junit.Assert;
29  import org.junit.Test;
30  
31  import antlr.CommonHiddenStreamToken;
32  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
33  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
34  import com.puppycrawl.tools.checkstyle.api.DetailAST;
35  import com.puppycrawl.tools.checkstyle.api.LocalizedMessage;
36  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
37  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
38  import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
39  
40  public class RequireThisCheckTest extends AbstractModuleTestSupport {
41      @Override
42      protected String getPackageLocation() {
43          return "com/puppycrawl/tools/checkstyle/checks/coding/requirethis";
44      }
45  
46      @Test
47      public void testIt() throws Exception {
48          final DefaultConfiguration checkConfig =
49              createModuleConfig(RequireThisCheck.class);
50          checkConfig.addAttribute("validateOnlyOverlapping", "false");
51          final String[] expected = {
52              "11:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
53              "17:9: " + getCheckMessage(MSG_METHOD, "method1", ""),
54              "31:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
55              "49:13: " + getCheckMessage(MSG_VARIABLE, "z", ""),
56              "56:9: " + getCheckMessage(MSG_VARIABLE, "z", ""),
57              "113:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
58              "114:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
59              "115:9: " + getCheckMessage(MSG_METHOD, "instanceMethod", ""),
60              "121:13: " + getCheckMessage(MSG_METHOD, "instanceMethod", "Issue2240."),
61              "122:13: " + getCheckMessage(MSG_VARIABLE, "i", "Issue2240."),
62              "134:9: " + getCheckMessage(MSG_METHOD, "foo", ""),
63              "142:9: " + getCheckMessage(MSG_VARIABLE, "s", ""),
64              "168:16: " + getCheckMessage(MSG_VARIABLE, "a", ""),
65              "168:20: " + getCheckMessage(MSG_VARIABLE, "a", ""),
66              "174:16: " + getCheckMessage(MSG_VARIABLE, "b", ""),
67              "174:20: " + getCheckMessage(MSG_VARIABLE, "b", ""),
68          };
69          verify(checkConfig,
70                 getPath("InputRequireThisEnumInnerClassesAndBugs.java"),
71                 expected);
72      }
73  
74      @Test
75      public void testMethodsOnly() throws Exception {
76          final DefaultConfiguration checkConfig =
77              createModuleConfig(RequireThisCheck.class);
78          checkConfig.addAttribute("checkFields", "false");
79          checkConfig.addAttribute("validateOnlyOverlapping", "false");
80          final String[] expected = {
81              "17:9: " + getCheckMessage(MSG_METHOD, "method1", ""),
82              "115:9: " + getCheckMessage(MSG_METHOD, "instanceMethod", ""),
83              "121:13: " + getCheckMessage(MSG_METHOD, "instanceMethod", "Issue2240."),
84              "134:9: " + getCheckMessage(MSG_METHOD, "foo", ""),
85          };
86          verify(checkConfig,
87                 getPath("InputRequireThisEnumInnerClassesAndBugs.java"),
88                 expected);
89      }
90  
91      @Test
92      public void testFieldsOnly() throws Exception {
93          final DefaultConfiguration checkConfig =
94              createModuleConfig(RequireThisCheck.class);
95          checkConfig.addAttribute("checkMethods", "false");
96          checkConfig.addAttribute("validateOnlyOverlapping", "false");
97          final String[] expected = {
98              "11:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
99              "31:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
100             "49:13: " + getCheckMessage(MSG_VARIABLE, "z", ""),
101             "56:9: " + getCheckMessage(MSG_VARIABLE, "z", ""),
102             "113:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
103             "114:9: " + getCheckMessage(MSG_VARIABLE, "i", ""),
104             "122:13: " + getCheckMessage(MSG_VARIABLE, "i", "Issue2240."),
105             "142:9: " + getCheckMessage(MSG_VARIABLE, "s", ""),
106             "168:16: " + getCheckMessage(MSG_VARIABLE, "a", ""),
107             "168:20: " + getCheckMessage(MSG_VARIABLE, "a", ""),
108             "174:16: " + getCheckMessage(MSG_VARIABLE, "b", ""),
109             "174:20: " + getCheckMessage(MSG_VARIABLE, "b", ""),
110         };
111         verify(checkConfig,
112                getPath("InputRequireThisEnumInnerClassesAndBugs.java"),
113                expected);
114     }
115 
116     @Test
117     public void testGenerics() throws Exception {
118         final DefaultConfiguration checkConfig =
119             createModuleConfig(RequireThisCheck.class);
120         checkConfig.addAttribute("validateOnlyOverlapping", "false");
121         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
122         verify(checkConfig, getPath("InputRequireThis15Extensions.java"), expected);
123     }
124 
125     @Test
126     public void testGithubIssue41() throws Exception {
127         final DefaultConfiguration checkConfig =
128                 createModuleConfig(RequireThisCheck.class);
129         checkConfig.addAttribute("validateOnlyOverlapping", "false");
130         final String[] expected = {
131             "7:19: " + getCheckMessage(MSG_VARIABLE, "number", ""),
132             "8:16: " + getCheckMessage(MSG_METHOD, "other", ""),
133         };
134         verify(checkConfig,
135                 getPath("InputRequireThisSimple.java"),
136                 expected);
137     }
138 
139     @Test
140     public void testTokensNotNull() {
141         final RequireThisCheck check = new RequireThisCheck();
142         Assert.assertNotNull("Acceptable tokens should not be null", check.getAcceptableTokens());
143         Assert.assertNotNull("Acceptable tokens should not be null", check.getDefaultTokens());
144         Assert.assertNotNull("Acceptable tokens should not be null", check.getRequiredTokens());
145     }
146 
147     @Test
148     public void testWithAnonymousClass() throws Exception {
149         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
150         checkConfig.addAttribute("validateOnlyOverlapping", "false");
151         final String[] expected = {
152             "19:25: " + getCheckMessage(MSG_METHOD, "doSideEffect", ""),
153             "23:24: " + getCheckMessage(MSG_VARIABLE, "bar", "InputRequireThisAnonymousEmpty."),
154             "46:17: " + getCheckMessage(MSG_VARIABLE, "foobar", ""),
155         };
156         verify(checkConfig,
157                 getPath("InputRequireThisAnonymousEmpty.java"),
158                 expected);
159     }
160 
161     @Test
162     public void testDefaultSwitch() {
163         final RequireThisCheck check = new RequireThisCheck();
164 
165         final DetailAST ast = new DetailAST();
166         ast.initialize(new CommonHiddenStreamToken(TokenTypes.ENUM, "ENUM"));
167 
168         check.visitToken(ast);
169         final SortedSet<LocalizedMessage> messages = check.getMessages();
170 
171         Assert.assertEquals("No exception messages expected", 0, messages.size());
172     }
173 
174     @Test
175     public void testValidateOnlyOverlappingFalse() throws Exception {
176         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
177         checkConfig.addAttribute("validateOnlyOverlapping", "false");
178         final String[] expected = {
179             "20:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
180             "21:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
181             "22:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
182             "23:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
183             "27:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
184             "28:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
185             "29:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
186             "33:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
187             "37:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
188             "41:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
189             "43:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
190             "45:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
191             "49:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
192             "50:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
193             "60:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
194             "61:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
195             "80:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
196             "119:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
197             "128:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
198             "132:9: " + getCheckMessage(MSG_METHOD, "method1", ""),
199             "168:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
200             "169:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
201             "170:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
202             "172:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
203             "176:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal1", ""),
204             "177:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal2", ""),
205             "178:9: " + getCheckMessage(MSG_VARIABLE, "fieldFinal3", ""),
206             "180:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
207             "185:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
208             "189:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
209             "210:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
210             "228:21: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
211             "238:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
212             "253:9: " + getCheckMessage(MSG_VARIABLE, "booleanField", ""),
213             "262:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
214             "270:18: " + getCheckMessage(MSG_METHOD, "addSuffixToField", ""),
215             "275:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
216             "275:18: " + getCheckMessage(MSG_METHOD, "addSuffixToField", ""),
217             "301:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
218             "340:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
219             "374:40: " + getCheckMessage(MSG_METHOD, "getServletRelativeAction", ""),
220             "376:20: " + getCheckMessage(MSG_METHOD, "processAction", ""),
221             "384:16: " + getCheckMessage(MSG_METHOD, "processAction", ""),
222         };
223         verify(checkConfig, getPath("InputRequireThisValidateOnlyOverlappingFalse.java"), expected);
224     }
225 
226     @Test
227     public void testValidateOnlyOverlappingTrue() throws Exception {
228         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
229         final String[] expected = {
230             "20:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
231             "43:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
232             "80:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
233             "119:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
234             "172:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
235             "180:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
236             "238:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
237             "253:9: " + getCheckMessage(MSG_VARIABLE, "booleanField", ""),
238             "262:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
239             "275:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
240             "301:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
241             "339:9: " + getCheckMessage(MSG_VARIABLE, "field1", ""),
242         };
243         verify(checkConfig, getPath("InputRequireThisValidateOnlyOverlappingTrue.java"), expected);
244     }
245 
246     @Test
247     public void testReceiverParameter() throws Exception {
248         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
249         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
250         verify(checkConfig, getPath("InputRequireThisReceiver.java"), expected);
251     }
252 
253     @Test
254     public void testBraceAlone() throws Exception {
255         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
256         checkConfig.addAttribute("validateOnlyOverlapping", "false");
257         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
258         verify(checkConfig, getPath("InputRequireThisBraceAlone.java"), expected);
259     }
260 
261     @Test
262     public void testStatic() throws Exception {
263         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
264         checkConfig.addAttribute("validateOnlyOverlapping", "false");
265         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
266         verify(checkConfig, getPath("InputRequireThisStatic.java"), expected);
267     }
268 
269     @Test
270     public void testMethodReferences() throws Exception {
271         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
272         final String[] expected = {
273             "15:9: " + getCheckMessage(MSG_VARIABLE, "tags", ""),
274         };
275         verify(checkConfig, getPath("InputRequireThisMethodReferences.java"), expected);
276     }
277 
278     @Test
279     public void testAllowLocalVars() throws Exception {
280         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
281         checkConfig.addAttribute("validateOnlyOverlapping", "false");
282         checkConfig.addAttribute("checkMethods", "false");
283         final String[] expected = {
284             "14:9: " + getCheckMessage(MSG_VARIABLE, "s1", ""),
285             "22:9: " + getCheckMessage(MSG_VARIABLE, "s1", ""),
286             "35:9: " + getCheckMessage(MSG_VARIABLE, "s2", ""),
287             "40:9: " + getCheckMessage(MSG_VARIABLE, "s2", ""),
288             "46:9: " + getCheckMessage(MSG_VARIABLE, "s2", ""),
289             "47:16: " + getCheckMessage(MSG_VARIABLE, "s1", ""),
290         };
291         verify(checkConfig, getPath("InputRequireThisAllowLocalVars.java"), expected);
292     }
293 
294     @Test
295     public void testAllowLambdaParameters() throws Exception {
296         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
297         checkConfig.addAttribute("validateOnlyOverlapping", "false");
298         checkConfig.addAttribute("checkMethods", "false");
299         final String[] expected = {
300             "13:9: " + getCheckMessage(MSG_VARIABLE, "s1", ""),
301             "35:21: " + getCheckMessage(MSG_VARIABLE, "z", ""),
302             "60:29: " + getCheckMessage(MSG_VARIABLE, "a", ""),
303             "60:34: " + getCheckMessage(MSG_VARIABLE, "b", ""),
304         };
305         verify(checkConfig, getPath("InputRequireThisAllowLambdaParameters.java"), expected);
306     }
307 
308     @Test
309     public void testCatchVariables() throws Exception {
310         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
311         checkConfig.addAttribute("validateOnlyOverlapping", "false");
312         final String[] expected = {
313             "29:21: " + getCheckMessage(MSG_VARIABLE, "ex", ""),
314         };
315         verify(checkConfig, getPath("InputRequireThisCatchVariables.java"), expected);
316     }
317 
318     @Test
319     public void testEnumConstant() throws Exception {
320         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
321         checkConfig.addAttribute("validateOnlyOverlapping", "false");
322         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
323         verify(checkConfig, getPath("InputRequireThisEnumConstant.java"), expected);
324     }
325 
326     @Test
327     public void testAnnotationInterface() throws Exception {
328         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
329         checkConfig.addAttribute("validateOnlyOverlapping", "false");
330         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
331         verify(checkConfig, getPath("InputRequireThisAnnotationInterface.java"), expected);
332     }
333 
334     @Test
335     public void testFor() throws Exception {
336         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
337         checkConfig.addAttribute("validateOnlyOverlapping", "false");
338         final String[] expected = {
339             "13:13: " + getCheckMessage(MSG_VARIABLE, "bottom", ""),
340             "21:34: " + getCheckMessage(MSG_VARIABLE, "name", ""),
341         };
342         verify(checkConfig, getPath("InputRequireThisFor.java"), expected);
343     }
344 
345     @Test
346     public void test() throws Exception {
347         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
348         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
349         verify(checkConfig, getPath("InputRequireThisCaseGroup.java"), expected);
350     }
351 
352     @Test
353     public void testExtendedMethod() throws Exception {
354         final DefaultConfiguration checkConfig = createModuleConfig(RequireThisCheck.class);
355         checkConfig.addAttribute("validateOnlyOverlapping", "false");
356         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
357         verify(checkConfig, getPath("InputRequireThisExtendedMethod.java"), expected);
358     }
359 
360     @Test
361     public void testUnusedMethod() throws Exception {
362         final DetailAST ident = new DetailAST();
363         ident.setText("testName");
364 
365         final Class<?> cls = Class.forName(RequireThisCheck.class.getName() + "$CatchFrame");
366         final Constructor<?> constructor = cls.getDeclaredConstructors()[0];
367         constructor.setAccessible(true);
368         final Object o = constructor.newInstance(null, ident);
369 
370         Assert.assertEquals("expected ident token", ident,
371                 TestUtil.getClassDeclaredMethod(cls, "getFrameNameIdent").invoke(o));
372     }
373 }