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.design;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.design.OneTopLevelClassCheck.MSG_KEY;
24  
25  import java.io.File;
26  import java.util.Arrays;
27  import java.util.List;
28  
29  import org.junit.jupiter.api.Test;
30  
31  import com.google.common.collect.ImmutableMap;
32  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
33  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
34  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
35  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
36  
37  public class OneTopLevelClassCheckTest extends AbstractModuleTestSupport {
38  
39      @Override
40      protected String getPackageLocation() {
41          return "com/puppycrawl/tools/checkstyle/checks/design/onetoplevelclass";
42      }
43  
44      @Test
45      public void testGetRequiredTokens() {
46          final OneTopLevelClassCheck checkObj = new OneTopLevelClassCheck();
47          final int[] expected = {TokenTypes.COMPILATION_UNIT};
48          assertWithMessage("Required tokens are invalid.")
49                  .that(checkObj.getRequiredTokens())
50                  .isEqualTo(expected);
51      }
52  
53      @Test
54      public void testClearState() throws Exception {
55          final DefaultConfiguration checkConfig =
56                  createModuleConfig(OneTopLevelClassCheck.class);
57          final String firstInputFilePath = getPath("InputOneTopLevelClassDeclarationOrder.java");
58          final String secondInputFilePath = getPath("InputOneTopLevelClassInterface2.java");
59  
60          final File[] inputs = {
61              new File(firstInputFilePath),
62              new File(secondInputFilePath),
63          };
64  
65          final List<String> expectedFirstInput = Arrays.asList(
66              "16:1: " + getCheckMessage(MSG_KEY, "InputDeclarationOrderEnum"),
67              "26:1: " + getCheckMessage(MSG_KEY, "InputDeclarationOrderAnnotation"));
68          final List<String> expectedSecondInput = Arrays.asList(
69              "9:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassInterface2inner1"),
70              "17:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassInterface2inner2"));
71  
72          verify(createChecker(checkConfig), inputs,
73              ImmutableMap.of(firstInputFilePath, expectedFirstInput,
74                  secondInputFilePath, expectedSecondInput));
75      }
76  
77      @Test
78      public void testAcceptableTokens() {
79          final OneTopLevelClassCheck check = new OneTopLevelClassCheck();
80          final int[] expected = {TokenTypes.COMPILATION_UNIT};
81          assertWithMessage("Default required tokens are invalid")
82              .that(check.getAcceptableTokens())
83              .isEqualTo(expected);
84      }
85  
86      @Test
87      public void testFileWithOneTopLevelClass() throws Exception {
88          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
89          verifyWithInlineConfigParser(
90                  getPath("InputOneTopLevelClass.java"), expected);
91      }
92  
93      @Test
94      public void testFileWithOneTopLevelInterface() throws Exception {
95          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
96          verifyWithInlineConfigParser(
97                  getPath("InputOneTopLevelClassInterface.java"), expected);
98      }
99  
100     @Test
101     public void testFileWithOneTopLevelEnum() throws Exception {
102         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
103         verifyWithInlineConfigParser(
104                 getPath("InputOneTopLevelClassEnum.java"), expected);
105     }
106 
107     @Test
108     public void testFileWithOneTopLevelAnnotation() throws Exception {
109         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
110         verifyWithInlineConfigParser(
111                 getPath("InputOneTopLevelClassAnnotation.java"), expected);
112     }
113 
114     @Test
115     public void testFileWithNoPublicTopLevelClass() throws Exception {
116         final String[] expected = {
117             "14:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassNoPublic2"),
118         };
119         verifyWithInlineConfigParser(
120                 getPath("InputOneTopLevelClassNoPublic.java"), expected);
121     }
122 
123     @Test
124     public void testFileWithThreeTopLevelInterface() throws Exception {
125         final String[] expected = {
126             "9:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassInterface3inner1"),
127             "17:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassInterface3inner2"),
128         };
129         verifyWithInlineConfigParser(
130                 getPath("InputOneTopLevelClassInterface3.java"), expected);
131     }
132 
133     @Test
134     public void testFileWithThreeTopLevelEnum() throws Exception {
135         final String[] expected = {
136             "9:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassEnum2inner1"),
137             "17:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassEnum2inner2"),
138         };
139         verifyWithInlineConfigParser(
140                 getPath("InputOneTopLevelClassEnum2.java"), expected);
141     }
142 
143     @Test
144     public void testFileWithThreeTopLevelAnnotation() throws Exception {
145         final String[] expected = {
146             "15:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassAnnotation2A"),
147             "20:1: " + getCheckMessage(MSG_KEY, "InputOneTopLevelClassAnnotation2B"),
148         };
149         verifyWithInlineConfigParser(
150                 getPath("InputOneTopLevelClassAnnotation2.java"), expected);
151     }
152 
153     @Test
154     public void testFileWithFewTopLevelClasses() throws Exception {
155         final String[] expected = {
156             "31:1: " + getCheckMessage(MSG_KEY, "NoSuperClone"),
157             "35:1: " + getCheckMessage(MSG_KEY, "InnerClone"),
158             "39:1: " + getCheckMessage(MSG_KEY, "CloneWithTypeArguments"),
159             "43:1: " + getCheckMessage(MSG_KEY, "CloneWithTypeArgumentsAndNoSuper"),
160             "47:1: " + getCheckMessage(MSG_KEY, "MyClassWithGenericSuperMethod"),
161             "51:1: " + getCheckMessage(MSG_KEY, "AnotherClass"),
162             "54:1: " + getCheckMessage(MSG_KEY, "NativeTest"),
163         };
164         verifyWithInlineConfigParser(
165                 getPath("InputOneTopLevelClassClone.java"), expected);
166     }
167 
168     @Test
169     public void testFileWithSecondEnumTopLevelClass() throws Exception {
170         final String[] expected = {
171             "16:1: " + getCheckMessage(MSG_KEY, "InputDeclarationOrderEnum2"),
172             "26:1: " + getCheckMessage(MSG_KEY, "InputDeclarationOrderAnnotation2"),
173         };
174         verifyWithInlineConfigParser(
175                 getPath("InputOneTopLevelClassDeclarationOrder2.java"), expected);
176     }
177 
178     @Test
179     public void testPackageInfoWithNoTypesDeclared() throws Exception {
180         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
181         verifyWithInlineConfigParser(
182                 getNonCompilablePath("package-info.java"), expected);
183     }
184 
185     @Test
186     public void testFileWithMultipleSameLine() throws Exception {
187         final String[] expected = {
188             "9:47: " + getCheckMessage(MSG_KEY, "ViolatingSecondType"),
189         };
190         verifyWithInlineConfigParser(
191                 getPath("InputOneTopLevelClassSameLine.java"), expected);
192     }
193 
194     @Test
195     public void testFileWithIndentation() throws Exception {
196         final String[] expected = {
197             "13:2: " + getCheckMessage(MSG_KEY, "ViolatingIndentedClass1"),
198             "17:5: " + getCheckMessage(MSG_KEY, "ViolatingIndentedClass2"),
199             "21:1: " + getCheckMessage(MSG_KEY, "ViolatingNonIndentedInterface"),
200         };
201         verifyWithInlineConfigParser(
202                 getPath("InputOneTopLevelClassIndentation.java"), expected);
203     }
204 
205     @Test
206     public void testOneTopLevelClassRecords() throws Exception {
207         final String[] expected = {
208             "13:1: " + getCheckMessage(MSG_KEY, "TestRecord1"),
209             "17:1: " + getCheckMessage(MSG_KEY, "TestRecord2"),
210         };
211         verifyWithInlineConfigParser(
212                 getNonCompilablePath("InputOneTopLevelClassRecords.java"), expected);
213     }
214 
215     @Test
216     public void testOneTopLevelClassEmpty() throws Exception {
217         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
218         verifyWithInlineConfigParser(
219                 getNonCompilablePath("InputOneTopLevelClassEmpty.java"), expected);
220     }
221 }