package com.fasterxml.jackson.databind.struct; import com.fasterxml.jackson.annotation.*; import com.fasterxml.jackson.databind.*; /** * Unit tests for verifying that basic {@link JsonUnwrapped} annotation * handling works as expected; some more advanced tests are separated out * to more specific test classes (like prefix/suffix handling). */ public class TestUnwrapped extends BaseMapTest { static class Unwrapping { public String name; @JsonUnwrapped public Location location; public Unwrapping() { } public Unwrapping(String str, int x, int y) { name = str; location = new Location(x, y); } } final static class Location { public int x; public int y; public Location() { } public Location(int x, int y) { this.x = x; this.y = y; } } static class DeepUnwrapping { @JsonUnwrapped public Unwrapping unwrapped; public DeepUnwrapping() { } public DeepUnwrapping(String str, int x, int y) { unwrapped = new Unwrapping(str, x, y); } } static class UnwrappingWithCreator { public String name; @JsonUnwrapped public Location location; @JsonCreator public UnwrappingWithCreator(@JsonProperty("name") String n) { name = n; } } // Class with two unwrapped properties static class TwoUnwrappedProperties { @JsonUnwrapped public Location location; @JsonUnwrapped public Name name; public TwoUnwrappedProperties() { } } static class Name { public String first, last; } // [databind#615] static class Parent { @JsonUnwrapped public Child c1; public Parent() { } public Parent(String str) { c1 = new Child(str); } } static class Child { public String field; public Child() { } public Child(String f) { field = f; } } static class Inner { public String animal; } static class Outer { // @JsonProperty @JsonUnwrapped private Inner inner; } // [databind#1493]: case-insensitive handling static class Person { @JsonUnwrapped(prefix = "businessAddress.") public Address businessAddress; } static class Address { public String street; public String addon; public String zip; public String town; public String country; } /* /********************************************************** /* Tests, serialization /********************************************************** */ private final ObjectMapper MAPPER = new ObjectMapper(); public void testSimpleUnwrappingSerialize() throws Exception { assertEquals("{\"name\":\"Tatu\",\"x\":1,\"y\":2}", MAPPER.writeValueAsString(new Unwrapping("Tatu", 1, 2))); } public void testDeepUnwrappingSerialize() throws Exception { assertEquals("{\"name\":\"Tatu\",\"x\":1,\"y\":2}", MAPPER.writeValueAsString(new DeepUnwrapping("Tatu", 1, 2))); } /* /********************************************************** /* Tests, deserialization /********************************************************** */ public void testSimpleUnwrappedDeserialize() throws Exception { Unwrapping bean = MAPPER.readValue("{\"name\":\"Tatu\",\"y\":7,\"x\":-13}", Unwrapping.class); assertEquals("Tatu", bean.name); Location loc = bean.location; assertNotNull(loc); assertEquals(-13, loc.x); assertEquals(7, loc.y); } public void testDoubleUnwrapping() throws Exception { TwoUnwrappedProperties bean = MAPPER.readValue("{\"first\":\"Joe\",\"y\":7,\"last\":\"Smith\",\"x\":-13}", TwoUnwrappedProperties.class); Location loc = bean.location; assertNotNull(loc); assertEquals(-13, loc.x); assertEquals(7, loc.y); Name name = bean.name; assertNotNull(name); assertEquals("Joe", name.first); assertEquals("Smith", name.last); } public void testDeepUnwrapping() throws Exception { DeepUnwrapping bean = MAPPER.readValue("{\"x\":3,\"name\":\"Bob\",\"y\":27}", DeepUnwrapping.class); Unwrapping uw = bean.unwrapped; assertNotNull(uw); assertEquals("Bob", uw.name); Location loc = uw.location; assertNotNull(loc); assertEquals(3, loc.x); assertEquals(27, loc.y); } public void testUnwrappedDeserializeWithCreator() throws Exception { UnwrappingWithCreator bean = MAPPER.readValue("{\"x\":1,\"y\":2,\"name\":\"Tatu\"}", UnwrappingWithCreator.class); assertEquals("Tatu", bean.name); Location loc = bean.location; assertNotNull(loc); assertEquals(1, loc.x); assertEquals(2, loc.y); } public void testIssue615() throws Exception { Parent input = new Parent("name"); String json = MAPPER.writeValueAsString(input); Parent output = MAPPER.readValue(json, Parent.class); assertEquals("name", output.c1.field); } public void testUnwrappedAsPropertyIndicator() throws Exception { Inner inner = new Inner(); inner.animal = "Zebra"; Outer outer = new Outer(); outer.inner = inner; String actual = MAPPER.writeValueAsString(outer); assertTrue(actual.contains("animal")); assertTrue(actual.contains("Zebra")); assertFalse(actual.contains("inner")); } // [databind#1493]: case-insensitive handling public void testCaseInsensitiveUnwrap() throws Exception { ObjectMapper mapper = new ObjectMapper(); mapper.enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_PROPERTIES); Person p = mapper.readValue("{ }", Person.class); assertNotNull(p); } }