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.puppycrawl.tools.checkstyle.internal.utils.TestUtil.findTokenInAstByPredicate;
23 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor;
24 import static org.junit.Assert.assertEquals;
25 import static org.junit.Assert.assertFalse;
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.io.File;
30 import java.util.Arrays;
31 import java.util.HashSet;
32 import java.util.List;
33 import java.util.Optional;
34 import java.util.Set;
35
36 import org.junit.Test;
37
38 import com.puppycrawl.tools.checkstyle.AbstractPathTestSupport;
39 import com.puppycrawl.tools.checkstyle.JavaParser;
40 import com.puppycrawl.tools.checkstyle.api.DetailAST;
41 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
42 import com.puppycrawl.tools.checkstyle.checks.naming.AccessModifier;
43
44 public class CheckUtilTest extends AbstractPathTestSupport {
45
46 @Override
47 protected String getPackageLocation() {
48 return "com/puppycrawl/tools/checkstyle/utils/checkutil";
49 }
50
51 @Test
52 public void testIsProperUtilsClass() throws ReflectiveOperationException {
53 assertTrue("Constructor is not private",
54 isUtilsClassHasPrivateConstructor(CheckUtil.class, true));
55 }
56
57 @Test
58 public void testParseDoubleWithIncorrectToken() {
59 final double parsedDouble = CheckUtil.parseDouble("1_02", TokenTypes.ASSIGN);
60 assertEquals("Invalid parse result", Double.NaN, parsedDouble, 0.0);
61 }
62
63 @Test
64 public void testElseWithCurly() {
65 final DetailAST ast = new DetailAST();
66 ast.setType(TokenTypes.ASSIGN);
67 ast.setText("ASSIGN");
68 assertFalse("Invalid elseIf check result 'ASSIGN' is not 'else if'",
69 CheckUtil.isElseIf(ast));
70
71 final DetailAST parentAst = new DetailAST();
72 parentAst.setType(TokenTypes.LCURLY);
73 parentAst.setText("LCURLY");
74
75 final DetailAST ifAst = new DetailAST();
76 ifAst.setType(TokenTypes.LITERAL_IF);
77 ifAst.setText("IF");
78 parentAst.addChild(ifAst);
79
80 assertFalse("Invalid elseIf check result: 'IF' is not 'else if'",
81 CheckUtil.isElseIf(ifAst));
82
83 final DetailAST parentAst2 = new DetailAST();
84 parentAst2.setType(TokenTypes.SLIST);
85 parentAst2.setText("SLIST");
86
87 parentAst2.addChild(ifAst);
88
89 assertFalse("Invalid elseIf check result: 'SLIST' is not 'else if'",
90 CheckUtil.isElseIf(ifAst));
91
92 final DetailAST elseAst = new DetailAST();
93 elseAst.setType(TokenTypes.LITERAL_ELSE);
94
95 elseAst.setFirstChild(ifAst);
96 assertTrue("Invalid elseIf check result", CheckUtil.isElseIf(ifAst));
97 }
98
99 @Test
100 public void testEquals() {
101 final DetailAST litStatic = new DetailAST();
102 litStatic.setType(TokenTypes.LITERAL_STATIC);
103
104 final DetailAST modifiers = new DetailAST();
105 modifiers.setType(TokenTypes.MODIFIERS);
106 modifiers.addChild(litStatic);
107
108 final DetailAST metDef = new DetailAST();
109 metDef.setType(TokenTypes.METHOD_DEF);
110 metDef.addChild(modifiers);
111
112 assertFalse("Invalid result: ast is not equals method",
113 CheckUtil.isEqualsMethod(metDef));
114
115 metDef.removeChildren();
116
117 final DetailAST metName = new DetailAST();
118 metName.setType(TokenTypes.IDENT);
119 metName.setText("equals");
120 metDef.addChild(metName);
121
122 final DetailAST modifiers2 = new DetailAST();
123 modifiers2.setType(TokenTypes.MODIFIERS);
124 metDef.addChild(modifiers2);
125
126 final DetailAST parameter1 = new DetailAST();
127 final DetailAST parameter2 = new DetailAST();
128
129 final DetailAST parameters = new DetailAST();
130 parameters.setType(TokenTypes.PARAMETERS);
131
132 parameters.addChild(parameter2);
133
134 parameters.addChild(parameter1);
135 metDef.addChild(parameters);
136
137 assertFalse("Invalid result: ast is not equals method",
138 CheckUtil.isEqualsMethod(metDef));
139 }
140
141 @Test
142 public void testGetAccessModifierFromModifiersTokenWrongTokenType() {
143 final DetailAST modifiers = new DetailAST();
144 modifiers.setType(TokenTypes.METHOD_DEF);
145
146 try {
147 CheckUtil.getAccessModifierFromModifiersToken(modifiers);
148 fail(IllegalArgumentException.class.getSimpleName() + " was expected.");
149 }
150 catch (IllegalArgumentException exc) {
151 final String expectedExceptionMsg = "expected non-null AST-token with type 'MODIFIERS'";
152 final String actualExceptionMsg = exc.getMessage();
153 assertEquals("Invalid exception message", expectedExceptionMsg, actualExceptionMsg);
154 }
155 }
156
157 @Test
158 public void testGetAccessModifierFromModifiersTokenWithNullParameter() {
159 try {
160 CheckUtil.getAccessModifierFromModifiersToken(null);
161 fail(IllegalArgumentException.class.getSimpleName() + " was expected.");
162 }
163 catch (IllegalArgumentException exc) {
164 final String expectedExceptionMsg = "expected non-null AST-token with type 'MODIFIERS'";
165 final String actualExceptionMsg = exc.getMessage();
166 assertEquals("Invalid exception message", expectedExceptionMsg, actualExceptionMsg);
167 }
168 }
169
170 @Test
171 public void testCreateFullType() throws Exception {
172 final DetailAST typeNode = getNodeFromFile(TokenTypes.TYPE);
173
174 assertEquals("Invalid full type", "Map[13x12]",
175 CheckUtil.createFullType(typeNode).toString());
176 }
177
178 @Test
179 public void testCreateFullTypeOfArray() throws Exception {
180 final DetailAST arrayTypeNode = getNodeFromFile(TokenTypes.VARIABLE_DEF)
181 .getNextSibling().getFirstChild().getNextSibling();
182
183 assertEquals("Invalid full type", "int[14x14]",
184 CheckUtil.createFullType(arrayTypeNode).toString());
185 }
186
187 @Test
188 public void testGetTypeParameterNames() throws Exception {
189 final DetailAST parameterizedClassNode = getNodeFromFile(TokenTypes.CLASS_DEF);
190 final List<String> expected = Arrays.asList("V", "C");
191
192 assertEquals("Invalid type parameters",
193 expected, CheckUtil.getTypeParameterNames(parameterizedClassNode));
194 }
195
196 @Test
197 public void testGetTypeParameters() throws Exception {
198 final DetailAST parameterizedClassNode = getNodeFromFile(TokenTypes.CLASS_DEF);
199 final DetailAST firstTypeParameter =
200 getNode(parameterizedClassNode, TokenTypes.TYPE_PARAMETER);
201 final List<DetailAST> expected = Arrays.asList(firstTypeParameter,
202 firstTypeParameter.getNextSibling().getNextSibling());
203
204 assertEquals("Invalid type parameters", expected,
205 CheckUtil.getTypeParameters(parameterizedClassNode));
206 }
207
208 @Test
209 public void testIsEqualsMethod() throws Exception {
210 final DetailAST equalsMethodNode = getNodeFromFile(TokenTypes.METHOD_DEF);
211 final DetailAST someOtherMethod = equalsMethodNode.getNextSibling();
212
213 assertTrue("Invalid result: AST provided is not equals method",
214 CheckUtil.isEqualsMethod(equalsMethodNode));
215 assertFalse("Invalid result: AST provided is equals method",
216 CheckUtil.isEqualsMethod(someOtherMethod));
217 }
218
219 @Test
220 public void testIsElseIf() throws Exception {
221 final DetailAST targetMethodNode = getNodeFromFile(TokenTypes.METHOD_DEF).getNextSibling();
222 final DetailAST firstElseNode = getNode(targetMethodNode, TokenTypes.LITERAL_ELSE);
223 final DetailAST ifElseWithCurlyBraces = firstElseNode.getFirstChild().getFirstChild();
224 final DetailAST ifElse = getNode(firstElseNode.getParent().getNextSibling(),
225 TokenTypes.LITERAL_ELSE).getFirstChild();
226 final DetailAST ifWithoutElse =
227 firstElseNode.getParent().getNextSibling().getNextSibling();
228
229 assertTrue("Invalid result: AST provided is not else if with curly",
230 CheckUtil.isElseIf(ifElseWithCurlyBraces));
231 assertTrue("Invalid result: AST provided is not else if with curly",
232 CheckUtil.isElseIf(ifElse));
233 assertFalse("Invalid result: AST provided is else if with curly",
234 CheckUtil.isElseIf(ifWithoutElse));
235 }
236
237 @Test
238 public void testIsNonVoidMethod() throws Exception {
239 final DetailAST nonVoidMethod = getNodeFromFile(TokenTypes.METHOD_DEF);
240 final DetailAST voidMethod = nonVoidMethod.getNextSibling();
241
242 assertTrue("Invalid result: AST provided is void method",
243 CheckUtil.isNonVoidMethod(nonVoidMethod));
244 assertFalse("Invalid result: AST provided is non void method",
245 CheckUtil.isNonVoidMethod(voidMethod));
246 }
247
248 @Test
249 public void testIsGetterMethod() throws Exception {
250 final DetailAST notGetterMethod = getNodeFromFile(TokenTypes.METHOD_DEF);
251 final DetailAST getterMethod = notGetterMethod.getNextSibling().getNextSibling();
252
253 assertTrue("Invalid result: AST provided is getter method",
254 CheckUtil.isGetterMethod(getterMethod));
255 assertFalse("Invalid result: AST provided is not getter method",
256 CheckUtil.isGetterMethod(notGetterMethod));
257 }
258
259 @Test
260 public void testIsSetterMethod() throws Exception {
261 final DetailAST firstClassMethod = getNodeFromFile(TokenTypes.METHOD_DEF);
262 final DetailAST setterMethod =
263 firstClassMethod.getNextSibling().getNextSibling().getNextSibling();
264 final DetailAST notSetterMethod = setterMethod.getNextSibling();
265
266 assertTrue("Invalid result: AST provided is setter method",
267 CheckUtil.isSetterMethod(setterMethod));
268 assertFalse("Invalid result: AST provided is not setter method",
269 CheckUtil.isSetterMethod(notSetterMethod));
270 }
271
272 @Test
273 public void testGetAccessModifierFromModifiersToken() throws Exception {
274 final DetailAST privateVariable = getNodeFromFile(TokenTypes.VARIABLE_DEF);
275 final DetailAST protectedVariable = privateVariable.getNextSibling();
276 final DetailAST publicVariable = protectedVariable.getNextSibling();
277 final DetailAST packageVariable = publicVariable.getNextSibling();
278
279 assertEquals("Invalid access modifier", AccessModifier.PRIVATE,
280 CheckUtil.getAccessModifierFromModifiersToken(privateVariable.getFirstChild()));
281 assertEquals("Invalid access modifier", AccessModifier.PROTECTED,
282 CheckUtil.getAccessModifierFromModifiersToken(protectedVariable.getFirstChild()));
283 assertEquals("Invalid access modifier", AccessModifier.PUBLIC,
284 CheckUtil.getAccessModifierFromModifiersToken(publicVariable.getFirstChild()));
285 assertEquals("Invalid access modifier", AccessModifier.PACKAGE,
286 CheckUtil.getAccessModifierFromModifiersToken(packageVariable.getFirstChild()));
287 }
288
289 @Test
290 public void testGetFirstNode() throws Exception {
291 final DetailAST classDef = getNodeFromFile(TokenTypes.CLASS_DEF);
292
293 assertEquals("Invalid first node", classDef.getFirstChild().getFirstChild(),
294 CheckUtil.getFirstNode(classDef));
295 }
296
297 @Test
298 public void testGetFirstNode1() {
299 final DetailAST child = new DetailAST();
300 child.setLineNo(5);
301 child.setColumnNo(6);
302
303 final DetailAST root = new DetailAST();
304 root.setLineNo(5);
305 root.setColumnNo(6);
306
307 root.addChild(child);
308
309 assertEquals("Unexpected node", root, CheckUtil.getFirstNode(root));
310 }
311
312 @Test
313 public void testGetFirstNode2() {
314 final DetailAST child = new DetailAST();
315 child.setLineNo(6);
316 child.setColumnNo(5);
317
318 final DetailAST root = new DetailAST();
319 root.setLineNo(5);
320 root.setColumnNo(6);
321
322 root.addChild(child);
323
324 assertEquals("Unexpected node", root, CheckUtil.getFirstNode(root));
325 }
326
327 @Test
328 public void testIsReceiverParameter() throws Exception {
329 final DetailAST objBlock = getNodeFromFile(TokenTypes.OBJBLOCK);
330 final DetailAST methodWithReceiverParameter = objBlock.getLastChild().getPreviousSibling();
331 final DetailAST receiverParameter =
332 getNode(methodWithReceiverParameter, TokenTypes.PARAMETER_DEF);
333 final DetailAST simpleParameter =
334 receiverParameter.getNextSibling().getNextSibling();
335
336 assertTrue("Invalid result: parameter provided is receiver parameter",
337 CheckUtil.isReceiverParameter(receiverParameter));
338 assertFalse("Invalid result: parameter provided is not receiver parameter",
339 CheckUtil.isReceiverParameter(simpleParameter));
340 }
341
342 @Test
343 public void testParseDoubleFloatingPointValues() {
344 assertEquals("Invalid parse result", -0.05,
345 CheckUtil.parseDouble("-0.05f", TokenTypes.NUM_FLOAT), 0);
346 assertEquals("Invalid parse result", 10.0,
347 CheckUtil.parseDouble("10.0", TokenTypes.NUM_DOUBLE), 0);
348 assertEquals("Invalid parse result", 1230,
349 CheckUtil.parseDouble("1.23e3", TokenTypes.NUM_DOUBLE), 0);
350 assertEquals("Invalid parse result", -321,
351 CheckUtil.parseDouble("-3.21E2", TokenTypes.NUM_DOUBLE), 0);
352 assertEquals("Invalid parse result", -0.0,
353 CheckUtil.parseDouble("-0.0", TokenTypes.NUM_DOUBLE), 0);
354 assertEquals("Invalid parse result", Double.NaN,
355 CheckUtil.parseDouble("NaN", TokenTypes.NUM_DOUBLE), 0);
356 }
357
358 @Test
359 public void testParseDoubleIntegerValues() {
360 assertEquals("Invalid parse result", 0.0,
361 CheckUtil.parseDouble("0L", TokenTypes.NUM_LONG), 0);
362 assertEquals("Invalid parse result", 0b101,
363 CheckUtil.parseDouble("0B101", TokenTypes.NUM_INT), 0);
364 assertEquals("Invalid parse result", 289_775_941,
365 CheckUtil.parseDouble("0b10001010001011010000101000101L", TokenTypes.NUM_LONG), 0);
366 assertEquals("Invalid parse result", 1.0,
367 CheckUtil.parseDouble("1", TokenTypes.NUM_INT), 0);
368 assertEquals("Invalid parse result", 8.0,
369 CheckUtil.parseDouble("8L", TokenTypes.NUM_LONG), 0);
370 assertEquals("Invalid parse result", -2.147_483_648E10,
371 CheckUtil.parseDouble("-21474836480", TokenTypes.NUM_LONG), 0);
372 assertEquals("Invalid parse result", -2,
373 CheckUtil.parseDouble("-2", TokenTypes.NUM_INT), 0);
374 assertEquals("Invalid parse result", -1,
375 CheckUtil.parseDouble("0xffffffff", TokenTypes.NUM_INT), 0);
376 assertEquals("Invalid parse result", 2915.0,
377 CheckUtil.parseDouble("0x0B63", TokenTypes.NUM_INT), 0);
378 assertEquals("Invalid parse result", 2.147_483_647E10,
379 CheckUtil.parseDouble("21474836470", TokenTypes.NUM_LONG), 0);
380 assertEquals("Invalid parse result", 59.0,
381 CheckUtil.parseDouble("073l", TokenTypes.NUM_LONG), 0);
382 }
383
384 @Test
385 public void testParseClassNames() {
386 final Set<String> actual = CheckUtil.parseClassNames(
387 "I.am.class.name.with.dot.in.the.end.", "ClassOnly", "my.Class");
388 final Set<String> expected = new HashSet<>();
389 expected.add("I.am.class.name.with.dot.in.the.end.");
390 expected.add("ClassOnly");
391 expected.add("my.Class");
392 expected.add("Class");
393 assertEquals("Result is not expected", expected, actual);
394 }
395
396 private DetailAST getNodeFromFile(int type) throws Exception {
397 return getNode(JavaParser.parseFile(new File(getPath("InputCheckUtilTest.java")),
398 JavaParser.Options.WITH_COMMENTS), type);
399 }
400
401 private static DetailAST getNode(DetailAST root, int type) {
402 final Optional<DetailAST> node = findTokenInAstByPredicate(root,
403 ast -> ast.getType() == type);
404
405 if (!node.isPresent()) {
406 fail("Cannot find node of specified type: " + type);
407 }
408
409 return node.get();
410 }
411
412 }