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.utils;
21
22 import static com.google.common.truth.Truth.assertWithMessage;
23 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor;
24
25 import java.util.Optional;
26
27 import org.junit.jupiter.api.Test;
28
29 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
30 import com.puppycrawl.tools.checkstyle.api.DetailAST;
31 import com.puppycrawl.tools.checkstyle.api.Scope;
32 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
33
34 public class ScopeUtilTest {
35
36 @Test
37 public void testIsProperUtilsClass() throws ReflectiveOperationException {
38 assertWithMessage("Constructor is not private")
39 .that(isUtilsClassHasPrivateConstructor(ScopeUtil.class))
40 .isTrue();
41 }
42
43 @Test
44 public void testInClassBlock() {
45 assertWithMessage("Should return false when passed is not class")
46 .that(ScopeUtil.isInClassBlock(new DetailAstImpl()))
47 .isFalse();
48 assertWithMessage("Should return false when passed is not class")
49 .that(ScopeUtil
50 .isInClassBlock(getNode(TokenTypes.LITERAL_NEW, TokenTypes.MODIFIERS)))
51 .isFalse();
52 assertWithMessage("Should return true when passed is class")
53 .that(ScopeUtil.isInClassBlock(
54 getNode(TokenTypes.OBJBLOCK, TokenTypes.CLASS_DEF, TokenTypes.MODIFIERS)))
55 .isTrue();
56 assertWithMessage("Should return false when passed is not class")
57 .that(ScopeUtil.isInClassBlock(getNode(TokenTypes.CLASS_DEF,
58 TokenTypes.INTERFACE_DEF, TokenTypes.MODIFIERS)))
59 .isFalse();
60 assertWithMessage("Should return false when passed is not class")
61 .that(ScopeUtil.isInClassBlock(getNode(TokenTypes.CLASS_DEF,
62 TokenTypes.ANNOTATION_DEF, TokenTypes.MODIFIERS)))
63 .isFalse();
64 assertWithMessage("Should return false when passed is not class")
65 .that(ScopeUtil.isInClassBlock(
66 getNode(TokenTypes.CLASS_DEF, TokenTypes.ENUM_DEF, TokenTypes.MODIFIERS)))
67 .isFalse();
68 assertWithMessage("Should return false when passed is not class")
69 .that(ScopeUtil.isInClassBlock(
70 getNode(TokenTypes.CLASS_DEF, TokenTypes.LITERAL_NEW, TokenTypes.IDENT)))
71 .isFalse();
72 assertWithMessage("Should return false when passed is not expected")
73 .that(ScopeUtil.isInClassBlock(getNode(TokenTypes.PACKAGE_DEF, TokenTypes.DOT)))
74 .isFalse();
75 }
76
77 @Test
78 public void testInEnumBlock() {
79 assertWithMessage("Should return false when passed is not enum")
80 .that(ScopeUtil.isInEnumBlock(new DetailAstImpl()))
81 .isFalse();
82 assertWithMessage("Should return false when passed is not enum")
83 .that(ScopeUtil
84 .isInEnumBlock(getNode(TokenTypes.LITERAL_NEW, TokenTypes.MODIFIERS)))
85 .isFalse();
86 assertWithMessage("Should return true when passed is enum")
87 .that(ScopeUtil.isInEnumBlock(
88 getNode(TokenTypes.OBJBLOCK, TokenTypes.ENUM_DEF, TokenTypes.MODIFIERS)))
89 .isTrue();
90 assertWithMessage("Should return false when passed is not enum")
91 .that(ScopeUtil.isInEnumBlock(getNode(TokenTypes.ENUM_DEF, TokenTypes.INTERFACE_DEF,
92 TokenTypes.MODIFIERS)))
93 .isFalse();
94 assertWithMessage("Should return false when passed is not enum")
95 .that(ScopeUtil.isInEnumBlock(getNode(TokenTypes.ENUM_DEF,
96 TokenTypes.ANNOTATION_DEF, TokenTypes.MODIFIERS)))
97 .isFalse();
98 assertWithMessage("Should return false when passed is not enum")
99 .that(ScopeUtil.isInEnumBlock(
100 getNode(TokenTypes.ENUM_DEF, TokenTypes.CLASS_DEF, TokenTypes.MODIFIERS)))
101 .isFalse();
102 assertWithMessage("Should return false when passed is not enum")
103 .that(ScopeUtil.isInEnumBlock(
104 getNode(TokenTypes.ENUM_DEF, TokenTypes.LITERAL_NEW, TokenTypes.IDENT)))
105 .isFalse();
106 assertWithMessage("Should return false when passed is not expected")
107 .that(ScopeUtil.isInEnumBlock(getNode(TokenTypes.PACKAGE_DEF, TokenTypes.DOT)))
108 .isFalse();
109 }
110
111 @Test
112 public void testIsInCodeBlock() {
113 assertWithMessage("invalid result")
114 .that(ScopeUtil.isInCodeBlock(getNode(TokenTypes.CLASS_DEF)))
115 .isFalse();
116 assertWithMessage("invalid result")
117 .that(ScopeUtil.isInCodeBlock(getNode(TokenTypes.ASSIGN, TokenTypes.VARIABLE_DEF)))
118 .isFalse();
119 assertWithMessage("invalid result")
120 .that(ScopeUtil.isInCodeBlock(getNode(TokenTypes.METHOD_DEF, TokenTypes.OBJBLOCK)))
121 .isTrue();
122 assertWithMessage("invalid result")
123 .that(ScopeUtil.isInCodeBlock(getNode(TokenTypes.CTOR_DEF, TokenTypes.OBJBLOCK)))
124 .isTrue();
125 assertWithMessage("invalid result")
126 .that(ScopeUtil
127 .isInCodeBlock(getNode(TokenTypes.INSTANCE_INIT, TokenTypes.OBJBLOCK)))
128 .isTrue();
129 assertWithMessage("invalid result")
130 .that(ScopeUtil.isInCodeBlock(getNode(TokenTypes.STATIC_INIT, TokenTypes.OBJBLOCK)))
131 .isTrue();
132 assertWithMessage("invalid result")
133 .that(ScopeUtil.isInCodeBlock(getNode(TokenTypes.LAMBDA, TokenTypes.ASSIGN)))
134 .isTrue();
135 }
136
137 @Test
138 public void testInRecordBlock() {
139 assertWithMessage("Should return false when passed is not record")
140 .that(ScopeUtil.isInRecordBlock(new DetailAstImpl()))
141 .isFalse();
142 assertWithMessage("Should return false when passed is not record")
143 .that(ScopeUtil
144 .isInRecordBlock(getNode(TokenTypes.LITERAL_NEW, TokenTypes.MODIFIERS)))
145 .isFalse();
146 assertWithMessage("Should return true when passed is record")
147 .that(ScopeUtil.isInRecordBlock(
148 getNode(TokenTypes.OBJBLOCK, TokenTypes.RECORD_DEF, TokenTypes.MODIFIERS)))
149 .isTrue();
150 assertWithMessage("Should return false when passed is not record")
151 .that(ScopeUtil.isInRecordBlock(getNode(TokenTypes.RECORD_DEF,
152 TokenTypes.INTERFACE_DEF, TokenTypes.MODIFIERS)))
153 .isFalse();
154 assertWithMessage("Should return false when passed is not record")
155 .that(ScopeUtil.isInRecordBlock(getNode(TokenTypes.RECORD_DEF,
156 TokenTypes.ANNOTATION_DEF, TokenTypes.MODIFIERS)))
157 .isFalse();
158 assertWithMessage("Should return false when passed is not record")
159 .that(ScopeUtil.isInRecordBlock(
160 getNode(TokenTypes.RECORD_DEF, TokenTypes.ENUM_DEF, TokenTypes.MODIFIERS)))
161 .isFalse();
162 assertWithMessage("Should return false when passed is not record")
163 .that(ScopeUtil.isInRecordBlock(
164 getNode(TokenTypes.RECORD_DEF, TokenTypes.LITERAL_NEW, TokenTypes.IDENT)))
165 .isFalse();
166 assertWithMessage("Should return false when passed is not expected")
167 .that(ScopeUtil.isInRecordBlock(getNode(TokenTypes.PACKAGE_DEF, TokenTypes.DOT)))
168 .isFalse();
169 }
170
171 @Test
172 public void testIsOuterMostTypeInterface() {
173 assertWithMessage("Should return false when passed is not outer most type")
174 .that(ScopeUtil
175 .isOuterMostType(getNode(TokenTypes.INTERFACE_DEF, TokenTypes.MODIFIERS)))
176 .isFalse();
177 }
178
179 @Test
180 public void testIsOuterMostTypeAnnotation() {
181 assertWithMessage("Should return false when passed is not outer most type")
182 .that(ScopeUtil
183 .isOuterMostType(getNode(TokenTypes.ANNOTATION_DEF, TokenTypes.MODIFIERS)))
184 .isFalse();
185 }
186
187 @Test
188 public void testIsOuterMostTypeEnum() {
189 assertWithMessage("Should return false when passed is not outer most type")
190 .that(ScopeUtil.isOuterMostType(getNode(TokenTypes.ENUM_DEF, TokenTypes.MODIFIERS)))
191 .isFalse();
192 }
193
194 @Test
195 public void testIsOuterMostTypeClass() {
196 assertWithMessage("Should return false when passed is not outer most type")
197 .that(ScopeUtil
198 .isOuterMostType(getNode(TokenTypes.CLASS_DEF, TokenTypes.MODIFIERS)))
199 .isFalse();
200 }
201
202 @Test
203 public void testIsOuterMostTypePackageDef() {
204 assertWithMessage("Should return false when passed is not outer most type")
205 .that(ScopeUtil.isOuterMostType(getNode(TokenTypes.PACKAGE_DEF, TokenTypes.DOT)))
206 .isTrue();
207 }
208
209 @Test
210 public void testIsLocalVariableDefCatch() {
211 assertWithMessage("Should return true when passed is variable def")
212 .that(ScopeUtil
213 .isLocalVariableDef(getNode(TokenTypes.LITERAL_CATCH, TokenTypes.PARAMETER_DEF)))
214 .isTrue();
215 }
216
217 @Test
218 public void testIsLocalVariableDefUnexpected() {
219 assertWithMessage("Should return false when passed is not variable def")
220 .that(ScopeUtil.isLocalVariableDef(getNode(TokenTypes.LITERAL_CATCH)))
221 .isFalse();
222 assertWithMessage("Should return false when passed is not variable def")
223 .that(ScopeUtil
224 .isLocalVariableDef(getNode(TokenTypes.COMMA, TokenTypes.PARAMETER_DEF)))
225 .isFalse();
226 }
227
228 @Test
229 public void testIsLocalVariableDefResource() {
230 final DetailAstImpl node = getNode(TokenTypes.RESOURCE);
231 final DetailAstImpl modifiers = new DetailAstImpl();
232 modifiers.setType(TokenTypes.MODIFIERS);
233 node.addChild(modifiers);
234 final DetailAstImpl ident = new DetailAstImpl();
235 ident.setType(TokenTypes.IDENT);
236 node.addChild(ident);
237 assertWithMessage("invalid result")
238 .that(ScopeUtil.isLocalVariableDef(node))
239 .isTrue();
240 final DetailAstImpl resourceWithIdent = getNode(TokenTypes.RESOURCE);
241 resourceWithIdent.addChild(ident);
242 assertWithMessage("invalid result")
243 .that(ScopeUtil.isLocalVariableDef(resourceWithIdent))
244 .isFalse();
245 assertWithMessage("invalid result")
246 .that(ScopeUtil.isLocalVariableDef(getNode(TokenTypes.RESOURCE)))
247 .isFalse();
248 }
249
250 @Test
251 public void testIsLocalVariableDefVariable() {
252 assertWithMessage("invalid result")
253 .that(ScopeUtil
254 .isLocalVariableDef(getNode(TokenTypes.SLIST, TokenTypes.VARIABLE_DEF)))
255 .isTrue();
256 assertWithMessage("invalid result")
257 .that(ScopeUtil
258 .isLocalVariableDef(getNode(TokenTypes.FOR_INIT, TokenTypes.VARIABLE_DEF)))
259 .isTrue();
260 assertWithMessage("invalid result")
261 .that(ScopeUtil
262 .isLocalVariableDef(getNode(TokenTypes.FOR_EACH_CLAUSE, TokenTypes.VARIABLE_DEF)))
263 .isTrue();
264 assertWithMessage("invalid result")
265 .that(ScopeUtil
266 .isLocalVariableDef(getNode(TokenTypes.CLASS_DEF, TokenTypes.VARIABLE_DEF)))
267 .isFalse();
268 }
269
270 @Test
271 public void testIsClassFieldDef() {
272 assertWithMessage("Should return true when passed is class field def")
273 .that(ScopeUtil.isClassFieldDef(getNode(TokenTypes.CLASS_DEF, TokenTypes.OBJBLOCK,
274 TokenTypes.VARIABLE_DEF)))
275 .isTrue();
276 assertWithMessage("Should return false when passed is unexpected")
277 .that(ScopeUtil.isClassFieldDef(getNode(TokenTypes.CLASS_DEF)))
278 .isFalse();
279 assertWithMessage("Should return false when passed is method variable def")
280 .that(ScopeUtil.isClassFieldDef(
281 getNode(TokenTypes.METHOD_DEF, TokenTypes.SLIST, TokenTypes.VARIABLE_DEF)))
282 .isFalse();
283 }
284
285 @Test
286 public void testSurroundingScope() {
287 final Optional<Scope> publicScope = ScopeUtil.getSurroundingScope(getNodeWithParentScope(
288 TokenTypes.LITERAL_PUBLIC, "public", TokenTypes.ANNOTATION_DEF));
289 assertWithMessage("Invalid surrounding scope")
290 .that(publicScope)
291 .isEqualTo(Optional.of(Scope.PUBLIC));
292 final Optional<Scope> protectedScope = ScopeUtil.getSurroundingScope(getNodeWithParentScope(
293 TokenTypes.LITERAL_PROTECTED, "protected", TokenTypes.INTERFACE_DEF));
294 assertWithMessage("Invalid surrounding scope")
295 .that(protectedScope)
296 .isEqualTo(Optional.of(Scope.PROTECTED));
297 final Optional<Scope> privateScope = ScopeUtil.getSurroundingScope(getNodeWithParentScope(
298 TokenTypes.LITERAL_PRIVATE, "private", TokenTypes.ENUM_DEF));
299 assertWithMessage("Invalid surrounding scope")
300 .that(privateScope)
301 .isEqualTo(Optional.of(Scope.PRIVATE));
302 final Optional<Scope> staticScope = ScopeUtil.getSurroundingScope(getNodeWithParentScope(
303 TokenTypes.LITERAL_STATIC, "static", TokenTypes.CLASS_DEF));
304 assertWithMessage("Invalid surrounding scope")
305 .that(staticScope)
306 .isEqualTo(Optional.of(Scope.PACKAGE));
307 }
308
309 @Test
310 public void testIsInScope() {
311 assertWithMessage("Should return true when node is in valid scope")
312 .that(ScopeUtil.isInScope(getNodeWithParentScope(TokenTypes.LITERAL_PUBLIC,
313 "public", TokenTypes.ANNOTATION_DEF), Scope.PUBLIC))
314 .isTrue();
315 assertWithMessage("Should return false when node is in invalid scope")
316 .that(ScopeUtil.isInScope(getNodeWithParentScope(TokenTypes.LITERAL_PROTECTED,
317 "protected", TokenTypes.INTERFACE_DEF), Scope.PRIVATE))
318 .isFalse();
319 }
320
321 @Test
322 public void testSurroundingScopeOfNodeChildOfLiteralNewIsAnoninner() {
323 final Optional<Scope> scope =
324 ScopeUtil.getSurroundingScope(getNode(TokenTypes.LITERAL_NEW, TokenTypes.IDENT));
325 assertWithMessage("Invalid surrounding scope")
326 .that(scope)
327 .isEqualTo(Optional.of(Scope.ANONINNER));
328 }
329
330 @Test
331 public void testIsInInterfaceBlock() {
332 final DetailAST ast = getNode(TokenTypes.INTERFACE_DEF, TokenTypes.OBJBLOCK,
333 TokenTypes.CLASS_DEF, TokenTypes.MODIFIERS);
334
335 assertWithMessage("Should return true when node is interface block")
336 .that(ScopeUtil.isInInterfaceBlock(ast.getParent()))
337 .isTrue();
338 assertWithMessage("Should return false when node is not interface block")
339 .that(ScopeUtil.isInInterfaceBlock(ast))
340 .isFalse();
341 }
342
343 @Test
344 public void testIsInAnnotationBlock() {
345 final DetailAST ast = getNode(TokenTypes.ANNOTATION_DEF, TokenTypes.OBJBLOCK,
346 TokenTypes.INTERFACE_DEF, TokenTypes.MODIFIERS);
347
348 assertWithMessage("Should return true when node is annotation block")
349 .that(ScopeUtil.isInAnnotationBlock(ast.getParent()))
350 .isTrue();
351 assertWithMessage("Should return false when node is not annotation block")
352 .that(ScopeUtil.isInAnnotationBlock(ast))
353 .isFalse();
354 }
355
356 @Test
357 public void testisInInterfaceOrAnnotationBlock() {
358 assertWithMessage("Should return true when node is in interface or annotation block")
359 .that(ScopeUtil.isInInterfaceOrAnnotationBlock(
360 getNode(TokenTypes.ANNOTATION_DEF, TokenTypes.OBJBLOCK)))
361 .isTrue();
362 assertWithMessage("Should return true when node is in interface or annotation block")
363 .that(ScopeUtil.isInInterfaceOrAnnotationBlock(
364 getNode(TokenTypes.INTERFACE_DEF, TokenTypes.OBJBLOCK)))
365 .isTrue();
366 assertWithMessage("Should return false when node is not in interface or annotation block")
367 .that(ScopeUtil.isInInterfaceOrAnnotationBlock(
368 getNode(TokenTypes.CLASS_DEF, TokenTypes.OBJBLOCK)))
369 .isFalse();
370 assertWithMessage("Should return false when node is not in interface or annotation block")
371 .that(ScopeUtil.isInInterfaceOrAnnotationBlock(
372 getNode(TokenTypes.LITERAL_NEW, TokenTypes.IDENT)))
373 .isFalse();
374 assertWithMessage("Should return false when node is not in interface or annotation block")
375 .that(ScopeUtil.isInInterfaceOrAnnotationBlock(
376 getNode(TokenTypes.ENUM_DEF, TokenTypes.OBJBLOCK)))
377 .isFalse();
378 }
379
380 private static DetailAstImpl getNode(int... nodeTypes) {
381 DetailAstImpl ast = new DetailAstImpl();
382 ast.setType(nodeTypes[0]);
383 for (int i = 1; i < nodeTypes.length; i++) {
384 final DetailAstImpl astChild = new DetailAstImpl();
385 astChild.setType(nodeTypes[i]);
386 ast.addChild(astChild);
387 ast = astChild;
388 }
389 return ast;
390 }
391
392 private static DetailAST getNodeWithParentScope(int literal, String scope,
393 int parentTokenType) {
394 final DetailAstImpl ast = getNode(parentTokenType, TokenTypes.MODIFIERS, literal);
395 ast.setText(scope);
396 final DetailAstImpl ast2 = getNode(TokenTypes.OBJBLOCK);
397 ((DetailAstImpl) ast.getParent().getParent()).addChild(ast2);
398 return ast;
399 }
400
401 }