diff options
author | Baptiste Pernet <pernetmu@gmail.com> | 2020-07-23 19:27:54 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-07-23 19:27:54 -0700 |
commit | d9c0332e5ad76d7e4f35d9906f0b8e94a5237627 (patch) | |
tree | 7079a25712fd088846e3c81b30ea87f21032f93a /src/test/java/com/fasterxml/jackson | |
parent | 5758c6bce6773108beeadd8090641f21778ba5e0 (diff) | |
download | jackson-databind-d9c0332e5ad76d7e4f35d9906f0b8e94a5237627.tar.gz |
FasterXML/jackson-databind#1296 @JsonIncludeProperties (#2771)
Implement #1296 (add and support `@JsonIncludeProperties`)
Diffstat (limited to 'src/test/java/com/fasterxml/jackson')
-rw-r--r-- | src/test/java/com/fasterxml/jackson/databind/deser/IncludeWithDeserTest.java | 202 | ||||
-rw-r--r-- | src/test/java/com/fasterxml/jackson/databind/ser/filter/IncludePropsForSerTest.java | 185 |
2 files changed, 387 insertions, 0 deletions
diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/IncludeWithDeserTest.java b/src/test/java/com/fasterxml/jackson/databind/deser/IncludeWithDeserTest.java new file mode 100644 index 000000000..0d10e8b07 --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/deser/IncludeWithDeserTest.java @@ -0,0 +1,202 @@ +package com.fasterxml.jackson.databind.deser; + +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.JsonIncludeProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * This unit test suite that tests use of {@link com.fasterxml.jackson.annotation.JsonIncludeProperties} + * annotation with deserialization. + */ +public class IncludeWithDeserTest + extends BaseMapTest +{ + @JsonIncludeProperties({"y", "z"}) + static class OnlyYAndZ + { + int _x = 0; + int _y = 0; + int _z = 0; + + public void setX(int value) + { + _x = value; + } + + public void setY(int value) + { + _y = value; + } + + public void setZ(int value) + { + _z = value; + } + + @JsonProperty("y") + void replacementForY(int value) + { + _y = value * 2; + } + } + + @JsonIncludeProperties({"y", "z"}) + static class OnlyY + { + public int x; + + public int y = 1; + } + + static class OnlyYWrapperForOnlyYAndZ + { + @JsonIncludeProperties("y") + public OnlyYAndZ onlyY; + } + + // for [databind#1060] + static class IncludeForListValuesY + { + @JsonIncludeProperties({"y"}) + //@JsonIgnoreProperties({"z"}) + public List<OnlyYAndZ> onlyYs; + + public IncludeForListValuesY() + { + onlyYs = Arrays.asList(new OnlyYAndZ()); + } + } + + @JsonIncludeProperties({"@class", "a"}) + static class MyMap extends HashMap<String, String> + { + } + + static class MapWrapper + { + @JsonIncludeProperties({"a"}) + public final HashMap<String, Integer> value = new HashMap<String, Integer>(); + } + + @JsonIncludeProperties({"foo", "bar"}) + @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class) + static class AnySetterObjectId + { + protected Map<String, AnySetterObjectId> values = new HashMap<String, AnySetterObjectId>(); + + @JsonAnySetter + public void anySet(String field, AnySetterObjectId value) + { + // Ensure that it is never called with null because of unresolved reference. + assertNotNull(value); + values.put(field, value); + } + } + + /* + /********************************************************** + /* Test methods + /********************************************************** + */ + + private final ObjectMapper MAPPER = objectMapper(); + + public void testSimpleInclude() throws Exception + { + OnlyYAndZ result = MAPPER.readValue( + aposToQuotes("{ 'x':1, '_x': 1, 'y':2, 'z':3 }"), + OnlyYAndZ.class); + assertEquals(0, result._x); + assertEquals(4, result._y); + assertEquals(3, result._z); + } + + public void testIncludeIgnoredAndUnrecognizedField() throws Exception + { + ObjectReader r = MAPPER.readerFor(OnlyY.class); + + // First, fine to get "y" only: + OnlyY result = r.readValue(aposToQuotes("{'x':3, 'y': 4}")); + assertEquals(0, result.x); + assertEquals(4, result.y); + + // but fail on ignored properties. + r = r.with(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES); + try { + r.readValue(aposToQuotes("{'x':3, 'y': 4, 'z': 5}")); + fail("Should fail"); + } catch (JsonMappingException e) { + verifyException(e, "Ignored field"); + } + + // or fail on unrecognized properties + try { + r.readValue(aposToQuotes("{'y': 3, 'z':2 }")); + fail("Should fail"); + } catch (JsonMappingException e) { + verifyException(e, "Unrecognized field"); + } + + // or success with the both settings disabled. + r = r.without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); + r = r.without(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES); + r.readValue(aposToQuotes("{'y': 3, 'z':2 }")); + assertEquals(4, result.y); + } + + + public void testMergeInclude() throws Exception + { + OnlyYWrapperForOnlyYAndZ onlyY = MAPPER.readValue( + aposToQuotes("{'onlyY': {'x': 2, 'y':3, 'z': 4}}"), + OnlyYWrapperForOnlyYAndZ.class + ); + assertEquals(0, onlyY.onlyY._x); + assertEquals(6, onlyY.onlyY._y); + assertEquals(0, onlyY.onlyY._z); + } + + public void testListInclude() throws Exception + { + IncludeForListValuesY result = MAPPER.readValue( + aposToQuotes("{'onlyYs':[{ 'x':1, 'y' : 2, 'z': 3 }]}"), + IncludeForListValuesY.class); + assertEquals(0, result.onlyYs.get(0)._x); + assertEquals(4, result.onlyYs.get(0)._y); + assertEquals(0, result.onlyYs.get(0)._z); + } + + public void testMapWrapper() throws Exception + { + MapWrapper result = MAPPER.readValue(aposToQuotes("{'value': {'a': 2, 'b': 3}}"), MapWrapper.class); + assertEquals(2, result.value.get("a").intValue()); + assertFalse(result.value.containsKey("b")); + } + + public void testMyMap() throws Exception + { + MyMap result = MAPPER.readValue(aposToQuotes("{'a': 2, 'b': 3}"), MyMap.class); + assertEquals("2", result.get("a")); + assertFalse(result.containsKey("b")); + } + + public void testForwardReferenceAnySetterComboWithInclude() throws Exception + { + String json = aposToQuotes("{'@id':1, 'foo':2, 'foo2':2, 'bar':{'@id':2, 'foo':1}}"); + AnySetterObjectId value = MAPPER.readValue(json, AnySetterObjectId.class); + assertSame(value.values.get("bar"), value.values.get("foo")); + assertNull(value.values.get("foo2")); + } +} diff --git a/src/test/java/com/fasterxml/jackson/databind/ser/filter/IncludePropsForSerTest.java b/src/test/java/com/fasterxml/jackson/databind/ser/filter/IncludePropsForSerTest.java new file mode 100644 index 000000000..952f1eb3c --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/ser/filter/IncludePropsForSerTest.java @@ -0,0 +1,185 @@ +package com.fasterxml.jackson.databind.ser.filter; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonIncludeProperties; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class IncludePropsForSerTest extends BaseMapTest +{ + @JsonIncludeProperties({"a", "d"}) + static class IncludeSome + { + public int a = 3; + public String b = "x"; + + public int getC() + { + return -6; + } + + public String getD() + { + return "abc"; + } + } + + @SuppressWarnings("serial") + @JsonIncludeProperties({"@class", "a"}) + static class MyMap extends HashMap<String, String> { } + + //allow use of @JsonIncludeProperties for properties + static class WrapperWithPropInclude + { + @JsonIncludeProperties({"y"}) + public XY value = new XY(); + } + + static class XY + { + public int x = 1; + public int y = 2; + } + + static class WrapperWithPropInclude2 + { + @JsonIncludeProperties("x") + public XYZ value = new XYZ(); + } + + static class WrapperWithPropIgnore + { + @JsonIgnoreProperties("y") + public XYZ value = new XYZ(); + } + + @JsonIncludeProperties({"x", "y"}) + static class XYZ + { + public int x = 1; + public int y = 2; + public int z = 3; + } + + // also ought to work without full typing? + static class WrapperWithPropIncludeUntyped + { + @JsonIncludeProperties({"x"}) + public Object value = new XYZ(); + } + + static class MapWrapper + { + @JsonIncludeProperties({"a"}) + public final HashMap<String, Integer> value = new HashMap<String, Integer>(); + + { + value.put("a", 1); + value.put("b", 2); + } + } + + // for [databind#1060] + static class IncludeForListValuesXY + { + @JsonIncludeProperties({"x"}) + public List<XY> coordinates; + + public IncludeForListValuesXY() + { + coordinates = Arrays.asList(new XY()); + } + } + + static class IncludeForListValuesXYZ + { + @JsonIncludeProperties({"x"}) + public List<XYZ> coordinates; + + public IncludeForListValuesXYZ() + { + coordinates = Arrays.asList(new XYZ()); + } + } + + /* + /**************************************************************** + /* Unit tests + /**************************************************************** + */ + + private final ObjectMapper MAPPER = objectMapper(); + + public void testExplicitIncludeWithBean() throws Exception + { + IncludeSome value = new IncludeSome(); + Map<String, Object> result = writeAndMap(MAPPER, value); + assertEquals(2, result.size()); + // verify that specified fields are ignored + assertFalse(result.containsKey("b")); + assertFalse(result.containsKey("c")); + // and that others are not + assertEquals(Integer.valueOf(value.a), result.get("a")); + assertEquals(value.getD(), result.get("d")); + } + + public void testExplicitIncludeWithMap() throws Exception + { + // test simulating need to filter out metadata like class name + MyMap value = new MyMap(); + value.put("a", "b"); + value.put("c", "d"); + value.put("@class", MyMap.class.getName()); + Map<String, Object> result = writeAndMap(MAPPER, value); + assertEquals(2, result.size()); + assertEquals(MyMap.class.getName(), result.get("@class")); + assertEquals(value.get("a"), result.get("a")); + } + + public void testIncludeViaOnlyProps() throws Exception + { + assertEquals("{\"value\":{\"y\":2}}", + MAPPER.writeValueAsString(new WrapperWithPropInclude())); + } + + // Also: should be fine even if nominal type is `java.lang.Object` + public void testIncludeViaPropForUntyped() throws Exception + { + assertEquals("{\"value\":{\"x\":1}}", + MAPPER.writeValueAsString(new WrapperWithPropIncludeUntyped())); + } + + public void testIncludeWithMapProperty() throws Exception + { + assertEquals("{\"value\":{\"a\":1}}", MAPPER.writeValueAsString(new MapWrapper())); + } + + public void testIncludeViaPropsAndClass() throws Exception + { + assertEquals("{\"value\":{\"x\":1}}", + MAPPER.writeValueAsString(new WrapperWithPropInclude2())); + } + + // for [databind#1060] + // Ensure that `@JsonIncludeProperties` applies to POJOs within lists, too + public void testIncludeForListValues() throws Exception + { + // should apply to elements + assertEquals(aposToQuotes("{'coordinates':[{'x':1}]}"), + MAPPER.writeValueAsString(new IncludeForListValuesXY())); + + // and combine values too + assertEquals(aposToQuotes("{'coordinates':[{'x':1}]}"), + MAPPER.writeValueAsString(new IncludeForListValuesXYZ())); + } + + public void testIgnoreWithInclude() throws Exception + { + assertEquals("{\"value\":{\"x\":1}}", MAPPER.writeValueAsString(new WrapperWithPropIgnore())); + } +} |