View Javadoc
1   ///////////////////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code and other text files for adherence to a set of rules.
3   // Copyright (C) 2001-2026 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.MissingJavadocTypeCheck.MSG_JAVADOC_MISSING;
24  
25  import java.util.ArrayList;
26  import java.util.List;
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.internal.utils.TestUtil;
33  import com.puppycrawl.tools.checkstyle.utils.CommonUtil;
34  
35  public class MissingJavadocTypeCheckTest extends AbstractModuleTestSupport {
36  
37      @Override
38      public String getPackageLocation() {
39          return "com/puppycrawl/tools/checkstyle/checks/javadoc/missingjavadoctype";
40      }
41  
42      @Test
43      public void testGetRequiredTokens() {
44          final MissingJavadocTypeCheck missingJavadocTypeCheck = new MissingJavadocTypeCheck();
45          missingJavadocTypeCheck.visitJavadocToken(null);
46          assertWithMessage(
47                  "MissingJavadocTypeCheck#getRequiredTokens should return empty array by default")
48                          .that(missingJavadocTypeCheck.getRequiredTokens())
49                          .isEmpty();
50      }
51  
52      @Test
53      public void testGetAcceptableTokens() {
54          final MissingJavadocTypeCheck missingJavadocTypeCheck = new MissingJavadocTypeCheck();
55  
56          final int[] actual = missingJavadocTypeCheck.getAcceptableTokens();
57          final int[] expected = {
58              TokenTypes.INTERFACE_DEF,
59              TokenTypes.CLASS_DEF,
60              TokenTypes.ENUM_DEF,
61              TokenTypes.ANNOTATION_DEF,
62              TokenTypes.RECORD_DEF,
63          };
64  
65          assertWithMessage("Default acceptable tokens are invalid")
66                  .that(actual)
67                  .isEqualTo(expected);
68      }
69  
70      @Test
71      public void testTagsOne() throws Exception {
72          final String[] expected = {
73              "15:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
74              "45:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
75              "70:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
76          };
77          verifyWithInlineConfigParser(
78                  getPath("InputMissingJavadocTypeTagsOne.java"), expected);
79      }
80  
81      @Test
82      public void testTagsTwo() throws Exception {
83          final String[] expected = {
84              "21:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
85          };
86          verifyWithInlineConfigParser(
87                  getPath("InputMissingJavadocTypeTagsTwo.java"), expected);
88      }
89  
90      @Test
91      public void testTagsThree() throws Exception {
92          final String[] expected = {
93              "21:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
94          };
95          verifyWithInlineConfigParser(
96                  getPath("InputMissingJavadocTypeTagsThree.java"), expected);
97      }
98  
99      @Test
100     public void testTagsFour() throws Exception {
101         final String[] expected = {
102             "21:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
103         };
104         verifyWithInlineConfigParser(
105                 getPath("InputMissingJavadocTypeTagsFour.java"), expected);
106     }
107 
108     @Test
109     public void testInner() throws Exception {
110         final String[] expected = {
111             "20:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
112             "27:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
113             "33:9: " + getCheckMessage(MSG_JAVADOC_MISSING),
114         };
115         verifyWithInlineConfigParser(
116                 getPath("InputMissingJavadocTypeInner.java"), expected);
117     }
118 
119     @Test
120     public void testMissingJavadocTypePublicOnly1One() throws Exception {
121         final String[] expected = {
122             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
123             "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
124             "21:9: " + getCheckMessage(MSG_JAVADOC_MISSING),
125             "41:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
126         };
127         verifyWithInlineConfigParser(
128                 getPath("InputMissingJavadocTypePublicOnly1One.java"), expected);
129     }
130 
131     @Test
132     public void testMissingJavadocTypePublicOnly1Two() throws Exception {
133         final String[] expected = {
134             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
135         };
136         verifyWithInlineConfigParser(
137                 getPath("InputMissingJavadocTypePublicOnly1Two.java"), expected);
138     }
139 
140     @Test
141     public void testMissingJavadocTypePublicOnly2One() throws Exception {
142         final String[] expected = {
143             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
144         };
145         verifyWithInlineConfigParser(
146                 getPath("InputMissingJavadocTypePublicOnly2One.java"), expected);
147     }
148 
149     @Test
150     public void testMissingJavadocTypePublicOnly2Two() throws Exception {
151         final String[] expected = {
152             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
153         };
154         verifyWithInlineConfigParser(
155                 getPath("InputMissingJavadocTypePublicOnly2Two.java"), expected);
156     }
157 
158     @Test
159     public void testPublic() throws Exception {
160         final String[] expected = {
161             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
162             "45:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
163         };
164         verifyWithInlineConfigParser(
165                 getPath("InputMissingJavadocTypeScopeInnerInterfaces1.java"),
166                expected);
167     }
168 
169     @Test
170     public void testProtest() throws Exception {
171         final String[] expected = {
172             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
173             "36:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
174             "45:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
175             "72:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
176         };
177         verifyWithInlineConfigParser(
178                 getPath("InputMissingJavadocTypeScopeInnerInterfaces2.java"),
179                expected);
180     }
181 
182     @Test
183     public void testPkg() throws Exception {
184         final String[] expected = {
185             "23:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
186             "25:9: " + getCheckMessage(MSG_JAVADOC_MISSING),
187             "27:13: " + getCheckMessage(MSG_JAVADOC_MISSING),
188         };
189         verifyWithInlineConfigParser(
190                 getPath("InputMissingJavadocTypeScopeInnerClasses1.java"), expected);
191     }
192 
193     @Test
194     public void testEclipse() throws Exception {
195         final String[] expected = {
196             "23:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
197         };
198         verifyWithInlineConfigParser(
199                 getPath("InputMissingJavadocTypeScopeInnerClasses2.java"), expected);
200     }
201 
202     @Test
203     public void testScopesOne() throws Exception {
204         final String[] expected = {
205             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
206             "26:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
207             "38:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
208             "50:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
209         };
210         verifyWithInlineConfigParser(
211                 getPath("InputMissingJavadocTypeNoJavadoc1One.java"),
212                expected);
213     }
214 
215     @Test
216     public void testScopesTwo() throws Exception {
217         final String[] expected = {
218             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
219             "16:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
220             "27:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
221             "39:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
222             "51:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
223             "63:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
224             "75:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
225         };
226         verifyWithInlineConfigParser(
227                 getPath("InputMissingJavadocTypeNoJavadoc1Two.java"),
228                expected);
229     }
230 
231     @Test
232     public void testLimitViolationsBySpecifyingTokens() throws Exception {
233         final String[] expected = {
234             "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
235         };
236         verifyWithInlineConfigParser(
237                 getPath("InputMissingJavadocTypeNoJavadocOnInterface.java"),
238                expected);
239     }
240 
241     @Test
242     public void testMissingJavadocTypeNoJavadoc2One() throws Exception {
243         final String[] expected = {
244             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
245             "26:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
246         };
247         verifyWithInlineConfigParser(
248                 getPath("InputMissingJavadocTypeNoJavadoc2One.java"),
249                expected);
250     }
251 
252     @Test
253     public void testMissingJavadocTypeNoJavadoc2Two() throws Exception {
254         final String[] expected = {
255             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
256         };
257         verifyWithInlineConfigParser(
258                 getPath("InputMissingJavadocTypeNoJavadoc2Two.java"),
259                expected);
260     }
261 
262     @Test
263     public void testMissingJavadocTypeNoJavadoc3One() throws Exception {
264         final String[] expected = {
265             "38:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
266             "50:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
267         };
268         verifyWithInlineConfigParser(
269                 getPath("InputMissingJavadocTypeNoJavadoc3One.java"),
270                expected);
271     }
272 
273     @Test
274     public void testMissingJavadocTypeNoJavadoc3Two() throws Exception {
275         final String[] expected = {
276             "16:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
277             "27:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
278             "39:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
279             "51:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
280             "63:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
281             "75:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
282         };
283         verifyWithInlineConfigParser(
284                 getPath("InputMissingJavadocTypeNoJavadoc3Two.java"),
285                expected);
286     }
287 
288     @Test
289     public void testDontAllowUnusedParameterTag() throws Exception {
290         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
291         verifyWithInlineConfigParser(
292                 getPath("InputMissingJavadocTypeUnusedParamInJavadocForClass.java"),
293                 expected);
294     }
295 
296     @Test
297     public void testSkipAnnotationsDefault() throws Exception {
298 
299         final String[] expected = {
300             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
301             "18:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
302             "22:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
303         };
304         verifyWithInlineConfigParser(
305                 getPath("InputMissingJavadocTypeSkipAnnotations1.java"),
306             expected);
307     }
308 
309     @Test
310     public void testSkipAnnotationsWithFullyQualifiedName() throws Exception {
311         final String[] expected = {
312             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
313             "18:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
314             "22:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
315         };
316         verifyWithInlineConfigParser(
317                 getPath("InputMissingJavadocTypeSkipAnnotations2.java"),
318                 expected);
319     }
320 
321     @Test
322     public void testSkipAnnotationsAllowed() throws Exception {
323 
324         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
325         verifyWithInlineConfigParser(
326                 getPath("InputMissingJavadocTypeSkipAnnotations3.java"),
327             expected);
328     }
329 
330     @Test
331     public void testSkipAnnotationsNotAllowed() throws Exception {
332 
333         final String[] expected = {
334             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
335             "18:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
336             "22:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
337         };
338         verifyWithInlineConfigParser(
339                 getPath("InputMissingJavadocTypeSkipAnnotations4.java"),
340             expected);
341     }
342 
343     @Test
344     public void testMissingJavadocTypeCheckRecords() throws Exception {
345 
346         final String[] expected = {
347             "15:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
348             "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
349             "20:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
350             "24:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
351             "32:9: " + getCheckMessage(MSG_JAVADOC_MISSING),
352             "33:13: " + getCheckMessage(MSG_JAVADOC_MISSING),
353             "42:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
354         };
355         verifyWithInlineConfigParser(
356                 getPath("InputMissingJavadocTypeRecords.java"),
357             expected);
358     }
359 
360     @Test
361     public void testInterfaceMemberScopeIsPublic() throws Exception {
362 
363         final String[] expected = {
364             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
365             "16:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
366             "20:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
367         };
368         verifyWithInlineConfigParser(
369                 getPath("InputMissingJavadocTypeInterfaceMemberScopeIsPublic.java"),
370             expected);
371     }
372 
373     @Test
374     public void testQualifiedAnnotation1() throws Exception {
375         final String[] expected = {
376             "17:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
377             "21:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
378             "24:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
379         };
380         verifyWithInlineConfigParser(
381             getPath("InputMissingJavadocTypeQualifiedAnnotation1.java"), expected);
382     }
383 
384     @Test
385     public void testQualifiedAnnotation2() throws Exception {
386         final String[] expected = {
387             "21:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
388             "24:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
389         };
390         verifyWithInlineConfigParser(
391             getPath("InputMissingJavadocTypeQualifiedAnnotation2.java"), expected);
392     }
393 
394     @Test
395     public void testQualifiedAnnotation3() throws Exception {
396         final String[] expected = {
397             "17:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
398             "23:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
399         };
400         verifyWithInlineConfigParser(
401             getPath("InputMissingJavadocTypeQualifiedAnnotation3.java"), expected);
402     }
403 
404     @Test
405     public void testQualifiedAnnotation4() throws Exception {
406         final String[] expected = {
407             "18:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
408             "22:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
409         };
410         verifyWithInlineConfigParser(
411             getPath("InputMissingJavadocTypeQualifiedAnnotation4.java"), expected);
412     }
413 
414     @Test
415     public void testQualifiedAnnotation5() throws Exception {
416         final String[] expected = CommonUtil.EMPTY_STRING_ARRAY;
417         verifyWithInlineConfigParser(
418             getPath("InputMissingJavadocTypeQualifiedAnnotation5.java"), expected);
419     }
420 
421     @Test
422     public void testMultipleQualifiedAnnotation() throws Exception {
423         final String[] expected = {
424             "30:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
425             "39:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
426         };
427         verifyWithInlineConfigParser(
428             getPath("InputMissingJavadocTypeMultipleQualifiedAnnotation.java"), expected);
429     }
430 
431     @Test
432     public void testQualifiedAnnotationWithParameters() throws Exception {
433         final String[] expected = {
434             "34:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
435             "38:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
436             "43:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
437             "51:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
438         };
439         verifyWithInlineConfigParser(
440             getPath("InputMissingJavadocTypeQualifiedAnnotationWithParameters.java"),
441             expected);
442     }
443 
444     @Test
445     public void testMissingJavadocTypeAboveComments() throws Exception {
446         final String[] expected = {
447             "14:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
448             "28:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
449         };
450         verifyWithInlineConfigParser(
451             getPath("InputMissingJavadocTypeAboveComments.java"),
452             expected);
453     }
454 
455     @Test
456     public void testNonJavadocBlockCommentDoesNotSatisfyJavadoc() throws Exception {
457         final String[] expected = {
458             "13:1: " + getCheckMessage(MSG_JAVADOC_MISSING),
459             "15:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
460             "21:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
461             "25:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
462         };
463         verifyWithInlineConfigParser(
464                 getPath("InputMissingJavadocTypeNonJavadocOnly.java"),
465                 expected);
466     }
467 
468     @Test
469     public void testMissingJavadocTypeEnum() throws Exception {
470         final String[] expected = {
471             "36:6: " + getCheckMessage(MSG_JAVADOC_MISSING),
472             "49:5: " + getCheckMessage(MSG_JAVADOC_MISSING),
473         };
474         verifyWithInlineConfigParser(
475             getPath("InputMissingJavadocTypeEnum.java"),
476             expected);
477     }
478 
479     @Test
480     public void testClearJavadocComments() {
481         final MissingJavadocTypeCheck check = new MissingJavadocTypeCheck();
482         final List<Object> mockList = new ArrayList<>();
483         mockList.add(new Object());
484         TestUtil.setInternalState(check, "javadocComments", mockList);
485         check.beginTree(null);
486         final List<?> javadocComments =
487                 (List<?>) TestUtil.getInternalState(check, "javadocComments", List.class);
488         assertWithMessage("javadocComments state is not cleared on beginTree")
489                 .that(javadocComments)
490                 .isEmpty();
491     }
492 
493 }