Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Test #86 Cannot read Optionals written with StdTypeResolverBuilder #335

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.fasterxml.jackson.datatype.jdk8;

import java.util.Objects;
import java.util.Optional;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.StdTypeResolverBuilder;

// [modules-java8#86] Cannot read `Optional`s written with `StdTypeResolverBuilder`
//
public class OptionalWithTypeResolver86Test
extends ModuleTestBase
{

public static class Foo<T> {
public Optional<T> value;

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Foo<?> foo = (Foo<?>) o;
return Objects.equals(value, foo.value);
}
}

public static class Pojo86 {
public String name;

// with static method
public static Pojo86 valueOf(String name) {
Pojo86 pojo = new Pojo86();
pojo.name = name;
return pojo;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Pojo86 pojo86 = (Pojo86) o;
return Objects.equals(name, pojo86.name);
}

}

// Base class for polymorphic types
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.WRAPPER_OBJECT)
public static abstract class Animal {
public String name;

protected Animal(String name) {
this.name = name;
}
}

// Subclass: Dog
public static class Dog extends Animal {
@JsonCreator
public Dog(@JsonProperty("name") String name) {
super(name);
}

@Override
public boolean equals(Object obj) {
return (obj instanceof Dog) && name.equals(((Dog) obj).name);
}
}

public void testRoundTrip()
throws Exception
{
_testOptionalWith(Optional.of("MyName"), String.class, "MyName");
_testOptionalWith(Optional.of(42), Integer.class, 42);
_testOptionalWith(Optional.of(Pojo86.valueOf("PojoName")),
Pojo86.class, Pojo86.valueOf("PojoName"));
}

public void testRoundTripPolymorphic()
throws Exception
{
_testOptionalPolymorphicWith(
Optional.of(new Dog("Buddy"))
);
}

private <T> void _testOptionalPolymorphicWith(Optional<T> value)
throws Exception
{
ObjectMapper mapper = configureObjectMapper();

// Serialize
Foo<T> foo = new Foo<>();
foo.value = value;
String json = mapper.writeValueAsString(foo);

// Deserialize
Foo<T> bean = mapper.readValue(json,
mapper.getTypeFactory().constructParametricType(Foo.class, Animal.class));
assertEquals(foo, bean); // Compare Foo objects directly
}

private <T> void _testOptionalWith(Optional<T> value, Class<T> type, T expectedValue)
throws Exception
{
ObjectMapper mapper = configureObjectMapper();

// Serialize
Foo<T> foo = new Foo<>();
foo.value = value;
String json = mapper.writeValueAsString(foo);

// Deserialize
Foo<T> bean = mapper.readValue(json,
mapper.getTypeFactory().constructParametricType(Foo.class, type));
assertEquals(value, bean.value);
assertEquals(expectedValue, bean.value.get());
}

private ObjectMapper configureObjectMapper(){
ObjectMapper mapper = mapperWithModule();
mapper.setDefaultTyping(
new StdTypeResolverBuilder()
.init(JsonTypeInfo.Id.CLASS, null)
.inclusion(JsonTypeInfo.As.WRAPPER_OBJECT)
);
return mapper;
}

}
Loading