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.checks.javadoc;
21  
22  import static com.google.common.truth.Truth.assertWithMessage;
23  import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck.MSG_MISSING_TAG;
24  import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck.MSG_TAG_FORMAT;
25  import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck.MSG_UNKNOWN_TAG;
26  import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck.MSG_UNUSED_TAG;
27  import static com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck.MSG_UNUSED_TAG_GENERAL;
28  
29  import org.junit.jupiter.api.Test;
30  
31  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
32  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
33  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
34  
35  public class JavadocTypeCheckTest extends AbstractModuleTestSupport {
36  
37      @Override
38      protected String getPackageLocation() {
39          return "com/puppycrawl/tools/checkstyle/checks/javadoc/javadoctype";
40      }
41  
42      @Test
43      public void testGetRequiredTokens() {
44          final JavadocTypeCheck javadocTypeCheck = new JavadocTypeCheck();
45          assertWithMessage("JavadocTypeCheck#getRequiredTokens should return empty array by default")
46              .that(javadocTypeCheck.getRequiredTokens())
47              .isEqualTo(CommonUtil.EMPTY_INT_ARRAY);
48      }
49  
50      @Test
51      public void testGetAcceptableTokens() {
52          final JavadocTypeCheck javadocTypeCheck = new JavadocTypeCheck();
53  
54          final int[] actual = javadocTypeCheck.getAcceptableTokens();
55          final int[] expected = {
56              TokenTypes.INTERFACE_DEF,
57              TokenTypes.CLASS_DEF,
58              TokenTypes.ENUM_DEF,
59              TokenTypes.ANNOTATION_DEF,
60              TokenTypes.RECORD_DEF,
61          };
62  
63          assertWithMessage("Default acceptable tokens are invalid")
64              .that(actual)
65              .isEqualTo(expected);
66      }
67  
68      @Test
69      public void testTags() throws Exception {
70          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
71          verifyWithInlineConfigParser(
72                  getPath("InputJavadocTypeTags.java"), expected);
73      }
74  
75      @Test
76      public void testInner() throws Exception {
77          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
78          verifyWithInlineConfigParser(
79                  getPath("InputJavadocTypeInner.java"), expected);
80      }
81  
82      @Test
83      public void testStrict() throws Exception {
84          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
85          verifyWithInlineConfigParser(
86                  getPath("InputJavadocTypePublicOnly.java"), expected);
87      }
88  
89      @Test
90      public void testProtected() throws Exception {
91          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
92          verifyWithInlineConfigParser(
93                  getPath("InputJavadocTypePublicOnly1.java"), expected);
94      }
95  
96      @Test
97      public void testProtectedTwo() throws Exception {
98          final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
99          verifyWithInlineConfigParser(
100                 getPath("InputJavadocTypePublicOnly1Two.java"), expected);
101     }
102 
103     @Test
104     public void testPublic() throws Exception {
105         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
106         verifyWithInlineConfigParser(
107                 getPath("InputJavadocTypeScopeInnerInterfaces.java"),
108                expected);
109     }
110 
111     @Test
112     public void testProtest() throws Exception {
113         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
114         verifyWithInlineConfigParser(
115                 getPath("InputJavadocTypeScopeInnerInterfaces1.java"),
116                expected);
117     }
118 
119     @Test
120     public void testPkg() throws Exception {
121         final String[] expected = {
122             "53:5: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
123         };
124         verifyWithInlineConfigParser(
125                 getPath("InputJavadocTypeScopeInnerClasses.java"), expected);
126     }
127 
128     @Test
129     public void testEclipse() throws Exception {
130         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
131         verifyWithInlineConfigParser(
132                 getPath("InputJavadocTypeScopeInnerClasses1.java"), expected);
133     }
134 
135     @Test
136     public void testAuthorRequired() throws Exception {
137         final String[] expected = {
138             "23:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
139         };
140         verifyWithInlineConfigParser(
141                 getPath("InputJavadocTypeWhitespace.java"), expected);
142     }
143 
144     @Test
145     public void testAuthorRegularEx()
146             throws Exception {
147         final String[] expected = {
148             "31:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
149             "67:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
150             "103:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
151         };
152         verifyWithInlineConfigParser(
153                 getPath("InputJavadocTypeJavadoc.java"), expected);
154     }
155 
156     @Test
157     public void testAuthorRegularExError()
158             throws Exception {
159         final String[] expected = {
160             "22:1: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
161             "31:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
162             "40:1: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
163             "58:1: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
164             "67:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
165             "76:1: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
166             "94:1: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
167             "103:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
168             "112:1: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
169         };
170         verifyWithInlineConfigParser(
171                 getPath("InputJavadocTypeJavadoc_1.java"), expected);
172     }
173 
174     @Test
175     public void testVersionRequired()
176             throws Exception {
177         final String[] expected = {
178             "23:1: " + getCheckMessage(MSG_MISSING_TAG, "@version"),
179         };
180         verifyWithInlineConfigParser(
181                 getPath("InputJavadocTypeWhitespace_1.java"), expected);
182     }
183 
184     @Test
185     public void testVersionRegularEx()
186             throws Exception {
187         final String[] expected = {
188             "31:1: " + getCheckMessage(MSG_MISSING_TAG, "@version"),
189             "67:1: " + getCheckMessage(MSG_MISSING_TAG, "@version"),
190             "103:1: " + getCheckMessage(MSG_MISSING_TAG, "@version"),
191         };
192         verifyWithInlineConfigParser(
193                 getPath("InputJavadocTypeJavadoc_3.java"), expected);
194     }
195 
196     @Test
197     public void testVersionRegularExError()
198             throws Exception {
199         final String[] expected = {
200             "22:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
201             "31:1: " + getCheckMessage(MSG_MISSING_TAG, "@version"),
202             "40:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
203             "49:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
204             "58:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
205             "67:1: " + getCheckMessage(MSG_MISSING_TAG, "@version"),
206             "76:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
207             "85:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
208             "94:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
209             "103:1: " + getCheckMessage(MSG_MISSING_TAG, "@version"),
210             "112:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
211             "121:1: " + getCheckMessage(MSG_TAG_FORMAT, "@version", "\\$Revision.*\\$"),
212         };
213         verifyWithInlineConfigParser(
214                 getPath("InputJavadocTypeJavadoc_2.java"), expected);
215     }
216 
217     @Test
218     public void testScopes() throws Exception {
219         final String[] expected = {
220             "18:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
221             "137:5: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
222         };
223         verifyWithInlineConfigParser(
224                 getPath("InputJavadocTypeNoJavadoc.java"),
225                expected);
226     }
227 
228     @Test
229     public void testLimitViolationsBySpecifyingTokens() throws Exception {
230         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
231         verifyWithInlineConfigParser(
232                 getPath("InputJavadocTypeNoJavadocOnInterface.java"),
233                expected);
234     }
235 
236     @Test
237     public void testScopes2() throws Exception {
238         final String[] expected = {
239             "18:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
240         };
241         verifyWithInlineConfigParser(
242                 getPath("InputJavadocTypeNoJavadoc_2.java"),
243                expected);
244     }
245 
246     @Test
247     public void testExcludeScope() throws Exception {
248         final String[] expected = {
249             "137:5: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
250         };
251         verifyWithInlineConfigParser(
252                 getPath("InputJavadocTypeNoJavadoc_1.java"),
253                expected);
254     }
255 
256     @Test
257     public void testTypeParameters() throws Exception {
258         final String[] expected = {
259             "21:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<D123>"),
260             "25:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <C456>"),
261             "59:8: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<C>"),
262             "62:5: " + getCheckMessage(MSG_MISSING_TAG, "@param <B>"),
263             "75:5: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "x"),
264             "79:5: " + getCheckMessage(MSG_UNUSED_TAG_GENERAL, "@param"),
265         };
266         verifyWithInlineConfigParser(
267                 getPath("InputJavadocTypeTypeParamsTags_1.java"), expected);
268     }
269 
270     @Test
271     public void testAllowMissingTypeParameters() throws Exception {
272         final String[] expected = {
273             "21:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<D123>"),
274             "58:8: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<C>"),
275             "74:5: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "x"),
276         };
277         verifyWithInlineConfigParser(
278                 getPath("InputJavadocTypeTypeParamsTags.java"), expected);
279     }
280 
281     @Test
282     public void testDontAllowUnusedParameterTag() throws Exception {
283         final String[] expected = {
284             "20:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "BAD"),
285             "21:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<BAD>"),
286             "23:4: " + getCheckMessage(MSG_UNUSED_TAG_GENERAL, "@param"),
287         };
288         verifyWithInlineConfigParser(
289                 getPath("InputJavadocTypeUnusedParamInJavadocForClass.java"),
290                 expected);
291     }
292 
293     @Test
294     public void testBadTag() throws Exception {
295         final String[] expected = {
296             "19:4: " + getCheckMessage(MSG_UNKNOWN_TAG, "mytag"),
297             "21:4: " + getCheckMessage(MSG_UNKNOWN_TAG, "mytag"),
298             "28:5: " + getCheckMessage(MSG_UNKNOWN_TAG, "mytag"),
299         };
300         verifyWithInlineConfigParser(
301                 getPath("InputJavadocTypeBadTag.java"),
302                expected);
303     }
304 
305     @Test
306     public void testBadTagSuppress() throws Exception {
307         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
308         verifyWithInlineConfigParser(
309                 getPath("InputJavadocTypeBadTag_1.java"),
310                 expected);
311     }
312 
313     @Test
314     public void testAllowedAnnotationsDefault() throws Exception {
315 
316         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
317         verifyWithInlineConfigParser(
318                 getPath("InputJavadocTypeAllowedAnnotations.java"),
319             expected);
320     }
321 
322     @Test
323     public void testAllowedAnnotationsWithFullyQualifiedName() throws Exception {
324         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
325         verifyWithInlineConfigParser(
326                 getPath("InputJavadocTypeAllowedAnnotations_1.java"),
327                 expected);
328     }
329 
330     @Test
331     public void testAllowedAnnotationsAllowed() throws Exception {
332 
333         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
334         verifyWithInlineConfigParser(
335                 getPath("InputJavadocTypeAllowedAnnotations_2.java"),
336             expected);
337     }
338 
339     @Test
340     public void testAllowedAnnotationsNotAllowed() throws Exception {
341 
342         final String[] expected = {
343             "38:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
344         };
345         verifyWithInlineConfigParser(
346                 getPath("InputJavadocTypeAllowedAnnotations_3.java"),
347             expected);
348     }
349 
350     @Test
351     public void testJavadocTypeRecords() throws Exception {
352         final String[] expected = {
353             "24:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
354             "33:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
355             "42:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
356             "55:1: " + getCheckMessage(MSG_TAG_FORMAT, "@author", "ABC"),
357             "65:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
358         };
359         verifyWithInlineConfigParser(
360                 getNonCompilablePath("InputJavadocTypeRecords.java"), expected);
361     }
362 
363     @Test
364     public void testJavadocTypeRecordComponents() throws Exception {
365 
366         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
367 
368         verifyWithInlineConfigParser(
369                 getNonCompilablePath("InputJavadocTypeRecordComponents.java"), expected);
370     }
371 
372     @Test
373     public void testJavadocTypeParamDescriptionWithAngularTags() throws Exception {
374         final String[] expected = {
375             "44:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<P>"),
376             "46:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <U>"),
377             "50:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "region"),
378         };
379 
380         verifyWithInlineConfigParser(
381                 getPath("InputJavadocTypeParamDescriptionWithAngularTags.java"), expected);
382     }
383 
384     @Test
385     public void testJavadocTypeRecordParamDescriptionWithAngularTags() throws Exception {
386         final String[] expected = {
387             "51:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<P>"),
388             "53:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <U>"),
389             "57:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "region"),
390             "60:1: " + getCheckMessage(MSG_MISSING_TAG, "@param a"),
391             "73:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "e"),
392             "76:1: " + getCheckMessage(MSG_MISSING_TAG, "@param c"),
393         };
394 
395         verifyWithInlineConfigParser(
396                 getNonCompilablePath(
397                         "InputJavadocTypeRecordParamDescriptionWithAngularTags.java"),
398                 expected);
399     }
400 
401     @Test
402     public void testJavadocTypeRecordComponents2() throws Exception {
403 
404         final String[] expected = {
405             "44:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <X>"),
406             "48:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "x"),
407             "59:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "notMyString"),
408             "62:1: " + getCheckMessage(MSG_MISSING_TAG, "@param myString"),
409             "62:1: " + getCheckMessage(MSG_MISSING_TAG, "@param myInt"),
410             "66:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "x"),
411             "68:1: " + getCheckMessage(MSG_MISSING_TAG, "@param myList"),
412             "75:1: " + getCheckMessage(MSG_MISSING_TAG, "@param X"),
413             "78:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "notMyString"),
414             "81:1: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
415             "81:1: " + getCheckMessage(MSG_MISSING_TAG, "@param myInt"),
416             "81:1: " + getCheckMessage(MSG_MISSING_TAG, "@param myString"),
417         };
418         verifyWithInlineConfigParser(
419                 getNonCompilablePath("InputJavadocTypeRecordComponents2.java"), expected);
420     }
421 
422     @Test
423     public void testJavadocTypeInterfaceMemberScopeIsPublic() throws Exception {
424 
425         final String[] expected = {
426             "19:5: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<T>"),
427             "24:5: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<T>"),
428         };
429         verifyWithInlineConfigParser(
430                 getPath("InputJavadocTypeInterfaceMemberScopeIsPublic.java"), expected);
431     }
432 
433     @Test
434     public void testTrimOptionProperty() throws Exception {
435         final String[] expected = {
436             "21:4: " + getCheckMessage(MSG_UNUSED_TAG, "@param", "<D123>"),
437         };
438         verifyWithInlineConfigParser(
439                 getPath("InputJavadocTypeTestTrimProperty.java"), expected);
440     }
441 
442     @Test
443     public void testAuthorFormat() throws Exception {
444         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
445         verifyWithInlineConfigParser(
446                 getPath("InputJavadocType1.java"), expected);
447     }
448 
449     @Test
450     public void testAuthorFormat2() throws Exception {
451         final String[] expected = {
452             "15:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
453         };
454         verifyWithInlineConfigParser(
455                 getPath("InputJavadocType2.java"), expected);
456     }
457 
458     @Test
459     public void testJavadocType() throws Exception {
460         final String[] expected = {
461             "28:5: " + getCheckMessage(MSG_MISSING_TAG, "@param <T>"),
462         };
463         verifyWithInlineConfigParser(
464                 getPath("InputJavadocType3.java"), expected);
465     }
466 
467     @Test
468     public void testJavadocType2() throws Exception {
469         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
470         verifyWithInlineConfigParser(
471                 getPath("InputJavadocType4.java"), expected);
472     }
473 
474     @Test
475     public void testJavadocTypeAboveComments() throws Exception {
476         final String[] expected = {
477             "15:1: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
478             "41:15: " + getCheckMessage(MSG_MISSING_TAG, "@author"),
479         };
480         verifyWithInlineConfigParser(
481                 getPath("InputJavadocTypeAboveComments.java"), expected);
482     }
483 }