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.ModifiedControlVariableCheck.MSG_KEY;
24
25 import java.io.File;
26 import java.util.Collection;
27 import java.util.Optional;
28 import java.util.Set;
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.JavaParser;
35 import com.puppycrawl.tools.checkstyle.api.DetailAST;
36 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
37 import com.puppycrawl.tools.checkstyle.internal.utils.TestUtil;
38 import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
39
40 public class ModifiedControlVariableCheckTest
41 extends AbstractModuleTestSupport {
42
43 @Override
44 protected String getPackageLocation() {
45 return "com/puppycrawl/tools/checkstyle/checks/coding/modifiedcontrolvariable";
46 }
47
48 @Test
49 public void testModifiedControlVariable() throws Exception {
50 final String[] expected = {
51 "17:14: " + getCheckMessage(MSG_KEY, "i"),
52 "20:15: " + getCheckMessage(MSG_KEY, "i"),
53 "23:37: " + getCheckMessage(MSG_KEY, "i"),
54 "24:17: " + getCheckMessage(MSG_KEY, "i"),
55 "52:15: " + getCheckMessage(MSG_KEY, "s"),
56 "59:14: " + getCheckMessage(MSG_KEY, "m"),
57 "70:15: " + getCheckMessage(MSG_KEY, "i"),
58 "71:15: " + getCheckMessage(MSG_KEY, "k"),
59 "81:15: " + getCheckMessage(MSG_KEY, "v"),
60 };
61 verifyWithInlineConfigParser(
62 getPath("InputModifiedControlVariableBothForLoops.java"), expected);
63 }
64
65 @Test
66 public void testEnhancedForLoopVariableTrue() throws Exception {
67
68 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
69 verifyWithInlineConfigParser(
70 getPath("InputModifiedControlVariableEnhancedForLoopVariable.java"),
71 expected);
72 }
73
74 @Test
75 public void testEnhancedForLoopVariableFalse() throws Exception {
76
77 final String[] expected = {
78 "16:18: " + getCheckMessage(MSG_KEY, "line"),
79 };
80 verifyWithInlineConfigParser(
81 getPath("InputModifiedControlVariableEnhancedForLoopVariable3.java"),
82 expected);
83 }
84
85 @Test
86 public void testEnhancedForLoopVariable2() throws Exception {
87
88 final String[] expected = {
89 "21:18: " + getCheckMessage(MSG_KEY, "i"),
90 };
91 verifyWithInlineConfigParser(
92 getPath("InputModifiedControlVariableEnhancedForLoopVariable2.java"),
93 expected);
94 }
95
96 @Test
97 public void testTokensNotNull() {
98 final ModifiedControlVariableCheck check = new ModifiedControlVariableCheck();
99 assertWithMessage("Acceptable tokens should not be null")
100 .that(check.getAcceptableTokens())
101 .isNotNull();
102 assertWithMessage("Default tokens should not be null")
103 .that(check.getDefaultTokens())
104 .isNotNull();
105 assertWithMessage("Required tokens should not be null")
106 .that(check.getRequiredTokens())
107 .isNotNull();
108 }
109
110 @Test
111 public void testImproperToken() {
112 final ModifiedControlVariableCheck check = new ModifiedControlVariableCheck();
113
114 final DetailAstImpl classDefAst = new DetailAstImpl();
115 classDefAst.setType(TokenTypes.CLASS_DEF);
116 classDefAst.setText("CLASS_DEF");
117
118 try {
119 check.visitToken(classDefAst);
120 assertWithMessage("IllegalStateException is expected").fail();
121 }
122 catch (IllegalStateException exc) {
123
124 assertWithMessage("Error message must include token name")
125 .that(exc.getMessage())
126 .contains("CLASS_DEF");
127 }
128
129 try {
130 check.leaveToken(classDefAst);
131 assertWithMessage("IllegalStateException is expected").fail();
132 }
133 catch (IllegalStateException exc) {
134
135 assertWithMessage("Error message must include token name")
136 .that(exc.getMessage())
137 .contains("CLASS_DEF");
138 }
139 }
140
141 @Test
142 public void testVariousAssignments() throws Exception {
143 final String[] expected = {
144 "14:15: " + getCheckMessage(MSG_KEY, "i"),
145 "15:15: " + getCheckMessage(MSG_KEY, "k"),
146 "21:15: " + getCheckMessage(MSG_KEY, "i"),
147 "22:15: " + getCheckMessage(MSG_KEY, "k"),
148 "28:15: " + getCheckMessage(MSG_KEY, "i"),
149 "29:15: " + getCheckMessage(MSG_KEY, "k"),
150 "35:15: " + getCheckMessage(MSG_KEY, "i"),
151 "36:15: " + getCheckMessage(MSG_KEY, "k"),
152 "42:15: " + getCheckMessage(MSG_KEY, "i"),
153 "43:15: " + getCheckMessage(MSG_KEY, "k"),
154 "48:15: " + getCheckMessage(MSG_KEY, "i"),
155 "49:15: " + getCheckMessage(MSG_KEY, "k"),
156 "55:15: " + getCheckMessage(MSG_KEY, "i"),
157 "56:15: " + getCheckMessage(MSG_KEY, "k"),
158 "62:15: " + getCheckMessage(MSG_KEY, "i"),
159 "63:15: " + getCheckMessage(MSG_KEY, "k"),
160 "69:15: " + getCheckMessage(MSG_KEY, "i"),
161 "70:15: " + getCheckMessage(MSG_KEY, "k"),
162 "76:15: " + getCheckMessage(MSG_KEY, "i"),
163 "77:15: " + getCheckMessage(MSG_KEY, "k"),
164 "83:14: " + getCheckMessage(MSG_KEY, "i"),
165 "84:14: " + getCheckMessage(MSG_KEY, "k"),
166 };
167 verifyWithInlineConfigParser(
168 getPath("InputModifiedControlVariableTestVariousAssignments.java"),
169 expected);
170 }
171
172 @Test
173 public void testRecordDecompositionInEnhancedForLoop() throws Exception {
174 final String[] expected = {
175 "32:15: " + getCheckMessage(MSG_KEY, "p"),
176 };
177 verifyWithInlineConfigParser(
178 getNonCompilablePath("InputModifiedControlVariableRecordDecomposition.java"),
179 expected);
180 }
181
182
183
184
185
186
187
188
189 @SuppressWarnings("unchecked")
190 @Test
191 public void testClearState() throws Exception {
192 final ModifiedControlVariableCheck check = new ModifiedControlVariableCheck();
193 final Optional<DetailAST> methodDef = TestUtil.findTokenInAstByPredicate(
194 JavaParser.parseFile(
195 new File(getPath("InputModifiedControlVariableEnhancedForLoopVariable.java")),
196 JavaParser.Options.WITHOUT_COMMENTS),
197 ast -> ast.getType() == TokenTypes.OBJBLOCK);
198
199 assertWithMessage("Ast should contain METHOD_DEF")
200 .that(methodDef.isPresent())
201 .isTrue();
202 assertWithMessage("State is not cleared on beginTree")
203 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check,
204 methodDef.orElseThrow(), "variableStack",
205 variableStack -> ((Collection<Set<String>>) variableStack).isEmpty()))
206 .isTrue();
207 }
208
209 }