View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2025 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.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheck.MSG_ACCESS;
24  import static com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheck.MSG_CONSTRUCTOR;
25  import static com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheck.MSG_INSTANCE;
26  import static com.puppycrawl.tools.checkstyle.checks.coding.DeclarationOrderCheck.MSG_STATIC;
27  
28  import java.util.SortedSet;
29  
30  import org.junit.jupiter.api.Test;
31  
32  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
33  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
34  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
35  import com.puppycrawl.tools.checkstyle.api.Violation;
36  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
37  
38  public class DeclarationOrderCheckTest
39      extends AbstractModuleTestSupport {
40  
41      @Override
42      protected String getPackageLocation() {
43          return "com/puppycrawl/tools/checkstyle/checks/coding/declarationorder";
44      }
45  
46      @Test
47      public void testDefault1() throws Exception {
48  
49          final String[] expected = {
50              "16:5: " + getCheckMessage(MSG_ACCESS),
51              "21:5: " + getCheckMessage(MSG_ACCESS),
52              "26:5: " + getCheckMessage(MSG_ACCESS),
53              "29:5: " + getCheckMessage(MSG_ACCESS),
54              "35:5: " + getCheckMessage(MSG_STATIC),
55              "42:9: " + getCheckMessage(MSG_ACCESS),
56              "60:9: " + getCheckMessage(MSG_STATIC),
57              "69:5: " + getCheckMessage(MSG_CONSTRUCTOR),
58              "95:5: " + getCheckMessage(MSG_INSTANCE),
59          };
60          verifyWithInlineConfigParser(
61                  getPath("InputDeclarationOrderDefault1.java"), expected);
62      }
63  
64      @Test
65      public void testDefault2() throws Exception {
66  
67          final String[] expected = {
68              "20:9: " + getCheckMessage(MSG_ACCESS),
69              "28:9: " + getCheckMessage(MSG_STATIC),
70              "34:5: " + getCheckMessage(MSG_ACCESS),
71              "39:5: " + getCheckMessage(MSG_ACCESS),
72              "44:5: " + getCheckMessage(MSG_ACCESS),
73              "47:5: " + getCheckMessage(MSG_ACCESS),
74              "53:5: " + getCheckMessage(MSG_STATIC),
75              "60:9: " + getCheckMessage(MSG_ACCESS),
76              "71:9: " + getCheckMessage(MSG_STATIC),
77              "80:5: " + getCheckMessage(MSG_CONSTRUCTOR),
78              "106:5: " + getCheckMessage(MSG_INSTANCE),
79              "111:9: " + getCheckMessage(MSG_ACCESS),
80          };
81          verifyWithInlineConfigParser(
82                  getPath("InputDeclarationOrderDefault2.java"), expected);
83      }
84  
85      @Test
86      public void testDefault3() throws Exception {
87          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
88          verifyWithInlineConfigParser(
89                  getPath("InputDeclarationOrderDefault3.java"),
90                  expected);
91      }
92  
93      @Test
94      public void testOnlyConstructors1() throws Exception {
95  
96          final String[] expected = {
97              "53:9: " + getCheckMessage(MSG_STATIC),
98              "62:5: " + getCheckMessage(MSG_CONSTRUCTOR),
99              "88:5: " + getCheckMessage(MSG_INSTANCE),
100         };
101         verifyWithInlineConfigParser(
102                 getPath("InputDeclarationOrderOnlyConstructors1.java"), expected);
103     }
104 
105     @Test
106     public void testOnlyConstructors2() throws Exception {
107 
108         final String[] expected = {
109             "27:9: " + getCheckMessage(MSG_STATIC),
110             "63:9: " + getCheckMessage(MSG_STATIC),
111             "72:5: " + getCheckMessage(MSG_CONSTRUCTOR),
112             "98:5: " + getCheckMessage(MSG_INSTANCE),
113         };
114         verifyWithInlineConfigParser(
115                 getPath("InputDeclarationOrderOnlyConstructors2.java"), expected);
116     }
117 
118     @Test
119     public void testOnlyModifiers1() throws Exception {
120 
121         final String[] expected = {
122             "16:5: " + getCheckMessage(MSG_ACCESS),
123             "21:5: " + getCheckMessage(MSG_ACCESS),
124             "26:5: " + getCheckMessage(MSG_ACCESS),
125             "29:5: " + getCheckMessage(MSG_ACCESS),
126             "35:5: " + getCheckMessage(MSG_STATIC),
127             "42:9: " + getCheckMessage(MSG_ACCESS),
128             "60:9: " + getCheckMessage(MSG_STATIC),
129             "94:5: " + getCheckMessage(MSG_INSTANCE),
130         };
131         verifyWithInlineConfigParser(
132                 getPath("InputDeclarationOrderOnlyModifiers1.java"), expected);
133     }
134 
135     @Test
136     public void testOnlyModifiers2() throws Exception {
137 
138         final String[] expected = {
139             "20:9: " + getCheckMessage(MSG_ACCESS),
140             "28:9: " + getCheckMessage(MSG_STATIC),
141             "34:5: " + getCheckMessage(MSG_ACCESS),
142             "39:5: " + getCheckMessage(MSG_ACCESS),
143             "44:5: " + getCheckMessage(MSG_ACCESS),
144             "47:5: " + getCheckMessage(MSG_ACCESS),
145             "53:5: " + getCheckMessage(MSG_STATIC),
146             "60:9: " + getCheckMessage(MSG_ACCESS),
147             "71:9: " + getCheckMessage(MSG_STATIC),
148             "105:5: " + getCheckMessage(MSG_INSTANCE),
149             "110:9: " + getCheckMessage(MSG_ACCESS),
150         };
151         verifyWithInlineConfigParser(
152                 getPath("InputDeclarationOrderOnlyModifiers2.java"), expected);
153     }
154 
155     @Test
156     public void testTokensNotNull() {
157         final DeclarationOrderCheck check = new DeclarationOrderCheck();
158         assertWithMessage("Acceptable tokens should not be null")
159             .that(check.getAcceptableTokens())
160             .isNotNull();
161         assertWithMessage("Default tokens should not be null")
162             .that(check.getDefaultTokens())
163             .isNotNull();
164         assertWithMessage("Required tokens should not be null")
165             .that(check.getRequiredTokens())
166             .isNotNull();
167     }
168 
169     @Test
170     public void testParents() {
171         final DetailAstImpl parent = new DetailAstImpl();
172         parent.setType(TokenTypes.STATIC_INIT);
173         final DetailAstImpl method = new DetailAstImpl();
174         method.setType(TokenTypes.METHOD_DEF);
175         parent.setFirstChild(method);
176         final DetailAstImpl ctor = new DetailAstImpl();
177         ctor.setType(TokenTypes.CTOR_DEF);
178         method.setNextSibling(ctor);
179 
180         final DeclarationOrderCheck check = new DeclarationOrderCheck();
181 
182         check.visitToken(method);
183         final SortedSet<Violation> violations1 = check.getViolations();
184 
185         assertWithMessage("No exception violations expected")
186             .that(violations1)
187             .isEmpty();
188 
189         check.visitToken(ctor);
190         final SortedSet<Violation> violations2 = check.getViolations();
191 
192         assertWithMessage("No exception violations expected")
193             .that(violations2)
194             .isEmpty();
195     }
196 
197     @Test
198     public void testImproperToken() {
199         final DetailAstImpl parent = new DetailAstImpl();
200         parent.setType(TokenTypes.STATIC_INIT);
201         final DetailAstImpl array = new DetailAstImpl();
202         array.setType(TokenTypes.ARRAY_INIT);
203         parent.setFirstChild(array);
204 
205         final DeclarationOrderCheck check = new DeclarationOrderCheck();
206 
207         check.visitToken(array);
208         final SortedSet<Violation> violations = check.getViolations();
209 
210         assertWithMessage("No exception violations expected")
211             .that(violations)
212             .isEmpty();
213     }
214 
215     @Test
216     public void testForwardReference() throws Exception {
217         final String[] expected = {
218             "20:5: " + getCheckMessage(MSG_ACCESS),
219             "22:5: " + getCheckMessage(MSG_ACCESS),
220             "23:5: " + getCheckMessage(MSG_ACCESS),
221             "24:5: " + getCheckMessage(MSG_ACCESS),
222             "25:5: " + getCheckMessage(MSG_ACCESS),
223             "26:5: " + getCheckMessage(MSG_ACCESS),
224             "32:5: " + getCheckMessage(MSG_ACCESS),
225             "50:5: " + getCheckMessage(MSG_STATIC),
226             "70:5: " + getCheckMessage(MSG_ACCESS),
227         };
228         verifyWithInlineConfigParser(
229                 getPath("InputDeclarationOrderForwardReference.java"), expected);
230     }
231 
232     @Test
233     public void testDeclarationOrderRecordsAndCompactCtors() throws Exception {
234         final String[] expected = {
235             "21:9: " + getCheckMessage(MSG_CONSTRUCTOR),
236             "24:9: " + getCheckMessage(MSG_STATIC),
237             "33:9: " + getCheckMessage(MSG_CONSTRUCTOR),
238             "36:9: " + getCheckMessage(MSG_STATIC),
239             "43:9: " + getCheckMessage(MSG_STATIC),
240         };
241         verifyWithInlineConfigParser(
242                 getPath("InputDeclarationOrderRecordsAndCompactCtors.java"),
243             expected);
244     }
245 
246     @Test
247     public void testDeclarationOrderInterfaceMemberScopeIsPublic() throws Exception {
248         final String[] expected = {
249             "21:3: " + getCheckMessage(MSG_STATIC),
250         };
251         verifyWithInlineConfigParser(
252                 getPath("InputDeclarationOrderInterfaceMemberScopeIsPublic.java"),
253             expected);
254     }
255 
256     @Test
257     public void testVariableAccess() throws Exception {
258         final String[] expected = {
259             "23:5: " + getCheckMessage(MSG_ACCESS),
260         };
261         verifyWithInlineConfigParser(
262                 getPath("InputDeclarationOrderVariableAccess.java"), expected);
263     }
264 
265     @Test
266     public void testAvoidDuplicatesForStaticFinalFields() throws Exception {
267         final String[] expected = {
268             "14:5: " + getCheckMessage(MSG_STATIC),
269         };
270         verifyWithInlineConfigParser(
271                 getPath("InputDeclarationOrderAvoidDuplicatesInStaticFinalFields.java"),
272                 expected);
273     }
274 
275 }