1
+ package com .fasterxml .jackson .databind .introspect ;
2
+
3
+ import org .junit .jupiter .api .Test ;
4
+
5
+ import com .fasterxml .jackson .annotation .JsonPropertyOrder ;
6
+ import com .fasterxml .jackson .databind .*;
7
+ import com .fasterxml .jackson .databind .testutil .DatabindTestUtil ;
8
+
9
+ import static org .junit .jupiter .api .Assertions .*;
10
+
11
+ // [databind#5152] Support "iPhone" style capitalized properties
12
+ public class IPhoneStyleProperty5152Test
13
+ extends DatabindTestUtil
14
+ {
15
+ static class IPhoneBean {
16
+ private String iPhone ;
17
+
18
+ public String getIPhone () {
19
+ return iPhone ;
20
+ }
21
+
22
+ public void setIPhone (String value ) {
23
+ iPhone = value ;
24
+ }
25
+ }
26
+
27
+ static class RegularBean {
28
+ private String phoneNumber ;
29
+
30
+ public String getPhoneNumber () {
31
+ return phoneNumber ;
32
+ }
33
+
34
+ public void setPhoneNumber (String value ) {
35
+ phoneNumber = value ;
36
+ }
37
+ }
38
+
39
+
40
+ static class DLogHeaderBean {
41
+ private String DLogHeader ;
42
+
43
+ public String getDLogHeader () {
44
+ return DLogHeader ;
45
+ }
46
+
47
+ public void setDLogHeader (String value ) {
48
+ DLogHeader = value ;
49
+ }
50
+ }
51
+
52
+ static class KBSBroadCastingBean {
53
+ private String KBSBroadCasting ;
54
+
55
+ public String getKBSBroadCasting () {
56
+ return KBSBroadCasting ;
57
+ }
58
+
59
+ public void setKBSBroadCasting (String value ) {
60
+ KBSBroadCasting = value ;
61
+ }
62
+ }
63
+
64
+ static class PhoneBean {
65
+ private String Phone ;
66
+
67
+ public String getPhone () {
68
+ return Phone ;
69
+ }
70
+ public void setPhone (String value ) {
71
+ Phone = value ;
72
+ }
73
+ }
74
+
75
+ @ JsonPropertyOrder ({ "4Roses" , "$dollar" , "_underscore" })
76
+ static class NonLetterFirstCharBean {
77
+ private String _4Roses ;
78
+ private String $dollar ;
79
+ private String _underscore ;
80
+
81
+ public String get4Roses () {
82
+ return _4Roses ;
83
+ }
84
+
85
+ public void set4Roses (String value ) {
86
+ _4Roses = value ;
87
+ }
88
+
89
+ public String get$dollar () {
90
+ return $dollar ;
91
+ }
92
+
93
+ public void set$dollar (String value ) {
94
+ $dollar = value ;
95
+ }
96
+
97
+ public String get_underscore () {
98
+ return _underscore ;
99
+ }
100
+
101
+ public void set_underscore (String value ) {
102
+ _underscore = value ;
103
+ }
104
+ }
105
+
106
+ private final ObjectMapper ENABLED = jsonMapperBuilder ()
107
+ .enable (MapperFeature .MIXED_CAPS_PROPERTY_NAMING )
108
+ .build ();
109
+
110
+ private final ObjectMapper ENABLED_WITH_VALIDATION = jsonMapperBuilder ()
111
+ .enable (MapperFeature .MIXED_CAPS_PROPERTY_NAMING )
112
+ .accessorNaming (new DefaultAccessorNamingStrategy .Provider ()
113
+ .withFirstCharAcceptance (false , false )) // Don't allow lowercase or non-letter first chars
114
+ .build ();
115
+
116
+ @ Test
117
+ public void testIPhoneStyleProperty () throws Exception {
118
+ // Test with iPhone style property
119
+ String json = "{\" iPhone\" :\" iPhone 15\" }" ;
120
+ IPhoneBean result = ENABLED .readValue (json , IPhoneBean .class );
121
+ assertNotNull (result );
122
+ assertEquals ("iPhone 15" , result .getIPhone ());
123
+
124
+ // Test serialization
125
+ String serialized = ENABLED .writeValueAsString (result );
126
+ assertEquals ("{\" iPhone\" :\" iPhone 15\" }" , serialized );
127
+ }
128
+
129
+ @ Test
130
+ public void testRegularPojoProperty () throws Exception {
131
+ // Test with regular POJO property
132
+ String json = "{\" phoneNumber\" :\" 123-456-7890\" }" ;
133
+ RegularBean result = ENABLED .readValue (json , RegularBean .class );
134
+ assertNotNull (result );
135
+ assertEquals ("123-456-7890" , result .getPhoneNumber ());
136
+
137
+ // Test serialization
138
+ String serialized = ENABLED .writeValueAsString (result );
139
+ assertEquals ("{\" phoneNumber\" :\" 123-456-7890\" }" , serialized );
140
+ }
141
+
142
+
143
+ @ Test
144
+ public void testDLogHeaderStyleProperty () throws Exception {
145
+ // Test with DLogHeader style property
146
+ String json = "{\" dLogHeader\" :\" Debug Log Header\" }" ;
147
+ DLogHeaderBean result = ENABLED .readValue (json , DLogHeaderBean .class );
148
+ assertNotNull (result );
149
+ assertEquals ("Debug Log Header" , result .getDLogHeader ());
150
+
151
+ // Test serialization
152
+ String serialized = ENABLED .writeValueAsString (result );
153
+ assertEquals ("{\" dLogHeader\" :\" Debug Log Header\" }" , serialized );
154
+ }
155
+
156
+ @ Test
157
+ public void testKBSBroadCastingStyleProperty () throws Exception {
158
+ // Test with KBSBroadCasting style property
159
+ String json = "{\" KBSBroadCasting\" :\" Korean Broadcasting System\" }" ;
160
+ KBSBroadCastingBean result = ENABLED .readValue (json , KBSBroadCastingBean .class );
161
+ assertNotNull (result );
162
+ assertEquals ("Korean Broadcasting System" , result .getKBSBroadCasting ());
163
+
164
+ // Test serialization
165
+ String serialized = ENABLED .writeValueAsString (result );
166
+ assertEquals ("{\" KBSBroadCasting\" :\" Korean Broadcasting System\" }" , serialized );
167
+ }
168
+
169
+ @ Test
170
+ public void testNonLetterFirstCharWithValidation () throws Exception {
171
+ // Test with validation enabled - should ignore properties starting with non-letters
172
+ NonLetterFirstCharBean result = ENABLED_WITH_VALIDATION .reader ()
173
+ .without (DeserializationFeature .FAIL_ON_UNKNOWN_PROPERTIES )
174
+ .readValue ("{\" 4Roses\" :\" Four Roses\" ,\" $dollar\" :\" Dollar\" ,\" _underscore\" :\" Underscore\" }" ,
175
+ NonLetterFirstCharBean .class );
176
+ assertNotNull (result );
177
+ assertNull (result .get4Roses ());
178
+ assertNull (result .get$dollar ());
179
+ assertNull (result .get_underscore ());
180
+
181
+ // Test serialization - should not include properties starting with non-letters
182
+ String serialized = ENABLED_WITH_VALIDATION .writeValueAsString (result );
183
+ assertEquals ("{}" , serialized );
184
+ }
185
+
186
+ @ Test
187
+ public void testNonLetterFirstCharWithoutValidation () throws Exception {
188
+ // Test without validation - should accept properties starting with non-letters
189
+ NonLetterFirstCharBean result = ENABLED .readValue (
190
+ "{\" 4Roses\" :\" Four Roses\" ,\" $dollar\" :\" Dollar\" ,\" _underscore\" :\" Underscore\" }" ,
191
+ NonLetterFirstCharBean .class );
192
+ assertNotNull (result );
193
+ assertEquals ("Four Roses" , result .get4Roses ());
194
+ assertEquals ("Dollar" , result .get$dollar ());
195
+ assertEquals ("Underscore" , result .get_underscore ());
196
+
197
+ // Test serialization
198
+ String serialized = ENABLED .writeValueAsString (result );
199
+ assertEquals ("{\" 4Roses\" :\" Four Roses\" ,\" $dollar\" :\" Dollar\" ,\" _underscore\" :\" Underscore\" }" , serialized );
200
+ }
201
+
202
+ @ Test
203
+ public void testPhoneStyleProperty () throws Exception {
204
+ // Test with Phone style property
205
+ String json = "{\" Phone\" :\" iPhone 15\" }" ;
206
+ PhoneBean result = ENABLED .readValue (json , PhoneBean .class );
207
+ assertNotNull (result );
208
+ assertEquals ("iPhone 15" , result .getPhone ());
209
+
210
+ // Test serialization
211
+ String serialized = ENABLED .writeValueAsString (result );
212
+ assertEquals ("{\" Phone\" :\" iPhone 15\" }" , serialized );
213
+ }
214
+
215
+ }
0 commit comments