View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2024 the original author or authors.
4   //
5   // This library is free software; you can redistribute it and/or
6   // modify it under the terms of the GNU Lesser General Public
7   // License as published by the Free Software Foundation; either
8   // version 2.1 of the License, or (at your option) any later version.
9   //
10  // This library is distributed in the hope that it will be useful,
11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  // Lesser General Public License for more details.
14  //
15  // You should have received a copy of the GNU Lesser General Public
16  // License along with this library; if not, write to the Free Software
17  // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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.List;
26  
27  import org.junit.jupiter.api.Test;
28  
29  import com.puppycrawl.tools.checkstyle.DetailAstImpl;
30  import com.puppycrawl.tools.checkstyle.api.Comment;
31  import com.puppycrawl.tools.checkstyle.api.DetailNode;
32  import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
33  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
34  import com.puppycrawl.tools.checkstyle.checks.javadoc.InvalidJavadocTag;
35  import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocNodeImpl;
36  import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTag;
37  import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagInfo;
38  import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTags;
39  
40  public class JavadocUtilTest {
41  
42      @Test
43      public void testTags() {
44          final String[] text = {
45              "/** @see elsewhere ",
46              " * {@link List }, {@link List link text }",
47              "   {@link List#add(Object) link text}",
48              " * {@link Class link text}",
49          };
50          final Comment comment = new Comment(text, 1, 4, text[3].length());
51          final JavadocTags allTags =
52              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.ALL);
53          assertWithMessage("Invalid valid tags size")
54              .that(allTags.getValidTags())
55              .hasSize(5);
56      }
57  
58      @Test
59      public void testBlockTag() {
60          final String[] text = {
61              "/** @see elsewhere ",
62              " */",
63          };
64          final Comment comment = new Comment(text, 1, 4, text[1].length());
65          final JavadocTags allTags =
66              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.ALL);
67          assertWithMessage("Invalid valid tags size")
68              .that(allTags.getValidTags())
69              .hasSize(1);
70      }
71  
72      @Test
73      public void testTagType() {
74          final String[] text = {
75              "/** @see block",
76              " * {@link List inline}, {@link List#add(Object)}",
77          };
78          final Comment comment = new Comment(text, 1, 2, text[1].length());
79          final JavadocTags blockTags =
80              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.BLOCK);
81          final JavadocTags inlineTags =
82              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.INLINE);
83          assertWithMessage("Invalid valid tags size")
84              .that(blockTags.getValidTags())
85              .hasSize(1);
86          assertWithMessage("Invalid valid tags size")
87              .that(inlineTags.getValidTags())
88              .hasSize(2);
89      }
90  
91      @Test
92      public void testInlineTagLinkText() {
93          final String[] text = {
94              "/** {@link List link text }",
95          };
96          final Comment comment = new Comment(text, 1, 1, text[0].length());
97          final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
98              comment, JavadocUtil.JavadocTagType.ALL).getValidTags();
99          assertWithMessage("Invalid first arg")
100             .that(tags.get(0).getFirstArg())
101             .isEqualTo("List link text");
102     }
103 
104     @Test
105     public void testInlineTagMethodRef() {
106         final String[] text = {
107             "/** {@link List#add(Object)}",
108         };
109         final Comment comment = new Comment(text, 1, 1, text[0].length());
110         final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
111             comment, JavadocUtil.JavadocTagType.ALL).getValidTags();
112         assertWithMessage("Invalid first arg")
113             .that(tags.get(0).getFirstArg())
114             .isEqualTo("List#add(Object)");
115     }
116 
117     @Test
118     public void testTagPositions() {
119         final String[] text = {
120             "/** @see elsewhere",
121             "    also {@link Name value} */",
122         };
123         final Comment comment = new Comment(text, 1, 2, text[1].length());
124 
125         final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
126             comment, JavadocUtil.JavadocTagType.ALL).getValidTags();
127 
128         assertWithMessage("Invalid tags size")
129             .that(tags)
130             .hasSize(2);
131 
132         final JavadocTag seeTag = tags.get(0);
133         assertWithMessage("Invalid tag name")
134             .that(seeTag.getTagName())
135             .isEqualTo(JavadocTagInfo.SEE.getName());
136         assertWithMessage("Invalid line number")
137             .that(seeTag.getLineNo())
138             .isEqualTo(1);
139         assertWithMessage("Invalid column number")
140             .that(seeTag.getColumnNo())
141             .isEqualTo(4);
142 
143         final JavadocTag linkTag = tags.get(1);
144         assertWithMessage("Invalid tag name")
145             .that(linkTag.getTagName())
146             .isEqualTo(JavadocTagInfo.LINK.getName());
147         assertWithMessage("Invalid line number")
148             .that(linkTag.getLineNo())
149             .isEqualTo(2);
150         assertWithMessage("Invalid column number")
151             .that(linkTag.getColumnNo())
152             .isEqualTo(10);
153     }
154 
155     @Test
156     public void testInlineTagPositions() {
157         final String[] text = {"/** Also {@link Name value} */"};
158         final Comment comment = new Comment(text, 1, 0, text[0].length());
159 
160         final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
161             comment, JavadocUtil.JavadocTagType.INLINE).getValidTags();
162 
163         assertWithMessage("Invalid tags size")
164             .that(tags)
165             .hasSize(1);
166         final int lineNo = tags.get(0).getLineNo();
167         assertWithMessage("Unexpected line number")
168             .that(lineNo)
169             .isEqualTo(0);
170         final int columnNo = tags.get(0).getColumnNo();
171         assertWithMessage("Unexpected column number")
172             .that(columnNo)
173             .isEqualTo(10);
174     }
175 
176     @Test
177     public void testInvalidTags() {
178         final String[] text = {
179             "/** @fake block",
180             " * {@bogus inline}",
181             " * {@link List valid}",
182         };
183         final Comment comment = new Comment(text, 1, 3, text[2].length());
184         final JavadocTags allTags =
185             JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.ALL);
186         assertWithMessage("Unexpected invalid tags size")
187             .that(allTags.getInvalidTags())
188             .hasSize(2);
189         assertTag("Unexpected invalid tag", new InvalidJavadocTag(1, 4, "fake"),
190                 allTags.getInvalidTags().get(0));
191         assertTag("Unexpected invalid tag", new InvalidJavadocTag(2, 4, "bogus"),
192                 allTags.getInvalidTags().get(1));
193         assertWithMessage("Unexpected valid tags size")
194             .that(allTags.getValidTags())
195             .hasSize(1);
196         assertTag("Unexpected valid tag", new JavadocTag(3, 4, "link", "List valid"),
197                 allTags.getValidTags().get(0));
198     }
199 
200     @Test
201     public void testEmptyBlockComment() {
202         final String emptyComment = "";
203         assertWithMessage("Should return false when empty string is passed")
204                 .that(JavadocUtil.isJavadocComment(emptyComment))
205                 .isFalse();
206     }
207 
208     @Test
209     public void testEmptyBlockCommentAst() {
210         final DetailAstImpl commentBegin = new DetailAstImpl();
211         commentBegin.setType(TokenTypes.BLOCK_COMMENT_BEGIN);
212         commentBegin.setText("/*");
213 
214         final DetailAstImpl commentContent = new DetailAstImpl();
215         commentContent.setType(TokenTypes.COMMENT_CONTENT);
216         commentContent.setText("");
217 
218         final DetailAstImpl commentEnd = new DetailAstImpl();
219         commentEnd.setType(TokenTypes.BLOCK_COMMENT_END);
220         commentEnd.setText("*/");
221 
222         commentBegin.setFirstChild(commentContent);
223         commentContent.setNextSibling(commentEnd);
224 
225         assertWithMessage("Should return false when empty block comment is passed")
226                 .that(JavadocUtil.isJavadocComment(commentBegin))
227                 .isFalse();
228     }
229 
230     @Test
231     public void testEmptyJavadocComment() {
232         final String emptyJavadocComment = "*";
233         assertWithMessage("Should return true when empty javadoc comment is passed")
234                 .that(JavadocUtil.isJavadocComment(emptyJavadocComment))
235                 .isTrue();
236     }
237 
238     @Test
239     public void testEmptyJavadocCommentAst() {
240         final DetailAstImpl commentBegin = new DetailAstImpl();
241         commentBegin.setType(TokenTypes.BLOCK_COMMENT_BEGIN);
242         commentBegin.setText("/*");
243 
244         final DetailAstImpl javadocCommentContent = new DetailAstImpl();
245         javadocCommentContent.setType(TokenTypes.COMMENT_CONTENT);
246         javadocCommentContent.setText("*");
247 
248         final DetailAstImpl commentEnd = new DetailAstImpl();
249         commentEnd.setType(TokenTypes.BLOCK_COMMENT_END);
250         commentEnd.setText("*/");
251 
252         commentBegin.setFirstChild(javadocCommentContent);
253         javadocCommentContent.setNextSibling(commentEnd);
254 
255         final DetailAstImpl commentBeginParent = new DetailAstImpl();
256         commentBeginParent.setType(TokenTypes.MODIFIERS);
257         commentBeginParent.setFirstChild(commentBegin);
258 
259         final DetailAstImpl aJavadocPosition = new DetailAstImpl();
260         aJavadocPosition.setType(TokenTypes.METHOD_DEF);
261         aJavadocPosition.setFirstChild(commentBeginParent);
262         assertWithMessage("Should return true when empty javadoc comment ast is passed")
263                 .that(JavadocUtil.isJavadocComment(commentBegin))
264                 .isTrue();
265     }
266 
267     @Test
268     public void testIsProperUtilsClass() throws ReflectiveOperationException {
269         assertWithMessage("Constructor is not private")
270                 .that(isUtilsClassHasPrivateConstructor(JavadocUtil.class))
271                 .isTrue();
272     }
273 
274     @Test
275     public void testGetTokenNameForId() {
276         assertWithMessage("Invalid token name")
277             .that(JavadocUtil.getTokenName(JavadocTokenTypes.EOF))
278             .isEqualTo("EOF");
279     }
280 
281     @Test
282     public void testGetTokenNameForLargeId() {
283         try {
284             JavadocUtil.getTokenName(30073);
285             assertWithMessage("exception expected").fail();
286         }
287         catch (IllegalArgumentException ex) {
288             assertWithMessage("Invalid exception message")
289                 .that(ex.getMessage())
290                 .isEqualTo("Unknown javadoc token id. Given id: 30073");
291         }
292     }
293 
294     @Test
295     public void testGetTokenNameForInvalidId() {
296         try {
297             JavadocUtil.getTokenName(110);
298             assertWithMessage("exception expected").fail();
299         }
300         catch (IllegalArgumentException ex) {
301             assertWithMessage("Invalid exception message")
302                 .that(ex.getMessage())
303                 .isEqualTo("Unknown javadoc token id. Given id: 110");
304         }
305     }
306 
307     @Test
308     public void testGetTokenNameForLowerBoundInvalidId() {
309         try {
310             JavadocUtil.getTokenName(10095);
311             assertWithMessage("exception expected").fail();
312         }
313         catch (IllegalArgumentException ex) {
314             assertWithMessage("Invalid exception message")
315                 .that(ex.getMessage())
316                 .isEqualTo("Unknown javadoc token id. Given id: 10095");
317         }
318     }
319 
320     @Test
321     public void testGetTokenIdThatIsUnknown() {
322         try {
323             JavadocUtil.getTokenId("");
324             assertWithMessage("exception expected").fail();
325         }
326         catch (IllegalArgumentException ex) {
327             assertWithMessage("Invalid exception message")
328                 .that(ex.getMessage())
329                 .isEqualTo("Unknown javadoc token name. Given name ");
330         }
331     }
332 
333     @Test
334     public void testGetTokenId() {
335         final int tokenId = JavadocUtil.getTokenId("JAVADOC");
336 
337         assertWithMessage("Invalid token id")
338             .that(tokenId)
339             .isEqualTo(JavadocTokenTypes.JAVADOC);
340     }
341 
342     @Test
343     public void testGetJavadocCommentContent() {
344         final DetailAstImpl detailAST = new DetailAstImpl();
345         final DetailAstImpl javadoc = new DetailAstImpl();
346 
347         javadoc.setText("1javadoc");
348         detailAST.setFirstChild(javadoc);
349         final String commentContent = JavadocUtil.getJavadocCommentContent(detailAST);
350 
351         assertWithMessage("Invalid comment content")
352             .that(commentContent)
353             .isEqualTo("javadoc");
354     }
355 
356     @Test
357     public void testGetFirstToken() {
358         final JavadocNodeImpl javadocNode = new JavadocNodeImpl();
359         final JavadocNodeImpl basetag = new JavadocNodeImpl();
360         basetag.setType(JavadocTokenTypes.BASE_TAG);
361         final JavadocNodeImpl body = new JavadocNodeImpl();
362         body.setType(JavadocTokenTypes.BODY);
363 
364         body.setParent(javadocNode);
365         basetag.setParent(javadocNode);
366         javadocNode.setChildren(basetag, body);
367 
368         final DetailNode result = JavadocUtil.findFirstToken(javadocNode, JavadocTokenTypes.BODY);
369 
370         assertWithMessage("Invalid first token")
371             .that(result)
372             .isEqualTo(body);
373     }
374 
375     @Test
376     public void testGetPreviousSibling() {
377         final JavadocNodeImpl root = new JavadocNodeImpl();
378 
379         final JavadocNodeImpl node = new JavadocNodeImpl();
380         node.setIndex(1);
381         node.setParent(root);
382 
383         final JavadocNodeImpl previousNode = new JavadocNodeImpl();
384         previousNode.setIndex(0);
385         node.setParent(root);
386 
387         root.setChildren(previousNode, node);
388 
389         final DetailNode previousSibling = JavadocUtil.getPreviousSibling(node);
390 
391         assertWithMessage("Unexpected node")
392             .that(previousSibling)
393             .isEqualTo(previousNode);
394     }
395 
396     @Test
397     public void testGetLastTokenName() {
398         assertWithMessage("Unexpected token name")
399             .that(JavadocUtil.getTokenName(10094))
400             .isEqualTo("RP");
401     }
402 
403     @Test
404     public void testEscapeAllControlChars() {
405         assertWithMessage("invalid result")
406             .that(JavadocUtil.escapeAllControlChars("abc"))
407             .isEqualTo("abc");
408         assertWithMessage("invalid result")
409             .that(JavadocUtil.escapeAllControlChars("1\\r2\\n3\\t"))
410             .isEqualTo("1\\r2\\n3\\t");
411     }
412 
413     private static void assertTag(String message, InvalidJavadocTag expected,
414             InvalidJavadocTag actual) {
415         assertWithMessage(message + " line")
416             .that(actual.getLine())
417             .isEqualTo(expected.getLine());
418         assertWithMessage(message + " column")
419             .that(actual.getCol())
420             .isEqualTo(expected.getCol());
421         assertWithMessage(message + " name")
422             .that(actual.getName())
423             .isEqualTo(expected.getName());
424     }
425 
426     private static void assertTag(String message, JavadocTag expected,
427             JavadocTag actual) {
428         assertWithMessage(message + " line")
429             .that(actual.getLineNo())
430             .isEqualTo(expected.getLineNo());
431         assertWithMessage(message + " column")
432             .that(actual.getColumnNo())
433             .isEqualTo(expected.getColumnNo());
434         assertWithMessage(message + " first arg")
435             .that(actual.getFirstArg())
436             .isEqualTo(expected.getFirstArg());
437         assertWithMessage(message + " tag name")
438             .that(actual.getTagName())
439             .isEqualTo(expected.getTagName());
440     }
441 
442 }