1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.json;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.commons.utils.CollectionUtils.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.net.*;
24 import java.util.*;
25
26 import org.apache.juneau.*;
27 import org.apache.juneau.annotation.*;
28 import org.apache.juneau.collections.*;
29 import org.junit.jupiter.api.*;
30
31 class Common_Test extends TestBase {
32
33
34
35
36 @Test void a01_trimNullsFromBeans() throws Exception {
37 var s = JsonSerializer.create().json5();
38 var p = JsonParser.DEFAULT;
39 var t1 = A.create();
40
41 var r = s.build().serialize(t1);
42 assertEquals("{s2:'s2'}", r);
43 var t2 = p.parse(r, A.class);
44 assertEquals(json(t2), json(t1));
45
46 s.keepNullProperties();
47 r = s.build().serialize(t1);
48 assertEquals("{s1:null,s2:'s2'}", r);
49 t2 = p.parse(r, A.class);
50 assertEquals(json(t2), json(t1));
51 }
52
53 public static class A {
54 public String s1, s2;
55
56 public static A create() {
57 var t = new A();
58 t.s2 = "s2";
59 return t;
60 }
61 }
62
63
64
65
66 @Test void a02_trimEmptyMaps() throws Exception {
67 var s = JsonSerializer.create().json5();
68 var p = JsonParser.DEFAULT;
69 var t1 = B.create();
70 var r = s.build().serialize(t1);
71
72 assertEquals("{f1:{},f2:{f2a:null,f2b:{s2:'s2'}}}", r);
73 var t2 = p.parse(r, B.class);
74 assertEquals(json(t2), json(t1));
75
76 s.trimEmptyMaps();
77 r = s.build().serialize(t1);
78 assertEquals("{f2:{f2a:null,f2b:{s2:'s2'}}}", r);
79 t2 = p.parse(r, B.class);
80 assertNull(t2.f1);
81 }
82
83 public static class B {
84 public TreeMap<String,A> f1, f2;
85
86 public static B create() {
87 var t = new B();
88 t.f1 = new TreeMap<>();
89 t.f2 = new TreeMap<>(){{put("f2a",null);put("f2b",A.create());}};
90 return t;
91 }
92 }
93
94
95
96
97 @Test void a03_trimEmptyLists() throws Exception {
98 var s = JsonSerializer.create().json5();
99 var p = JsonParser.DEFAULT;
100 var t1 = C.create();
101 var r = s.build().serialize(t1);
102
103 assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
104 var t2 = p.parse(r, C.class);
105 assertEquals(json(t2), json(t1));
106
107 s.trimEmptyCollections();
108 r = s.build().serialize(t1);
109 assertEquals("{f2:[null,{s2:'s2'}]}", r);
110 t2 = p.parse(r, C.class);
111 assertNull(t2.f1);
112 }
113
114 public static class C {
115 public List<A> f1, f2;
116
117 public static C create() {
118 var t = new C();
119 t.f1 = l();
120 t.f2 = l(null,A.create());
121 return t;
122 }
123 }
124
125
126
127
128 @Test void a04_trimEmptyArrays() throws Exception {
129 var s = JsonSerializer.create().json5();
130 var p = JsonParser.DEFAULT;
131 var t1 = D.create();
132 var r = s.build().serialize(t1);
133
134 assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
135 var t2 = p.parse(r, D.class);
136 assertEquals(json(t2), json(t1));
137
138 s.trimEmptyCollections();
139 r = s.build().serialize(t1);
140 assertEquals("{f2:[null,{s2:'s2'}]}", r);
141 t2 = p.parse(r, D.class);
142 assertNull(t2.f1);
143 }
144
145 public static class D {
146 public A[] f1, f2;
147
148 public static D create() {
149 var t = new D();
150 t.f1 = a();
151 t.f2 = a(null, A.create());
152 return t;
153 }
154 }
155
156
157
158
159 @Test void a05_beanPropertyProperies() throws Exception {
160 var s = Json5Serializer.DEFAULT;
161 var t = new E1();
162 var r = s.serialize(t);
163
164 assertEquals("{x1:{f1:1},x2:{f1:1},x3:[{f1:1}],x4:[{f1:1}],x5:[{f1:1}],x6:[{f1:1}]}", r);
165 r = s.getSchemaSerializer().serialize(t);
166 assertEquals(r.indexOf("f2"), -1);
167 }
168
169 public static class E1 {
170 @Beanp(properties="f1") public E2 x1 = new E2();
171 @Beanp(properties="f1") public Map<String,Integer> x2 = m("f1",1,"f2",2);
172 @Beanp(properties="f1") public E2[] x3 = {new E2()};
173 @Beanp(properties="f1") public List<E2> x4 = l(new E2());
174 @Beanp(properties="f1") public JsonMap[] x5 = {JsonMap.of("f1",1,"f2",2)};
175 @Beanp(properties="f1") public List<JsonMap> x6 = l(JsonMap.of("f1",1,"f2",2));
176 }
177
178 public static class E2 {
179 public int f1 = 1;
180 public int f2 = 2;
181 }
182
183
184
185
186 @Test void a06_beanPropertyProperiesOnListOfBeans() throws Exception {
187 var s = Json5Serializer.DEFAULT;
188 var l = new LinkedList<>();
189 var t = new F();
190 t.x1.add(new F());
191 l.add(t);
192 var json = s.serialize(l);
193 assertEquals("[{x1:[{x2:2}],x2:2}]", json);
194 }
195
196 public static class F {
197 @Beanp(properties="x2") public List<F> x1 = new LinkedList<>();
198 public int x2 = 2;
199 }
200
201
202
203
204 @Test void a07_uRIAttr() throws Exception {
205 var s = Json5Serializer.DEFAULT;
206 var p = JsonParser.DEFAULT;
207
208 var t = new G();
209 t.uri = new URI("http://uri");
210 t.f1 = new URI("http://f1");
211 t.f2 = url("http://f2");
212
213 var json = s.serialize(t);
214 t = p.parse(json, G.class);
215 assertEquals("http://uri", t.uri.toString());
216 assertEquals("http://f1", t.f1.toString());
217 assertEquals("http://f2", t.f2.toString());
218 }
219
220 public static class G {
221 public URI uri;
222 public URI f1;
223 public URL f2;
224 }
225
226
227
228
229 @Test void a08_recursion() throws Exception {
230 var s = JsonSerializer.create().json5().maxDepth(Integer.MAX_VALUE);
231
232 var r1 = new R1();
233 var r2 = new R2();
234 var r3 = new R3();
235 r1.r2 = r2;
236 r2.r3 = r3;
237 r3.r1 = r1;
238
239
240 assertThrowsWithMessage(Exception.class, "It's recommended you use the BeanTraverseContext.BEANTRAVERSE_detectRecursions setting to help locate the loop.", ()->s.build().serialize(r1));
241
242
243 s.detectRecursions();
244 assertThrowsWithMessage(Exception.class, "$R1", ()->s.build().serialize(r1));
245
246 s.ignoreRecursions();
247 assertEquals("{name:'foo',r2:{name:'bar',r3:{name:'baz'}}}", s.build().serialize(r1));
248
249
250 s.build().getSchemaSerializer().serialize(r1);
251 }
252
253 public static class R1 {
254 public String name = "foo";
255 public R2 r2;
256 }
257 public static class R2 {
258 public String name = "bar";
259 public R3 r3;
260 }
261 public static class R3 {
262 public String name = "baz";
263 public R1 r1;
264 }
265
266
267
268
269 @Test void a09_basicBean() throws Exception {
270 var s = JsonSerializer.create().json5().keepNullProperties().sortProperties().build();
271
272 var a = new J();
273 a.setF1("J");
274 a.setF2(100);
275 a.setF3(true);
276 assertEquals("{f1:'J',f2:100,f3:true}", s.serialize(a));
277 }
278
279 public static class J {
280 private String f1;
281 public String getF1() { return f1; }
282 public void setF1(String v) { f1 = v; }
283
284 private int f2 = -1;
285 public int getF2() { return f2; }
286 public void setF2(int v) { f2 = v; }
287
288 private boolean f3;
289 public boolean isF3() { return f3; }
290 public void setF3(boolean v) { f3 = v; }
291
292 @Override
293 public String toString() {
294 return ("J(f1: " + this.getF1() + ", f2: " + this.getF2() + ")");
295 }
296 }
297
298
299
300
301
302 @Test
303 void a10_beanpFormat() throws Exception {
304 var s = JsonSerializer.create().json5().sortProperties().build();
305
306 var bean = new K();
307 var json = s.serialize(bean);
308
309
310 assertTrue(json.contains("floatField:'3.14'"));
311 assertTrue(json.contains("floatWithCurrency:'$19.99'"));
312 assertTrue(json.contains("doubleField:'2.718'"));
313 assertTrue(json.contains("privateField:'9.88'"));
314 assertTrue(json.contains("intField:'00042'"));
315 assertTrue(json.contains("longField:'0000001234567890'"));
316 assertTrue(json.contains("hexField:'0xFF00FF'"));
317 assertTrue(json.contains("scientificField:'6.022e+23'") || json.contains("scientificField:'6.022E+23'"));
318 assertTrue(json.contains("name:'Test'"));
319 }
320
321 public static class K {
322 @Beanp(format="%.2f")
323 public float floatField = 3.14159f;
324
325 @Beanp(format="$%.2f")
326 public float floatWithCurrency = 19.987f;
327
328 @Beanp(format="%.3f")
329 public double doubleField = 2.71828;
330
331 @Beanp(format="%05d")
332 public int intField = 42;
333
334 @Beanp(format="%016d")
335 public long longField = 1234567890L;
336
337 @Beanp(format="0x%06X")
338 public int hexField = 0xFF00FF;
339
340 @Beanp(format="%.3e")
341 public double scientificField = 6.02214076e23;
342
343 public String name = "Test";
344
345 @Beanp(format="%.2f")
346 private float privateField = 9.876f;
347
348 public float getPrivateField() { return privateField; }
349 public void setPrivateField(float f) { privateField = f; }
350 }
351 }