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              "22:5: " + getCheckMessage(MSG_KEY, "public"),
45              "29:5: " + getCheckMessage(MSG_KEY, "public"),
46              "37:5: " + getCheckMessage(MSG_KEY, "public"),
47              "40:5: " + getCheckMessage(MSG_KEY, "abstract"),
48              "42:5: " + getCheckMessage(MSG_KEY, "public"),
49              "42: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              "37:5: " + getCheckMessage(MSG_KEY, "abstract"),
76              "40: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              "22:5: " + getCheckMessage(MSG_KEY, "public"),
87              "29:5: " + getCheckMessage(MSG_KEY, "public"),
88              "37:5: " + getCheckMessage(MSG_KEY, "public"),
89              "42: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             "24:9: " + getCheckMessage(MSG_KEY, "public"),
116             "31:9: " + getCheckMessage(MSG_KEY, "public"),
117             "37:9: " + getCheckMessage(MSG_KEY, "public"),
118             "40:9: " + getCheckMessage(MSG_KEY, "abstract"),
119             "42:9: " + getCheckMessage(MSG_KEY, "public"),
120             "42: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             "24:9: " + getCheckMessage(MSG_KEY, "public"),
131             "31:9: " + getCheckMessage(MSG_KEY, "public"),
132             "37:9: " + getCheckMessage(MSG_KEY, "public"),
133             "40:9: " + getCheckMessage(MSG_KEY, "abstract"),
134             "42:9: " + getCheckMessage(MSG_KEY, "public"),
135             "42: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             "21:5: " + getCheckMessage(MSG_KEY, "final"),
146             "24:5: " + getCheckMessage(MSG_KEY, "static"),
147             "26:5: " + getCheckMessage(MSG_KEY, "static"),
148             "26:5: " + getCheckMessage(MSG_KEY, "final"),
149             "32:5: " + getCheckMessage(MSG_KEY, "public"),
150             "34:5: " + getCheckMessage(MSG_KEY, "public"),
151             "34:5: " + getCheckMessage(MSG_KEY, "final"),
152             "39:5: " + getCheckMessage(MSG_KEY, "public"),
153             "39:5: " + getCheckMessage(MSG_KEY, "static"),
154             "43:5: " + getCheckMessage(MSG_KEY, "public"),
155             "43:5: " + getCheckMessage(MSG_KEY, "static"),
156             "43: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             "23:5: " + getCheckMessage(MSG_KEY, "static"),
167             "26:5: " + getCheckMessage(MSG_KEY, "static"),
168             "29:5: " + getCheckMessage(MSG_KEY, "public"),
169             "32:5: " + getCheckMessage(MSG_KEY, "public"),
170             "34:5: " + getCheckMessage(MSG_KEY, "public"),
171             "34:5: " + getCheckMessage(MSG_KEY, "static"),
172             "39:5: " + getCheckMessage(MSG_KEY, "public"),
173             "39: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             "21:5: " + getCheckMessage(MSG_KEY, "final"),
184             "26:5: " + getCheckMessage(MSG_KEY, "final"),
185             "29:5: " + getCheckMessage(MSG_KEY, "public"),
186             "31:5: " + getCheckMessage(MSG_KEY, "public"),
187             "31:5: " + getCheckMessage(MSG_KEY, "final"),
188             "37:5: " + getCheckMessage(MSG_KEY, "public"),
189             "39:5: " + getCheckMessage(MSG_KEY, "public"),
190             "39: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             "21:5: " + getCheckMessage(MSG_KEY, "final"),
201             "24:5: " + getCheckMessage(MSG_KEY, "static"),
202             "26:5: " + getCheckMessage(MSG_KEY, "static"),
203             "26:5: " + getCheckMessage(MSG_KEY, "final"),
204             "34:5: " + getCheckMessage(MSG_KEY, "final"),
205             "37:5: " + getCheckMessage(MSG_KEY, "static"),
206             "39:5: " + getCheckMessage(MSG_KEY, "static"),
207             "39: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             "22:5: " + getCheckMessage(MSG_KEY, "static"),
234             "26:5: " + getCheckMessage(MSG_KEY, "public"),
235             "29:5: " + getCheckMessage(MSG_KEY, "public"),
236             "29:5: " + getCheckMessage(MSG_KEY, "static"),
237             "40:5: " + getCheckMessage(MSG_KEY, "static"),
238             "46:5: " + getCheckMessage(MSG_KEY, "public"),
239             "51:5: " + getCheckMessage(MSG_KEY, "public"),
240             "51:5: " + getCheckMessage(MSG_KEY, "static"),
241             "63:5: " + getCheckMessage(MSG_KEY, "static"),
242             "67:5: " + getCheckMessage(MSG_KEY, "public"),
243             "69:5: " + getCheckMessage(MSG_KEY, "public"),
244             "69: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             "22:5: " + getCheckMessage(MSG_KEY, "static"),
255             "29:5: " + getCheckMessage(MSG_KEY, "static"),
256             "38:5: " + getCheckMessage(MSG_KEY, "static"),
257             "49:5: " + getCheckMessage(MSG_KEY, "static"),
258             "58:5: " + getCheckMessage(MSG_KEY, "static"),
259             "65: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             "23:5: " + getCheckMessage(MSG_KEY, "public"),
270             "26:5: " + getCheckMessage(MSG_KEY, "public"),
271             "39:5: " + getCheckMessage(MSG_KEY, "public"),
272             "45:5: " + getCheckMessage(MSG_KEY, "public"),
273             "55:5: " + getCheckMessage(MSG_KEY, "public"),
274             "58: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             "25:9: " + getCheckMessage(MSG_KEY, "public"),
303             "25:9: " + getCheckMessage(MSG_KEY, "static"),
304             "33:9: " + getCheckMessage(MSG_KEY, "public"),
305             "33: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             "25:9: " + getCheckMessage(MSG_KEY, "public"),
318             "25:9: " + getCheckMessage(MSG_KEY, "static"),
319             "33:9: " + getCheckMessage(MSG_KEY, "public"),
320             "33: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             "21:5: " + getCheckMessage(MSG_KEY, "final"),
331             "24:5: " + getCheckMessage(MSG_KEY, "static"),
332             "26:5: " + getCheckMessage(MSG_KEY, "static"),
333             "26:5: " + getCheckMessage(MSG_KEY, "final"),
334             "32:5: " + getCheckMessage(MSG_KEY, "public"),
335             "34:5: " + getCheckMessage(MSG_KEY, "public"),
336             "34:5: " + getCheckMessage(MSG_KEY, "final"),
337             "39:5: " + getCheckMessage(MSG_KEY, "public"),
338             "39:5: " + getCheckMessage(MSG_KEY, "static"),
339             "44:5: " + getCheckMessage(MSG_KEY, "public"),
340             "44:5: " + getCheckMessage(MSG_KEY, "static"),
341             "44:5: " + getCheckMessage(MSG_KEY, "final"),
342             "54:5: " + getCheckMessage(MSG_KEY, "public"),
343             "59:5: " + getCheckMessage(MSG_KEY, "public"),
344             "64:5: " + getCheckMessage(MSG_KEY, "public"),
345             "67:5: " + getCheckMessage(MSG_KEY, "abstract"),
346             "69:5: " + getCheckMessage(MSG_KEY, "public"),
347             "69:5: " + getCheckMessage(MSG_KEY, "abstract"),
348             "77:5: " + getCheckMessage(MSG_KEY, "static"),
349             "80:5: " + getCheckMessage(MSG_KEY, "public"),
350             "82:5: " + getCheckMessage(MSG_KEY, "public"),
351             "82: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 
410 }