Skip to content

Commit 12233b7

Browse files
committed
Add Records+JsonAnySetter workarounds shared in FasterXML#3439, as test cases.
1 parent 8c14e09 commit 12233b7

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.fasterxml.jackson.databind.records;
2+
3+
import com.fasterxml.jackson.annotation.JsonAnySetter;
4+
import com.fasterxml.jackson.annotation.JsonCreator;
5+
import com.fasterxml.jackson.annotation.JsonProperty;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException;
8+
import com.fasterxml.jackson.databind.testutil.DatabindTestUtil;
9+
import org.junit.jupiter.api.Test;
10+
import org.opentest4j.AssertionFailedError;
11+
12+
import java.util.LinkedHashMap;
13+
import java.util.Map;
14+
15+
import static org.junit.jupiter.api.Assertions.assertEquals;
16+
import static org.junit.jupiter.api.Assertions.fail;
17+
18+
public class RecordWithJsonAnySetterTest extends DatabindTestUtil {
19+
20+
// Workaround mentioned in [databind#3439]
21+
record RecordWithAnySetterMethodWithAltCtor(int id, Map<String, Object> any) {
22+
@JsonCreator
23+
public RecordWithAnySetterMethodWithAltCtor(@JsonProperty("id") int id) {
24+
this(id, new LinkedHashMap<>());
25+
}
26+
27+
@JsonAnySetter
28+
private void updateProperty(String name, Object value) {
29+
any.put(name, value);
30+
}
31+
}
32+
33+
// Workaround mentioned in [databind#3439]
34+
record RecordWithAnySetterMethodWithCanonCtor(int id, Map<String, Object> any) {
35+
36+
RecordWithAnySetterMethodWithCanonCtor {
37+
any = (any != null) ? any : new LinkedHashMap<>();
38+
}
39+
40+
@JsonAnySetter
41+
public void addAny(String name, Object value) {
42+
any.put(name, value);
43+
}
44+
}
45+
46+
// Workaround mentioned in [databind#3439]
47+
record RecordWithAnySetterComponentAltCtor(int id, @JsonAnySetter Map<String, Object> any) {
48+
@JsonCreator
49+
public RecordWithAnySetterComponentAltCtor(@JsonProperty("id") int id) {
50+
this(id, new LinkedHashMap<>());
51+
}
52+
}
53+
54+
// A proper one without workaround
55+
record RecordWithAnySetterComponentCanonCtor(int id, @JsonAnySetter Map<String, Object> any) {
56+
}
57+
58+
private final ObjectMapper MAPPER = newJsonMapper();
59+
60+
@Test
61+
public void testDeserialize_WithAnySetterMethod_WithAltConstructor() throws Exception {
62+
RecordWithAnySetterMethodWithAltCtor value = MAPPER.readValue(
63+
a2q("{'id':123,'any1':'Any 1','any2':'Any 2'}"), RecordWithAnySetterMethodWithAltCtor.class);
64+
65+
Map<String, Object> expectedAny = new LinkedHashMap<>();
66+
expectedAny.put("any1", "Any 1");
67+
expectedAny.put("any2", "Any 2");
68+
assertEquals(new RecordWithAnySetterMethodWithAltCtor(123, expectedAny), value);
69+
}
70+
71+
@Test
72+
public void testDeserialize_WithAnySetterMethod_WithCanonicalConstructor() throws Exception {
73+
RecordWithAnySetterMethodWithCanonCtor value = MAPPER.readValue(
74+
a2q("{'id':123,'any1':'Any 1','any2':'Any 2'}"), RecordWithAnySetterMethodWithCanonCtor.class);
75+
76+
Map<String, Object> expectedAny = new LinkedHashMap<>();
77+
expectedAny.put("any1", "Any 1");
78+
expectedAny.put("any2", "Any 2");
79+
try {
80+
assertEquals(new RecordWithAnySetterMethodWithCanonCtor(123, expectedAny), value);
81+
fail("Used to fail, but is now working again");
82+
} catch (AssertionFailedError e) {
83+
// Used to work, but stopped working starting from 2.18.0 likely due to [databind#4558]
84+
verifyException(e, "RecordWithAnySetterMethodWithCanonCtor[id=123, any={}]");
85+
}
86+
}
87+
88+
@Test
89+
public void testDeserialize_WithAnySetterComponent_WithAltConstructor() throws Exception {
90+
try {
91+
RecordWithAnySetterComponentAltCtor value = MAPPER.readValue(
92+
a2q("{'id':123,'any1':'Any 1','any2':'Any 2'}"), RecordWithAnySetterComponentAltCtor.class);
93+
fail("Used to fail, but is now: " + value);
94+
} catch (UnrecognizedPropertyException e) {
95+
// Used to work, but stopped working starting from 2.15.0 due to [databind#3737]
96+
verifyException(e, "Unrecognized field \"any1\"");
97+
}
98+
}
99+
100+
@Test
101+
public void testDeserialize_WithAnySetterComponent_WithCanonicalConstructor() throws Exception {
102+
RecordWithAnySetterComponentCanonCtor value = MAPPER.readValue(
103+
a2q("{'id':123,'any1':'Any 1','any2':'Any 2'}"), RecordWithAnySetterComponentCanonCtor.class);
104+
105+
Map<String, Object> expectedAny = new LinkedHashMap<>();
106+
expectedAny.put("any1", "Any 1");
107+
expectedAny.put("any2", "Any 2");
108+
assertEquals(new RecordWithAnySetterComponentCanonCtor(123, expectedAny), value);
109+
}
110+
}

0 commit comments

Comments
 (0)