1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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.ReturnCountCheck.MSG_KEY;
24 import static com.puppycrawl.tools.checkstyle.checks.coding.ReturnCountCheck.MSG_KEY_VOID;
25 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.getExpectedThrowable;
26
27 import java.io.File;
28 import java.util.Collection;
29 import java.util.Optional;
30 import java.util.Set;
31
32 import org.junit.jupiter.api.Test;
33
34 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
35 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
36 import com.puppycrawl.tools.checkstyle.JavaParser;
37 import com.puppycrawl.tools.checkstyle.api.DetailAST;
38 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
39 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
40 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
41
42 public class ReturnCountCheckTest extends AbstractModuleTestSupport {
43
44 @Override
45 public String getPackageLocation() {
46 return "com/puppycrawl/tools/checkstyle/checks/coding/returncount";
47 }
48
49 @Test
50 public void testDefault() throws Exception {
51 final String[] expected = {
52 "28:5: " + getCheckMessage(MSG_KEY_VOID, 7, 1),
53 "40:5: " + getCheckMessage(MSG_KEY_VOID, 2, 1),
54 "45:17: " + getCheckMessage(MSG_KEY_VOID, 6, 1),
55 "59:5: " + getCheckMessage(MSG_KEY, 7, 2),
56 };
57 verifyWithInlineConfigParser(
58 getPath("InputReturnCountSwitches.java"), expected);
59 }
60
61 @Test
62 public void testFormat() throws Exception {
63 final String[] expected = {
64 "15:5: " + getCheckMessage(MSG_KEY, 7, 2),
65 "28:5: " + getCheckMessage(MSG_KEY_VOID, 7, 1),
66 "40:5: " + getCheckMessage(MSG_KEY_VOID, 2, 1),
67 "45:17: " + getCheckMessage(MSG_KEY_VOID, 6, 1),
68 "59:5: " + getCheckMessage(MSG_KEY, 7, 2),
69 };
70 verifyWithInlineConfigParser(
71 getPath("InputReturnCountSwitches2.java"), expected);
72 }
73
74 @Test
75 public void testMethodsAndLambdas() throws Exception {
76 final String[] expected = {
77 "25:55: " + getCheckMessage(MSG_KEY, 2, 1),
78 "37:49: " + getCheckMessage(MSG_KEY, 2, 1),
79 "44:42: " + getCheckMessage(MSG_KEY, 3, 1),
80 "51:5: " + getCheckMessage(MSG_KEY, 2, 1),
81 "59:57: " + getCheckMessage(MSG_KEY, 2, 1),
82 };
83 verifyWithInlineConfigParser(
84 getPath("InputReturnCountLambda.java"), expected);
85 }
86
87 @Test
88 public void testLambdasOnly() throws Exception {
89 final String[] expected = {
90 "43:42: " + getCheckMessage(MSG_KEY, 3, 2),
91 };
92 verifyWithInlineConfigParser(
93 getPath("InputReturnCountLambda2.java"), expected);
94 }
95
96 @Test
97 public void testMethodsOnly() throws Exception {
98 final String[] expected = {
99 "35:5: " + getCheckMessage(MSG_KEY, 3, 2),
100 "42:5: " + getCheckMessage(MSG_KEY, 4, 2),
101 "50:5: " + getCheckMessage(MSG_KEY, 4, 2),
102 "65:5: " + getCheckMessage(MSG_KEY, 3, 2),
103 };
104 verifyWithInlineConfigParser(
105 getPath("InputReturnCountLambda3.java"), expected);
106 }
107
108 @Test
109 public void testWithReturnOnlyAsTokens() throws Exception {
110 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
111 verifyWithInlineConfigParser(
112 getPath("InputReturnCountLambda4.java"), expected);
113 }
114
115 @Test
116 public void testImproperToken() {
117 final ReturnCountCheck check = new ReturnCountCheck();
118
119 final DetailAstImpl classDefAst = new DetailAstImpl();
120 classDefAst.setType(TokenTypes.CLASS_DEF);
121
122 getExpectedThrowable(IllegalStateException.class,
123 () -> check.visitToken(classDefAst));
124
125 getExpectedThrowable(IllegalStateException.class,
126 () -> check.leaveToken(classDefAst));
127 }
128
129 @Test
130 public void testMaxForVoid() throws Exception {
131 final String[] expected = {
132 "14:5: " + getCheckMessage(MSG_KEY_VOID, 1, 0),
133 "18:5: " + getCheckMessage(MSG_KEY_VOID, 1, 0),
134 "24:5: " + getCheckMessage(MSG_KEY_VOID, 2, 0),
135 "40:5: " + getCheckMessage(MSG_KEY, 3, 2),
136 "51:5: " + getCheckMessage(MSG_KEY_VOID, 2, 0),
137 };
138 verifyWithInlineConfigParser(
139 getPath("InputReturnCountVoid.java"), expected);
140 }
141
142
143
144
145
146
147
148
149 @SuppressWarnings("unchecked")
150 @Test
151 public void testClearState() throws Exception {
152 final ReturnCountCheck check = new ReturnCountCheck();
153 final Optional<DetailAST> methodDef = TestUtil.findTokenInAstByPredicate(
154 JavaParser.parseFile(new File(getPath("InputReturnCountVoid.java")),
155 JavaParser.Options.WITHOUT_COMMENTS),
156 ast -> ast.getType() == TokenTypes.METHOD_DEF);
157
158 assertWithMessage("Ast should contain METHOD_DEF")
159 .that(methodDef.isPresent())
160 .isTrue();
161 assertWithMessage("State is not cleared on beginTree")
162 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check,
163 methodDef.orElseThrow(), "contextStack",
164 contextStack -> ((Collection<Set<String>>) contextStack).isEmpty()))
165 .isTrue();
166 }
167
168
169
170
171
172
173
174 @Test
175 public void testImproperVisitToken() {
176 final ReturnCountCheck check = new ReturnCountCheck();
177 final DetailAstImpl classDefAst = new DetailAstImpl();
178 classDefAst.setType(TokenTypes.CLASS_DEF);
179 final IllegalStateException exception = getExpectedThrowable(IllegalStateException.class,
180 () -> check.visitToken(classDefAst), "IllegalStateException was expected");
181
182 assertWithMessage("Message doesn't contain ast")
183 .that(exception.getMessage())
184 .isEqualTo(classDefAst.toString());
185 }
186
187
188
189
190
191
192
193 @Test
194 public void testImproperLeaveToken() {
195 final ReturnCountCheck check = new ReturnCountCheck();
196 final DetailAstImpl classDefAst = new DetailAstImpl();
197 classDefAst.setType(TokenTypes.CLASS_DEF);
198 final IllegalStateException exception = getExpectedThrowable(IllegalStateException.class,
199 () -> check.leaveToken(classDefAst), "IllegalStateException was expected");
200
201 assertWithMessage("Message doesn't contain ast")
202 .that(exception.getMessage())
203 .isEqualTo(classDefAst.toString());
204 }
205
206 }