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