View Javadoc
1   ////////////////////////////////////////////////////////////////////////////////
2   // checkstyle: Checks Java source code for adherence to a set of rules.
3   // Copyright (C) 2001-2017 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.puppycrawl.tools.checkstyle.JavadocDetailNodeParser.MSG_JAVADOC_PARSE_RULE_ERROR;
23  import static com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser.MSG_UNCLOSED_HTML_TAG;
24  import static com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck.MSG_JAVADOC_MISSED_HTML_CLOSE;
25  import static com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck.MSG_JAVADOC_WRONG_SINGLETON_TAG;
26  import static com.puppycrawl.tools.checkstyle.checks.javadoc.SummaryJavadocCheck.MSG_SUMMARY_FIRST_SENTENCE;
27  import static java.util.Arrays.asList;
28  import static java.util.Collections.singletonList;
29  import static org.junit.Assert.assertEquals;
30  
31  import java.io.File;
32  import java.util.LinkedHashMap;
33  import java.util.List;
34  import java.util.Map;
35  
36  import org.junit.Assert;
37  import org.junit.Rule;
38  import org.junit.Test;
39  import org.junit.contrib.java.lang.system.SystemErrRule;
40  import org.junit.rules.TemporaryFolder;
41  
42  import com.puppycrawl.tools.checkstyle.AbstractModuleTestSupport;
43  import com.puppycrawl.tools.checkstyle.DefaultConfiguration;
44  import com.puppycrawl.tools.checkstyle.TreeWalker;
45  import com.puppycrawl.tools.checkstyle.api.DetailNode;
46  import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
47  import com.puppycrawl.tools.checkstyle.utils.CommonUtils;
48  import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
49  
50  public class AbstractJavadocCheckTest extends AbstractModuleTestSupport {
51  
52      @Rule
53      public final SystemErrRule systemErr = new SystemErrRule().enableLog().mute();
54  
55      @Rule
56      public final TemporaryFolder temporaryFolder = new TemporaryFolder();
57  
58      @Override
59      protected String getPackageLocation() {
60          return "com/puppycrawl/tools/checkstyle/checks/javadoc/abstractjavadoc";
61      }
62  
63      @Test
64      public void testJavadocTagsWithoutArgs() throws Exception {
65          final DefaultConfiguration checkconfig = createModuleConfig(TempCheck.class);
66          final String[] expected = {
67              "5: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 7,
68                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
69              "10: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 4,
70                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
71              "13: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 6,
72                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
73              "16: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 8,
74                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
75              "22: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 10,
76                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
77              "27: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 7,
78                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
79              "32: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 7,
80                      "mismatched input '<EOF>' expecting {WS, NEWLINE}", "JAVADOC_TAG"),
81              "37: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 6,
82                      "no viable alternative at input '<EOF>'", "JAVADOC_TAG"),
83              "58: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 13,
84                      "mismatched input '}' expecting {LEADING_ASTERISK, WS, NEWLINE}",
85                      "JAVADOC_INLINE_TAG"),
86              "65: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 19,
87                      "no viable alternative at input '}'", "REFERENCE"),
88          };
89          verify(checkconfig, getPath("InputAbstractJavadocJavadocTagsWithoutArgs.java"), expected);
90      }
91  
92      @Test
93      public void testNumberFormatException() throws Exception {
94          final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
95          final String[] expected = {
96              "3: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 52,
97                      "mismatched input ';' expecting MEMBER", "REFERENCE"),
98          };
99          verify(checkConfig, getPath("InputAbstractJavadocNumberFormatException.java"), expected);
100     }
101 
102     @Test
103     public void testCustomTag() throws Exception {
104         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
105         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
106         verify(checkConfig, getPath("InputAbstractJavadocCustomTag.java"), expected);
107     }
108 
109     @Test
110     public void testParsingErrors() throws Exception {
111         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
112         final String[] expected = {
113             "4: " + getCheckMessage(MSG_JAVADOC_MISSED_HTML_CLOSE, 4, "unclosedTag"),
114             "8: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 35, "img"),
115         };
116         verify(checkConfig, getPath("InputAbstractJavadocParsingErrors.java"), expected);
117         assertEquals("Error is unexpected", "", systemErr.getLog());
118     }
119 
120     @Test
121     public void testWithMultipleChecks() throws Exception {
122         final DefaultConfiguration checksConfig = createModuleConfig(TreeWalker.class);
123         checksConfig.addChild(createModuleConfig(AtclauseOrderCheck.class));
124         checksConfig.addChild(createModuleConfig(JavadocParagraphCheck.class));
125 
126         final DefaultConfiguration checkerConfig = createRootConfig(checksConfig);
127 
128         verify(checkerConfig, getPath("InputAbstractJavadocCorrectParagraph.java"));
129     }
130 
131     @Test
132     public void testAntlrError() throws Exception {
133         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
134         final String[] expected = {
135             "4: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 78,
136                     "mismatched input '(' expecting <EOF>", "JAVADOC"),
137         };
138         verify(checkConfig, getPath("InputAbstractJavadocInvalidAtSeeReference.java"), expected);
139         assertEquals("Error is unexpected", "", systemErr.getLog());
140     }
141 
142     @Test
143     public void testCheckReuseAfterParseErrorWithFollowingAntlrErrorInTwoFiles() throws Exception {
144         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
145         final Map<String, List<String>> expectedMessages = new LinkedHashMap<>(2);
146         expectedMessages.put(getPath("InputAbstractJavadocParsingErrors.java"), asList(
147             "4: " + getCheckMessage(MSG_JAVADOC_MISSED_HTML_CLOSE, 4, "unclosedTag"),
148             "8: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 35, "img")
149         ));
150         expectedMessages.put(getPath("InputAbstractJavadocInvalidAtSeeReference.java"),
151             singletonList("4: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 78,
152                     "mismatched input '(' expecting <EOF>", "JAVADOC")
153         ));
154         verify(createChecker(checkConfig), new File[] {
155             new File(getPath("InputAbstractJavadocParsingErrors.java")),
156             new File(getPath("InputAbstractJavadocInvalidAtSeeReference.java")), },
157                 expectedMessages);
158         assertEquals("Error is unexpected", "", systemErr.getLog());
159     }
160 
161     @Test
162     public void testCheckReuseAfterParseErrorWithFollowingAntlrErrorInSingleFile()
163             throws Exception {
164         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
165         final String[] expected = {
166             "4: " + getCheckMessage(MSG_JAVADOC_MISSED_HTML_CLOSE, 4, "unclosedTag"),
167             "8: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR, 82,
168                     "mismatched input '(' expecting <EOF>", "JAVADOC"),
169         };
170         verify(checkConfig,
171             getPath("InputAbstractJavadocUnclosedTagAndInvalidAtSeeReference.java"), expected);
172     }
173 
174     @Test
175     public void testPosition()
176             throws Exception {
177         JavadocCatchCheck.clearCounter();
178         final DefaultConfiguration checkConfig = createModuleConfig(JavadocCatchCheck.class);
179         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
180         verify(checkConfig, getPath("InputAbstractJavadocPosition.java"), expected);
181         assertEquals("Invalid number of javadocs",
182             65, JavadocCatchCheck.javadocsNumber);
183     }
184 
185     @Test
186     public void testPositionWithSinglelineComments()
187             throws Exception {
188         JavadocCatchCheck.clearCounter();
189         final DefaultConfiguration checkConfig = createModuleConfig(JavadocCatchCheck.class);
190         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
191         verify(checkConfig,
192             getPath("InputAbstractJavadocPositionWithSinglelineComments.java"), expected);
193         assertEquals("Invalid number of javadocs",
194                 65, JavadocCatchCheck.javadocsNumber);
195     }
196 
197     @Test
198     public void testPositionOnlyComments()
199             throws Exception {
200         JavadocCatchCheck.clearCounter();
201         final DefaultConfiguration checkConfig = createModuleConfig(JavadocCatchCheck.class);
202         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
203         verify(checkConfig, getPath("InputAbstractJavadocPositionOnlyComments.java"), expected);
204         assertEquals("Invalid number of javadocs",
205                 0, JavadocCatchCheck.javadocsNumber);
206     }
207 
208     @Test
209     public void testTokens() {
210         final int[] defaultJavadocTokens = {JavadocTokenTypes.JAVADOC};
211         final AbstractJavadocCheck check = new AbstractJavadocCheck() {
212 
213             @Override
214             public void visitJavadocToken(DetailNode ast) {
215                 // no code necessary
216             }
217 
218             @Override
219             public int[] getDefaultJavadocTokens() {
220                 return defaultJavadocTokens;
221             }
222         };
223 
224         Assert.assertNotNull("Default tokens should not be null", check.getDefaultTokens());
225         Assert.assertArrayEquals("Acceptable tokens should be equal to default",
226                 check.getDefaultTokens(), check.getAcceptableTokens());
227         Assert.assertArrayEquals("Required tokens should be equal to default",
228                 check.getDefaultTokens(), check.getRequiredTokens());
229         Assert.assertArrayEquals("Invalid default javadoc tokens",
230                 defaultJavadocTokens, check.getDefaultJavadocTokens());
231         Assert.assertArrayEquals("Invalid acceptable javadoc tokens",
232                 defaultJavadocTokens, check.getAcceptableJavadocTokens());
233         Assert.assertNotEquals("Invalid required javadoc tokens",
234                 defaultJavadocTokens, check.getRequiredJavadocTokens());
235     }
236 
237     @Test
238     public void testAcceptableTokensFail()
239             throws Exception {
240         final DefaultConfiguration checkConfig =
241             createModuleConfig(TokenIsNotInAcceptablesJavadocCheck.class);
242         checkConfig.addAttribute("javadocTokens", "RETURN_LITERAL");
243         try {
244             final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
245             verify(checkConfig, getPath("InputAbstractJavadocMain.java"), expected);
246             Assert.fail("CheckstyleException is expected");
247         }
248         catch (IllegalStateException ex) {
249             final String expected = "Javadoc Token "
250                     + "\"RETURN_LITERAL\" was not found in "
251                     + "Acceptable javadoc tokens list in check";
252             Assert.assertTrue("Invalid exception, should start with: " + expected,
253                     ex.getMessage().startsWith(expected));
254         }
255     }
256 
257     @Test
258     public void testAcceptableTokensPass()
259             throws Exception {
260         final DefaultConfiguration checkConfig =
261             createModuleConfig(TokenIsNotInAcceptablesJavadocCheck.class);
262         checkConfig.addAttribute("javadocTokens", "DEPRECATED_LITERAL");
263 
264         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
265         verify(checkConfig, getPath("InputAbstractJavadocMain.java"), expected);
266     }
267 
268     @Test
269     public void testRequiredTokenIsNotInDefaultTokens() throws Exception {
270         final DefaultConfiguration checkConfig =
271             createModuleConfig(RequiredTokenIsNotInDefaultsJavadocCheck.class);
272         final String pathToEmptyFile = temporaryFolder.newFile("file.java").getPath();
273 
274         try {
275             final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
276             verify(checkConfig, pathToEmptyFile, expected);
277             Assert.fail("CheckstyleException is expected");
278         }
279         catch (IllegalStateException ex) {
280             final String expected = "Javadoc Token \""
281                     + JavadocTokenTypes.RETURN_LITERAL + "\" from required"
282                     + " javadoc tokens was not found in default javadoc tokens list in check";
283             Assert.assertTrue("Invalid exception, should start with: " + expected,
284                     ex.getMessage().startsWith(expected));
285         }
286     }
287 
288     @Test
289     public void testVisitLeaveToken()
290             throws Exception {
291         JavadocVisitLeaveCheck.clearCounter();
292         final DefaultConfiguration checkConfig = createModuleConfig(JavadocVisitLeaveCheck.class);
293         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
294         verify(checkConfig, getPath("InputAbstractJavadocPosition.java"), expected);
295         Assert.assertTrue("Javadoc visit count should be greater than zero",
296                 JavadocVisitLeaveCheck.visitCount > 0);
297         assertEquals("Javadoc visit and leave count should be equal",
298                 JavadocVisitLeaveCheck.visitCount, JavadocVisitLeaveCheck.leaveCount);
299     }
300 
301     @Test
302     public void testNoWsBeforeDescriptionInJavadocTags() throws Exception {
303         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
304         final String[] expected = {
305             "13: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
306                     23, "mismatched input 'd' expecting <EOF>", "JAVADOC"),
307             "22: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
308                     30, "mismatched input '-' expecting <EOF>", "JAVADOC"),
309             "28: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
310                     39, "mismatched input '-' expecting <EOF>", "JAVADOC"),
311             "40: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
312                     34, "mismatched input '-' expecting <EOF>", "JAVADOC"),
313             "48: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
314                     31, "mismatched input '-' expecting <EOF>", "JAVADOC"),
315             "57: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
316                     15, "mismatched input '-' expecting <EOF>", "JAVADOC"),
317             "64: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
318                     32, "mismatched input '-' expecting <EOF>", "JAVADOC"),
319             "71: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
320                     17, "mismatched input '<' expecting <EOF>", "JAVADOC"),
321             "78: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
322                     34, "no viable alternative at input '-'", "JAVADOC_INLINE_TAG"),
323             "85: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
324                     39, "no viable alternative at input '-'", "JAVADOC_INLINE_TAG"),
325             "92: " + getCheckMessage(MSG_JAVADOC_PARSE_RULE_ERROR,
326                     19, "no viable alternative at input '<'", "JAVADOC_INLINE_TAG"),
327         };
328         verify(checkConfig, getPath("InputAbstractJavadocNoWsBeforeDescriptionInJavadocTags.java"),
329                 expected);
330     }
331 
332     @Test
333     public void testWrongSingletonTagInJavadoc() throws Exception {
334         final DefaultConfiguration checkConfig = createModuleConfig(TempCheck.class);
335         final String[] expected = {
336             "5: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "embed"),
337             "10: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "keygen"),
338             "15: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "SOURCE"),
339             "20: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "TRACK"),
340             "25: " + getCheckMessage(MSG_JAVADOC_WRONG_SINGLETON_TAG, 9, "WBR"),
341         };
342         verify(checkConfig, getPath("InputAbstractJavadocWrongSingletonTagInJavadoc.java"),
343                 expected);
344     }
345 
346     @Test
347     public void testNonTightHtmlTagIntolerantCheck() throws Exception {
348         final DefaultConfiguration checkConfig =
349                 createModuleConfig(NonTightHtmlTagIntolerantCheck.class);
350         checkConfig.addAttribute("violateExecutionOnNonTightHtml", "true");
351         final String[] expected = {
352             "6: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
353             "13: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
354             "16: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
355             "21: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
356             "27: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
357             "34: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
358             "54: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
359             "71: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
360             "80: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
361             "124: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
362         };
363         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags.java"), expected);
364     }
365 
366     @Test
367     public void testNonTightHtmlTagIntolerantCheckReportingNoViolation() throws Exception {
368         final DefaultConfiguration checkConfig =
369                 createModuleConfig(NonTightHtmlTagIntolerantCheck.class);
370         final String[] expected = CommonUtils.EMPTY_STRING_ARRAY;
371         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags.java"), expected);
372     }
373 
374     @Test
375     public void testNonTightHtmlTagIntolerantCheckVisitCount()
376             throws Exception {
377         final DefaultConfiguration checkConfig =
378                 createModuleConfig(NonTightHtmlTagIntolerantCheck.class);
379         checkConfig.addAttribute("violateExecutionOnNonTightHtml", "true");
380         checkConfig.addAttribute("reportVisitJavadocToken", "true");
381         final String[] expected = {
382             "6: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
383             "13: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
384             "16: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
385             "21: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
386             "27: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
387             "34: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
388             "41:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
389             "54: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
390             "62:13: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
391             "71: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
392             "80: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
393             "99:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
394             "105:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
395             "109:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
396             "124: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
397         };
398         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags.java"), expected);
399     }
400 
401     @Test
402     public void testVisitCountForCheckAcceptingJavadocWithNonTightHtml()
403             throws Exception {
404         final DefaultConfiguration checkConfig =
405                 createModuleConfig(NonTightHtmlTagTolerantCheck.class);
406         checkConfig.addAttribute("violateExecutionOnNonTightHtml", "true");
407         checkConfig.addAttribute("reportVisitJavadocToken", "true");
408         final String[] expected = {
409             "4:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
410             "5:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
411             "6: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
412             "6:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
413             "7:4: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
414             "7:39: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
415             "13: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
416             "13:9: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
417             "13:13: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
418             "16: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
419             "16:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
420             "20:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
421             "21: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
422             "21:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
423             "21:30: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
424             "26:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
425             "26:22: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
426             "27: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
427             "32:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
428             "33:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
429             "34: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
430             "34:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
431             "34:23: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
432             "39:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
433             "39:20: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
434             "39:34: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
435             "41: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "li"),
436             "41:16: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
437             "41:21: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
438             "49:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
439             "51: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
440             "51:22: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
441             "56:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
442             "57:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
443             "60: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "tr"),
444             "79:8: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
445             "85: " + getCheckMessage(MSG_UNCLOSED_HTML_TAG, "p"),
446             "85:9: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
447             "85:13: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
448             "85:33: " + getCheckMessage(MSG_SUMMARY_FIRST_SENTENCE),
449         };
450         verify(checkConfig, getPath("InputAbstractJavadocNonTightHtmlTags2.java"), expected);
451     }
452 
453     private static class TempCheck extends AbstractJavadocCheck {
454 
455         @Override
456         public int[] getDefaultJavadocTokens() {
457             return CommonUtils.EMPTY_INT_ARRAY;
458         }
459 
460         @Override
461         public void visitJavadocToken(DetailNode ast) {
462             // do nothing
463         }
464     }
465 
466     private static class JavadocCatchCheck extends AbstractJavadocCheck {
467         private static int javadocsNumber;
468 
469         public static void clearCounter() {
470             javadocsNumber = 0;
471         }
472 
473         @Override
474         public int[] getDefaultJavadocTokens() {
475             return new int[] {JavadocTokenTypes.JAVADOC};
476         }
477 
478         @Override
479         public void visitJavadocToken(DetailNode ast) {
480             assertEquals(ast.toString(), "JAVADOC", ast.getText());
481             final DetailNode text = JavadocUtils.findFirstToken(ast, JavadocTokenTypes.TEXT);
482             Assert.assertNotNull("Empty javadoc text at " + ast, text);
483             assertEquals(ast.toString(), "Javadoc", text.getText());
484             javadocsNumber++;
485         }
486     }
487 
488     private static class RequiredTokenIsNotInDefaultsJavadocCheck extends AbstractJavadocCheck {
489         @Override
490         public int[] getRequiredJavadocTokens() {
491             return new int[] {JavadocTokenTypes.RETURN_LITERAL};
492         }
493 
494         @Override
495         public int[] getDefaultJavadocTokens() {
496             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
497         }
498 
499         @Override
500         public int[] getAcceptableJavadocTokens() {
501             return CommonUtils.EMPTY_INT_ARRAY;
502         }
503 
504         @Override
505         public void visitJavadocToken(DetailNode ast) {
506             // not used
507         }
508     }
509 
510     private static class TokenIsNotInAcceptablesJavadocCheck extends AbstractJavadocCheck {
511         @Override
512         public int[] getRequiredJavadocTokens() {
513             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
514         }
515 
516         @Override
517         public int[] getDefaultJavadocTokens() {
518             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
519         }
520 
521         @Override
522         public int[] getAcceptableJavadocTokens() {
523             return new int[] {JavadocTokenTypes.DEPRECATED_LITERAL};
524         }
525 
526         @Override
527         public void visitJavadocToken(DetailNode ast) {
528             // not used
529         }
530     }
531 
532     private static class JavadocVisitLeaveCheck extends AbstractJavadocCheck {
533         private static int visitCount;
534         private static int leaveCount;
535 
536         public static void clearCounter() {
537             visitCount = 0;
538             leaveCount = 0;
539         }
540 
541         @Override
542         public int[] getRequiredJavadocTokens() {
543             return new int[] {JavadocTokenTypes.TEXT};
544         }
545 
546         @Override
547         public int[] getDefaultJavadocTokens() {
548             return getRequiredJavadocTokens();
549         }
550 
551         @Override
552         public int[] getAcceptableJavadocTokens() {
553             return getRequiredJavadocTokens();
554         }
555 
556         @Override
557         public void visitJavadocToken(DetailNode ast) {
558             visitCount++;
559         }
560 
561         @Override
562         public void leaveJavadocToken(DetailNode ast) {
563             leaveCount++;
564         }
565     }
566 
567     public static class NonTightHtmlTagIntolerantCheck extends AbstractJavadocCheck {
568 
569         private boolean reportVisitJavadocToken;
570 
571         public final void setReportVisitJavadocToken(boolean reportVisitJavadocToken) {
572             this.reportVisitJavadocToken = reportVisitJavadocToken;
573         }
574 
575         @Override
576         public int[] getDefaultJavadocTokens() {
577             return new int[] {
578                 JavadocTokenTypes.P_TAG_START,
579                 JavadocTokenTypes.LI_TAG_START,
580                 JavadocTokenTypes.BODY_TAG_START,
581             };
582         }
583 
584         @Override
585         public void visitJavadocToken(DetailNode ast) {
586             if (reportVisitJavadocToken) {
587                 log(ast.getLineNumber(), ast.getColumnNumber(), MSG_SUMMARY_FIRST_SENTENCE);
588             }
589         }
590 
591         @Override
592         public boolean acceptJavadocWithNonTightHtml() {
593             return false;
594         }
595     }
596 
597     public static class NonTightHtmlTagTolerantCheck extends AbstractJavadocCheck {
598 
599         private boolean reportVisitJavadocToken;
600 
601         public final void setReportVisitJavadocToken(boolean reportVisitJavadocToken) {
602             this.reportVisitJavadocToken = reportVisitJavadocToken;
603         }
604 
605         @Override
606         public int[] getDefaultJavadocTokens() {
607             return new int[] {
608                 JavadocTokenTypes.P_TAG_START,
609                 JavadocTokenTypes.LI_TAG_START,
610                 JavadocTokenTypes.BODY_TAG_START,
611             };
612         }
613 
614         @Override
615         public void visitJavadocToken(DetailNode ast) {
616             if (reportVisitJavadocToken) {
617                 log(ast.getLineNumber(), ast.getColumnNumber(), MSG_SUMMARY_FIRST_SENTENCE);
618             }
619         }
620     }
621 }