AnnotatedClassGetSuperTypesTest.java
package tools.jackson.databind.introspect;
import java.io.Serializable;
import java.util.*;
import org.junit.jupiter.api.Test;
import tools.jackson.databind.DeserializationConfig;
import tools.jackson.databind.JavaType;
import tools.jackson.databind.ObjectMapper;
import tools.jackson.databind.testutil.DatabindTestUtil;
import static org.junit.jupiter.api.Assertions.*;
/**
* Tests for {@link AnnotatedClass#getSuperTypes()} added in 3.2.
*/
@SuppressWarnings("serial")
public class AnnotatedClassGetSuperTypesTest extends DatabindTestUtil
{
static class SimpleBean {
public int value;
}
static class ChildBean extends SimpleBean implements Serializable {
public String name;
}
interface MarkerA { }
interface MarkerB extends MarkerA { }
static class MultiLevel extends ChildBean implements MarkerB {
}
private final ObjectMapper MAPPER = newJsonMapper();
// Simple class whose only super type is Object (which is pruned) should
// have an empty super types list
@Test
public void testGetSuperTypesForSimpleClass() {
AnnotatedClass ac = _resolve(SimpleBean.class);
List<JavaType> superTypes = ac.getSuperTypes();
assertNotNull(superTypes);
// SimpleBean extends Object directly; Object is excluded from super types
assertTrue(superTypes.isEmpty(),
"SimpleBean should have no super types (Object is excluded)");
}
// Interfaces listed before super-class chain; Object excluded
@Test
public void testGetSuperTypesForChildClass() {
AnnotatedClass ac = _resolve(ChildBean.class);
List<JavaType> superTypes = ac.getSuperTypes();
// Exact order: interfaces of ChildBean first, then super-class chain
_assertExactOrder(superTypes,
Serializable.class, SimpleBean.class);
}
// Multi-level: at each level, interfaces before super-class, recursing up
@Test
public void testGetSuperTypesForMultiLevel() {
AnnotatedClass ac = _resolve(MultiLevel.class);
List<JavaType> superTypes = ac.getSuperTypes();
// Order: MultiLevel's own interfaces (MarkerB, MarkerA),
// then ChildBean (super-class), ChildBean's interfaces (Serializable),
// then SimpleBean (ChildBean's super-class)
_assertExactOrder(superTypes,
MarkerB.class, MarkerA.class,
ChildBean.class, Serializable.class, SimpleBean.class);
}
@Test
public void testGetSuperTypesReturnsUnmodifiableList() {
AnnotatedClass ac = _resolve(ChildBean.class);
List<JavaType> superTypes = ac.getSuperTypes();
assertThrows(UnsupportedOperationException.class, () -> {
superTypes.add(null);
});
}
// Object class itself should have no super types
@Test
public void testGetSuperTypesForObjectClass() {
AnnotatedClass ac = _resolve(Object.class);
List<JavaType> superTypes = ac.getSuperTypes();
assertNotNull(superTypes);
assertTrue(superTypes.isEmpty(),
"Object class itself should have no super types");
}
// Interface type should list super-interfaces in order
@Test
public void testGetSuperTypesForInterface() {
AnnotatedClass ac = _resolve(MarkerB.class);
List<JavaType> superTypes = ac.getSuperTypes();
_assertExactOrder(superTypes, MarkerA.class);
}
private AnnotatedClass _resolve(Class<?> cls) {
DeserializationConfig config = MAPPER.deserializationConfig();
JavaType type = MAPPER.constructType(cls);
return AnnotatedClassResolver.resolve(config, type, config);
}
private static void _assertExactOrder(List<JavaType> actual, Class<?>... expected) {
List<Class<?>> actualClasses = new ArrayList<>();
for (JavaType t : actual) {
actualClasses.add(t.getRawClass());
}
List<Class<?>> expectedList = Arrays.asList(expected);
assertEquals(expectedList, actualClasses,
"Super types should match in exact order");
}
}