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
117 try {
118 check.visitToken(classDefAst);
119 assertWithMessage("IllegalStateException is expected").fail();
120 }
121 catch (IllegalStateException ex) {
122
123 }
124
125 try {
126 check.leaveToken(classDefAst);
127 assertWithMessage("IllegalStateException is expected").fail();
128 }
129 catch (IllegalStateException ex) {
130
131 }
132 }
133
134 @Test
135 public void testVariousAssignments() throws Exception {
136 final String[] expected = {
137 "14:15: " + getCheckMessage(MSG_KEY, "i"),
138 "15:15: " + getCheckMessage(MSG_KEY, "k"),
139 "21:15: " + getCheckMessage(MSG_KEY, "i"),
140 "22:15: " + getCheckMessage(MSG_KEY, "k"),
141 "28:15: " + getCheckMessage(MSG_KEY, "i"),
142 "29:15: " + getCheckMessage(MSG_KEY, "k"),
143 "35:15: " + getCheckMessage(MSG_KEY, "i"),
144 "36:15: " + getCheckMessage(MSG_KEY, "k"),
145 "42:15: " + getCheckMessage(MSG_KEY, "i"),
146 "43:15: " + getCheckMessage(MSG_KEY, "k"),
147 "48:15: " + getCheckMessage(MSG_KEY, "i"),
148 "49:15: " + getCheckMessage(MSG_KEY, "k"),
149 "55:15: " + getCheckMessage(MSG_KEY, "i"),
150 "56:15: " + getCheckMessage(MSG_KEY, "k"),
151 "62:15: " + getCheckMessage(MSG_KEY, "i"),
152 "63:15: " + getCheckMessage(MSG_KEY, "k"),
153 "69:15: " + getCheckMessage(MSG_KEY, "i"),
154 "70:15: " + getCheckMessage(MSG_KEY, "k"),
155 "76:15: " + getCheckMessage(MSG_KEY, "i"),
156 "77:15: " + getCheckMessage(MSG_KEY, "k"),
157 "83:14: " + getCheckMessage(MSG_KEY, "i"),
158 "84:14: " + getCheckMessage(MSG_KEY, "k"),
159 };
160 verifyWithInlineConfigParser(
161 getPath("InputModifiedControlVariableTestVariousAssignments.java"),
162 expected);
163 }
164
165 @Test
166 public void testRecordDecompositionInEnhancedForLoop() throws Exception {
167 final String[] expected = {
168 "32:15: " + getCheckMessage(MSG_KEY, "p"),
169 };
170 verifyWithInlineConfigParser(
171 getNonCompilablePath("InputModifiedControlVariableRecordDecomposition.java"),
172 expected);
173 }
174
175
176
177
178
179
180
181
182 @Test
183 @SuppressWarnings("unchecked")
184 public void testClearState() throws Exception {
185 final ModifiedControlVariableCheck check = new ModifiedControlVariableCheck();
186 final Optional<DetailAST> methodDef = TestUtil.findTokenInAstByPredicate(
187 JavaParser.parseFile(
188 new File(getPath("InputModifiedControlVariableEnhancedForLoopVariable.java")),
189 JavaParser.Options.WITHOUT_COMMENTS),
190 ast -> ast.getType() == TokenTypes.OBJBLOCK);
191
192 assertWithMessage("Ast should contain METHOD_DEF")
193 .that(methodDef.isPresent())
194 .isTrue();
195 assertWithMessage("State is not cleared on beginTree")
196 .that(TestUtil.isStatefulFieldClearedDuringBeginTree(check,
197 methodDef.orElseThrow(), "variableStack",
198 variableStack -> ((Collection<Set<String>>) variableStack).isEmpty()))
199 .isTrue();
200 }
201
202 }