xref: /aosp_15_r20/external/jackson-annotations/src/test/java/com/fasterxml/jackson/annotation/FormatTest.java (revision 2bf6642460ffb10303bd46207a4555f36d9e5945)
1 package com.fasterxml.jackson.annotation;
2 
3 import com.fasterxml.jackson.annotation.JsonFormat.Feature;
4 import com.fasterxml.jackson.annotation.JsonFormat.Shape;
5 
6 /**
7  * Tests to verify that it is possibly to merge {@link JsonFormat.Value}
8  * instances for overrides.
9  */
10 public class FormatTest extends TestBase
11 {
12     private final JsonFormat.Value EMPTY = JsonFormat.Value.empty();
13 
14     @JsonFormat(shape=JsonFormat.Shape.BOOLEAN, pattern="xyz", timezone="bogus")
15     private final static class Bogus { }
16 
testEmptyInstanceDefaults()17     public void testEmptyInstanceDefaults() {
18         JsonFormat.Value empty = JsonFormat.Value.empty();
19         for (Feature f : Feature.values()) {
20             assertNull(empty.getFeature(f));
21         }
22         assertFalse(empty.hasLocale());
23         assertFalse(empty.hasPattern());
24         assertFalse(empty.hasShape());
25         assertFalse(empty.hasTimeZone());
26         assertFalse(empty.hasLenient());
27 
28         assertFalse(empty.isLenient());
29     }
30 
testEquality()31     public void testEquality() {
32         assertTrue(EMPTY.equals(EMPTY));
33         assertTrue(new JsonFormat.Value().equals(new JsonFormat.Value()));
34 
35         JsonFormat.Value v1 = JsonFormat.Value.forShape(Shape.BOOLEAN);
36         JsonFormat.Value v2 = JsonFormat.Value.forShape(Shape.BOOLEAN);
37         JsonFormat.Value v3 = JsonFormat.Value.forShape(Shape.SCALAR);
38 
39         assertTrue(v1.equals(v2));
40         assertTrue(v2.equals(v1));
41 
42         assertFalse(v1.equals(v3));
43         assertFalse(v3.equals(v1));
44         assertFalse(v2.equals(v3));
45         assertFalse(v3.equals(v2));
46 
47         // not strictly guaranteed but...
48         assertFalse(v1.hashCode() == v3.hashCode());
49 
50         // then let's converge
51         assertEquals(v1, v3.withShape(Shape.BOOLEAN));
52         assertFalse(v1.equals(v1.withPattern("ZBC")));
53         assertFalse(v1.equals(v1.withFeature(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)));
54         assertFalse(v1.equals(v1.withoutFeature(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)));
55     }
56 
testToString()57     public void testToString() {
58         assertEquals("JsonFormat.Value(pattern=,shape=STRING,lenient=null,locale=null,timezone=null,features=EMPTY)",
59                 JsonFormat.Value.forShape(JsonFormat.Shape.STRING).toString());
60         assertEquals("JsonFormat.Value(pattern=[.],shape=ANY,lenient=null,locale=null,timezone=null,features=EMPTY)",
61                 JsonFormat.Value.forPattern("[.]").toString());
62     }
63 
testFromAnnotation()64     public void testFromAnnotation()
65     {
66         JsonFormat ann = Bogus.class.getAnnotation(JsonFormat.class);
67         JsonFormat.Value v = JsonFormat.Value.from(ann);
68         assertEquals("xyz", v.getPattern());
69         assertEquals(JsonFormat.Shape.BOOLEAN, v.getShape());
70         // note: since it's not valid, should not try access as real thing
71         assertEquals("bogus", v.timeZoneAsString());
72 
73         // also:
74         assertSame(EMPTY, JsonFormat.Value.from(null));
75     }
76 
testSimpleMerge()77     public void testSimpleMerge()
78     {
79         // Start with an empty instance
80         assertFalse(EMPTY.hasLocale());
81         assertFalse(EMPTY.hasPattern());
82         assertFalse(EMPTY.hasShape());
83         assertFalse(EMPTY.hasTimeZone());
84 
85         assertNull(EMPTY.getLocale());
86 
87         // then with a non-empty one
88         final String TEST_PATTERN = "format-string"; // not parsed, usage varies
89 
90         JsonFormat.Value v = JsonFormat.Value.forPattern(TEST_PATTERN);
91         assertTrue(v.hasPattern());
92         assertEquals(TEST_PATTERN, v.getPattern());
93         assertFalse(v.hasLocale());
94         assertFalse(v.hasShape());
95         assertFalse(v.hasTimeZone());
96 
97         // and ensure nothing overridden with empty
98         JsonFormat.Value merged = v.withOverrides(EMPTY);
99         assertEquals(TEST_PATTERN, merged.getPattern());
100         assertFalse(merged.hasLocale());
101         assertFalse(merged.hasShape());
102         assertFalse(merged.hasTimeZone());
103 
104         // minor optimization: overriding with itself has no effect
105         assertSame(merged, merged.withOverrides(merged));
106 
107         // but that empty is overridden
108         merged = JsonFormat.Value.merge(EMPTY, v);
109         assertEquals(TEST_PATTERN, merged.getPattern());
110         assertFalse(merged.hasLocale());
111         assertFalse(merged.hasShape());
112         assertFalse(merged.hasTimeZone());
113 
114         // also some shortcuts:
115         assertSame(merged, merged.withOverrides(null));
116 
117         // then with some other combinations
118         final JsonFormat.Shape TEST_SHAPE = JsonFormat.Shape.NUMBER;
119         JsonFormat.Value v2 = JsonFormat.Value.forShape(TEST_SHAPE);
120 
121         merged = v.withOverrides(v2);
122         assertEquals(TEST_PATTERN, merged.getPattern());
123         assertFalse(merged.hasLocale());
124         assertEquals(TEST_SHAPE, merged.getShape());
125         assertFalse(merged.hasTimeZone());
126 
127         merged = v2.withOverrides(v);
128         assertEquals(TEST_PATTERN, merged.getPattern());
129         assertFalse(merged.hasLocale());
130         assertEquals(TEST_SHAPE, merged.getShape());
131         assertFalse(merged.hasTimeZone());
132     }
133 
testMultiMerge()134     public void testMultiMerge()
135     {
136         final String TEST_PATTERN = "format-string"; // not parsed, usage varies
137         JsonFormat.Value format2 = JsonFormat.Value.forPattern(TEST_PATTERN);
138         JsonFormat.Value format3 = JsonFormat.Value.forLeniency(Boolean.FALSE);
139 
140         JsonFormat.Value merged = JsonFormat.Value.mergeAll(EMPTY, format2, format3);
141         assertEquals(TEST_PATTERN, merged.getPattern());
142         assertEquals(Boolean.FALSE, merged.getLenient());
143     }
144 
145     /*
146     /**********************************************************
147     /* Test specific value properties
148     /**********************************************************
149      */
150 
testLeniency()151     public void testLeniency() {
152         JsonFormat.Value empty = JsonFormat.Value.empty();
153         assertFalse(empty.hasLenient());
154         assertFalse(empty.isLenient());
155         assertNull(empty.getLenient());
156 
157         JsonFormat.Value lenient = empty.withLenient(Boolean.TRUE);
158         assertTrue(lenient.hasLenient());
159         assertTrue(lenient.isLenient());
160         assertEquals(Boolean.TRUE, lenient.getLenient());
161         assertTrue(lenient.equals(lenient));
162         assertFalse(empty.equals(lenient));
163         assertFalse(lenient.equals(empty));
164 
165         // should NOT create now one if no change:
166         assertSame(lenient, lenient.withLenient(Boolean.TRUE));
167 
168         JsonFormat.Value strict = lenient.withLenient(Boolean.FALSE);
169         assertTrue(strict.hasLenient());
170         assertFalse(strict.isLenient());
171         assertEquals(Boolean.FALSE, strict.getLenient());
172         assertTrue(strict.equals(strict));
173         assertFalse(empty.equals(strict));
174         assertFalse(strict.equals(empty));
175         assertFalse(lenient.equals(strict));
176         assertFalse(strict.equals(lenient));
177 
178         // and finally, can also clear up setting
179         JsonFormat.Value dunno = lenient.withLenient(null);
180         assertFalse(dunno.hasLenient());
181         assertFalse(dunno.isLenient());
182         assertNull(dunno.getLenient());
183         assertTrue(empty.equals(dunno));
184         assertTrue(dunno.equals(empty));
185         assertFalse(lenient.equals(dunno));
186         assertFalse(dunno.equals(lenient));
187     }
188 
testCaseInsensitiveValues()189     public void testCaseInsensitiveValues() {
190         JsonFormat.Value empty = JsonFormat.Value.empty();
191         assertNull(empty.getFeature(Feature.ACCEPT_CASE_INSENSITIVE_VALUES));
192 
193         JsonFormat.Value insensitive = empty.withFeature(Feature.ACCEPT_CASE_INSENSITIVE_VALUES);
194         assertTrue(insensitive.getFeature(Feature.ACCEPT_CASE_INSENSITIVE_VALUES));
195 
196         JsonFormat.Value sensitive = empty.withoutFeature(Feature.ACCEPT_CASE_INSENSITIVE_VALUES);
197         assertFalse(sensitive.getFeature(Feature.ACCEPT_CASE_INSENSITIVE_VALUES));
198     }
199 
testShape()200     public void testShape() {
201         assertFalse(JsonFormat.Shape.STRING.isNumeric());
202         assertFalse(JsonFormat.Shape.STRING.isStructured());
203 
204         assertTrue(JsonFormat.Shape.NUMBER_INT.isNumeric());
205         assertTrue(JsonFormat.Shape.NUMBER_FLOAT.isNumeric());
206         assertTrue(JsonFormat.Shape.NUMBER.isNumeric());
207 
208         assertTrue(JsonFormat.Shape.ARRAY.isStructured());
209         assertTrue(JsonFormat.Shape.OBJECT.isStructured());
210     }
211 
testFeatures()212     public void testFeatures() {
213         JsonFormat.Features f1 = JsonFormat.Features.empty();
214         JsonFormat.Features f2 = f1.with(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
215                 .without(Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
216         assertTrue(f1.equals(f1));
217         assertFalse(f1.equals(f2));
218         assertFalse(f1.equals(null));
219         assertFalse(f1.equals("foo"));
220 
221         assertNull(f1.get(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
222         assertEquals(Boolean.TRUE, f2.get(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
223 
224         assertNull(f1.get(Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS));
225         assertEquals(Boolean.FALSE, f2.get(Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS));
226 
227         JsonFormat.Features f3 = f1.withOverrides(f2);
228         assertEquals(Boolean.TRUE, f3.get(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
229         assertEquals(Boolean.FALSE, f3.get(Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS));
230 
231         // switch values around
232         JsonFormat.Features f4 = JsonFormat.Features.construct(
233                 new Feature[] { // enabled:
234                         Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS
235         }, new Feature[] { // enabled
236                 Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY
237         });
238         assertEquals(Boolean.FALSE, f4.get(Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY));
239         assertEquals(Boolean.TRUE, f4.get(Feature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS));
240     }
241 }
242