NoTypeInfo1654ReferenceTest.java
package tools.jackson.databind.jsontype;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.Test;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import tools.jackson.core.JacksonException;
import tools.jackson.core.JsonGenerator;
import tools.jackson.core.JsonParser;
import tools.jackson.databind.*;
import tools.jackson.databind.annotation.JsonDeserialize;
import tools.jackson.databind.annotation.JsonSerialize;
import tools.jackson.databind.testutil.DatabindTestUtil;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
/**
* Test for Reference types (Optional, AtomicReference) with
* {@code @JsonTypeInfo(use = Id.NONE)} override.
*/
class NoTypeInfo1654ReferenceTest extends DatabindTestUtil
{
// [databind#1654]
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME)
static class Value1654 {
public int x;
protected Value1654() { }
public Value1654(int x) {
this.x = x;
}
}
static class Value1654TypedOptionalContainer {
public Optional<Value1654> value;
protected Value1654TypedOptionalContainer() { }
public Value1654TypedOptionalContainer(Value1654 v) {
value = Optional.ofNullable(v);
}
}
static class Value1654UntypedOptionalContainer {
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
public Optional<Value1654> value;
protected Value1654UntypedOptionalContainer() { }
public Value1654UntypedOptionalContainer(Value1654 v) {
value = Optional.ofNullable(v);
}
}
static class Value1654UsingCustomSerDeserUntypedOptionalContainer {
@JsonDeserialize(contentUsing = Value1654Deserializer.class)
@JsonSerialize(contentUsing = Value1654Serializer.class)
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
public Optional<Value1654> value;
protected Value1654UsingCustomSerDeserUntypedOptionalContainer() { }
public Value1654UsingCustomSerDeserUntypedOptionalContainer(Value1654 v) {
value = Optional.ofNullable(v);
}
}
static class Value1654TypedAtomicRefContainer {
public AtomicReference<Value1654> value;
protected Value1654TypedAtomicRefContainer() { }
public Value1654TypedAtomicRefContainer(Value1654 v) {
value = new AtomicReference<>(v);
}
}
static class Value1654UsingCustomSerDeserUntypedAtomicRefContainer {
@JsonDeserialize(contentUsing = Value1654Deserializer.class)
@JsonSerialize(contentUsing = Value1654Serializer.class)
@JsonTypeInfo(use = JsonTypeInfo.Id.NONE)
public AtomicReference<Value1654> value;
protected Value1654UsingCustomSerDeserUntypedAtomicRefContainer() { }
public Value1654UsingCustomSerDeserUntypedAtomicRefContainer(Value1654 v) {
value = new AtomicReference<>(v);
}
}
static class Value1654Deserializer extends ValueDeserializer<Value1654> {
@Override
public Value1654 deserialize(JsonParser p, DeserializationContext ctxt) {
JsonNode n = ctxt.readTree(p);
if (!n.has("v")) {
ctxt.reportInputMismatch(Value1654.class, "Bad JSON input (no 'v'): " + n);
}
return new Value1654(n.path("v").intValue());
}
}
static class Value1654Serializer extends ValueSerializer<Value1654> {
@Override
public void serialize(Value1654 value, JsonGenerator gen, SerializationContext ctxt)
throws JacksonException {
gen.writeStartObject(value);
gen.writeNumberProperty("v", value.x);
gen.writeEndObject();
}
}
/*
/**********************************************************************
/* Test methods
/**********************************************************************
*/
private final ObjectMapper MAPPER = newJsonMapper();
// [databind#1654]: no override, default polymorphic type id for Optional
@Test
void withoutNoTypeElementOverrideSerAndDeserOptional() throws Exception {
Value1654TypedOptionalContainer cont = new Value1654TypedOptionalContainer(new Value1654(42));
String json = MAPPER.writeValueAsString(cont);
String typeId = Value1654.class.getName();
typeId = "'@type':'" + typeId.substring(typeId.lastIndexOf('.') + 1) + "'";
assertEquals(a2q("{'value':{"+typeId+",'x':42}}"), json);
Value1654TypedOptionalContainer result = MAPPER.readValue(json, Value1654TypedOptionalContainer.class);
assertTrue(result.value.isPresent());
assertEquals(42, result.value.get().x);
}
// [databind#1654]: override, no polymorphic type id for Optional, serialization
@Test
void withNoTypeInfoDefaultSerOptional() throws Exception {
Value1654UntypedOptionalContainer cont = new Value1654UntypedOptionalContainer(new Value1654(42));
assertEquals(a2q("{'value':{'x':42}}"), MAPPER.writeValueAsString(cont));
}
// [databind#1654]: override, no polymorphic type id for Optional, deserialization
@Test
void withNoTypeInfoDefaultDeserOptional() throws Exception {
String noTypeJson = a2q("{'value':{'x':42}}");
Value1654UntypedOptionalContainer result = MAPPER.readValue(noTypeJson,
Value1654UntypedOptionalContainer.class);
assertTrue(result.value.isPresent());
assertEquals(42, result.value.get().x);
}
// [databind#1654]: override, no polymorphic type id for Optional, custom serialization
@Test
void withNoTypeInfoOverrideSerOptional() throws Exception {
Value1654UsingCustomSerDeserUntypedOptionalContainer cont =
new Value1654UsingCustomSerDeserUntypedOptionalContainer(new Value1654(42));
assertEquals(a2q("{'value':{'v':42}}"), MAPPER.writeValueAsString(cont));
}
// [databind#1654]: override, no polymorphic type id for Optional, custom deserialization
@Test
void withNoTypeInfoOverrideDeserOptional() throws Exception {
String noTypeJson = a2q("{'value':{'v':42}}");
Value1654UsingCustomSerDeserUntypedOptionalContainer result = MAPPER.readValue(noTypeJson,
Value1654UsingCustomSerDeserUntypedOptionalContainer.class);
assertTrue(result.value.isPresent());
assertEquals(42, result.value.get().x);
}
// [databind#1654]: no override, default polymorphic type id for AtomicReference
@Test
void withoutNoTypeElementOverrideSerAndDeserAtomicRef() throws Exception {
Value1654TypedAtomicRefContainer cont = new Value1654TypedAtomicRefContainer(new Value1654(42));
String json = MAPPER.writeValueAsString(cont);
String typeId = Value1654.class.getName();
typeId = "'@type':'" + typeId.substring(typeId.lastIndexOf('.') + 1) + "'";
assertEquals(a2q("{'value':{"+typeId+",'x':42}}"), json);
Value1654TypedAtomicRefContainer result = MAPPER.readValue(json, Value1654TypedAtomicRefContainer.class);
assertEquals(42, result.value.get().x);
}
// [databind#1654]: override, no polymorphic type id for AtomicReference, custom serialization
@Test
void withNoTypeInfoOverrideSerAtomicRef() throws Exception {
Value1654UsingCustomSerDeserUntypedAtomicRefContainer cont =
new Value1654UsingCustomSerDeserUntypedAtomicRefContainer(new Value1654(42));
assertEquals(a2q("{'value':{'v':42}}"), MAPPER.writeValueAsString(cont));
}
// [databind#1654]: override, no polymorphic type id for AtomicReference, custom deserialization
@Test
void withNoTypeInfoOverrideDeserAtomicRef() throws Exception {
String noTypeJson = a2q("{'value':{'v':42}}");
Value1654UsingCustomSerDeserUntypedAtomicRefContainer result = MAPPER.readValue(noTypeJson,
Value1654UsingCustomSerDeserUntypedAtomicRefContainer.class);
assertEquals(42, result.value.get().x);
}
}