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.lang.reflect.Field;
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.List;
29 import java.util.Map;
30 import java.util.Optional;
31 import java.util.TreeMap;
32
33 import org.junit.jupiter.api.Test;
34
35 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
36 import com.puppycrawl.tools.checkstyle.api.DetailAST;
37 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
38
39 public class TokenUtilTest {
40
41 @Test
42 public void testIsProperUtilsClass() throws ReflectiveOperationException {
43 assertWithMessage("Constructor is not private")
44 .that(isUtilsClassHasPrivateConstructor(TokenUtil.class))
45 .isTrue();
46 }
47
48 @Test
49 public void testGetIntFromAccessibleField() throws NoSuchFieldException {
50 final Field field = Integer.class.getField("MAX_VALUE");
51 final int maxValue = TokenUtil.getIntFromField(field, 0);
52
53 assertWithMessage("Invalid getIntFromField result")
54 .that(maxValue)
55 .isEqualTo(Integer.MAX_VALUE);
56 }
57
58 @Test
59 public void testGetIntFromInaccessibleField() throws NoSuchFieldException {
60 final Field field = Integer.class.getDeclaredField("value");
61
62 try {
63 TokenUtil.getIntFromField(field, 0);
64 assertWithMessage("IllegalStateException is expected").fail();
65 }
66 catch (IllegalStateException expected) {
67
68
69 final String message = expected.getMessage();
70 assertWithMessage("Invalid exception message: " + message)
71 .that(message.startsWith("java.lang.IllegalAccessException: ")
72 && message.contains("com.puppycrawl.tools.checkstyle.utils.TokenUtil")
73 && message.contains("access a member of class java.lang.Integer"))
74 .isTrue();
75 }
76 }
77
78 @Test
79 public void testNameToValueMapFromPublicIntFields() {
80 final Map<String, Integer> actualMap =
81 TokenUtil.nameToValueMapFromPublicIntFields(Integer.class);
82 final Map<String, Integer> expectedMap = new TreeMap<>();
83 expectedMap.put("BYTES", Integer.BYTES);
84 expectedMap.put("SIZE", Integer.SIZE);
85 expectedMap.put("MAX_VALUE", Integer.MAX_VALUE);
86 expectedMap.put("MIN_VALUE", Integer.MIN_VALUE);
87
88 assertWithMessage("Unexpected name to value map")
89 .that(actualMap)
90 .isEqualTo(expectedMap);
91 }
92
93 @Test
94 public void testInvertMap() {
95 final Map<String, Integer> map = new TreeMap<>();
96 map.put("ZERO", 0);
97 map.put("ONE", 1);
98 map.put("TWO", 2);
99 map.put("NEGATIVE", -1);
100
101 final Map<Integer, String> invertedMap = TokenUtil.invertMap(map);
102
103 assertWithMessage("Key set of 'map' and values of 'invertedMap' should be the same.")
104 .that(invertedMap.values())
105 .containsExactlyElementsIn(map.keySet());
106 assertWithMessage("Values of 'map' and key set of 'invertedMap' should be the same.")
107 .that(invertedMap.keySet())
108 .containsExactlyElementsIn(map.values());
109 }
110
111 @Test
112 public void testTokenValueIncorrect() throws IllegalAccessException {
113 int maxId = 0;
114 final Field[] fields = TokenTypes.class.getDeclaredFields();
115 for (final Field field : fields) {
116
117 if (field.getType() != Integer.TYPE) {
118 continue;
119 }
120
121 final String name = field.getName();
122 final int id = field.getInt(name);
123 if (id > maxId) {
124 maxId = id;
125 }
126 }
127
128 final int nextAfterMaxId = maxId + 1;
129 try {
130 TokenUtil.getTokenName(nextAfterMaxId);
131 assertWithMessage("IllegalArgumentException is expected").fail();
132 }
133 catch (IllegalArgumentException expectedException) {
134 assertWithMessage("Invalid exception message")
135 .that(expectedException.getMessage())
136 .isEqualTo("unknown TokenTypes id '" + nextAfterMaxId + "'");
137 }
138 }
139
140 @Test
141 public void testTokenValueCorrect() throws IllegalAccessException {
142 final Field[] fields = TokenTypes.class.getDeclaredFields();
143 for (final Field field : fields) {
144
145 if (field.getType() != Integer.TYPE) {
146 continue;
147 }
148
149 final String name = field.getName();
150 final int id = field.getInt(name);
151
152 assertWithMessage("Invalid token name")
153 .that(TokenUtil.getTokenName(id))
154 .isEqualTo(name);
155 }
156 }
157
158 @Test
159 public void testTokenValueIncorrect2() {
160 final int id = 0;
161 try {
162 TokenUtil.getTokenName(id);
163 assertWithMessage("IllegalArgumentException is expected").fail();
164 }
165 catch (IllegalArgumentException expected) {
166 assertWithMessage("Invalid exception message")
167 .that(expected.getMessage())
168 .isEqualTo("unknown TokenTypes id '" + id + "'");
169 }
170 }
171
172 @Test
173 public void testTokenIdIncorrect() {
174 final String id = "NON_EXISTENT_VALUE";
175 try {
176 TokenUtil.getTokenId(id);
177 assertWithMessage("IllegalArgumentException is expected").fail();
178 }
179 catch (IllegalArgumentException expected) {
180 assertWithMessage("Invalid exception message")
181 .that(expected.getMessage())
182 .isEqualTo("unknown TokenTypes value '" + id + "'");
183 }
184 }
185
186 @Test
187 public void testShortDescriptionIncorrect() {
188 final String id = "NON_EXISTENT_VALUE";
189 try {
190 TokenUtil.getShortDescription(id);
191 assertWithMessage("IllegalArgumentException is expected").fail();
192 }
193 catch (IllegalArgumentException expected) {
194 assertWithMessage("Invalid exception message")
195 .that(expected.getMessage())
196 .isEqualTo("unknown TokenTypes value '" + id + "'");
197 }
198 }
199
200 @Test
201 public void testIsCommentType() {
202 assertWithMessage("Should return true when valid type passed")
203 .that(TokenUtil.isCommentType(TokenTypes.SINGLE_LINE_COMMENT))
204 .isTrue();
205 assertWithMessage("Should return true when valid type passed")
206 .that(TokenUtil.isCommentType(TokenTypes.BLOCK_COMMENT_BEGIN))
207 .isTrue();
208 assertWithMessage("Should return true when valid type passed")
209 .that(TokenUtil.isCommentType(TokenTypes.BLOCK_COMMENT_END))
210 .isTrue();
211 assertWithMessage("Should return true when valid type passed")
212 .that(TokenUtil.isCommentType(TokenTypes.COMMENT_CONTENT))
213 .isTrue();
214 assertWithMessage("Should return true when valid type passed")
215 .that(TokenUtil.isCommentType("COMMENT_CONTENT"))
216 .isTrue();
217 assertWithMessage("Should return false when invalid type passed")
218 .that(TokenUtil.isCommentType(TokenTypes.CLASS_DEF))
219 .isFalse();
220 assertWithMessage("Should return false when invalid type passed")
221 .that(TokenUtil.isCommentType("CLASS_DEF"))
222 .isFalse();
223 }
224
225 @Test
226 public void testGetTokenTypesTotalNumber() {
227 final int tokenTypesTotalNumber = TokenUtil.getTokenTypesTotalNumber();
228
229 assertWithMessage("Invalid token total number")
230 .that(tokenTypesTotalNumber)
231 .isEqualTo(189);
232 }
233
234 @Test
235 public void testGetAllTokenIds() {
236 final int[] allTokenIds = TokenUtil.getAllTokenIds();
237 final int sum = Arrays.stream(allTokenIds).sum();
238
239 assertWithMessage("Invalid token length")
240 .that(allTokenIds.length)
241 .isEqualTo(189);
242 assertWithMessage("invalid sum")
243 .that(sum)
244 .isEqualTo(19820);
245 }
246
247 @Test
248 public void testGetTokenNameWithGreatestPossibleId() {
249 final int id = TokenTypes.COMMENT_CONTENT;
250 final String tokenName = TokenUtil.getTokenName(id);
251
252 assertWithMessage("Invalid token name")
253 .that(tokenName)
254 .isEqualTo("COMMENT_CONTENT");
255 }
256
257 @Test
258 public void testCorrectBehaviourOfGetTokenId() {
259 final String id = "COMPILATION_UNIT";
260
261 assertWithMessage("Invalid token id")
262 .that(TokenUtil.getTokenId(id))
263 .isEqualTo(TokenTypes.COMPILATION_UNIT);
264 }
265
266 @Test
267 public void testCorrectBehaviourOfShortDescription() {
268 final String id = "COMPILATION_UNIT";
269 final String shortDescription = TokenUtil.getShortDescription(id);
270
271 assertWithMessage("Invalid short description")
272 .that(shortDescription)
273 .isEqualTo("This is the root node for the source file.");
274 }
275
276 @Test
277 public void testFindFirstTokenByPredicate() {
278 final DetailAstImpl astForTest = new DetailAstImpl();
279 final DetailAstImpl child = new DetailAstImpl();
280 final DetailAstImpl firstSibling = new DetailAstImpl();
281 final DetailAstImpl secondSibling = new DetailAstImpl();
282 final DetailAstImpl thirdSibling = new DetailAstImpl();
283 firstSibling.setText("first");
284 secondSibling.setText("second");
285 thirdSibling.setText("third");
286 secondSibling.setNextSibling(thirdSibling);
287 firstSibling.setNextSibling(secondSibling);
288 child.setNextSibling(firstSibling);
289 astForTest.setFirstChild(child);
290 final Optional<DetailAST> result = TokenUtil.findFirstTokenByPredicate(astForTest,
291 ast -> "second".equals(ast.getText()));
292
293 assertWithMessage("Invalid second sibling")
294 .that(result.orElse(null))
295 .isEqualTo(secondSibling);
296 }
297
298 @Test
299 public void testForEachChild() {
300 final DetailAstImpl astForTest = new DetailAstImpl();
301 final DetailAstImpl child = new DetailAstImpl();
302 final DetailAstImpl firstSibling = new DetailAstImpl();
303 final DetailAstImpl secondSibling = new DetailAstImpl();
304 final DetailAstImpl thirdSibling = new DetailAstImpl();
305 firstSibling.setType(TokenTypes.DOT);
306 secondSibling.setType(TokenTypes.CLASS_DEF);
307 thirdSibling.setType(TokenTypes.IDENT);
308 secondSibling.setNextSibling(thirdSibling);
309 firstSibling.setNextSibling(secondSibling);
310 child.setNextSibling(firstSibling);
311 astForTest.setFirstChild(child);
312 final List<DetailAST> children = new ArrayList<>();
313 TokenUtil.forEachChild(astForTest, TokenTypes.CLASS_DEF, children::add);
314 final DetailAST firstChild = children.get(0);
315
316 assertWithMessage("Must be one match")
317 .that(children)
318 .hasSize(1);
319 assertWithMessage("Mismatched child node")
320 .that(firstChild)
321 .isEqualTo(secondSibling);
322 }
323
324 @Test
325 public void testIsTypeDeclaration() {
326 assertWithMessage("Should return true when valid type passed")
327 .that(TokenUtil.isTypeDeclaration(TokenTypes.CLASS_DEF))
328 .isTrue();
329 assertWithMessage("Should return true when valid type passed")
330 .that(TokenUtil.isTypeDeclaration(TokenTypes.INTERFACE_DEF))
331 .isTrue();
332 assertWithMessage("Should return true when valid type passed")
333 .that(TokenUtil.isTypeDeclaration(TokenTypes.ANNOTATION_DEF))
334 .isTrue();
335 assertWithMessage("Should return true when valid type passed")
336 .that(TokenUtil.isTypeDeclaration(TokenTypes.ENUM_DEF))
337 .isTrue();
338 assertWithMessage("Should return true when valid type passed")
339 .that(TokenUtil.isTypeDeclaration(TokenTypes.RECORD_DEF))
340 .isTrue();
341 }
342
343 @Test
344 public void testIsOfTypeTrue() {
345 final int type = TokenTypes.LITERAL_CATCH;
346 final DetailAstImpl astForTest = new DetailAstImpl();
347 astForTest.setType(type);
348 final boolean result1 = TokenUtil.isOfType(type, TokenTypes.LITERAL_FOR,
349 TokenTypes.LITERAL_IF, TokenTypes.LITERAL_CATCH);
350 final boolean result2 = TokenUtil.isOfType(astForTest, TokenTypes.LITERAL_FOR,
351 TokenTypes.LITERAL_IF, TokenTypes.LITERAL_CATCH);
352
353 assertWithMessage("Token type did not match")
354 .that(result1)
355 .isTrue();
356 assertWithMessage("Token type did not match")
357 .that(result2)
358 .isTrue();
359 }
360
361 @Test
362 public void testIsOfTypeFalse() {
363 final int type = TokenTypes.LITERAL_CATCH;
364 final DetailAstImpl astForTest1 = new DetailAstImpl();
365 final DetailAstImpl astForTest2 = null;
366 astForTest1.setType(type);
367 final boolean result1 = TokenUtil.isOfType(type, TokenTypes.LITERAL_FOR,
368 TokenTypes.LITERAL_IF, TokenTypes.LITERAL_ELSE);
369 final boolean result2 = TokenUtil.isOfType(astForTest1, TokenTypes.LITERAL_FOR,
370 TokenTypes.LITERAL_IF, TokenTypes.LITERAL_ELSE);
371 final boolean result3 = TokenUtil.isOfType(astForTest2, TokenTypes.LITERAL_FOR,
372 TokenTypes.LITERAL_IF, TokenTypes.LITERAL_ELSE);
373
374 assertWithMessage("Token type should not match")
375 .that(result1)
376 .isFalse();
377 assertWithMessage("Token type should not match")
378 .that(result2)
379 .isFalse();
380 assertWithMessage("Token type should not match")
381 .that(result3)
382 .isFalse();
383 }
384
385 @Test
386 public void testIsBooleanLiteralType() {
387 assertWithMessage("Result is not expected")
388 .that(TokenUtil.isBooleanLiteralType(TokenTypes.LITERAL_TRUE))
389 .isTrue();
390 assertWithMessage("Result is not expected")
391 .that(TokenUtil.isBooleanLiteralType(TokenTypes.LITERAL_FALSE))
392 .isTrue();
393 assertWithMessage("Result is not expected")
394 .that(TokenUtil.isBooleanLiteralType(TokenTypes.LOR))
395 .isFalse();
396 }
397
398 }