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