xref: /aosp_15_r20/external/doclava/doclet_adapter/src/test/java/com/google/doclava/javadoc/ClassDocImplTest.java (revision feeed43c7c55e85932c547a3cefc559df175227c)
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.google.doclava.javadoc;
18 
19 import static org.junit.Assert.assertArrayEquals;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 
26 import com.sun.javadoc.FieldDoc;
27 import com.sun.javadoc.MethodDoc;
28 import com.sun.javadoc.ProgramElementDoc;
29 import java.lang.reflect.Modifier;
30 import java.util.Arrays;
31 import org.junit.Before;
32 import org.junit.Ignore;
33 import org.junit.Test;
34 
35 public class ClassDocImplTest extends BaseTest {
36 
37     private ClassDocImpl abstractEmptyInterface;
38     private ClassDocImpl abstractEmptyClass;
39     private ClassDocImpl publicClass;
40     private ClassDocImpl publicEnum;
41     private ClassDocImpl publicAnnotation;
42     private ClassDocImpl publicInterface;
43     private ClassDocImpl simpleEnum;
44     private ClassDocImpl serializable;
45     private ClassDocImpl extendsSerializable;
46     private ClassDocImpl extendsExternalizable;
47     private ClassDocImpl implementsSerializable;
48     private ClassDocImpl implementsExternalizable;
49 
50     private ClassDocImpl javaLangError;
51     private ClassDocImpl javaLangException;
52     private ClassDocImpl javaLangObject;
53     private ClassDocImpl javaLangThrowable;
54     private ClassDocImpl javaUtilMap;
55 
56     private ClassDocImpl publicClassWithNests;
57     private ClassDocImpl publicClassWithNests$Nest1;
58     private ClassDocImpl publicClassWithNests$Nest1$Nest2;
59     private ClassDocImpl publicClassWithNests$Nest1$Nest2$Nest3;
60     private ClassDocImpl innerClasses;
61 
62     private ClassDocImpl constructors;
63 
64     private ClassDocImpl packagePrivateClass;
65 
66     private ClassDocImpl fieldsAccessModifiers;
67     private ClassDocImpl methodsAccessModifiers;
68 
69     @Before
setUp()70     public void setUp() {
71         super.setUp();
72         abstractEmptyClass = ClassDocImpl.create(CLASS.publicAbstractClass, context);
73         abstractEmptyInterface = ClassDocImpl.create(CLASS.publicAbstractInterface, context);
74 
75         publicClass = ClassDocImpl.create(CLASS.publicClass, context);
76         publicClassWithNests = ClassDocImpl.create(CLASS.publicClassWithNests, context);
77         publicEnum = ClassDocImpl.create(CLASS.publicEnum, context);
78         simpleEnum = ClassDocImpl.create(CLASS.simpleEnum, context);
79         // note that it is created using AnnotationTypeDocImpl ctor.
80         publicAnnotation = AnnotationTypeDocImpl.create(CLASS.publicAnnotation, context);
81         publicInterface = ClassDocImpl.create(CLASS.publicInterface, context);
82         packagePrivateClass = ClassDocImpl.create(CLASS.packagePrivateClass, context);
83 
84         javaLangError = ClassDocImpl.create(INSTANCE.javaLangError, context);
85         javaLangException = ClassDocImpl.create(INSTANCE.javaLangException, context);
86         javaLangObject = ClassDocImpl.create(INSTANCE.javaLangObject, context);
87         javaLangThrowable = ClassDocImpl.create(INSTANCE.javaLangThrowable, context);
88         javaUtilMap = ClassDocImpl.create(CLASS.javaUtilMap, context);
89 
90         publicClassWithNests = ClassDocImpl.create(CLASS.publicClassWithNests, context);
91         publicClassWithNests$Nest1 = ClassDocImpl.create(CLASS.publicClassWithNests$Nest1, context);
92         publicClassWithNests$Nest1$Nest2 = ClassDocImpl.create(
93                 CLASS.publicClassWithNests$Nest1$Nest2, context);
94         publicClassWithNests$Nest1$Nest2$Nest3 = ClassDocImpl.create(
95                 CLASS.publicClassWithNests$Nest1$Nest2$Nest3, context);
96         innerClasses = ClassDocImpl.create(CLASS.innerClasses, context);
97 
98         constructors = ClassDocImpl.create(CLASS.constructors, context);
99 
100         implementsSerializable = ClassDocImpl.create(CLASS.implementsSerializable, context);
101         implementsExternalizable = ClassDocImpl.create(CLASS.implementsExternalizable, context);
102         serializable = ClassDocImpl.create(INTERFACE.serializable, context);
103         extendsSerializable = ClassDocImpl.create(INTERFACE.extendsSerializable, context);
104         extendsExternalizable = ClassDocImpl.create(INTERFACE.extendsExternalizable, context);
105 
106         fieldsAccessModifiers = ClassDocImpl.create(CLASS.fieldsAccessModifiers, context);
107         methodsAccessModifiers = ClassDocImpl.create(CLASS.methodsAccessModifiers, context);
108     }
109 
110     @Test
isClass()111     public void isClass() {
112         assertFalse(publicAnnotation.isClass());
113         assertFalse(publicInterface.isClass());
114 
115         assertTrue(publicClass.isClass());
116         assertTrue(publicEnum.isClass());
117         assertTrue(javaLangObject.isClass());
118         assertTrue(javaLangError.isClass());
119         assertTrue(javaLangException.isClass());
120     }
121 
122     @Test
isOrdinaryClass()123     public void isOrdinaryClass() {
124         // not an enumeration, interface, annotation, exception, or an error.
125         assertFalse(publicAnnotation.isOrdinaryClass());
126         assertFalse(publicEnum.isOrdinaryClass());
127         assertFalse(publicInterface.isOrdinaryClass());
128         assertFalse(javaLangError.isOrdinaryClass());
129         assertFalse(javaLangException.isOrdinaryClass());
130 
131         assertTrue(publicClass.isOrdinaryClass());
132         assertTrue(javaLangObject.isOrdinaryClass());
133     }
134 
135     @Test
isEnum()136     public void isEnum() {
137         assertTrue(publicEnum.isEnum());
138 
139         assertFalse(publicAnnotation.isEnum());
140         assertFalse(publicClass.isEnum());
141         assertFalse(publicInterface.isEnum());
142         assertFalse(javaLangError.isEnum());
143         assertFalse(javaLangException.isEnum());
144         assertFalse(javaLangObject.isEnum());
145     }
146 
147     @Test
isInterface()148     public void isInterface() {
149         assertTrue(publicInterface.isInterface());
150 
151         assertFalse(publicAnnotation.isInterface());
152         assertFalse(publicClass.isInterface());
153         assertFalse(publicEnum.isInterface());
154         assertFalse(javaLangError.isInterface());
155         assertFalse(javaLangException.isInterface());
156         assertFalse(javaLangObject.isInterface());
157     }
158 
159     @Test
isException()160     public void isException() {
161         assertTrue(javaLangException.isException());
162 
163         assertFalse(publicAnnotation.isException());
164         assertFalse(publicClass.isException());
165         assertFalse(publicEnum.isException());
166         assertFalse(publicInterface.isException());
167         assertFalse(javaLangError.isException());
168         assertFalse(javaLangObject.isException());
169     }
170 
171     @Test
isError()172     public void isError() {
173         assertTrue(javaLangError.isError());
174 
175         assertFalse(publicAnnotation.isError());
176         assertFalse(publicClass.isError());
177         assertFalse(publicEnum.isError());
178         assertFalse(publicInterface.isError());
179         assertFalse(javaLangException.isError());
180         assertFalse(javaLangObject.isError());
181     }
182 
183     @Test
name()184     public void name() {
185         assertEquals("AbstractEmptyClass", abstractEmptyClass.name());
186         assertEquals("AbstractEmptyInterface", abstractEmptyInterface.name());
187         assertEquals("PublicInterface", publicInterface.name());
188         assertEquals("PublicAnnotation", publicAnnotation.name());
189         assertEquals("PublicClass", publicClass.name());
190         assertEquals("PublicEnum", publicEnum.name());
191 
192         assertEquals("Error", javaLangError.name());
193         assertEquals("Exception", javaLangException.name());
194         assertEquals("Object", javaLangObject.name());
195 
196         assertEquals("PublicClassWithNests", publicClassWithNests.name());
197         assertEquals("PublicClassWithNests.Nest1", publicClassWithNests$Nest1.name());
198         assertEquals("PublicClassWithNests.Nest1.Nest2", publicClassWithNests$Nest1$Nest2.name());
199     }
200 
201     @Test
qualifiedName()202     public void qualifiedName() {
203         assertEquals("com.example.classes.AbstractEmptyClass", abstractEmptyClass.qualifiedName());
204         assertEquals("com.example.classes.AbstractEmptyInterface",
205                 abstractEmptyInterface.qualifiedName());
206         assertEquals("com.example.classes.PublicInterface", publicInterface.qualifiedName());
207         assertEquals("com.example.classes.PublicAnnotation", publicAnnotation.qualifiedName());
208         assertEquals("com.example.classes.PublicClass", publicClass.qualifiedName());
209         assertEquals("com.example.classes.PublicEnum", publicEnum.qualifiedName());
210 
211         assertEquals("java.lang.Error", javaLangError.qualifiedName());
212         assertEquals("java.lang.Exception", javaLangException.qualifiedName());
213         assertEquals("java.lang.Object", javaLangObject.qualifiedName());
214 
215         assertEquals("com.example.classes.PublicClassWithNests",
216                 publicClassWithNests.qualifiedName());
217         assertEquals("com.example.classes.PublicClassWithNests.Nest1",
218                 publicClassWithNests$Nest1.qualifiedName());
219         assertEquals("com.example.classes.PublicClassWithNests.Nest1.Nest2",
220                 publicClassWithNests$Nest1$Nest2.qualifiedName());
221     }
222 
223     /**
224      * @see #constructors()
225      */
226     @Test
isIncluded()227     public void isIncluded() {
228         assertTrue(publicClass.isIncluded());
229 
230         assertFalse(packagePrivateClass.isIncluded());
231     }
232 
233     @Test
isAbstract()234     public void isAbstract() {
235         assertTrue(abstractEmptyClass.isAbstract());
236         assertTrue(abstractEmptyInterface.isAbstract());
237         assertTrue(publicInterface.isAbstract());
238         assertTrue(publicAnnotation.isAbstract());
239 
240         assertFalse(publicClass.isAbstract());
241         assertFalse(publicEnum.isAbstract());
242         assertFalse(javaLangError.isAbstract());
243         assertFalse(javaLangException.isAbstract());
244         assertFalse(javaLangObject.isAbstract());
245     }
246 
247     @Test
isSerializable()248     public void isSerializable() {
249         // Classes
250         assertTrue(implementsSerializable.isSerializable());
251         assertTrue(implementsExternalizable.isSerializable());
252 
253         assertFalse(javaLangObject.isSerializable());
254 
255         // Interfaces
256         assertTrue(extendsSerializable.isSerializable());
257         assertTrue(extendsExternalizable.isSerializable());
258     }
259 
260     @Test
isExternalizable()261     public void isExternalizable() {
262         // Classes
263         assertTrue(implementsExternalizable.isExternalizable());
264 
265         assertFalse(implementsSerializable.isExternalizable());
266         assertFalse(javaLangObject.isExternalizable());
267 
268         // Interfaces
269         assertTrue(extendsExternalizable.isExternalizable());
270 
271         assertFalse(extendsSerializable.isExternalizable());
272     }
273 
274     @Ignore("Not yet implemented")
275     @Test
serializationMethods()276     public void serializationMethods() {
277     }
278 
279     @Ignore("Not yet implemented")
280     @Test
serializableFields()281     public void serializableFields() {
282     }
283 
284     @Ignore("Not yet implemented")
285     @Test
definesSerializableFields()286     public void definesSerializableFields() {
287     }
288 
289     @Test
superclass()290     public void superclass() {
291         // a) interfaces (always null)
292         assertNull(publicInterface.superclass());
293 
294         // b) classes
295         // 1. Object (no superclass)
296         assertNull(javaLangObject.superclass());
297         // 2. Object <- PublicClass
298         assertEquals(javaLangObject, publicClass.superclass());
299         // 3. Object <- Throwable <- Error
300         assertEquals(javaLangThrowable, javaLangError.superclass());
301         assertNotEquals(javaLangObject, javaLangError.superclass());
302         assertEquals(javaLangObject, javaLangError.superclass().superclass());
303     }
304 
305     @Test
superclassType()306     public void superclassType() {
307         // a) interfaces (always null)
308         assertNull(publicInterface.superclassType());
309 
310         // b) classes
311         // 1. Object (no superclass)
312         assertNull(javaLangObject.superclassType());
313         // 2. Object <- PublicClass
314         assertEquals("java.lang.Object", publicClass.superclassType().qualifiedTypeName());
315         // 3. Object <- Throwable <- Error
316         assertEquals("java.lang.Throwable", javaLangError.superclassType().qualifiedTypeName());
317         assertNotEquals("java.lang.Object", javaLangError.superclassType().qualifiedTypeName());
318     }
319 
320     @Test
subclassOf()321     public void subclassOf() {
322         // 1. Class is subclass of itself
323         assertTrue(javaLangObject.subclassOf(javaLangObject));
324         assertTrue(javaLangError.subclassOf(javaLangError));
325         assertTrue(publicClass.subclassOf(publicClass));
326 
327         // 2. Class is subclass of java.lang.Object
328         assertTrue(javaLangError.subclassOf(javaLangObject));
329         assertTrue(publicClass.subclassOf(javaLangObject));
330 
331         // 3. Interface is subclass of java.lang.Object *only*
332         assertTrue(publicInterface.subclassOf(javaLangObject));
333         assertFalse(publicInterface.subclassOf(publicInterface));
334         assertFalse(extendsExternalizable.subclassOf(extendsSerializable));
335     }
336 
337     @Ignore("Not yet implemented")
338     @Test
interfaces()339     public void interfaces() {
340     }
341 
342     @Test
interfaceTypes()343     public void interfaceTypes() {
344         // a) interfaces
345         // 1. Serializable
346         var types = serializable.interfaceTypes();
347         assertArrayEmpty(types);
348 
349         // 2. Interface extends Serializable
350         types = extendsSerializable.interfaceTypes();
351         assertEquals(1, types.length);
352         assertEquals("java.io.Serializable", types[0].qualifiedTypeName());
353 
354         // b) classes
355         // 1. Object does not implement any interface
356         types = javaLangObject.interfaceTypes();
357         assertArrayEmpty(types);
358 
359         // 2. Class implements Serializable
360         types = implementsSerializable.interfaceTypes();
361         assertEquals(1, types.length);
362         assertEquals("java.io.Serializable", types[0].qualifiedTypeName());
363     }
364 
365     @Test
typeParameters()366     public void typeParameters() {
367         var params = javaLangObject.typeParameters();
368         assertArrayEmpty(params);
369 
370         params = javaUtilMap.typeParameters();
371         assertEquals(2, params.length);
372         assertEquals("K", params[0].simpleTypeName());
373         assertEquals("V", params[1].simpleTypeName());
374     }
375 
376     @Ignore("Not yet implemented")
377     @Test
typeParamTags()378     public void typeParamTags() {
379     }
380 
381     /**
382      * @implNote This (and also {@link #fields_filter()} and {@link #isIncluded()}) tests do not
383      * cover cases when Doclet is supplied with a non-default
384      * <b>selection control</b> flag (default is {@code -protected}), i.e. {@code -public}, {@code
385      * -package} or {@code -private}. It also does not currently cover selection control options
386      * from new Doclet API (e.g. {@code --show-members}.
387      * @see jdk.javadoc.doclet definition of <b>selection control</b> in "Terminology" section
388      * @see jdk.javadoc.doclet new options in "Options" section
389      */
390     @Test
fields()391     public void fields() {
392         // 1. Class with four fields (public, protected, private and package-private).
393         // Should include only public and protected.
394         var classFields = fieldsAccessModifiers.fields();
395         assertEquals(2, classFields.length);
396 
397         // 2. Public enum has no declared constructors, but has one implicit private.
398         var enumFields = publicEnum.fields();
399         assertArrayEmpty(enumFields);
400 
401         //TODO: Handle all selection control variants.
402     }
403 
404     /**
405      * @see #fields()
406      */
407     @Test
fields_filter()408     public void fields_filter() {
409         // 1. Class with four fields (public, protected, private and package-private).
410 
411         // filter(true): Should include only public and protected.
412         var classFields = fieldsAccessModifiers.fields(true);
413         assertEquals(2, classFields.length);
414 
415         // filter(false): Should include all four.
416         classFields = fieldsAccessModifiers.fields(false);
417         assertEquals(4, classFields.length);
418     }
419 
420     @Test
enumConstants()421     public void enumConstants() {
422         assertArrayEmpty(publicClass.enumConstants());
423         assertArrayEmpty(publicInterface.enumConstants());
424         assertArrayEmpty(publicAnnotation.enumConstants());
425 
426         FieldDoc[] constants = simpleEnum.enumConstants();
427         assertEquals(3, constants.length);
428         assertEquals("A", constants[0].name());
429         assertEquals("B", constants[1].name());
430         assertEquals("C", constants[2].name());
431     }
432 
assertArrayEmpty(T[] array)433     private static <T> void assertArrayEmpty(T[] array) {
434         assertEquals(0, array.length);
435     }
436 
437     /**
438      * @implNote This (and also {@link #fields_filter()} and {@link #isIncluded()}) tests do not
439      * cover cases when Doclet is supplied with a non-default <b>selection control</b> flag (default
440      * is {@code -protected}), i.e. {@code -public}, {@code -package} or {@code -private}. It also
441      * does not currently cover selection control options from new Doclet API (e.g.
442      * {@code --show-members}.
443      * @see jdk.javadoc.doclet definition of <b>selection control</b> in "Terminology" section
444      * @see jdk.javadoc.doclet new options in "Options" section
445      */
446     @Test
methods()447     public void methods() {
448         assertArrayEmpty(publicClass.methods());
449 
450         // Class with 4 methods (public, protected, private and package-private).
451         // Should include only public and protected.
452         MethodDoc[] methods = methodsAccessModifiers.methods();
453         assertEquals(2, methods.length);
454     }
455 
456     /**
457      * @see #methods()
458      */
459     @Test
methods_filter()460     public void methods_filter() {
461         // 1. Class with four methods (public, protected, private and package-private).
462 
463         // filter(true): Should include only public and protected.
464         MethodDoc[] methods = methodsAccessModifiers.methods(true);
465         assertEquals(2, methods.length);
466 
467         // filter(false): Should include all four.
468         methods = methodsAccessModifiers.methods(false);
469         assertEquals(4, methods.length);
470     }
471 
472     /**
473      * @implNote This (and also {@link #constructors_filter_false()},
474      * {@link #constructors_filter_true()} and {@link #isIncluded()}) tests do not cover cases when
475      * Doclet is supplied with a non-default <b>selection control</b> flag (default is
476      * {@code -protected}), i.e. {@code -public}, {@code -package} or {@code -private}. It also does
477      * not currently cover selection control options from new Doclet API (e.g.
478      * {@code --show-members}.
479      * @see jdk.javadoc.doclet definition of <b>selection control</b> in "Terminology" section
480      * @see jdk.javadoc.doclet new options in "Options" section
481      */
482     @Test
constructors()483     public void constructors() {
484         // 1. Class with four constructors (public, protected, private and package-private).
485         // Should include only public and protected.
486         var ctors = constructors.constructors();
487         assertEquals(2, ctors.length);
488 
489         // 2. Public enum has no declared constructors, but has one implicit private.
490         var enumConstructors = publicEnum.constructors();
491         assertArrayEmpty(enumConstructors);
492 
493         //TODO: Handle all selection control variants.
494     }
495 
496     /**
497      * @see #constructors()
498      */
499     @Test
constructors_filter_true()500     public void constructors_filter_true() {
501         // 1. Class with four constructors (public, protected, private and package-private).
502         // Should include only public and protected.
503         var ctors = constructors.constructors(true);
504         assertEquals(2, ctors.length);
505 
506         // 2. Public enum has no declared constructors, but has one implicit private.
507         var enumConstructors = publicEnum.constructors(true);
508         assertArrayEmpty(enumConstructors);
509     }
510 
511     /**
512      * @see #constructors()
513      */
514     @Test
constructors_filter_false()515     public void constructors_filter_false() {
516         // 1. Class with four constructors (public, protected, private and package-private).
517         // Should include all four.
518         var ctors = constructors.constructors(false);
519         assertEquals(4, ctors.length);
520 
521         // 2. Public enum has no declared constructors, but has one implicit private.
522         var enumConstructors = publicEnum.constructors(false);
523         assertEquals(1, enumConstructors.length);
524     }
525 
526     @Test
innerClasses()527     public void innerClasses() {
528         // Test is intentionally empty as it innerClasses() is effectively innerClasses(true) and
529         // is covered in #innerClasses_filter_true().
530     }
531 
532     /**
533      * @implNote This (and also {@link #innerClasses_filter_false()}, and {@link #isIncluded()})
534      * tests do not cover cases when Doclet is supplied with a non-default <b>selection control</b>
535      * flag (default is {@code -protected}), i.e. {@code -public}, {@code -package} or
536      * {@code -private}. It also does not currently cover selection control options from new Doclet
537      * API (e.g. {@code --show-members}.
538      * @see jdk.javadoc.doclet definition of <b>selection control</b> in "Terminology" section
539      * @see jdk.javadoc.doclet new options in "Options" section
540      */
541     @Test
innerClasses_filter_true()542     public void innerClasses_filter_true() {
543         // 1. No inner classes
544         assertArrayEmpty(publicAnnotation.innerClasses(true));
545         assertArrayEmpty(publicClass.innerClasses(true));
546         assertArrayEmpty(publicEnum.innerClasses(true));
547         assertArrayEmpty(publicInterface.innerClasses(true));
548 
549         // 2. innerClasses() should return only immediate inner classes.
550         /*
551         public class PublicClassWithNests {
552             public class Nest1 {
553                 public class Nest2 {
554                     public class Nest3 {
555                     }
556                 }
557             }
558         }
559          */
560         assertArrayEquals(new String[]{"PublicClassWithNests.Nest1"},
561                 getInnerClassesNames(publicClassWithNests, true));
562         assertArrayEquals(new String[]{"PublicClassWithNests.Nest1.Nest2"},
563                 getInnerClassesNames(publicClassWithNests$Nest1, true));
564         assertArrayEquals(new String[]{"PublicClassWithNests.Nest1.Nest2.Nest3"},
565                 getInnerClassesNames(publicClassWithNests$Nest1$Nest2, true));
566         assertArrayEmpty(getInnerClassesNames(publicClassWithNests$Nest1$Nest2$Nest3, true));
567 
568         // InnerClasses has 16 inner classes:
569         // {public,private,protected,package-private}
570         // x
571         // {annotation,class,enum,interface}
572 
573         // 3. innerClasses() should return only classes and interfaces (no annotations/enums).
574         assertTrue(Arrays.stream(innerClasses.innerClasses(true))
575                 .allMatch(cls -> cls.isClass() || cls.isInterface())
576         );
577 
578         // 4. innerClasses() should return only public/protected/package-private (no private).
579         assertTrue(Arrays.stream(innerClasses.innerClasses(true))
580                 .allMatch(cls -> cls.isPublic() || cls.isProtected() || cls.isPackagePrivate())
581         );
582     }
583 
584     @Test
innerClasses_filter_false()585     public void innerClasses_filter_false() {
586         // 1. No inner classes
587         assertArrayEmpty(publicAnnotation.innerClasses(false));
588         assertArrayEmpty(publicClass.innerClasses(false));
589         assertArrayEmpty(publicEnum.innerClasses(false));
590         assertArrayEmpty(publicInterface.innerClasses(false));
591 
592         // 2. innerClasses() should return only immediate inner classes.
593         /*
594         public class PublicClassWithNests {
595             public class Nest1 {
596                 public class Nest2 {
597                     public class Nest3 {
598                     }
599                 }
600             }
601         }
602          */
603         assertArrayEquals(new String[]{"PublicClassWithNests.Nest1"},
604                 getInnerClassesNames(publicClassWithNests, false));
605         assertArrayEquals(new String[]{"PublicClassWithNests.Nest1.Nest2"},
606                 getInnerClassesNames(publicClassWithNests$Nest1, false));
607         assertArrayEquals(new String[]{"PublicClassWithNests.Nest1.Nest2.Nest3"},
608                 getInnerClassesNames(publicClassWithNests$Nest1$Nest2, false));
609         assertArrayEmpty(getInnerClassesNames(publicClassWithNests$Nest1$Nest2$Nest3, false));
610 
611         // InnerClasses has 16 inner classes:
612         // {public,private,protected,package-private}
613         // x
614         // {annotation,class,enum,interface}
615 
616         // 3. innerClasses() should return only classes and interfaces (no annotations/enums).
617         assertTrue(Arrays.stream(innerClasses.innerClasses(false))
618                 .allMatch(cls -> cls.isClass() || cls.isInterface())
619         );
620 
621         // 4. innerClasses() should return all (public/protected/package-private/private).
622         assertTrue(Arrays.stream(innerClasses.innerClasses(false))
623                 .allMatch(cls -> cls.isPublic() || cls.isProtected() || cls.isPackagePrivate()
624                         || cls.isPrivate())
625         );
626     }
627 
getInnerClassesNames(ClassDocImpl cls, boolean filter)628     private static String[] getInnerClassesNames(ClassDocImpl cls, boolean filter) {
629         return Arrays.stream(cls.innerClasses(filter))
630                 .map(ProgramElementDoc::name)
631                 .toArray(String[]::new);
632     }
633 
634     @Ignore("Not yet implemented")
635     @Test
findClass()636     public void findClass() {
637     }
638 
639     @Ignore("Not yet implemented")
640     @Test
importedClasses()641     public void importedClasses() {
642     }
643 
644     @Ignore("Not yet implemented")
645     @Test
importedPackages()646     public void importedPackages() {
647     }
648 
649     @Test
typeName()650     public void typeName() {
651         assertEquals("AbstractEmptyClass", abstractEmptyClass.typeName());
652         assertEquals("AbstractEmptyInterface", abstractEmptyInterface.typeName());
653         assertEquals("PublicInterface", publicInterface.typeName());
654         assertEquals("PublicAnnotation", publicAnnotation.typeName());
655         assertEquals("PublicClass", publicClass.typeName());
656         assertEquals("PublicEnum", publicEnum.typeName());
657 
658         assertEquals("Error", javaLangError.typeName());
659         assertEquals("Exception", javaLangException.typeName());
660         assertEquals("Object", javaLangObject.typeName());
661 
662         assertEquals("PublicClassWithNests", publicClassWithNests.typeName());
663         assertEquals("PublicClassWithNests.Nest1", publicClassWithNests$Nest1.typeName());
664         assertEquals("PublicClassWithNests.Nest1.Nest2",
665                 publicClassWithNests$Nest1$Nest2.typeName());
666     }
667 
668     @Test
qualifiedTypeName()669     public void qualifiedTypeName() {
670         assertEquals("com.example.classes.AbstractEmptyClass",
671                 abstractEmptyClass.qualifiedTypeName());
672         assertEquals("com.example.classes.AbstractEmptyInterface",
673                 abstractEmptyInterface.qualifiedName());
674         assertEquals("com.example.classes.PublicInterface", publicInterface.qualifiedName());
675         assertEquals("com.example.classes.PublicAnnotation", publicAnnotation.qualifiedName());
676         assertEquals("com.example.classes.PublicClass", publicClass.qualifiedName());
677         assertEquals("com.example.classes.PublicEnum", publicEnum.qualifiedName());
678 
679         assertEquals("java.lang.Error", javaLangError.qualifiedName());
680         assertEquals("java.lang.Exception", javaLangException.qualifiedName());
681         assertEquals("java.lang.Object", javaLangObject.qualifiedName());
682 
683         assertEquals("com.example.classes.PublicClassWithNests",
684                 publicClassWithNests.qualifiedName());
685         assertEquals("com.example.classes.PublicClassWithNests.Nest1",
686                 publicClassWithNests$Nest1.qualifiedName());
687         assertEquals("com.example.classes.PublicClassWithNests.Nest1.Nest2",
688                 publicClassWithNests$Nest1$Nest2.qualifiedName());
689 
690         assertEquals("java.util.Map", javaUtilMap.qualifiedTypeName());
691     }
692 
693     @Test
simpleTypeName()694     public void simpleTypeName() {
695         assertEquals("AbstractEmptyClass", abstractEmptyClass.simpleTypeName());
696         assertEquals("AbstractEmptyInterface", abstractEmptyInterface.simpleTypeName());
697         assertEquals("PublicInterface", publicInterface.simpleTypeName());
698         assertEquals("PublicAnnotation", publicAnnotation.simpleTypeName());
699         assertEquals("PublicClass", publicClass.simpleTypeName());
700         assertEquals("PublicEnum", publicEnum.simpleTypeName());
701 
702         assertEquals("Error", javaLangError.simpleTypeName());
703         assertEquals("Exception", javaLangException.simpleTypeName());
704         assertEquals("Object", javaLangObject.simpleTypeName());
705 
706         assertEquals("PublicClassWithNests", publicClassWithNests.simpleTypeName());
707         assertEquals("Nest1", publicClassWithNests$Nest1.simpleTypeName());
708         assertEquals("Nest2", publicClassWithNests$Nest1$Nest2.simpleTypeName());
709     }
710 
711     @Test
dimension()712     public void dimension() {
713         assertEquals("", publicClass.dimension());
714     }
715 
716     @Test
isPrimitive()717     public void isPrimitive() {
718         assertFalse(publicClass.isPrimitive());
719         assertFalse(publicInterface.isPrimitive());
720         assertFalse(publicEnum.isPrimitive());
721     }
722 
723     @Test
asClassDoc()724     public void asClassDoc() {
725         assertEquals(publicClass, publicClass.asClassDoc());
726         assertEquals(publicInterface, publicInterface.asClassDoc());
727         assertEquals(publicEnum, publicEnum.asClassDoc());
728     }
729 
730     @Test
asParameterizedType()731     public void asParameterizedType() {
732         assertNull(publicClass.asParameterizedType());
733         assertNull(publicInterface.asParameterizedType());
734         assertNull(publicEnum.asParameterizedType());
735     }
736 
737     @Test
asTypeVariable()738     public void asTypeVariable() {
739         assertNull(publicClass.asTypeVariable());
740         assertNull(publicInterface.asTypeVariable());
741         assertNull(publicEnum.asTypeVariable());
742     }
743 
744     @Test
asWildcardType()745     public void asWildcardType() {
746         assertNull(publicClass.asWildcardType());
747         assertNull(publicInterface.asWildcardType());
748         assertNull(publicEnum.asWildcardType());
749     }
750 
751     @Test
asAnnotatedType()752     public void asAnnotatedType() {
753         assertNull(publicClass.asAnnotatedType());
754         assertNull(publicInterface.asAnnotatedType());
755         assertNull(publicEnum.asAnnotatedType());
756     }
757 
758     @Test
asAnnotationTypeDoc()759     public void asAnnotationTypeDoc() {
760         assertNull(publicClass.asAnnotationTypeDoc());
761         assertNull(publicInterface.asAnnotationTypeDoc());
762         assertNull(publicEnum.asAnnotationTypeDoc());
763     }
764 
765     @Ignore("Not yet implemented")
766     @Test
getElementType()767     public void getElementType() {
768     }
769 
770     @Test
modifiers()771     public void modifiers() {
772         assertEquals("public abstract", abstractEmptyClass.modifiers());
773         assertEquals("public", publicClass.modifiers());
774         assertEquals("public final", publicEnum.modifiers());
775 
776         // interfaces and annotations should not have 'abstract' modifier
777         assertEquals("public interface", publicInterface.modifiers());
778         assertEquals("public interface", publicAnnotation.modifiers());
779     }
780 
781     @Test
modifierSpecifier()782     public void modifierSpecifier() {
783         assertEquals(Modifier.PUBLIC | Modifier.ABSTRACT,
784                 abstractEmptyClass.modifierSpecifier());
785         assertEquals(Modifier.PUBLIC, publicClass.modifierSpecifier());
786         assertEquals(Modifier.PUBLIC | Modifier.FINAL, publicEnum.modifierSpecifier());
787 
788         // interfaces and annotations should not have 'abstract' modifier
789         assertEquals(Modifier.PUBLIC | Modifier.INTERFACE, publicInterface.modifierSpecifier());
790         assertEquals(Modifier.PUBLIC | Modifier.INTERFACE, publicAnnotation.modifierSpecifier());
791     }
792 }