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