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 org.junit.Assert.assertArrayEquals;
23  import static org.junit.Assert.assertEquals;
24  import static org.junit.Assert.assertFalse;
25  import static org.junit.Assert.assertTrue;
26  import static org.junit.Assert.fail;
27  
28  import java.lang.reflect.Method;
29  
30  import org.junit.Test;
31  
32  import com.puppycrawl.tools.checkstyle.api.DetailAST;
33  import com.puppycrawl.tools.checkstyle.api.TokenTypes;
34  
35  public class JavadocTagInfoTest {
36  
37      /* Additional test for jacoco, since valueOf()
38       * is generated by javac and jacoco reports that
39       * valueOf() is uncovered.
40       */
41      @Test
42      public void testJavadocTagInfoValueOf() {
43          final JavadocTagInfo tag = JavadocTagInfo.valueOf("AUTHOR");
44          assertEquals("Invalid valueOf result", JavadocTagInfo.AUTHOR, tag);
45      }
46  
47      /* Additional test for jacoco, since valueOf()
48       * is generated by javac and jacoco reports that
49       * valueOf() is uncovered.
50       */
51      @Test
52      public void testTypeValueOf() {
53          final JavadocTagInfo.Type type = JavadocTagInfo.Type.valueOf("BLOCK");
54          assertEquals("Invalid valueOf result", JavadocTagInfo.Type.BLOCK, type);
55      }
56  
57      /* Additional test for jacoco, since values()
58       * is generated by javac and jacoco reports that
59       * values() is uncovered.
60       */
61      @Test
62      public void testTypeValues() {
63          final JavadocTagInfo.Type[] expected = {
64              JavadocTagInfo.Type.BLOCK,
65              JavadocTagInfo.Type.INLINE,
66          };
67          final JavadocTagInfo.Type[] actual = JavadocTagInfo.Type.values();
68          assertArrayEquals("Invalid Type values", expected, actual);
69      }
70  
71      @Test
72      public void testAuthor() {
73          final DetailAST ast = new DetailAST();
74  
75          final int[] validTypes = {
76              TokenTypes.PACKAGE_DEF,
77              TokenTypes.CLASS_DEF,
78              TokenTypes.INTERFACE_DEF,
79              TokenTypes.ENUM_DEF,
80              TokenTypes.ANNOTATION_DEF,
81          };
82          for (int type: validTypes) {
83              ast.setType(type);
84              assertTrue("Invalid ast type for current tag: " + ast.getType(),
85                      JavadocTagInfo.AUTHOR.isValidOn(ast));
86          }
87  
88          ast.setType(TokenTypes.LAMBDA);
89          assertFalse("Should return false when ast type is invalid for current tag",
90                  JavadocTagInfo.AUTHOR.isValidOn(ast));
91      }
92  
93      @Test
94      public void testOthers() throws ReflectiveOperationException {
95          final JavadocTagInfo[] tags = {
96              JavadocTagInfo.CODE,
97              JavadocTagInfo.DOC_ROOT,
98              JavadocTagInfo.LINK,
99              JavadocTagInfo.LINKPLAIN,
100             JavadocTagInfo.LITERAL,
101             JavadocTagInfo.SEE,
102             JavadocTagInfo.SINCE,
103             JavadocTagInfo.VALUE,
104         };
105         for (JavadocTagInfo tagInfo : tags) {
106             final DetailAST astParent = new DetailAST();
107             astParent.setType(TokenTypes.LITERAL_CATCH);
108 
109             final DetailAST ast = new DetailAST();
110             final Method setParent = ast.getClass().getDeclaredMethod("setParent", DetailAST.class);
111             setParent.setAccessible(true);
112             setParent.invoke(ast, astParent);
113 
114             final int[] validTypes = {
115                 TokenTypes.PACKAGE_DEF,
116                 TokenTypes.CLASS_DEF,
117                 TokenTypes.INTERFACE_DEF,
118                 TokenTypes.ENUM_DEF,
119                 TokenTypes.ANNOTATION_DEF,
120                 TokenTypes.METHOD_DEF,
121                 TokenTypes.CTOR_DEF,
122                 TokenTypes.VARIABLE_DEF,
123             };
124             for (int type: validTypes) {
125                 ast.setType(type);
126                 assertTrue("Invalid ast type for current tag: " + ast.getType(),
127                         tagInfo.isValidOn(ast));
128             }
129 
130             astParent.setType(TokenTypes.SLIST);
131             ast.setType(TokenTypes.VARIABLE_DEF);
132             assertFalse("Should return false when ast type is invalid for current tag",
133                     tagInfo.isValidOn(ast));
134 
135             ast.setType(TokenTypes.PARAMETER_DEF);
136             assertFalse("Should return false when ast type is invalid for current tag",
137                     tagInfo.isValidOn(ast));
138         }
139     }
140 
141     @Test
142     public void testDeprecated() throws ReflectiveOperationException {
143         final DetailAST ast = new DetailAST();
144         final DetailAST astParent = new DetailAST();
145         astParent.setType(TokenTypes.LITERAL_CATCH);
146         final Method setParent = ast.getClass().getDeclaredMethod("setParent", DetailAST.class);
147         setParent.setAccessible(true);
148         setParent.invoke(ast, astParent);
149 
150         final int[] validTypes = {
151             TokenTypes.CLASS_DEF,
152             TokenTypes.INTERFACE_DEF,
153             TokenTypes.ENUM_DEF,
154             TokenTypes.ANNOTATION_DEF,
155             TokenTypes.METHOD_DEF,
156             TokenTypes.CTOR_DEF,
157             TokenTypes.ENUM_CONSTANT_DEF,
158             TokenTypes.ANNOTATION_FIELD_DEF,
159             TokenTypes.VARIABLE_DEF,
160         };
161         for (int type: validTypes) {
162             ast.setType(type);
163             assertTrue("Invalid ast type for current tag: " + ast.getType(),
164                     JavadocTagInfo.DEPRECATED.isValidOn(ast));
165         }
166 
167         astParent.setType(TokenTypes.SLIST);
168         ast.setType(TokenTypes.VARIABLE_DEF);
169         assertFalse("Should return false when ast type is invalid for current tag",
170                 JavadocTagInfo.DEPRECATED.isValidOn(ast));
171 
172         ast.setType(TokenTypes.PARAMETER_DEF);
173         assertFalse("Should return false when ast type is invalid for current tag",
174                 JavadocTagInfo.DEPRECATED.isValidOn(ast));
175     }
176 
177     @Test
178     public void testSerial() throws ReflectiveOperationException {
179         final DetailAST ast = new DetailAST();
180         final DetailAST astParent = new DetailAST();
181         astParent.setType(TokenTypes.LITERAL_CATCH);
182         final Method setParent = ast.getClass().getDeclaredMethod("setParent", DetailAST.class);
183         setParent.setAccessible(true);
184         setParent.invoke(ast, astParent);
185 
186         final int[] validTypes = {
187             TokenTypes.VARIABLE_DEF,
188         };
189         for (int type: validTypes) {
190             ast.setType(type);
191             assertTrue("Invalid ast type for current tag: " + ast.getType(),
192                     JavadocTagInfo.SERIAL.isValidOn(ast));
193         }
194 
195         astParent.setType(TokenTypes.SLIST);
196         ast.setType(TokenTypes.VARIABLE_DEF);
197         assertFalse("Should return false when ast type is invalid for current tag",
198                 JavadocTagInfo.SERIAL.isValidOn(ast));
199 
200         ast.setType(TokenTypes.PARAMETER_DEF);
201         assertFalse("Should return false when ast type is invalid for current tag",
202                 JavadocTagInfo.SERIAL.isValidOn(ast));
203     }
204 
205     @Test
206     public void testException() {
207         final DetailAST ast = new DetailAST();
208 
209         final int[] validTypes = {
210             TokenTypes.METHOD_DEF,
211             TokenTypes.CTOR_DEF,
212         };
213         for (int type: validTypes) {
214             ast.setType(type);
215             assertTrue("Invalid ast type for current tag: " + ast.getType(),
216                     JavadocTagInfo.EXCEPTION.isValidOn(ast));
217         }
218 
219         ast.setType(TokenTypes.LAMBDA);
220         assertFalse("Should return false when ast type is invalid for current tag",
221                 JavadocTagInfo.EXCEPTION.isValidOn(ast));
222     }
223 
224     @Test
225     public void testThrows() {
226         final DetailAST ast = new DetailAST();
227 
228         final int[] validTypes = {
229             TokenTypes.METHOD_DEF,
230             TokenTypes.CTOR_DEF,
231         };
232         for (int type: validTypes) {
233             ast.setType(type);
234             assertTrue("Invalid ast type for current tag: " + ast.getType(),
235                     JavadocTagInfo.THROWS.isValidOn(ast));
236         }
237 
238         ast.setType(TokenTypes.LAMBDA);
239         assertFalse("Should return false when ast type is invalid for current tag",
240                 JavadocTagInfo.THROWS.isValidOn(ast));
241     }
242 
243     @Test
244     public void testVersions() {
245         final DetailAST ast = new DetailAST();
246 
247         final int[] validTypes = {
248             TokenTypes.PACKAGE_DEF,
249             TokenTypes.CLASS_DEF,
250             TokenTypes.INTERFACE_DEF,
251             TokenTypes.ENUM_DEF,
252             TokenTypes.ANNOTATION_DEF,
253         };
254         for (int type: validTypes) {
255             ast.setType(type);
256             assertTrue("Invalid ast type for current tag: " + ast.getType(),
257                     JavadocTagInfo.VERSION.isValidOn(ast));
258         }
259 
260         ast.setType(TokenTypes.LAMBDA);
261         assertFalse("Should return false when ast type is invalid for current tag",
262                 JavadocTagInfo.VERSION.isValidOn(ast));
263     }
264 
265     @Test
266     public void testParam() {
267         final DetailAST ast = new DetailAST();
268 
269         final int[] validTypes = {
270             TokenTypes.CLASS_DEF,
271             TokenTypes.INTERFACE_DEF,
272             TokenTypes.METHOD_DEF,
273             TokenTypes.CTOR_DEF,
274         };
275         for (int type: validTypes) {
276             ast.setType(type);
277             assertTrue("Invalid ast type for current tag: " + ast.getType(),
278                     JavadocTagInfo.PARAM.isValidOn(ast));
279         }
280 
281         ast.setType(TokenTypes.LAMBDA);
282         assertFalse("Should return false when ast type is invalid for current tag",
283                 JavadocTagInfo.PARAM.isValidOn(ast));
284     }
285 
286     @Test
287     public void testReturn() {
288         final DetailAST ast = new DetailAST();
289         final DetailAST astChild = new DetailAST();
290         astChild.setType(TokenTypes.TYPE);
291         ast.setFirstChild(astChild);
292         final DetailAST astChild2 = new DetailAST();
293         astChild2.setType(TokenTypes.LITERAL_INT);
294         astChild.setFirstChild(astChild2);
295 
296         final int[] validTypes = {
297             TokenTypes.METHOD_DEF,
298         };
299         for (int type: validTypes) {
300             ast.setType(type);
301             assertTrue("Invalid ast type for current tag: " + ast.getType(),
302                     JavadocTagInfo.RETURN.isValidOn(ast));
303         }
304 
305         astChild2.setType(TokenTypes.LITERAL_VOID);
306         assertFalse("Should return false when ast type is invalid for current tag",
307                 JavadocTagInfo.RETURN.isValidOn(ast));
308 
309         ast.setType(TokenTypes.LAMBDA);
310         assertFalse("Should return false when ast type is invalid for current tag",
311                 JavadocTagInfo.RETURN.isValidOn(ast));
312     }
313 
314     @Test
315     public void testSerialField() {
316         final DetailAST ast = new DetailAST();
317         final DetailAST astChild = new DetailAST();
318         astChild.setType(TokenTypes.TYPE);
319         ast.setFirstChild(astChild);
320         final DetailAST astChild2 = new DetailAST();
321         astChild2.setType(TokenTypes.ARRAY_DECLARATOR);
322         astChild2.setText("ObjectStreamField");
323         astChild.setFirstChild(astChild2);
324 
325         final int[] validTypes = {
326             TokenTypes.VARIABLE_DEF,
327         };
328         for (int type: validTypes) {
329             ast.setType(type);
330             assertTrue("Invalid ast type for current tag: " + ast.getType(),
331                     JavadocTagInfo.SERIAL_FIELD.isValidOn(ast));
332         }
333 
334         astChild2.setText("1111");
335         assertFalse("Should return false when ast type is invalid for current tag",
336                 JavadocTagInfo.SERIAL_FIELD.isValidOn(ast));
337 
338         astChild2.setType(TokenTypes.LITERAL_VOID);
339         assertFalse("Should return false when ast type is invalid for current tag",
340                 JavadocTagInfo.SERIAL_FIELD.isValidOn(ast));
341 
342         ast.setType(TokenTypes.LAMBDA);
343         assertFalse("Should return false when ast type is invalid for current tag",
344                 JavadocTagInfo.SERIAL_FIELD.isValidOn(ast));
345     }
346 
347     @Test
348     public void testSerialData() {
349         final DetailAST ast = new DetailAST();
350         ast.setType(TokenTypes.METHOD_DEF);
351         final DetailAST astChild = new DetailAST();
352         astChild.setType(TokenTypes.IDENT);
353         astChild.setText("writeObject");
354         ast.setFirstChild(astChild);
355 
356         final String[] validNames = {
357             "writeObject",
358             "readObject",
359             "writeExternal",
360             "readExternal",
361             "writeReplace",
362             "readResolve",
363         };
364         for (String name: validNames) {
365             astChild.setText(name);
366             assertTrue("Invalid ast type for current tag: " + ast.getType(),
367                     JavadocTagInfo.SERIAL_DATA.isValidOn(ast));
368         }
369 
370         astChild.setText("1111");
371         assertFalse("Should return false when ast type is invalid for current tag",
372                 JavadocTagInfo.SERIAL_DATA.isValidOn(ast));
373 
374         ast.setType(TokenTypes.LAMBDA);
375         assertFalse("Should return false when ast type is invalid for current tag",
376                 JavadocTagInfo.SERIAL_DATA.isValidOn(ast));
377     }
378 
379     @Test
380     public void testCoverage() {
381         assertEquals("Invalid type", JavadocTagInfo.Type.BLOCK, JavadocTagInfo.VERSION.getType());
382 
383         assertEquals("Invalid toString result", "text [@version] name [version] type [BLOCK]",
384             JavadocTagInfo.VERSION.toString());
385 
386         try {
387             JavadocTagInfo.fromName(null);
388             fail("IllegalArgumentException is expected");
389         }
390         catch (IllegalArgumentException ex) {
391             assertEquals("Invalid exception message",
392                     "the name is null", ex.getMessage());
393         }
394 
395         try {
396             JavadocTagInfo.fromName("myname");
397             fail("IllegalArgumentException is expected");
398         }
399         catch (IllegalArgumentException ex) {
400             assertEquals("Invalid exception message",
401                     "the name [myname] is not a valid Javadoc tag name", ex.getMessage());
402         }
403 
404         try {
405             JavadocTagInfo.fromText(null);
406             fail("IllegalArgumentException is expected");
407         }
408         catch (IllegalArgumentException ex) {
409             assertEquals("Invalid exception message", "the text is null", ex.getMessage());
410         }
411 
412         try {
413             JavadocTagInfo.fromText("myname");
414             fail("IllegalArgumentException is expected");
415         }
416         catch (IllegalArgumentException ex) {
417             assertEquals("Invalid exception message",
418                     "the text [myname] is not a valid Javadoc tag text", ex.getMessage());
419         }
420 
421         assertEquals("Invalid fromText result",
422                 JavadocTagInfo.VERSION, JavadocTagInfo.fromText("@version"));
423     }
424 }