From db7ca264720e79060c07772d63868e906150b48d Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 13 Apr 2023 00:13:25 +0900 Subject: [PATCH 01/11] Add suspicious tests --- .../objectid/TestObjectIdDeserialization.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index bc213b734b..af049ed866 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -352,6 +352,24 @@ public void testUnresolvableAsNull() throws Exception assertNull(w.node); } + public void testUnresolvableIdShouldFail() throws Exception + { + IdWrapper w = MAPPER.readerFor(IdWrapper.class) + .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(a2q("{'node':123}")); + assertNotNull(w); + assertNull(w.node); + } + + public void testUnresolvableIdShouldFail2() throws Exception + { + IdWrapper w = MAPPER.readerFor(IdWrapper.class) + .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(a2q("{}")); + assertNotNull(w); + assertNull(w.node); + } + public void testKeepCollectionOrdering() throws Exception { String json = "{\"employees\":[2,1," From 4f9629885ca9f6a5373814f4ccbc671ef5354b51 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 13 Apr 2023 00:17:03 +0900 Subject: [PATCH 02/11] Update TestObjectIdDeserialization.java --- .../jackson/databind/objectid/TestObjectIdDeserialization.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index af049ed866..79082ee3fa 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -357,6 +357,7 @@ public void testUnresolvableIdShouldFail() throws Exception IdWrapper w = MAPPER.readerFor(IdWrapper.class) .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) .readValue(a2q("{'node':123}")); + // should fail, but passes assertNotNull(w); assertNull(w.node); } @@ -366,6 +367,7 @@ public void testUnresolvableIdShouldFail2() throws Exception IdWrapper w = MAPPER.readerFor(IdWrapper.class) .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) .readValue(a2q("{}")); + // should fail, but passes also? assertNotNull(w); assertNull(w.node); } From e27793328982823201eb1c5f9042104519bf6002 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 13 Apr 2023 19:39:58 +0900 Subject: [PATCH 03/11] Update TestObjectIdDeserialization.java --- .../objectid/TestObjectIdDeserialization.java | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index 79082ee3fa..80ba164ac5 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -357,17 +357,6 @@ public void testUnresolvableIdShouldFail() throws Exception IdWrapper w = MAPPER.readerFor(IdWrapper.class) .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) .readValue(a2q("{'node':123}")); - // should fail, but passes - assertNotNull(w); - assertNull(w.node); - } - - public void testUnresolvableIdShouldFail2() throws Exception - { - IdWrapper w = MAPPER.readerFor(IdWrapper.class) - .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(a2q("{}")); - // should fail, but passes also? assertNotNull(w); assertNull(w.node); } From 9ff8e0ae719a4152446532311c5807ac9984a3b2 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 13 Apr 2023 20:25:10 +0900 Subject: [PATCH 04/11] Improve doc and test cases --- .../databind/DeserializationFeature.java | 4 +- .../UnresolvedObjectIdConfigTest.java | 117 ++++++++++++++++++ 2 files changed, 119 insertions(+), 2 deletions(-) create mode 100644 src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java index 3a95d20fe8..0470b3da26 100644 --- a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java +++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java @@ -189,8 +189,8 @@ public enum DeserializationFeature implements ConfigFeature /** * Feature that determines what happens if an Object Id reference is encountered * that does not refer to an actual Object with that id ("unresolved Object Id"): - * either an exception is thrown (true), or a null object is used - * instead (false). + * either an exception {@link com.fasterxml.jackson.databind.deser.UnresolvedForwardReference} + * is thrown (true), or a null object is used instead (false). * Note that if this is set to false, no further processing is done; * specifically, if reference is defined via setter method, that method will NOT * be called. diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java b/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java new file mode 100644 index 0000000000..4857b994cd --- /dev/null +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java @@ -0,0 +1,117 @@ +package com.fasterxml.jackson.databind.objectid; + +import com.fasterxml.jackson.annotation.JsonIdentityInfo; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; +import com.fasterxml.jackson.databind.BaseMapTest; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.UnresolvedForwardReference; + +/** + * Unit test to verify handling of Object Id deserialization in + * conjunction with {@link DeserializationFeature#FAIL_ON_UNRESOLVED_OBJECT_IDS}. + */ +public class UnresolvedObjectIdConfigTest extends BaseMapTest { + + /* + /********************************************************** + /* Set Up + /********************************************************** + */ + + static class IdWrapper { + @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") + public ValueNode node; + + public IdWrapper() {} + + public IdWrapper(int v) { + node = new ValueNode(v); + } + } + + static class ValueNode { + public int value; + public IdWrapper next; + + public ValueNode() {this(0);} + + public ValueNode(int v) {value = v;} + } + + /* + /********************************************************** + /* Tests + /********************************************************** + */ + + private final ObjectMapper MAPPER = newJsonMapper(); + + public void testDefaultSetting() { + assertTrue(MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)); + } + + public void testSuccessResolvedObjectIds() throws Exception { + String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':1}}}"); + + IdWrapper wrapper = MAPPER.readerFor(IdWrapper.class) + .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(json); + + assertSame(wrapper.node, wrapper.node.next.node); + assertSame(wrapper.node.next.node, wrapper.node.next.node.next.node); + } + + public void testUnresolvedObjectIdsFailure() throws Exception { + // Object id 2 is unresolved + String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); + + try { + // This will also throw exception, enabled by default + MAPPER.readerFor(IdWrapper.class) + .readValue(json); + fail("should not pass"); + } catch (UnresolvedForwardReference e) { + verifyException(e, "Unresolved forward reference", "Object id [2]"); + } + + try { + // This will also throw exception, same as default + MAPPER.readerFor(IdWrapper.class) + .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(json); + fail("should not pass"); + } catch (UnresolvedForwardReference e) { + verifyException(e, "Unresolved forward reference", "Object id [2]"); + } + } + + public void testUnresolvedObjectIdsDoesNotFail() throws Exception { + // Object id 2 is unresolved + String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); + + // But does not fail, because configured such + IdWrapper wrapper = MAPPER.readerFor(IdWrapper.class) + .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(json); + + assertNull(wrapper.node.next.node); + } + + public void testMissingObjectIdsShouldNotFailEitherWay() throws Exception { + // Object id is just "missing", not unresolved + String json = a2q("{'node':{'@id':1,'value':7,'next':{}}}"); + + // Missing id does not fail either enabled, + IdWrapper withWrapper = MAPPER.readerFor(IdWrapper.class) + .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(json); + assertNull(withWrapper.node.next.node); + + // or disabled. + IdWrapper withoutWrapper = MAPPER.readerFor(IdWrapper.class) + .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(json); + assertNull(withoutWrapper.node.next.node); + } +} From 71adba892b78ce984c49eb8f49e74bec888e8d4a Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 13 Apr 2023 21:02:37 +0900 Subject: [PATCH 05/11] Add tests --- .../objectid/TestObjectIdDeserialization.java | 23 ++++++- .../UnresolvedObjectIdConfigTest.java | 60 ++++++++----------- 2 files changed, 47 insertions(+), 36 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index 80ba164ac5..80b7812ee0 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -352,13 +352,34 @@ public void testUnresolvableAsNull() throws Exception assertNull(w.node); } - public void testUnresolvableIdShouldFail() throws Exception + public void testUnresolvableAsNullSymmetry() throws Exception { IdWrapper w = MAPPER.readerFor(IdWrapper.class) + .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) + .readValue(a2q("{'node':123}")); + assertNotNull(w); + assertNull(w.node); + + IdWrapper w2 = MAPPER.readerFor(IdWrapper.class) .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) .readValue(a2q("{'node':123}")); + assertNotNull(w2); + assertNull(w2.node); + } + + public void testUnresolvableAsNull2() throws Exception + { + IdWrapper w = MAPPER + .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false) + .readValue(a2q("{'node':123}"), IdWrapper.class); assertNotNull(w); assertNull(w.node); + + IdWrapper w2 = MAPPER + .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true) + .readValue(a2q("{'node':123}"), IdWrapper.class); + assertNotNull(w2); + assertNull(w2.node); } public void testKeepCollectionOrdering() throws Exception diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java b/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java index 4857b994cd..81d49c2871 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java @@ -19,20 +19,20 @@ public class UnresolvedObjectIdConfigTest extends BaseMapTest { /********************************************************** */ - static class IdWrapper { + static class NodeWrapper { @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") public ValueNode node; - public IdWrapper() {} + public NodeWrapper() {} - public IdWrapper(int v) { + public NodeWrapper(int v) { node = new ValueNode(v); } } static class ValueNode { public int value; - public IdWrapper next; + public NodeWrapper next; public ValueNode() {this(0);} @@ -45,31 +45,32 @@ static class ValueNode { /********************************************************** */ - private final ObjectMapper MAPPER = newJsonMapper(); + private final ObjectMapper DEFAULT_MAPPER = newJsonMapper(); + + private final ObjectMapper DISABLED_MAPPER = newJsonMapper() + .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false); + + private final ObjectMapper ENABLED_MAPPER = newJsonMapper() + .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true); public void testDefaultSetting() { - assertTrue(MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)); + assertTrue(DEFAULT_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)); } public void testSuccessResolvedObjectIds() throws Exception { String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':1}}}"); - IdWrapper wrapper = MAPPER.readerFor(IdWrapper.class) - .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(json); + NodeWrapper wrapper = DEFAULT_MAPPER.readValue(json, NodeWrapper.class); assertSame(wrapper.node, wrapper.node.next.node); assertSame(wrapper.node.next.node, wrapper.node.next.node.next.node); } public void testUnresolvedObjectIdsFailure() throws Exception { - // Object id 2 is unresolved String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); - try { // This will also throw exception, enabled by default - MAPPER.readerFor(IdWrapper.class) - .readValue(json); + DEFAULT_MAPPER.readValue(json, NodeWrapper.class); fail("should not pass"); } catch (UnresolvedForwardReference e) { verifyException(e, "Unresolved forward reference", "Object id [2]"); @@ -77,9 +78,7 @@ public void testUnresolvedObjectIdsFailure() throws Exception { try { // This will also throw exception, same as default - MAPPER.readerFor(IdWrapper.class) - .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(json); + ENABLED_MAPPER.readValue(json, NodeWrapper.class); fail("should not pass"); } catch (UnresolvedForwardReference e) { verifyException(e, "Unresolved forward reference", "Object id [2]"); @@ -90,28 +89,19 @@ public void testUnresolvedObjectIdsDoesNotFail() throws Exception { // Object id 2 is unresolved String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); - // But does not fail, because configured such - IdWrapper wrapper = MAPPER.readerFor(IdWrapper.class) - .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(json); + // But does not fail, because disabled to fail + NodeWrapper wrapper = DISABLED_MAPPER.readValue(json, NodeWrapper.class); assertNull(wrapper.node.next.node); } - public void testMissingObjectIdsShouldNotFailEitherWay() throws Exception { - // Object id is just "missing", not unresolved - String json = a2q("{'node':{'@id':1,'value':7,'next':{}}}"); - - // Missing id does not fail either enabled, - IdWrapper withWrapper = MAPPER.readerFor(IdWrapper.class) - .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(json); - assertNull(withWrapper.node.next.node); - - // or disabled. - IdWrapper withoutWrapper = MAPPER.readerFor(IdWrapper.class) - .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(json); - assertNull(withoutWrapper.node.next.node); + + public void testUnresolvableIdShouldFail() throws Exception + { + TestObjectIdDeserialization.IdWrapper w = ENABLED_MAPPER + .readValue(a2q("{'node':123}"), TestObjectIdDeserialization.IdWrapper.class); + assertNotNull(w); + assertNull(w.node); } + } From 0175f2cc86dd1d7e0f0dc7636c61a73312c833d6 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 13 Apr 2023 21:06:20 +0900 Subject: [PATCH 06/11] Fix failing tests --- .../objectid/TestObjectIdDeserialization.java | 13 ++++++++----- .../objectid/UnresolvedObjectIdConfigTest.java | 10 ---------- 2 files changed, 8 insertions(+), 15 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index 80b7812ee0..7d0a70cc01 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -375,11 +375,14 @@ public void testUnresolvableAsNull2() throws Exception assertNotNull(w); assertNull(w.node); - IdWrapper w2 = MAPPER - .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true) - .readValue(a2q("{'node':123}"), IdWrapper.class); - assertNotNull(w2); - assertNull(w2.node); + try { + IdWrapper w2 = MAPPER + .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true) + .readValue(a2q("{'node':123}"), IdWrapper.class); + fail("should not pass"); + } catch (UnresolvedForwardReference e) { + verifyException(e, "Unresolved forward reference", "Object id [123]"); + } } public void testKeepCollectionOrdering() throws Exception diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java b/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java index 81d49c2871..f85a29f030 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java @@ -94,14 +94,4 @@ public void testUnresolvedObjectIdsDoesNotFail() throws Exception { assertNull(wrapper.node.next.node); } - - - public void testUnresolvableIdShouldFail() throws Exception - { - TestObjectIdDeserialization.IdWrapper w = ENABLED_MAPPER - .readValue(a2q("{'node':123}"), TestObjectIdDeserialization.IdWrapper.class); - assertNotNull(w); - assertNull(w.node); - } - } From a7c867e31328016b0053b97b27bf55f696c2e5fe Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Thu, 13 Apr 2023 21:14:11 +0900 Subject: [PATCH 07/11] Make tests more descriptive --- .../databind/objectid/TestObjectIdDeserialization.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index 7d0a70cc01..25a176e9a7 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -352,14 +352,16 @@ public void testUnresolvableAsNull() throws Exception assertNull(w.node); } - public void testUnresolvableAsNullSymmetry() throws Exception + public void testUnresolvableWithFeatureSymmetry() throws Exception { + // specifically configured to "not" fail IdWrapper w = MAPPER.readerFor(IdWrapper.class) .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) .readValue(a2q("{'node':123}")); assertNotNull(w); assertNull(w.node); + // specifically configured to fail, but doesn't IdWrapper w2 = MAPPER.readerFor(IdWrapper.class) .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) .readValue(a2q("{'node':123}")); @@ -367,14 +369,16 @@ public void testUnresolvableAsNullSymmetry() throws Exception assertNull(w2.node); } - public void testUnresolvableAsNull2() throws Exception + public void testUnresolvableConfigureFeatureSymmetry() throws Exception { + // specifically configured to "not" fail IdWrapper w = MAPPER .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false) .readValue(a2q("{'node':123}"), IdWrapper.class); assertNotNull(w); assertNull(w.node); + // specifically configured to fail try { IdWrapper w2 = MAPPER .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true) From 649f18405049d12988266c3fa6f7f7def7da342f Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Fri, 14 Apr 2023 00:23:31 +0900 Subject: [PATCH 08/11] Add more JavaDoc info. --- .../com/fasterxml/jackson/databind/DeserializationFeature.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java index 0470b3da26..b9373cdc5e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java +++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java @@ -190,6 +190,7 @@ public enum DeserializationFeature implements ConfigFeature * Feature that determines what happens if an Object Id reference is encountered * that does not refer to an actual Object with that id ("unresolved Object Id"): * either an exception {@link com.fasterxml.jackson.databind.deser.UnresolvedForwardReference} + * containing information about {@link com.fasterxml.jackson.databind.deser.UnresolvedId} * is thrown (true), or a null object is used instead (false). * Note that if this is set to false, no further processing is done; * specifically, if reference is defined via setter method, that method will NOT From c5ae6f7d508fb03232e60723570ac7926108d5a6 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Tue, 18 Apr 2023 20:29:47 +0900 Subject: [PATCH 09/11] Clean up tests --- .../objectid/TestObjectIdDeserialization.java | 96 ++++++++++++++---- .../UnresolvedObjectIdConfigTest.java | 97 ------------------- 2 files changed, 76 insertions(+), 117 deletions(-) delete mode 100644 src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index 25a176e9a7..40eabc58c1 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -182,6 +182,26 @@ public ObjectIdResolver newForDeserialization(Object c) } } + static class SomeWrapper { + @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") + public SomeNode node; + + public SomeWrapper() {} + + public SomeWrapper(int v) { + node = new SomeNode(v); + } + } + + static class SomeNode { + public int value; + public SomeWrapper next; + + public SomeNode() {this(0);} + + public SomeNode(int v) {value = v;} + } + /* /***************************************************** /* Unit tests, external id deserialization @@ -369,26 +389,6 @@ public void testUnresolvableWithFeatureSymmetry() throws Exception assertNull(w2.node); } - public void testUnresolvableConfigureFeatureSymmetry() throws Exception - { - // specifically configured to "not" fail - IdWrapper w = MAPPER - .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false) - .readValue(a2q("{'node':123}"), IdWrapper.class); - assertNotNull(w); - assertNull(w.node); - - // specifically configured to fail - try { - IdWrapper w2 = MAPPER - .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true) - .readValue(a2q("{'node':123}"), IdWrapper.class); - fail("should not pass"); - } catch (UnresolvedForwardReference e) { - verifyException(e, "Unresolved forward reference", "Object id [123]"); - } - } - public void testKeepCollectionOrdering() throws Exception { String json = "{\"employees\":[2,1," @@ -503,4 +503,60 @@ public void testNullObjectId() throws Exception assertNotNull(value); assertEquals(3, value.value); } + + /* + /***************************************************** + /* Unit tests in conjunction with DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS + /***************************************************** + */ + + + private final ObjectMapper DEFAULT_MAPPER = newJsonMapper(); + + private final ObjectMapper DISABLED_MAPPER = newJsonMapper() + .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false); + + private final ObjectMapper ENABLED_MAPPER = newJsonMapper() + .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true); + + public void testDefaultSetting() { + assertTrue(DEFAULT_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)); + assertTrue(ENABLED_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)); + assertFalse(DISABLED_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)); + } + + public void testSuccessResolvedObjectIds() throws Exception { + String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':1}}}"); + + SomeWrapper wrapper = DEFAULT_MAPPER.readValue(json, SomeWrapper.class); + + assertSame(wrapper.node, wrapper.node.next.node); + assertSame(wrapper.node.next.node, wrapper.node.next.node.next.node); + } + + public void testUnresolvedObjectIdsFailure() throws Exception { + // With node id of 2 that doesn't exist, + String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); + + // This will not fail, because disabled to fail + SomeWrapper wrapper = DISABLED_MAPPER.readValue(json, SomeWrapper.class); + assertNull(wrapper.node.next.node); + + try { + // This will also throw exception, enabled by default + DEFAULT_MAPPER.readValue(json, SomeWrapper.class); + fail("should not pass"); + } catch (UnresolvedForwardReference e) { + verifyException(e, "Unresolved forward reference", "Object id [2]"); + } + + try { + // This will also throw exception, same as default + ENABLED_MAPPER.readValue(json, SomeWrapper.class); + fail("should not pass"); + } catch (UnresolvedForwardReference e) { + verifyException(e, "Unresolved forward reference", "Object id [2]"); + } + } + } diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java b/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java deleted file mode 100644 index f85a29f030..0000000000 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/UnresolvedObjectIdConfigTest.java +++ /dev/null @@ -1,97 +0,0 @@ -package com.fasterxml.jackson.databind.objectid; - -import com.fasterxml.jackson.annotation.JsonIdentityInfo; -import com.fasterxml.jackson.annotation.ObjectIdGenerators; -import com.fasterxml.jackson.databind.BaseMapTest; -import com.fasterxml.jackson.databind.DeserializationFeature; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.deser.UnresolvedForwardReference; - -/** - * Unit test to verify handling of Object Id deserialization in - * conjunction with {@link DeserializationFeature#FAIL_ON_UNRESOLVED_OBJECT_IDS}. - */ -public class UnresolvedObjectIdConfigTest extends BaseMapTest { - - /* - /********************************************************** - /* Set Up - /********************************************************** - */ - - static class NodeWrapper { - @JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property = "@id") - public ValueNode node; - - public NodeWrapper() {} - - public NodeWrapper(int v) { - node = new ValueNode(v); - } - } - - static class ValueNode { - public int value; - public NodeWrapper next; - - public ValueNode() {this(0);} - - public ValueNode(int v) {value = v;} - } - - /* - /********************************************************** - /* Tests - /********************************************************** - */ - - private final ObjectMapper DEFAULT_MAPPER = newJsonMapper(); - - private final ObjectMapper DISABLED_MAPPER = newJsonMapper() - .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, false); - - private final ObjectMapper ENABLED_MAPPER = newJsonMapper() - .configure(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS, true); - - public void testDefaultSetting() { - assertTrue(DEFAULT_MAPPER.isEnabled(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS)); - } - - public void testSuccessResolvedObjectIds() throws Exception { - String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':1}}}"); - - NodeWrapper wrapper = DEFAULT_MAPPER.readValue(json, NodeWrapper.class); - - assertSame(wrapper.node, wrapper.node.next.node); - assertSame(wrapper.node.next.node, wrapper.node.next.node.next.node); - } - - public void testUnresolvedObjectIdsFailure() throws Exception { - String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); - try { - // This will also throw exception, enabled by default - DEFAULT_MAPPER.readValue(json, NodeWrapper.class); - fail("should not pass"); - } catch (UnresolvedForwardReference e) { - verifyException(e, "Unresolved forward reference", "Object id [2]"); - } - - try { - // This will also throw exception, same as default - ENABLED_MAPPER.readValue(json, NodeWrapper.class); - fail("should not pass"); - } catch (UnresolvedForwardReference e) { - verifyException(e, "Unresolved forward reference", "Object id [2]"); - } - } - - public void testUnresolvedObjectIdsDoesNotFail() throws Exception { - // Object id 2 is unresolved - String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); - - // But does not fail, because disabled to fail - NodeWrapper wrapper = DISABLED_MAPPER.readValue(json, NodeWrapper.class); - - assertNull(wrapper.node.next.node); - } -} From b34e6038459be2803ce0cfd4a67c0da23e1cb138 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Tue, 18 Apr 2023 20:31:43 +0900 Subject: [PATCH 10/11] Update TestObjectIdDeserialization.java --- .../objectid/TestObjectIdDeserialization.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index 40eabc58c1..7197b21308 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -374,17 +374,19 @@ public void testUnresolvableAsNull() throws Exception public void testUnresolvableWithFeatureSymmetry() throws Exception { - // specifically configured to "not" fail - IdWrapper w = MAPPER.readerFor(IdWrapper.class) + ObjectMapper mapper = newJsonMapper(); + + // configured to "not" fail + IdWrapper w = mapper.reader() .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(a2q("{'node':123}")); + .readValue(a2q("{'node':123}"), IdWrapper.class); assertNotNull(w); assertNull(w.node); - // specifically configured to fail, but doesn't - IdWrapper w2 = MAPPER.readerFor(IdWrapper.class) + // configured to fail, but doesn't + IdWrapper w2 = mapper.reader() .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(a2q("{'node':123}")); + .readValue(a2q("{'node':123}"), IdWrapper.class); assertNotNull(w2); assertNull(w2.node); } From 7ff9d073abfc07da5567371e1d9de50338dfa0f0 Mon Sep 17 00:00:00 2001 From: joohyukkim Date: Tue, 18 Apr 2023 20:36:47 +0900 Subject: [PATCH 11/11] Clean up test --- .../objectid/TestObjectIdDeserialization.java | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java index 7197b21308..9f6e895c20 100644 --- a/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java +++ b/src/test/java/com/fasterxml/jackson/databind/objectid/TestObjectIdDeserialization.java @@ -372,25 +372,6 @@ public void testUnresolvableAsNull() throws Exception assertNull(w.node); } - public void testUnresolvableWithFeatureSymmetry() throws Exception - { - ObjectMapper mapper = newJsonMapper(); - - // configured to "not" fail - IdWrapper w = mapper.reader() - .without(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(a2q("{'node':123}"), IdWrapper.class); - assertNotNull(w); - assertNull(w.node); - - // configured to fail, but doesn't - IdWrapper w2 = mapper.reader() - .with(DeserializationFeature.FAIL_ON_UNRESOLVED_OBJECT_IDS) - .readValue(a2q("{'node':123}"), IdWrapper.class); - assertNotNull(w2); - assertNull(w2.node); - } - public void testKeepCollectionOrdering() throws Exception { String json = "{\"employees\":[2,1," @@ -537,15 +518,15 @@ public void testSuccessResolvedObjectIds() throws Exception { } public void testUnresolvedObjectIdsFailure() throws Exception { - // With node id of 2 that doesn't exist, + // Set-up : node id of 2 that doesn't exist, String json = a2q("{'node':{'@id':1,'value':7,'next':{'node':2}}}"); - // This will not fail, because disabled to fail + // 1. Does not fail, because disabled such. SomeWrapper wrapper = DISABLED_MAPPER.readValue(json, SomeWrapper.class); assertNull(wrapper.node.next.node); try { - // This will also throw exception, enabled by default + // 2. Will fail by default. DEFAULT_MAPPER.readValue(json, SomeWrapper.class); fail("should not pass"); } catch (UnresolvedForwardReference e) { @@ -553,7 +534,7 @@ public void testUnresolvedObjectIdsFailure() throws Exception { } try { - // This will also throw exception, same as default + // 3. Will also throw exception, because configured as such. ENABLED_MAPPER.readValue(json, SomeWrapper.class); fail("should not pass"); } catch (UnresolvedForwardReference e) {