Skip to content

Commit e1b8129

Browse files
committed
Add test cases for issue FasterXML#4119.
1 parent a5000a5 commit e1b8129

File tree

1 file changed

+174
-0
lines changed

1 file changed

+174
-0
lines changed
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
package com.fasterxml.jackson.databind.records;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.annotation.JsonProperty.Access;
5+
import com.fasterxml.jackson.databind.BaseMapTest;
6+
import com.fasterxml.jackson.databind.ObjectMapper;
7+
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
8+
9+
public class RecordWithReadOnlyTest extends BaseMapTest {
10+
11+
record RecordWithReadOnly(int id, @JsonProperty(access = Access.READ_ONLY) String name) {
12+
}
13+
14+
record RecordWithReadOnlyNamedProperty(int id, @JsonProperty(value = "name", access = Access.READ_ONLY) String name) {
15+
}
16+
17+
record RecordWithReadOnlyAccessor(int id, String name) {
18+
19+
@JsonProperty(access = Access.READ_ONLY)
20+
@Override
21+
public String name() {
22+
return name;
23+
}
24+
}
25+
26+
record RecordWithReadOnlyComponentOverriddenAccessor(int id, @JsonProperty(access = Access.READ_ONLY) String name) {
27+
28+
// @JsonProperty on overridden method is not automatically inherited by overriding method
29+
@Override
30+
public String name() {
31+
return name;
32+
}
33+
}
34+
35+
record RecordWithReadOnlyPrimitiveType(@JsonProperty(access = Access.READ_ONLY) int id, String name) {
36+
}
37+
38+
record RecordWithReadOnlyAll(@JsonProperty(access = Access.READ_ONLY) int id,
39+
@JsonProperty(access = Access.READ_ONLY) String name) {
40+
}
41+
42+
record RecordWithReadOnlyAllAndNoArgConstructor(@JsonProperty(access = Access.READ_ONLY) int id,
43+
@JsonProperty(access = Access.READ_ONLY) String name) {
44+
45+
public RecordWithReadOnlyAllAndNoArgConstructor() {
46+
this(-1, "no-arg");
47+
}
48+
}
49+
50+
private final ObjectMapper MAPPER = newJsonMapper();
51+
52+
/*
53+
/**********************************************************************
54+
/* Test methods, JsonProperty.access=READ_ONLY
55+
/**********************************************************************
56+
*/
57+
58+
public void testSerializeReadOnlyProperty() throws Exception {
59+
String json = MAPPER.writeValueAsString(new RecordWithReadOnly(123, "Bob"));
60+
assertEquals(a2q("{'id':123,'name':'Bob'}"), json);
61+
}
62+
63+
public void testDeserializeReadOnlyProperty() throws Exception {
64+
RecordWithReadOnly value = MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"), RecordWithReadOnly.class);
65+
assertEquals(new RecordWithReadOnly(123, null), value);
66+
}
67+
68+
/*
69+
/**********************************************************************
70+
/* Test methods, JsonProperty.access=READ_ONLY + JsonProperty.value=...
71+
/**********************************************************************
72+
*/
73+
74+
public void testSerializeReadOnlyNamedProperty() throws Exception {
75+
String json = MAPPER.writeValueAsString(new RecordWithReadOnlyNamedProperty(123, "Bob"));
76+
assertEquals(a2q("{'name':'Bob','id':123}"), json);
77+
}
78+
79+
/**
80+
* Currently documents a bug where a property was NOT ignored during deserialization if given an explicit name.
81+
* Also reproducible in 2.14.x.
82+
*/
83+
public void testDeserializeReadOnlyNamedProperty() throws Exception {
84+
RecordWithReadOnlyNamedProperty value = MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"), RecordWithReadOnlyNamedProperty.class);
85+
assertEquals(new RecordWithReadOnlyNamedProperty(123, "Bob"), value); // BUG: should be `null` instead of "Bob"
86+
}
87+
88+
/*
89+
/**********************************************************************
90+
/* Test methods, JsonProperty.access=READ_ONLY accessor
91+
/**********************************************************************
92+
*/
93+
94+
public void testSerializeReadOnlyAccessor() throws Exception {
95+
String json = MAPPER.writeValueAsString(new RecordWithReadOnlyAccessor(123, "Bob"));
96+
assertEquals(a2q("{'id':123,'name':'Bob'}"), json);
97+
}
98+
99+
public void testDeserializeReadOnlyAccessor() throws Exception {
100+
RecordWithReadOnlyAccessor expected = new RecordWithReadOnlyAccessor(123, null);
101+
102+
assertEquals(expected, MAPPER.readValue(a2q("{'id':123}"), RecordWithReadOnlyAccessor.class));
103+
assertEquals(expected, MAPPER.readValue(a2q("{'id':123,'name':null}"), RecordWithReadOnlyAccessor.class));
104+
assertEquals(expected, MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"), RecordWithReadOnlyAccessor.class));
105+
}
106+
107+
/*
108+
/**********************************************************************
109+
/* Test methods, JsonProperty.access=READ_ONLY component, but accessor method was overridden without re-annotating with JsonProperty.access=READ_ONLY
110+
/**********************************************************************
111+
*/
112+
113+
public void testSerializeReadOnlyComponentOverrideAccessor() throws Exception {
114+
String json = MAPPER.writeValueAsString(new RecordWithReadOnlyComponentOverriddenAccessor(123, "Bob"));
115+
assertEquals(a2q("{'id':123,'name':'Bob'}"), json);
116+
}
117+
118+
public void testDeserializeReadOnlyComponentOverrideAccessor() throws Exception {
119+
RecordWithReadOnlyComponentOverriddenAccessor expected = new RecordWithReadOnlyComponentOverriddenAccessor(123, null);
120+
121+
assertEquals(expected, MAPPER.readValue(a2q("{'id':123}"), RecordWithReadOnlyComponentOverriddenAccessor.class));
122+
assertEquals(expected, MAPPER.readValue(a2q("{'id':123,'name':null}"), RecordWithReadOnlyComponentOverriddenAccessor.class));
123+
assertEquals(expected, MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"), RecordWithReadOnlyComponentOverriddenAccessor.class));
124+
}
125+
126+
/*
127+
/**********************************************************************
128+
/* Test methods, JsonProperty.access=READ_ONLY parameter of primitive type
129+
/**********************************************************************
130+
*/
131+
132+
public void testSerializeReadOnlyPrimitiveTypeProperty() throws Exception {
133+
String json = MAPPER.writeValueAsString(new RecordWithReadOnlyPrimitiveType(123, "Bob"));
134+
assertEquals(a2q("{'id':123,'name':'Bob'}"), json);
135+
}
136+
137+
public void testDeserializeReadOnlyPrimitiveTypeProperty() throws Exception {
138+
RecordWithReadOnlyPrimitiveType value = MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"), RecordWithReadOnlyPrimitiveType.class);
139+
assertEquals(new RecordWithReadOnlyPrimitiveType(0, "Bob"), value);
140+
}
141+
142+
/*
143+
/**********************************************************************
144+
/* Test methods, JsonProperty.access=READ_ONLY all parameters
145+
/**********************************************************************
146+
*/
147+
148+
public void testSerializeReadOnlyAllProperties() throws Exception {
149+
String json = MAPPER.writeValueAsString(new RecordWithReadOnlyAll(123, "Bob"));
150+
assertEquals(a2q("{'id':123,'name':'Bob'}"), json);
151+
}
152+
153+
public void testDeserializeReadOnlyAllProperties() throws Exception {
154+
try {
155+
MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"), RecordWithReadOnlyAll.class);
156+
fail("should not pass");
157+
} catch (InvalidDefinitionException e) {
158+
verifyException(e, "Cannot construct instance");
159+
verifyException(e, "RecordWithReadOnlyAll");
160+
verifyException(e, "no Creators, like default constructor, exist");
161+
verifyException(e, "cannot deserialize from Object value");
162+
}
163+
}
164+
165+
public void testSerializeReadOnlyAllProperties_WithNoArgConstructor() throws Exception {
166+
String json = MAPPER.writeValueAsString(new RecordWithReadOnlyAllAndNoArgConstructor(123, "Bob"));
167+
assertEquals(a2q("{'id':123,'name':'Bob'}"), json);
168+
}
169+
170+
public void testDeserializeReadOnlyAllProperties_WithNoArgConstructor() throws Exception {
171+
RecordWithReadOnlyAllAndNoArgConstructor value = MAPPER.readValue(a2q("{'id':123,'name':'Bob'}"), RecordWithReadOnlyAllAndNoArgConstructor.class);
172+
assertEquals(new RecordWithReadOnlyAllAndNoArgConstructor(), value);
173+
}
174+
}

0 commit comments

Comments
 (0)