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.checks.annotation.SuppressWarningsCheck.MSG_KEY_SUPPRESSED_WARNING_NOT_ALLOWED;
24 import static com.puppycrawl.tools.checkstyle.internal.utils.TestUtil.isUtilsClassHasPrivateConstructor;
25
26 import java.util.Set;
27
28 import org.junit.jupiter.api.Test;
29
30 import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
31 import com.puppycrawl.tools.checkstyle.DetailAstImpl;
32 import com.puppycrawl.tools.checkstyle.api.DetailAST;
33 import com.puppycrawl.tools.checkstyle.api.TokenTypes;
34 import com.puppycrawl.tools.checkstyle.checks.annotation.SuppressWarningsCheck;
35
36 public class AnnotationUtilTest extends AbstractModuleTestSupport {
37
38 @Override
39 protected String getPackageLocation() {
40 return "com/puppycrawl/tools/checkstyle/utils/annotationutil";
41 }
42
43 @Test
44 public void testIsProperUtilsClass() {
45 try {
46 isUtilsClassHasPrivateConstructor(AnnotationUtil.class);
47 assertWithMessage("Exception is expected").fail();
48 }
49 catch (ReflectiveOperationException ex) {
50 assertWithMessage("Invalid exception message")
51 .that(ex)
52 .hasCauseThat()
53 .hasMessageThat()
54 .isEqualTo("do not instantiate.");
55 }
56 }
57
58 @Test
59 public void testContainsAnnotationNull() {
60 try {
61 AnnotationUtil.containsAnnotation(null);
62 assertWithMessage("IllegalArgumentException is expected").fail();
63 }
64 catch (IllegalArgumentException ex) {
65 assertWithMessage("Invalid exception message")
66 .that(ex.getMessage())
67 .isEqualTo("the ast is null");
68 }
69 }
70
71 @Test
72 public void testContainsAnnotationNull2() {
73 try {
74 AnnotationUtil.containsAnnotation(null, "");
75 assertWithMessage("IllegalArgumentException is expected").fail();
76 }
77 catch (IllegalArgumentException ex) {
78 assertWithMessage("Invalid exception message")
79 .that(ex.getMessage())
80 .isEqualTo("the ast is null");
81 }
82 }
83
84 @Test
85 public void testContainsAnnotationFalse() {
86 final DetailAstImpl ast = new DetailAstImpl();
87 ast.setType(1);
88 assertWithMessage("AnnotationUtil should not contain " + ast)
89 .that(AnnotationUtil.containsAnnotation(ast))
90 .isFalse();
91 }
92
93 @Test
94 public void testContainsAnnotationFalse2() {
95 final DetailAstImpl ast = new DetailAstImpl();
96 ast.setType(1);
97 final DetailAstImpl ast2 = new DetailAstImpl();
98 ast2.setType(TokenTypes.MODIFIERS);
99 ast.addChild(ast2);
100 assertWithMessage("AnnotationUtil should not contain " + ast)
101 .that(AnnotationUtil.containsAnnotation(ast))
102 .isFalse();
103 }
104
105 @Test
106 public void testContainsAnnotationTrue() {
107 final DetailAstImpl ast = new DetailAstImpl();
108 ast.setType(1);
109 final DetailAstImpl ast2 = new DetailAstImpl();
110 ast2.setType(TokenTypes.MODIFIERS);
111 ast.addChild(ast2);
112 final DetailAstImpl ast3 = new DetailAstImpl();
113 ast3.setType(TokenTypes.ANNOTATION);
114 ast2.addChild(ast3);
115 assertWithMessage("AnnotationUtil should contain " + ast)
116 .that(AnnotationUtil.containsAnnotation(ast))
117 .isTrue();
118 }
119
120 @Test
121 public void testAnnotationHolderNull() {
122 try {
123 AnnotationUtil.getAnnotationHolder(null);
124 assertWithMessage("IllegalArgumentException is expected").fail();
125 }
126 catch (IllegalArgumentException ex) {
127 assertWithMessage("Invalid exception message")
128 .that(ex.getMessage())
129 .isEqualTo("the ast is null");
130 }
131 }
132
133 @Test
134 public void testAnnotationNull() {
135 try {
136 AnnotationUtil.getAnnotation(null, null);
137 assertWithMessage("IllegalArgumentException is expected").fail();
138 }
139 catch (IllegalArgumentException ex) {
140 assertWithMessage("Invalid exception message")
141 .that(ex.getMessage())
142 .isEqualTo("the ast is null");
143 }
144 }
145
146 @Test
147 public void testAnnotationNull2() {
148 try {
149 AnnotationUtil.getAnnotation(new DetailAstImpl(), null);
150 assertWithMessage("IllegalArgumentException is expected").fail();
151 }
152 catch (IllegalArgumentException ex) {
153 assertWithMessage("Invalid exception message")
154 .that(ex.getMessage())
155 .isEqualTo("the annotation is null");
156 }
157 }
158
159 @Test
160 public void testAnnotationEmpty() {
161 try {
162 AnnotationUtil.getAnnotation(new DetailAstImpl(), "");
163 assertWithMessage("IllegalArgumentException is expected").fail();
164 }
165 catch (IllegalArgumentException ex) {
166 assertWithMessage("Invalid exception message")
167 .that(ex.getMessage())
168 .isEqualTo("the annotation is empty or spaces");
169 }
170 }
171
172 @Test
173 public void testContainsAnnotationWithNull() {
174 try {
175 AnnotationUtil.getAnnotation(null, "");
176 assertWithMessage("IllegalArgumentException is expected").fail();
177 }
178 catch (IllegalArgumentException ex) {
179 assertWithMessage("Invalid exception message")
180 .that(ex.getMessage())
181 .isEqualTo("the ast is null");
182 }
183 }
184
185 @Test
186 public void testContainsAnnotationListWithNullAst() {
187 try {
188 AnnotationUtil.containsAnnotation(null, Set.of("Override"));
189 assertWithMessage("IllegalArgumentException is expected").fail();
190 }
191 catch (IllegalArgumentException ex) {
192 assertWithMessage("Invalid exception message")
193 .that(ex.getMessage())
194 .isEqualTo("the ast is null");
195 }
196 }
197
198 @Test
199 public void testContainsAnnotationListWithNullList() {
200 final DetailAST ast = new DetailAstImpl();
201 final Set<String> annotations = null;
202 try {
203 AnnotationUtil.containsAnnotation(ast, annotations);
204 assertWithMessage("IllegalArgumentException is expected").fail();
205 }
206 catch (IllegalArgumentException ex) {
207 assertWithMessage("Invalid exception message")
208 .that(ex.getMessage())
209 .isEqualTo("annotations cannot be null");
210 }
211 }
212
213 @Test
214 public void testContainsAnnotationListWithEmptyList() {
215 final DetailAST ast = new DetailAstImpl();
216 final Set<String> annotations = Set.of();
217 final boolean result = AnnotationUtil.containsAnnotation(ast, annotations);
218 assertWithMessage("An empty set should lead to a false result")
219 .that(result)
220 .isFalse();
221 }
222
223 @Test
224 public void testContainsAnnotationListWithNoAnnotationNode() {
225 final DetailAstImpl ast = new DetailAstImpl();
226 final DetailAstImpl modifiersAst = new DetailAstImpl();
227 modifiersAst.setType(TokenTypes.MODIFIERS);
228 ast.addChild(modifiersAst);
229 final Set<String> annotations = Set.of("Override");
230 final boolean result = AnnotationUtil.containsAnnotation(ast, annotations);
231 assertWithMessage("An empty ast should lead to a false result")
232 .that(result)
233 .isFalse();
234 }
235
236 @Test
237 public void testContainsAnnotationListWithNoMatchingAnnotation() {
238 final DetailAstImpl ast = new DetailAstImpl();
239 final DetailAstImpl modifiersAst = create(
240 TokenTypes.MODIFIERS,
241 create(
242 TokenTypes.ANNOTATION,
243 create(
244 TokenTypes.DOT,
245 create(
246 TokenTypes.IDENT,
247 "Override")
248 )
249 )
250 );
251 ast.addChild(modifiersAst);
252 final Set<String> annotations = Set.of("Deprecated");
253 final boolean result = AnnotationUtil.containsAnnotation(ast, annotations);
254 assertWithMessage("No matching annotation found")
255 .that(result)
256 .isFalse();
257 }
258
259 @Test
260 public void testContainsAnnotation() {
261 final DetailAstImpl astForTest = new DetailAstImpl();
262 astForTest.setType(TokenTypes.PACKAGE_DEF);
263 final DetailAstImpl child = new DetailAstImpl();
264 final DetailAstImpl annotations = new DetailAstImpl();
265 final DetailAstImpl annotation = new DetailAstImpl();
266 final DetailAstImpl annotationNameHolder = new DetailAstImpl();
267 final DetailAstImpl annotationName = new DetailAstImpl();
268 annotations.setType(TokenTypes.ANNOTATIONS);
269 annotation.setType(TokenTypes.ANNOTATION);
270 annotationNameHolder.setType(TokenTypes.AT);
271 annotationName.setText("Annotation");
272
273 annotationNameHolder.setNextSibling(annotationName);
274 annotation.setFirstChild(annotationNameHolder);
275 annotations.setFirstChild(annotation);
276 child.setNextSibling(annotations);
277 astForTest.setFirstChild(child);
278
279 assertWithMessage("Annotation should contain " + astForTest)
280 .that(AnnotationUtil.containsAnnotation(astForTest, "Annotation"))
281 .isTrue();
282 }
283
284 @Test
285 public void testContainsAnnotationWithStringFalse() {
286 final DetailAstImpl astForTest = new DetailAstImpl();
287 astForTest.setType(TokenTypes.PACKAGE_DEF);
288 final DetailAstImpl child = new DetailAstImpl();
289 final DetailAstImpl annotations = new DetailAstImpl();
290 final DetailAstImpl annotation = new DetailAstImpl();
291 final DetailAstImpl annotationNameHolder = new DetailAstImpl();
292 final DetailAstImpl annotationName = new DetailAstImpl();
293 annotations.setType(TokenTypes.ANNOTATIONS);
294 annotation.setType(TokenTypes.ANNOTATION);
295 annotationNameHolder.setType(TokenTypes.AT);
296 annotationName.setText("Annotation");
297
298 annotationNameHolder.setNextSibling(annotationName);
299 annotation.setFirstChild(annotationNameHolder);
300 annotations.setFirstChild(annotation);
301 child.setNextSibling(annotations);
302 astForTest.setFirstChild(child);
303
304 assertWithMessage("Annotation should not contain " + astForTest)
305 .that(AnnotationUtil.containsAnnotation(astForTest, "AnnotationBad"))
306 .isFalse();
307 }
308
309 @Test
310 public void testContainsAnnotationWithComment() {
311 final DetailAstImpl astForTest = new DetailAstImpl();
312 astForTest.setType(TokenTypes.PACKAGE_DEF);
313 final DetailAstImpl child = new DetailAstImpl();
314 final DetailAstImpl annotations = new DetailAstImpl();
315 final DetailAstImpl annotation = new DetailAstImpl();
316 final DetailAstImpl annotationNameHolder = new DetailAstImpl();
317 final DetailAstImpl annotationName = new DetailAstImpl();
318 final DetailAstImpl comment = new DetailAstImpl();
319 annotations.setType(TokenTypes.ANNOTATIONS);
320 annotation.setType(TokenTypes.ANNOTATION);
321 annotationNameHolder.setType(TokenTypes.AT);
322 comment.setType(TokenTypes.BLOCK_COMMENT_BEGIN);
323 annotationName.setText("Annotation");
324
325 annotationNameHolder.setNextSibling(annotationName);
326 annotation.setFirstChild(comment);
327 comment.setNextSibling(annotationNameHolder);
328 annotations.setFirstChild(annotation);
329 child.setNextSibling(annotations);
330 astForTest.setFirstChild(child);
331
332 assertWithMessage("Annotation should contain " + astForTest)
333 .that(AnnotationUtil.containsAnnotation(astForTest, "Annotation"))
334 .isTrue();
335 }
336
337 @Test
338 public void testCompactNoUnchecked() throws Exception {
339
340 final String[] expected = {
341 "16:20: " + getCheckMessage(SuppressWarningsCheck.class,
342 MSG_KEY_SUPPRESSED_WARNING_NOT_ALLOWED, "unchecked"),
343 "22:28: " + getCheckMessage(SuppressWarningsCheck.class,
344 MSG_KEY_SUPPRESSED_WARNING_NOT_ALLOWED, "unchecked"),
345 "40:36: " + getCheckMessage(SuppressWarningsCheck.class,
346 MSG_KEY_SUPPRESSED_WARNING_NOT_ALLOWED, "unchecked"),
347 "69:28: " + getCheckMessage(SuppressWarningsCheck.class,
348 MSG_KEY_SUPPRESSED_WARNING_NOT_ALLOWED, "unchecked"),
349 "72:49: " + getCheckMessage(SuppressWarningsCheck.class,
350 MSG_KEY_SUPPRESSED_WARNING_NOT_ALLOWED, "unchecked"),
351 };
352
353 verifyWithInlineConfigParser(
354 getPath("InputAnnotationUtil1.java"), expected);
355 }
356
357 @Test
358 public void testValuePairAnnotation() throws Exception {
359
360 final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
361
362 verifyWithInlineConfigParser(
363 getPath("InputAnnotationUtil2.java"), expected);
364 }
365
366 private static DetailAstImpl create(int tokenType) {
367 final DetailAstImpl ast = new DetailAstImpl();
368 ast.setType(tokenType);
369 return ast;
370 }
371
372 private static DetailAstImpl create(int tokenType, String text) {
373 final DetailAstImpl ast = create(tokenType);
374 ast.setText(text);
375 return ast;
376 }
377
378 private static DetailAstImpl create(int tokenType, DetailAstImpl child) {
379 final DetailAstImpl ast = create(tokenType);
380 ast.addChild(child);
381 return ast;
382 }
383 }