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.sizes;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.sizes.ExecutableStatementCountCheck.MSG_KEY;
24  import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
25  
26  import java.util.Collection;
27  
28  import org.antlr.v4.runtime.CommonToken;
29  import org.junit.jupiter.api.Test;
30  
31  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
32  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
33  import com.puppycrawl.tools.checkstyle.api.Context;
34  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
35  import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
36  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
37  
38  public class ExecutableStatementCountCheckTest
39      extends AbstractModuleTestSupport {
40  
41      @Override
42      public String getPackageLocation() {
43          return "com/puppycrawl/tools/checkstyle/checks/sizes/executablestatementcount";
44      }
45  
46      @SuppressWarnings("unchecked")
47      @Test
48      public void testStatefulFieldsClearedOnBeginTree() {
49          final DetailAstImpl ast = new DetailAstImpl();
50          ast.setType(TokenTypes.STATIC_INIT);
51          final ExecutableStatementCountCheck check = new ExecutableStatementCountCheck();
52          assertWithMessage("Stateful field is not cleared after beginTree")
53                  .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check, ast, "contextStack",
54                          contextStack -> ((Collection<Context>) contextStack).isEmpty()))
55                  .isTrue();
56      }
57  
58      @Test
59      public void testMaxZero() throws Exception {
60  
61          final String[] expected = {
62              "12:5: " + getCheckMessage(MSG_KEY, 3, 0),
63              "15:17: " + getCheckMessage(MSG_KEY, 1, 0),
64              "25:5: " + getCheckMessage(MSG_KEY, 2, 0),
65              "35:5: " + getCheckMessage(MSG_KEY, 1, 0),
66              "42:5: " + getCheckMessage(MSG_KEY, 3, 0),
67              "56:5: " + getCheckMessage(MSG_KEY, 2, 0),
68              "66:5: " + getCheckMessage(MSG_KEY, 2, 0),
69              "75:5: " + getCheckMessage(MSG_KEY, 2, 0),
70              "84:5: " + getCheckMessage(MSG_KEY, 2, 0),
71              "87:13: " + getCheckMessage(MSG_KEY, 1, 0),
72              "98:29: " + getCheckMessage(MSG_KEY, 1, 0),
73          };
74  
75          verifyWithInlineConfigParser(
76                  getPath("InputExecutableStatementCountMaxZero.java"), expected);
77      }
78  
79      @Test
80      public void testMethodDef() throws Exception {
81  
82          final String[] expected = {
83              "12:5: " + getCheckMessage(MSG_KEY, 3, 0),
84              "15:17: " + getCheckMessage(MSG_KEY, 1, 0),
85              "25:5: " + getCheckMessage(MSG_KEY, 2, 0),
86              "35:5: " + getCheckMessage(MSG_KEY, 1, 0),
87              "42:5: " + getCheckMessage(MSG_KEY, 3, 0),
88              "60:13: " + getCheckMessage(MSG_KEY, 1, 0),
89          };
90  
91          verifyWithInlineConfigParser(
92                  getPath("InputExecutableStatementCountMethodDef.java"), expected);
93      }
94  
95      @Test
96      public void testCtorDef() throws Exception {
97  
98          final String[] expected = {
99              "12:5: " + getCheckMessage(MSG_KEY, 2, 0),
100             "22:5: " + getCheckMessage(MSG_KEY, 2, 0),
101         };
102 
103         verifyWithInlineConfigParser(
104                 getPath("InputExecutableStatementCountCtorDef.java"), expected);
105     }
106 
107     @Test
108     public void testStaticInit() throws Exception {
109 
110         final String[] expected = {
111             "13:5: " + getCheckMessage(MSG_KEY, 2, 0),
112         };
113 
114         verifyWithInlineConfigParser(
115                 getPath("InputExecutableStatementCountStaticInit.java"), expected);
116     }
117 
118     @Test
119     public void testInstanceInit() throws Exception {
120 
121         final String[] expected = {
122             "13:5: " + getCheckMessage(MSG_KEY, 2, 0),
123         };
124 
125         verifyWithInlineConfigParser(
126                 getPath("InputExecutableStatementCountInstanceInit.java"), expected);
127     }
128 
129     @Test
130     public void testVisitTokenWithWrongTokenType() {
131         final ExecutableStatementCountCheck checkObj =
132             new ExecutableStatementCountCheck();
133         final DetailAstImpl ast = new DetailAstImpl();
134         ast.initialize(
135             new CommonToken(TokenTypes.ENUM, "ENUM"));
136         final IllegalStateException visit =
137                 getExpectedThrowable(IllegalStateException.class,
138                         () -> checkObj.visitToken(ast));
139         assertWithMessage("Invalid exception message")
140             .that(visit.getMessage())
141             .isEqualTo("ENUM[0x-1]");
142     }
143 
144     @Test
145     public void testLeaveTokenWithWrongTokenType() {
146         final ExecutableStatementCountCheck checkObj =
147             new ExecutableStatementCountCheck();
148         final DetailAstImpl ast = new DetailAstImpl();
149         ast.initialize(
150             new CommonToken(TokenTypes.ENUM, "ENUM"));
151         final IllegalStateException leave =
152                 getExpectedThrowable(IllegalStateException.class,
153                         () -> checkObj.leaveToken(ast));
154         assertWithMessage("Invalid exception message")
155             .that(leave.getMessage())
156             .isEqualTo("ENUM[0x-1]");
157     }
158 
159     @Test
160     public void testDefaultConfiguration() throws Exception {
161 
162         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
163         verifyWithInlineConfigParser(
164                 getPath("InputExecutableStatementCountDefaultConfig.java"), expected);
165     }
166 
167     @Test
168     public void testExecutableStatementCountRecords() throws Exception {
169 
170         final int max = 1;
171 
172         final String[] expected = {
173             "15:9: " + getCheckMessage(MSG_KEY, 3, max),
174             "24:9: " + getCheckMessage(MSG_KEY, 3, max),
175             "33:9: " + getCheckMessage(MSG_KEY, 3, max),
176             "41:9: " + getCheckMessage(MSG_KEY, 4, max),
177             "51:9: " + getCheckMessage(MSG_KEY, 6, max),
178             "65:17: " + getCheckMessage(MSG_KEY, 6, max),
179         };
180 
181         verifyWithInlineConfigParser(
182                 getPath("InputExecutableStatementCountRecords.java"),
183                 expected);
184     }
185 
186     @Test
187     public void testExecutableStatementCountLambdas() throws Exception {
188 
189         final int max = 1;
190 
191         final String[] expected = {
192             "16:22: " + getCheckMessage(MSG_KEY, 6, max),
193             "25:22: " + getCheckMessage(MSG_KEY, 2, max),
194             "26:26: " + getCheckMessage(MSG_KEY, 2, max),
195             "30:26: " + getCheckMessage(MSG_KEY, 4, max),
196         };
197 
198         verifyWithInlineConfigParser(
199                 getPath("InputExecutableStatementCountLambdas.java"), expected);
200     }
201 
202 }