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.checks.modifier;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.modifier.InterfaceMemberImpliedModifierCheck.MSG_KEY;
24  
25  import org.junit.jupiter.api.Test;
26  
27  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
28  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
29  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
30  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
31  
32  public class InterfaceMemberImpliedModifierCheckTest
33      extends AbstractModuleTestSupport {
34  
35      @Override
36      protected String getPackageLocation() {
37          return "com/puppycrawl/tools/checkstyle/checks/modifier/interfacememberimpliedmodifier";
38      }
39  
40      @Test
41      public void testMethodsOnInterfaceNoImpliedPublicAbstract() throws Exception {
42          final String[] expected = {
43              "21:5: " + getCheckMessage(MSG_KEY, "public"),
44              "27:5: " + getCheckMessage(MSG_KEY, "public"),
45              "34:5: " + getCheckMessage(MSG_KEY, "public"),
46              "36:5: " + getCheckMessage(MSG_KEY, "abstract"),
47              "38:5: " + getCheckMessage(MSG_KEY, "public"),
48              "38:5: " + getCheckMessage(MSG_KEY, "abstract"),
49          };
50          verifyWithInlineConfigParser(
51                  getPath("InputInterfaceMemberImpliedModifierMethodsOnInterface.java"),
52              expected);
53      }
54  
55      @Test
56      public void testGetRequiredTokens() {
57          final InterfaceMemberImpliedModifierCheck check = new InterfaceMemberImpliedModifierCheck();
58          final int[] actual = check.getRequiredTokens();
59          final int[] expected = {
60              TokenTypes.METHOD_DEF,
61              TokenTypes.VARIABLE_DEF,
62              TokenTypes.INTERFACE_DEF,
63              TokenTypes.CLASS_DEF,
64              TokenTypes.ENUM_DEF,
65          };
66          assertWithMessage("Required tokens are invalid")
67              .that(actual)
68              .isEqualTo(expected);
69      }
70  
71      @Test
72      public void testMethodsOnInterfaceNoImpliedAbstractAllowImpliedPublic() throws Exception {
73          final String[] expected = {
74              "36:5: " + getCheckMessage(MSG_KEY, "abstract"),
75              "38:5: " + getCheckMessage(MSG_KEY, "abstract"),
76          };
77          verifyWithInlineConfigParser(
78                  getPath("InputInterfaceMemberImpliedModifierMethodsOnInterface2.java"),
79              expected);
80      }
81  
82      @Test
83      public void testMethodsOnInterfaceNoImpliedPublicAllowImpliedAbstract() throws Exception {
84          final String[] expected = {
85              "21:5: " + getCheckMessage(MSG_KEY, "public"),
86              "27:5: " + getCheckMessage(MSG_KEY, "public"),
87              "34:5: " + getCheckMessage(MSG_KEY, "public"),
88              "38:5: " + getCheckMessage(MSG_KEY, "public"),
89          };
90          verifyWithInlineConfigParser(
91                  getPath("InputInterfaceMemberImpliedModifierMethodsOnInterface3.java"),
92              expected);
93      }
94  
95      @Test
96      public void testMethodsOnInterfaceAllowImpliedPublicAbstract() throws Exception {
97          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
98          verifyWithInlineConfigParser(
99                  getPath("InputInterfaceMemberImpliedModifierMethodsOnInterface4.java"),
100             expected);
101     }
102 
103     @Test
104     public void testMethodsOnClassIgnored() throws Exception {
105         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
106         verifyWithInlineConfigParser(
107                 getPath("InputInterfaceMemberImpliedModifierMethodsOnClass.java"),
108             expected);
109     }
110 
111     @Test
112     public void testMethodsOnInterfaceNestedNoImpliedPublicAbstract() throws Exception {
113         final String[] expected = {
114             "23:9: " + getCheckMessage(MSG_KEY, "public"),
115             "29:9: " + getCheckMessage(MSG_KEY, "public"),
116             "34:9: " + getCheckMessage(MSG_KEY, "public"),
117             "36:9: " + getCheckMessage(MSG_KEY, "abstract"),
118             "38:9: " + getCheckMessage(MSG_KEY, "public"),
119             "38:9: " + getCheckMessage(MSG_KEY, "abstract"),
120         };
121         verifyWithInlineConfigParser(
122                 getPath("InputInterfaceMemberImpliedModifierMethodsOnInterfaceNested.java"),
123             expected);
124     }
125 
126     @Test
127     public void testMethodsOnClassNestedNoImpliedPublicAbstract() throws Exception {
128         final String[] expected = {
129             "23:9: " + getCheckMessage(MSG_KEY, "public"),
130             "29:9: " + getCheckMessage(MSG_KEY, "public"),
131             "34:9: " + getCheckMessage(MSG_KEY, "public"),
132             "36:9: " + getCheckMessage(MSG_KEY, "abstract"),
133             "38:9: " + getCheckMessage(MSG_KEY, "public"),
134             "38:9: " + getCheckMessage(MSG_KEY, "abstract"),
135         };
136         verifyWithInlineConfigParser(
137                 getPath("InputInterfaceMemberImpliedModifierMethodsOnClassNested.java"),
138             expected);
139     }
140 
141     @Test
142     public void testFieldsOnInterfaceNoImpliedPublicStaticFinal() throws Exception {
143         final String[] expected = {
144             "20:5: " + getCheckMessage(MSG_KEY, "final"),
145             "22:5: " + getCheckMessage(MSG_KEY, "static"),
146             "24:5: " + getCheckMessage(MSG_KEY, "static"),
147             "24:5: " + getCheckMessage(MSG_KEY, "final"),
148             "26:5: " + getCheckMessage(MSG_KEY, "public"),
149             "28:5: " + getCheckMessage(MSG_KEY, "public"),
150             "28:5: " + getCheckMessage(MSG_KEY, "final"),
151             "30:5: " + getCheckMessage(MSG_KEY, "public"),
152             "30:5: " + getCheckMessage(MSG_KEY, "static"),
153             "32:5: " + getCheckMessage(MSG_KEY, "public"),
154             "32:5: " + getCheckMessage(MSG_KEY, "static"),
155             "32:5: " + getCheckMessage(MSG_KEY, "final"),
156         };
157         verifyWithInlineConfigParser(
158                 getPath("InputInterfaceMemberImpliedModifierFieldsOnInterface.java"),
159             expected);
160     }
161 
162     @Test
163     public void testFieldsOnInterfaceNoImpliedPublicStaticAllowImpliedFinal() throws Exception {
164         final String[] expected = {
165             "22:5: " + getCheckMessage(MSG_KEY, "static"),
166             "24:5: " + getCheckMessage(MSG_KEY, "static"),
167             "26:5: " + getCheckMessage(MSG_KEY, "public"),
168             "28:5: " + getCheckMessage(MSG_KEY, "public"),
169             "30:5: " + getCheckMessage(MSG_KEY, "public"),
170             "30:5: " + getCheckMessage(MSG_KEY, "static"),
171             "32:5: " + getCheckMessage(MSG_KEY, "public"),
172             "32:5: " + getCheckMessage(MSG_KEY, "static"),
173         };
174         verifyWithInlineConfigParser(
175                 getPath("InputInterfaceMemberImpliedModifierFieldsOnInterface2.java"),
176             expected);
177     }
178 
179     @Test
180     public void testFieldsOnInterfaceNoImpliedPublicFinalAllowImpliedStatic() throws Exception {
181         final String[] expected = {
182             "20:5: " + getCheckMessage(MSG_KEY, "final"),
183             "24:5: " + getCheckMessage(MSG_KEY, "final"),
184             "26:5: " + getCheckMessage(MSG_KEY, "public"),
185             "28:5: " + getCheckMessage(MSG_KEY, "public"),
186             "28:5: " + getCheckMessage(MSG_KEY, "final"),
187             "30:5: " + getCheckMessage(MSG_KEY, "public"),
188             "32:5: " + getCheckMessage(MSG_KEY, "public"),
189             "32:5: " + getCheckMessage(MSG_KEY, "final"),
190         };
191         verifyWithInlineConfigParser(
192                 getPath("InputInterfaceMemberImpliedModifierFieldsOnInterface3.java"),
193             expected);
194     }
195 
196     @Test
197     public void testFieldsOnInterfaceNoImpliedStaticFinalAllowImpliedPublic() throws Exception {
198         final String[] expected = {
199             "20:5: " + getCheckMessage(MSG_KEY, "final"),
200             "22:5: " + getCheckMessage(MSG_KEY, "static"),
201             "24:5: " + getCheckMessage(MSG_KEY, "static"),
202             "24:5: " + getCheckMessage(MSG_KEY, "final"),
203             "28:5: " + getCheckMessage(MSG_KEY, "final"),
204             "30:5: " + getCheckMessage(MSG_KEY, "static"),
205             "32:5: " + getCheckMessage(MSG_KEY, "static"),
206             "32:5: " + getCheckMessage(MSG_KEY, "final"),
207         };
208         verifyWithInlineConfigParser(
209                 getPath("InputInterfaceMemberImpliedModifierFieldsOnInterface4.java"),
210             expected);
211     }
212 
213     @Test
214     public void testFieldsOnInterfaceAllowImpliedPublicStaticFinal() throws Exception {
215         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
216         verifyWithInlineConfigParser(
217                 getPath("InputInterfaceMemberImpliedModifierFieldsOnInterface5.java"),
218             expected);
219     }
220 
221     @Test
222     public void testFieldsOnClassIgnored() throws Exception {
223         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
224         verifyWithInlineConfigParser(
225                 getPath("InputInterfaceMemberImpliedModifierFieldsOnClass.java"),
226             expected);
227     }
228 
229     @Test
230     public void testNestedOnInterfaceNoImpliedPublicStatic() throws Exception {
231         final String[] expected = {
232             "21:5: " + getCheckMessage(MSG_KEY, "static"),
233             "24:5: " + getCheckMessage(MSG_KEY, "public"),
234             "27:5: " + getCheckMessage(MSG_KEY, "public"),
235             "27:5: " + getCheckMessage(MSG_KEY, "static"),
236             "35:5: " + getCheckMessage(MSG_KEY, "static"),
237             "40:5: " + getCheckMessage(MSG_KEY, "public"),
238             "45:5: " + getCheckMessage(MSG_KEY, "public"),
239             "45:5: " + getCheckMessage(MSG_KEY, "static"),
240             "53:5: " + getCheckMessage(MSG_KEY, "static"),
241             "56:5: " + getCheckMessage(MSG_KEY, "public"),
242             "59:5: " + getCheckMessage(MSG_KEY, "public"),
243             "59:5: " + getCheckMessage(MSG_KEY, "static"),
244         };
245         verifyWithInlineConfigParser(
246                 getPath("InputInterfaceMemberImpliedModifierNestedOnInterface.java"),
247             expected);
248     }
249 
250     @Test
251     public void testNestedOnInterfaceNoImpliedStaticAllowImpliedPublic() throws Exception {
252         final String[] expected = {
253             "21:5: " + getCheckMessage(MSG_KEY, "static"),
254             "27:5: " + getCheckMessage(MSG_KEY, "static"),
255             "35:5: " + getCheckMessage(MSG_KEY, "static"),
256             "45:5: " + getCheckMessage(MSG_KEY, "static"),
257             "53:5: " + getCheckMessage(MSG_KEY, "static"),
258             "59:5: " + getCheckMessage(MSG_KEY, "static"),
259         };
260         verifyWithInlineConfigParser(
261                 getPath("InputInterfaceMemberImpliedModifierNestedOnInterface2.java"),
262             expected);
263     }
264 
265     @Test
266     public void testNestedOnInterfaceNoImpliedPublicAllowImpliedStatic() throws Exception {
267         final String[] expected = {
268             "24:5: " + getCheckMessage(MSG_KEY, "public"),
269             "27:5: " + getCheckMessage(MSG_KEY, "public"),
270             "40:5: " + getCheckMessage(MSG_KEY, "public"),
271             "45:5: " + getCheckMessage(MSG_KEY, "public"),
272             "56:5: " + getCheckMessage(MSG_KEY, "public"),
273             "59:5: " + getCheckMessage(MSG_KEY, "public"),
274         };
275         verifyWithInlineConfigParser(
276                 getPath("InputInterfaceMemberImpliedModifierNestedOnInterface3.java"),
277             expected);
278     }
279 
280     @Test
281     public void testNestedOnInterfaceAllowImpliedPublicStatic() throws Exception {
282         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
283         verifyWithInlineConfigParser(
284                 getPath("InputInterfaceMemberImpliedModifierNestedOnInterface4.java"),
285             expected);
286     }
287 
288     @Test
289     public void testNestedOnClassIgnored() throws Exception {
290         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
291         verifyWithInlineConfigParser(
292                 getPath("InputInterfaceMemberImpliedModifierNestedOnClass.java"),
293             expected);
294     }
295 
296     @Test
297     public void testNestedOnInterfaceNestedNoImpliedPublicStatic() throws Exception {
298         final String[] expected = {
299             "20:9: " + getCheckMessage(MSG_KEY, "public"),
300             "20:9: " + getCheckMessage(MSG_KEY, "static"),
301             "23:9: " + getCheckMessage(MSG_KEY, "public"),
302             "23:9: " + getCheckMessage(MSG_KEY, "static"),
303             "28:9: " + getCheckMessage(MSG_KEY, "public"),
304             "28:9: " + getCheckMessage(MSG_KEY, "static"),
305         };
306         verifyWithInlineConfigParser(
307                 getPath("InputInterfaceMemberImpliedModifierNestedOnInterfaceNested.java"),
308             expected);
309     }
310 
311     @Test
312     public void testNestedOnClassNestedNoImpliedPublicStatic() throws Exception {
313         final String[] expected = {
314             "20:9: " + getCheckMessage(MSG_KEY, "public"),
315             "20:9: " + getCheckMessage(MSG_KEY, "static"),
316             "23:9: " + getCheckMessage(MSG_KEY, "public"),
317             "23:9: " + getCheckMessage(MSG_KEY, "static"),
318             "28:9: " + getCheckMessage(MSG_KEY, "public"),
319             "28:9: " + getCheckMessage(MSG_KEY, "static"),
320         };
321         verifyWithInlineConfigParser(
322                 getPath("InputInterfaceMemberImpliedModifierNestedOnClassNested.java"),
323             expected);
324     }
325 
326     @Test
327     public void testPackageScopeInterface() throws Exception {
328         final String[] expected = {
329             "20:5: " + getCheckMessage(MSG_KEY, "final"),
330             "22:5: " + getCheckMessage(MSG_KEY, "static"),
331             "24:5: " + getCheckMessage(MSG_KEY, "static"),
332             "24:5: " + getCheckMessage(MSG_KEY, "final"),
333             "26:5: " + getCheckMessage(MSG_KEY, "public"),
334             "28:5: " + getCheckMessage(MSG_KEY, "public"),
335             "28:5: " + getCheckMessage(MSG_KEY, "final"),
336             "30:5: " + getCheckMessage(MSG_KEY, "public"),
337             "30:5: " + getCheckMessage(MSG_KEY, "static"),
338             "32:5: " + getCheckMessage(MSG_KEY, "public"),
339             "32:5: " + getCheckMessage(MSG_KEY, "static"),
340             "32:5: " + getCheckMessage(MSG_KEY, "final"),
341             "37:5: " + getCheckMessage(MSG_KEY, "public"),
342             "43:5: " + getCheckMessage(MSG_KEY, "public"),
343             "48:5: " + getCheckMessage(MSG_KEY, "public"),
344             "50:5: " + getCheckMessage(MSG_KEY, "abstract"),
345             "52:5: " + getCheckMessage(MSG_KEY, "public"),
346             "52:5: " + getCheckMessage(MSG_KEY, "abstract"),
347             "57:5: " + getCheckMessage(MSG_KEY, "static"),
348             "60:5: " + getCheckMessage(MSG_KEY, "public"),
349             "63:5: " + getCheckMessage(MSG_KEY, "public"),
350             "63:5: " + getCheckMessage(MSG_KEY, "static"),
351         };
352         verifyWithInlineConfigParser(
353                 getPath("InputInterfaceMemberImpliedModifierPackageScopeInterface.java"),
354             expected);
355     }
356 
357     @Test
358     public void testPrivateMethodsOnInterface() throws Exception {
359         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
360         verifyWithInlineConfigParser(
361                 getPath("InputInterfaceMemberImpliedModifierPrivateMethods.java"),
362             expected);
363     }
364 
365     @Test
366     public void testIllegalState() {
367         final DetailAstImpl init = new DetailAstImpl();
368         init.setType(TokenTypes.STATIC_INIT);
369         final DetailAstImpl objBlock = new DetailAstImpl();
370         objBlock.setType(TokenTypes.OBJBLOCK);
371         objBlock.addChild(init);
372         final DetailAstImpl interfaceAst = new DetailAstImpl();
373         interfaceAst.setType(TokenTypes.INTERFACE_DEF);
374         interfaceAst.addChild(objBlock);
375         final InterfaceMemberImpliedModifierCheck check =
376             new InterfaceMemberImpliedModifierCheck();
377         try {
378             check.visitToken(init);
379             assertWithMessage("IllegalStateException is expected").fail();
380         }
381         catch (IllegalStateException ex) {
382             assertWithMessage("Error message is unexpected")
383                 .that(ex.getMessage())
384                 .isEqualTo(init.toString());
385         }
386     }
387 
388     @Test
389     public void testSealedClassInInterface() throws Exception {
390         final String[] expected = {
391             "18:5: " + getCheckMessage(MSG_KEY, "final"),
392             "18:5: " + getCheckMessage(MSG_KEY, "public"),
393             "18:5: " + getCheckMessage(MSG_KEY, "static"),
394             "23:5: " + getCheckMessage(MSG_KEY, "abstract"),
395             "23:5: " + getCheckMessage(MSG_KEY, "public"),
396             "27:5: " + getCheckMessage(MSG_KEY, "public"),
397             "27:5: " + getCheckMessage(MSG_KEY, "static"),
398             "31:9: " + getCheckMessage(MSG_KEY, "abstract"),
399             "31:9: " + getCheckMessage(MSG_KEY, "public"),
400             "36:5: " + getCheckMessage(MSG_KEY, "static"),
401             "36:5: " + getCheckMessage(MSG_KEY, "public"),
402             "40:5: " + getCheckMessage(MSG_KEY, "public"),
403             "40:5: " + getCheckMessage(MSG_KEY, "static"),
404         };
405         verifyWithInlineConfigParser(
406                 getNonCompilablePath("InputInterfaceMemberImpliedModifierSealedClasses.java"),
407             expected);
408     }
409 }