View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2025 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.JavadocCommentsTokenTypes;
32  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
33  import com.puppycrawl.tools.checkstyle.checks.javadoc.InvalidJavadocTag;
34  import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTag;
35  import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagInfo;
36  import com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTags;
37  
38  public class JavadocUtilTest {
39  
40      @Test
41      public void testTags() {
42          final String[] text = {
43              "/** @see elsewhere ",
44              " * {@link List }, {@link List link text }",
45              "   {@link List#add(Object) link text}",
46              " * {@link Class link text}",
47          };
48          final Comment comment = new Comment(text, 1, 4, text[3].length());
49          final JavadocTags allTags =
50              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.ALL);
51          assertWithMessage("Invalid valid tags size")
52              .that(allTags.getValidTags())
53              .hasSize(5);
54      }
55  
56      @Test
57      public void testBlockTag() {
58          final String[] text = {
59              "/** @see elsewhere ",
60              " */",
61          };
62          final Comment comment = new Comment(text, 1, 4, text[1].length());
63          final JavadocTags allTags =
64              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.ALL);
65          assertWithMessage("Invalid valid tags size")
66              .that(allTags.getValidTags())
67              .hasSize(1);
68      }
69  
70      @Test
71      public void testTagType() {
72          final String[] text = {
73              "/** @see block",
74              " * {@link List inline}, {@link List#add(Object)}",
75          };
76          final Comment comment = new Comment(text, 1, 2, text[1].length());
77          final JavadocTags blockTags =
78              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.BLOCK);
79          final JavadocTags inlineTags =
80              JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.INLINE);
81          assertWithMessage("Invalid valid tags size")
82              .that(blockTags.getValidTags())
83              .hasSize(1);
84          assertWithMessage("Invalid valid tags size")
85              .that(inlineTags.getValidTags())
86              .hasSize(2);
87      }
88  
89      @Test
90      public void testInlineTagLinkText() {
91          final String[] text = {
92              "/** {@link List link text }",
93          };
94          final Comment comment = new Comment(text, 1, 1, text[0].length());
95          final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
96              comment, JavadocUtil.JavadocTagType.ALL).getValidTags();
97          assertWithMessage("Invalid first arg")
98              .that(tags.get(0).getFirstArg())
99              .isEqualTo("List link text");
100     }
101 
102     @Test
103     public void testInlineTagMethodRef() {
104         final String[] text = {
105             "/** {@link List#add(Object)}",
106         };
107         final Comment comment = new Comment(text, 1, 1, text[0].length());
108         final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
109             comment, JavadocUtil.JavadocTagType.ALL).getValidTags();
110         assertWithMessage("Invalid first arg")
111             .that(tags.get(0).getFirstArg())
112             .isEqualTo("List#add(Object)");
113     }
114 
115     @Test
116     public void testTagPositions() {
117         final String[] text = {
118             "/** @see elsewhere",
119             "    also {@link Name value} */",
120         };
121         final Comment comment = new Comment(text, 1, 2, text[1].length());
122 
123         final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
124             comment, JavadocUtil.JavadocTagType.ALL).getValidTags();
125 
126         assertWithMessage("Invalid tags size")
127             .that(tags)
128             .hasSize(2);
129 
130         final JavadocTag seeTag = tags.get(0);
131         assertWithMessage("Invalid tag name")
132             .that(seeTag.getTagName())
133             .isEqualTo(JavadocTagInfo.SEE.getName());
134         assertWithMessage("Invalid line number")
135             .that(seeTag.getLineNo())
136             .isEqualTo(1);
137         assertWithMessage("Invalid column number")
138             .that(seeTag.getColumnNo())
139             .isEqualTo(4);
140 
141         final JavadocTag linkTag = tags.get(1);
142         assertWithMessage("Invalid tag name")
143             .that(linkTag.getTagName())
144             .isEqualTo(JavadocTagInfo.LINK.getName());
145         assertWithMessage("Invalid line number")
146             .that(linkTag.getLineNo())
147             .isEqualTo(2);
148         assertWithMessage("Invalid column number")
149             .that(linkTag.getColumnNo())
150             .isEqualTo(10);
151     }
152 
153     @Test
154     public void testInlineTagPositions() {
155         final String[] text = {"/** Also {@link Name value} */"};
156         final Comment comment = new Comment(text, 1, 0, text[0].length());
157 
158         final List<JavadocTag> tags = JavadocUtil.getJavadocTags(
159             comment, JavadocUtil.JavadocTagType.INLINE).getValidTags();
160 
161         assertWithMessage("Invalid tags size")
162             .that(tags)
163             .hasSize(1);
164         final int lineNo = tags.get(0).getLineNo();
165         assertWithMessage("Unexpected line number")
166             .that(lineNo)
167             .isEqualTo(0);
168         final int columnNo = tags.get(0).getColumnNo();
169         assertWithMessage("Unexpected column number")
170             .that(columnNo)
171             .isEqualTo(10);
172     }
173 
174     @Test
175     public void testInvalidTags() {
176         final String[] text = {
177             "/** @fake block",
178             " * {@bogus inline}",
179             " * {@link List valid}",
180         };
181         final Comment comment = new Comment(text, 1, 3, text[2].length());
182         final JavadocTags allTags =
183             JavadocUtil.getJavadocTags(comment, JavadocUtil.JavadocTagType.ALL);
184         assertWithMessage("Unexpected invalid tags size")
185             .that(allTags.getInvalidTags())
186             .hasSize(2);
187         assertTag("Unexpected invalid tag", new InvalidJavadocTag(1, 4, "fake"),
188                 allTags.getInvalidTags().get(0));
189         assertTag("Unexpected invalid tag", new InvalidJavadocTag(2, 4, "bogus"),
190                 allTags.getInvalidTags().get(1));
191         assertWithMessage("Unexpected valid tags size")
192             .that(allTags.getValidTags())
193             .hasSize(1);
194         assertTag("Unexpected valid tag", new JavadocTag(3, 4, "link", "List valid"),
195                 allTags.getValidTags().get(0));
196     }
197 
198     @Test
199     public void testEmptyBlockComment() {
200         final String emptyComment = "";
201         assertWithMessage("Should return false when empty string is passed")
202                 .that(JavadocUtil.isJavadocComment(emptyComment))
203                 .isFalse();
204     }
205 
206     @Test
207     public void testEmptyBlockCommentAst() {
208         final DetailAstImpl commentBegin = new DetailAstImpl();
209         commentBegin.setType(TokenTypes.BLOCK_COMMENT_BEGIN);
210         commentBegin.setText("/*");
211 
212         final DetailAstImpl commentContent = new DetailAstImpl();
213         commentContent.setType(TokenTypes.COMMENT_CONTENT);
214         commentContent.setText("");
215 
216         final DetailAstImpl commentEnd = new DetailAstImpl();
217         commentEnd.setType(TokenTypes.BLOCK_COMMENT_END);
218         commentEnd.setText("*/");
219 
220         commentBegin.setFirstChild(commentContent);
221         commentContent.setNextSibling(commentEnd);
222 
223         assertWithMessage("Should return false when empty block comment is passed")
224                 .that(JavadocUtil.isJavadocComment(commentBegin))
225                 .isFalse();
226     }
227 
228     @Test
229     public void testEmptyJavadocComment() {
230         final String emptyJavadocComment = "*";
231         assertWithMessage("Should return true when empty javadoc comment is passed")
232                 .that(JavadocUtil.isJavadocComment(emptyJavadocComment))
233                 .isTrue();
234     }
235 
236     @Test
237     public void testEmptyJavadocCommentAst() {
238         final DetailAstImpl commentBegin = new DetailAstImpl();
239         commentBegin.setType(TokenTypes.BLOCK_COMMENT_BEGIN);
240         commentBegin.setText("/*");
241 
242         final DetailAstImpl javadocCommentContent = new DetailAstImpl();
243         javadocCommentContent.setType(TokenTypes.COMMENT_CONTENT);
244         javadocCommentContent.setText("*");
245 
246         final DetailAstImpl commentEnd = new DetailAstImpl();
247         commentEnd.setType(TokenTypes.BLOCK_COMMENT_END);
248         commentEnd.setText("*/");
249 
250         commentBegin.setFirstChild(javadocCommentContent);
251         javadocCommentContent.setNextSibling(commentEnd);
252 
253         final DetailAstImpl commentBeginParent = new DetailAstImpl();
254         commentBeginParent.setType(TokenTypes.MODIFIERS);
255         commentBeginParent.setFirstChild(commentBegin);
256 
257         final DetailAstImpl aJavadocPosition = new DetailAstImpl();
258         aJavadocPosition.setType(TokenTypes.METHOD_DEF);
259         aJavadocPosition.setFirstChild(commentBeginParent);
260         assertWithMessage("Should return true when empty javadoc comment ast is passed")
261                 .that(JavadocUtil.isJavadocComment(commentBegin))
262                 .isTrue();
263     }
264 
265     @Test
266     public void testIsProperUtilsClass() throws ReflectiveOperationException {
267         assertWithMessage("Constructor is not private")
268                 .that(isUtilsClassHasPrivateConstructor(JavadocUtil.class))
269                 .isTrue();
270     }
271 
272     @Test
273     public void testGetTokenNameForId() {
274         assertWithMessage("Invalid token name")
275             .that(JavadocUtil.getTokenName(JavadocCommentsTokenTypes.JAVADOC_CONTENT))
276             .isEqualTo("JAVADOC_CONTENT");
277     }
278 
279     @Test
280     public void testGetTokenNameForLargeId() {
281         try {
282             JavadocUtil.getTokenName(30073);
283             assertWithMessage("exception expected").fail();
284         }
285         catch (IllegalArgumentException exc) {
286             assertWithMessage("Invalid exception message")
287                 .that(exc.getMessage())
288                 .isEqualTo("Unknown javadoc token id. Given id: 30073");
289         }
290     }
291 
292     @Test
293     public void testGetTokenNameForInvalidId() {
294         try {
295             JavadocUtil.getTokenName(110);
296             assertWithMessage("exception expected").fail();
297         }
298         catch (IllegalArgumentException exc) {
299             assertWithMessage("Invalid exception message")
300                 .that(exc.getMessage())
301                 .isEqualTo("Unknown javadoc token id. Given id: 110");
302         }
303     }
304 
305     @Test
306     public void testGetTokenNameForLowerBoundInvalidId() {
307         try {
308             JavadocUtil.getTokenName(10095);
309             assertWithMessage("exception expected").fail();
310         }
311         catch (IllegalArgumentException exc) {
312             assertWithMessage("Invalid exception message")
313                 .that(exc.getMessage())
314                 .isEqualTo("Unknown javadoc token id. Given id: 10095");
315         }
316     }
317 
318     @Test
319     public void testGetTokenIdThatIsUnknown() {
320         try {
321             JavadocUtil.getTokenId("");
322             assertWithMessage("exception expected").fail();
323         }
324         catch (IllegalArgumentException exc) {
325             assertWithMessage("Invalid exception message")
326                 .that(exc.getMessage())
327                 .isEqualTo("Unknown javadoc token name. Given name ");
328         }
329     }
330 
331     @Test
332     public void testGetTokenId() {
333         final int tokenId = JavadocUtil.getTokenId("JAVADOC_CONTENT");
334 
335         assertWithMessage("Invalid token id")
336             .that(tokenId)
337             .isEqualTo(JavadocCommentsTokenTypes.JAVADOC_CONTENT);
338     }
339 
340     @Test
341     public void testGetJavadocCommentContent() {
342         final DetailAstImpl detailAST = new DetailAstImpl();
343         final DetailAstImpl javadoc = new DetailAstImpl();
344 
345         javadoc.setText("1javadoc");
346         detailAST.setFirstChild(javadoc);
347         final String commentContent = JavadocUtil.getJavadocCommentContent(detailAST);
348 
349         assertWithMessage("Invalid comment content")
350             .that(commentContent)
351             .isEqualTo("javadoc");
352     }
353 
354     @Test
355     public void testGetLastTokenName() {
356         assertWithMessage("Unexpected token name")
357             .that(JavadocUtil.getTokenName(103))
358             .isEqualTo("CUSTOM_BLOCK_TAG");
359     }
360 
361     @Test
362     public void testEscapeAllControlChars() {
363         assertWithMessage("invalid result")
364             .that(JavadocUtil.escapeAllControlChars("abc"))
365             .isEqualTo("abc");
366         assertWithMessage("invalid result")
367             .that(JavadocUtil.escapeAllControlChars("1\\r2\\n3\\t"))
368             .isEqualTo("1\\r2\\n3\\t");
369     }
370 
371     private static void assertTag(String message, InvalidJavadocTag expected,
372             InvalidJavadocTag actual) {
373         assertWithMessage(message + " line")
374             .that(actual.getLine())
375             .isEqualTo(expected.getLine());
376         assertWithMessage(message + " column")
377             .that(actual.getCol())
378             .isEqualTo(expected.getCol());
379         assertWithMessage(message + " name")
380             .that(actual.getName())
381             .isEqualTo(expected.getName());
382     }
383 
384     private static void assertTag(String message, JavadocTag expected,
385             JavadocTag actual) {
386         assertWithMessage(message + " line")
387             .that(actual.getLineNo())
388             .isEqualTo(expected.getLineNo());
389         assertWithMessage(message + " column")
390             .that(actual.getColumnNo())
391             .isEqualTo(expected.getColumnNo());
392         assertWithMessage(message + " first arg")
393             .that(actual.getFirstArg())
394             .isEqualTo(expected.getFirstArg());
395         assertWithMessage(message + " tag name")
396             .that(actual.getTagName())
397             .isEqualTo(expected.getTagName());
398     }
399 
400 }