SealedTypesWithTypedSerializationTest.java
package tools.jackson.databind.jsontype;
import java.util.*;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.*;
import tools.jackson.databind.*;
import tools.jackson.databind.testutil.DatabindTestUtil;
import static org.junit.jupiter.api.Assertions.*;
import static com.fasterxml.jackson.annotation.JsonTypeInfo.*;
public class SealedTypesWithTypedSerializationTest
extends DatabindTestUtil
{
/*
/**********************************************************
/* Helper types
/**********************************************************
*/
/**
* Polymorphic base class
*/
@JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY)
public static sealed abstract class Animal permits Dog, Cat {
public String name;
protected Animal(String n) { name = n; }
}
@JsonTypeName("doggie")
static final class Dog extends Animal
{
public int boneCount;
private Dog() { super(null); }
public Dog(String name, int b) {
super(name);
boneCount = b;
}
}
@JsonTypeName("kitty")
static final class Cat extends Animal
{
public String furColor;
private Cat() { super(null); }
public Cat(String name, String c) {
super(name);
furColor = c;
}
}
public class AnimalWrapper {
public Animal animal;
public AnimalWrapper(Animal a) { animal = a; }
}
@JsonTypeInfo(use=Id.MINIMAL_CLASS, include=As.WRAPPER_OBJECT)
interface TypeWithWrapper { }
@JsonTypeInfo(use=Id.CLASS, include=As.WRAPPER_ARRAY)
interface TypeWithArray { }
@JsonTypeInfo(use=Id.NAME)
@JsonTypeName("empty")
public class Empty { }
@JsonTypeInfo(include=As.PROPERTY, use=Id.CLASS)
public class Super {}
public class A extends Super {}
public class B extends Super {}
/*
/**********************************************************
/* Unit tests
/**********************************************************
*/
private final ObjectMapper MAPPER = newJsonMapper();
/**
* First things first, let's ensure we can serialize using
* class name, written as main-level property name
*/
@Test
public void testSimpleClassAsProperty() throws Exception
{
Map<String,Object> result = writeAndMap(MAPPER, new Cat("Beelzebub", "tabby"));
assertEquals(3, result.size());
assertEquals("Beelzebub", result.get("name"));
assertEquals("tabby", result.get("furColor"));
// should we try customized class name?
String classProp = Id.CLASS.getDefaultPropertyName();
assertEquals(Cat.class.getName(), result.get(classProp));
}
/**
* Test inclusion using wrapper style
*/
@Test
public void testTypeAsWrapper() throws Exception
{
ObjectMapper m = jsonMapperBuilder()
.addMixIn(Animal.class, TypeWithWrapper.class)
.build();
Map<String,Object> result = writeAndMap(m, new Cat("Venla", "black"));
// should get a wrapper; keyed by minimal class name ("Cat" here)
assertEquals(1, result.size());
// minimal class name is prefixed by dot, and for inner classes it's bit longer
Map<?,?> cat = (Map<?,?>) result.get(".SealedTypesWithTypedSerializationTest$Cat");
assertNotNull(cat);
assertEquals(2, cat.size());
assertEquals("Venla", cat.get("name"));
assertEquals("black", cat.get("furColor"));
}
/**
* Test inclusion using 2-element array
*/
@Test
public void testTypeAsArray() throws Exception
{
ObjectMapper m = jsonMapperBuilder()
.addMixIn(Animal.class, TypeWithArray.class)
.build();
// hmmh. Not good idea to rely on exact output, order may change. But...
Map<String,Object> result = writeAndMap(m, new AnimalWrapper(new Dog("Amadeus", 7)));
// First level, wrapper
assertEquals(1, result.size());
List<?> l = (List<?>) result.get("animal");
assertNotNull(l);
assertEquals(2, l.size());
assertEquals(Dog.class.getName(), l.get(0));
Map<?,?> doggie = (Map<?,?>) l.get(1);
assertNotNull(doggie);
assertEquals(2, doggie.size());
assertEquals("Amadeus", doggie.get("name"));
assertEquals(Integer.valueOf(7), doggie.get("boneCount"));
}
}