From 4727cc33af2f6f02bf5a833030ea78e489b0c83c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pascal=20G=C3=A9linas?= Date: Thu, 12 Dec 2013 09:43:17 -0500 Subject: [PATCH] Test case for issue #351. --- .../struct/TestObjectIdDeserialization.java | 104 +++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/struct/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/struct/TestObjectIdDeserialization.java index a65e7934b0e..c1bd1161f42 100644 --- a/src/test/java/com/fasterxml/jackson/databind/struct/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/struct/TestObjectIdDeserialization.java @@ -1,9 +1,14 @@ package com.fasterxml.jackson.databind.struct; +import java.util.HashMap; +import java.util.Map; + +import com.fasterxml.jackson.annotation.JsonAnySetter; import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.ObjectIdGenerators; - import com.fasterxml.jackson.databind.*; +import com.fasterxml.jackson.databind.struct.TestObjectId.Company; +import com.fasterxml.jackson.databind.struct.TestObjectId.Employee; /** * Unit test to verify handling of Object Id deserialization @@ -102,6 +107,26 @@ public void setCustomId(int i) { } } + static class MappedCompany { + public Map employees; + } + + static class ArrayCompany { + public Employee[] employees; + } + + @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class) + static class AnySetterObjectId { + private Map values = new HashMap(); + + @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); + } + } + private final ObjectMapper mapper = new ObjectMapper(); /* @@ -166,7 +191,82 @@ public void testSimpleDeserWithForwardRefs() throws Exception assertEquals(7, result.node.value); assertSame(result.node, result.node.next.node); } - + + public void testLateForwardReferenceInCollection() throws Exception + { + String json = "{\"employees\":[" + + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," + + "{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" + + "]}"; + Company company = mapper.readValue(json, Company.class); + assertEquals(2, company.employees.size()); + // Deser must keep object ordering. + Employee firstEmployee = company.employees.get(0); + Employee secondEmployee = company.employees.get(1); + assertEquals(1, firstEmployee.id); + assertEquals(2, secondEmployee.id); + assertSame(secondEmployee, firstEmployee.reports.get(0)); // Ensure that forward reference was properly resolved and in order. + assertSame(firstEmployee, secondEmployee.manager); // And that back reference is also properly resolved. + } + + // Variant of before but forward reference is not "wrapped" inside a collection, might be easier to fix first. + public void testLateForwardReference() throws Exception + { + String json = "{\"employees\":[" + + "{\"id\":1,\"name\":\"First\",\"manager\":2,\"reports\":[]}," + + "{\"id\":2,\"name\":\"Second\",\"manager\":null,\"reports\":[1]}" + + "]}"; + Company company = mapper.readValue(json, Company.class); + assertEquals(2, company.employees.size()); + // Deser must keep object ordering. + Employee firstEmployee = company.employees.get(0); + Employee secondEmployee = company.employees.get(1); + assertEquals(1, firstEmployee.id); + assertEquals(2, secondEmployee.id); + assertEquals(secondEmployee, firstEmployee.manager); // Ensure that forward reference was properly resolved. + assertEquals(firstEmployee, secondEmployee.reports.get(0)); // And that back reference is also properly resolved. + } + + public void testLateForwardReferenceInMap() throws Exception + { + String json = "{\"employees\":{" + + "\"1\":{\"id\":1,\"name\":\"First\",\"manager\":2,\"reports\":[]}," + + "\"2\": 2," + + "\"3\":{\"id\":2,\"name\":\"Second\",\"manager\":null,\"reports\":[1]}" + + "}}"; + MappedCompany company = mapper.readValue(json, MappedCompany.class); + assertEquals(3, company.employees.size()); + // Deser must keep object ordering. + Employee firstEmployee = company.employees.get(1); + Employee secondEmployee = company.employees.get(3); + assertEquals(1, firstEmployee.id); + assertEquals(2, secondEmployee.id); + assertEquals(secondEmployee, firstEmployee.manager); // Ensure that forward reference was properly resolved. + assertEquals(firstEmployee, secondEmployee.reports.get(0)); // And that back reference is also properly resolved. + } + + public void testLateForwardReferenceInArray() throws Exception { + String json = "{\"employees\":[" + + "{\"id\":1,\"name\":\"First\",\"manager\":null,\"reports\":[2]}," + + "2,{\"id\":2,\"name\":\"Second\",\"manager\":1,\"reports\":[]}" + + "]}"; + ArrayCompany company = mapper.readValue(json, ArrayCompany.class); + assertEquals(3, company.employees.length); + // Deser must keep object ordering. + Employee firstEmployee = company.employees[0]; + Employee secondEmployee = company.employees[1]; + assertEquals(1, firstEmployee.id); + assertEquals(2, secondEmployee.id); + assertSame(secondEmployee, firstEmployee.reports.get(0)); // Ensure that forward reference was properly resolved and in order. + assertSame(firstEmployee, secondEmployee.manager); // And that back reference is also properly resolved. + } + + public void testForwardReferenceAnySetterCombo() throws Exception { + String json = "{\"@id\":1, \"foo\":2, \"bar\":{\"@id\":2, \"foo\":1}}"; + AnySetterObjectId value = mapper.readValue(json, AnySetterObjectId.class); + assertSame(value.values.get("bar"), value.values.get("foo")); + } + /* /***************************************************** /* Unit tests, custom (property-based) id deserialization