View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.juneau.httppart;
18  
19  import static java.lang.String.*;
20  import static org.apache.juneau.TestUtils.*;
21  import static org.apache.juneau.common.utils.StringUtils.*;
22  import static org.apache.juneau.httppart.HttpPartSchema.*;
23  import static org.junit.jupiter.api.Assertions.*;
24  
25  import java.util.*;
26  
27  import org.apache.juneau.*;
28  import org.apache.juneau.collections.*;
29  import org.apache.juneau.common.utils.*;
30  import org.apache.juneau.oapi.*;
31  import org.apache.juneau.serializer.*;
32  import org.junit.jupiter.api.*;
33  
34  class OpenApiPartSerializer_Test extends TestBase {
35  
36  	static OpenApiSerializerSession s = OpenApiSerializer.DEFAULT.getSession();
37  
38  	private static String serialize(HttpPartSchema schema, Object o) throws SchemaValidationException, SerializeException {
39  		return s.serialize(null, schema, o);
40  	}
41  
42  	//-----------------------------------------------------------------------------------------------------------------
43  	// Input validations
44  	//-----------------------------------------------------------------------------------------------------------------
45  
46  	@Test void a01_outputValidations_nullOutput() throws Exception {
47  		assertEquals("null", serialize(T_NONE, null));
48  		assertEquals("null", serialize(tNone().required(false).build(), null));
49  		assertThrowsWithMessage(SchemaValidationException.class, "Required value not provided.", ()->serialize(tNone().required().build(), null));
50  		assertThrowsWithMessage(SchemaValidationException.class, "Required value not provided.", ()->serialize(tNone().required(true).build(), null));
51  	}
52  
53  	@Test void a02_outputValidations_emptyOutput() throws Exception {
54  		assertEquals("", serialize(tNone().allowEmptyValue().build(), ""));
55  		assertEquals("", serialize(tNone().allowEmptyValue().build(), ""));
56  		assertThrowsWithMessage(SchemaValidationException.class, "Empty value not allowed.", ()->serialize(tNone().allowEmptyValue(false).build(), ""));
57  		assertThrowsWithMessage(SchemaValidationException.class, "Empty value not allowed.", ()->serialize(tNone().allowEmptyValue(false).build(), ""));
58  		assertEquals(" ", serialize(tNone().allowEmptyValue(false).build(), " "));
59  	}
60  
61  	@Test void a03_outputValidations_pattern() throws Exception {
62  		var ps = tNone().pattern("x.*").allowEmptyValue().build();
63  		assertEquals("x", serialize(ps, "x"));
64  		assertEquals("xx", serialize(ps, "xx"));
65  		assertEquals("null", serialize(ps, null));
66  
67  		assertThrowsWithMessage(SchemaValidationException.class, "Value does not match expected pattern.  Must match pattern: x.*", ()->serialize(ps, "y"));
68  		assertThrowsWithMessage(SchemaValidationException.class, "Value does not match expected pattern.  Must match pattern: x.*", ()->serialize(ps, ""));
69  
70  		// Blank/null patterns are ignored.
71  		assertEquals("x", serialize(tNone().pattern("").allowEmptyValue().build(), "x"));
72  		assertEquals("x", serialize(tNone().pattern(null).allowEmptyValue().build(), "x"));
73  	}
74  
75  	@Test void a04_outputValidations_enum() throws Exception {
76  		var ps = tNone()._enum("foo").allowEmptyValue().build();
77  
78  		assertEquals("foo", serialize(ps, "foo"));
79  		assertEquals("null", serialize(ps, null));
80  
81  		assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values.  Must be one of the following:  foo", ()->serialize(ps, "bar"));
82  		assertThrowsWithMessage(SchemaValidationException.class, "Value does not match one of the expected values.  Must be one of the following:  foo", ()->serialize(ps, ""));
83  
84  		assertEquals("foo", serialize(tNone()._enum((Set<String>)null).build(), "foo"));
85  		assertEquals("foo", serialize(tNone()._enum((Set<String>)null).allowEmptyValue().build(), "foo"));
86  		assertEquals("foo", serialize(tNone()._enum("foo","foo").build(), "foo"));
87  	}
88  
89  	@Test void a05_outputValidations_minMaxLength() throws Exception {
90  		var ps = tNone().minLength(1L).maxLength(2L).allowEmptyValue().build();
91  
92  		assertEquals("null", serialize(ps, null));
93  		assertEquals("1", serialize(ps, "1"));
94  		assertEquals("12", serialize(ps, "12"));
95  
96  		assertThrowsWithMessage(SchemaValidationException.class, "Minimum length of value not met.", ()->serialize(ps, ""));
97  		assertThrowsWithMessage(SchemaValidationException.class, "Maximum length of value exceeded.", ()->serialize(ps, "123"));
98  	}
99  
100 	//-----------------------------------------------------------------------------------------------------------------
101 	// type = string
102 	//-----------------------------------------------------------------------------------------------------------------
103 
104 	public static class C1 {
105 		private byte[] f;
106 		public C1(byte[] f) {
107 			this.f = f;
108 		}
109 		public byte[] toByteArray() {
110 			return f;
111 		}
112 	}
113 
114 	public static class C2 {
115 		private String f;
116 		public C2(String s) {
117 			f = s;
118 		}
119 		@Override
120 		public String toString() {
121 			return f;
122 		}
123 	}
124 
125 	public static class C3 {
126 		private String[] f;
127 		public C3(String...in) {
128 			f = in;
129 		}
130 		public String[] toStringArray() {
131 			return f;
132 		}
133 	}
134 
135 
136 	@Test void c01_stringType_simple() throws Exception {
137 		var ps = T_STRING;
138 		assertEquals("foo", serialize(ps, "foo"));
139 	}
140 
141 	@Test void c02_stringType_default() throws Exception {
142 		var ps = tString()._default("x").build();
143 		assertEquals("foo", serialize(ps, "foo"));
144 		assertEquals("x", serialize(ps, null));
145 	}
146 
147 	@Test void c03_stringType_byteFormat() throws Exception {
148 		var ps = T_BYTE;
149 		byte[] foob = "foo".getBytes();
150 		var expected = base64Encode(foob);
151 		assertEquals(expected, serialize(ps, foob));
152 		assertEquals(expected, serialize(ps, new C1(foob)));
153 		assertEquals("null", serialize(ps, new C1(null)));
154 		assertEquals("null", serialize(ps, null));
155 	}
156 
157 	@Test void c04_stringType_binaryFormat() throws Exception {
158 		var ps = T_BINARY;
159 		var foob = "foo".getBytes();
160 		var expected = toHex(foob);
161 		assertEquals(expected, serialize(ps, foob));
162 		assertEquals(expected, serialize(ps, new C1(foob)));
163 		assertEquals("null", serialize(ps, new C1(null)));
164 		assertEquals("null", serialize(ps, null));
165 	}
166 
167 	@Test void c05_stringType_binarySpacedFormat() throws Exception {
168 		var ps = T_BINARY_SPACED;
169 		var foob = "foo".getBytes();
170 		var expected = toSpacedHex(foob);
171 		assertEquals(expected, serialize(ps, foob));
172 		assertEquals(expected, serialize(ps, new C1(foob)));
173 		assertEquals("null", serialize(ps, new C1(null)));
174 		assertEquals("null", serialize(ps, null));
175 	}
176 
177 	@Test void c06_stringType_dateFormat() throws Exception {
178 		var ps = T_DATE;
179 		var in = StringUtils.parseIsoCalendar("2012-12-21");
180 		assertTrue(serialize(ps, in).contains("2012"));
181 		assertEquals("null", serialize(ps, null));
182 	}
183 
184 	@Test void c07_stringType_dateTimeFormat() throws Exception {
185 		var ps = T_DATETIME;
186 		var in = StringUtils.parseIsoCalendar("2012-12-21T12:34:56.789");
187 		assertTrue(serialize(ps, in).contains("2012"));
188 		assertEquals("null", serialize(ps, null));
189 	}
190 
191 	@Test void c08_stringType_uonFormat() throws Exception {
192 		var ps = T_UON;
193 		assertEquals("foo", serialize(ps, "foo"));
194 		assertEquals("~'foo~'", serialize(ps, "'foo'"));
195 		assertEquals("foo", serialize(ps, new C2("foo")));
196 		assertEquals("null", serialize(ps, new C2(null)));
197 		assertEquals("'null'", serialize(ps, new C2("null")));
198 		assertEquals("null", serialize(ps, null));
199 		// UonPartSerializerTest should handle all other cases.
200 	}
201 
202 	@Test void c09_stringType_noneFormat() throws Exception {
203 		// If no format is specified, then we should transform directly from a string.
204 		var ps = T_STRING;
205 		assertEquals("foo", serialize(ps, "foo"));
206 		assertEquals("'foo'", serialize(ps, "'foo'"));
207 		assertEquals("foo", serialize(ps, new C2("foo")));
208 		assertEquals("null", serialize(ps, new C2(null)));
209 		assertEquals("null", serialize(ps, new C2("null")));
210 		assertEquals("null", serialize(ps, null));
211 	}
212 
213 	@Test void c10_stringType_noneFormat_2d() throws Exception {
214 		var ps = tArray(tString()).build();
215 		assertEquals("foo,bar,null", serialize(ps, new String[]{"foo","bar",null}));
216 		assertEquals("foo,bar,null", serialize(ps, list("foo","bar",null)));
217 		assertEquals("foo,bar,null", serialize(ps, new Object[]{"foo","bar",null}));
218 		assertEquals("foo,bar,null", serialize(ps, list((Object)"foo",(Object)"bar",null)));
219 		assertEquals("foo,bar,null,null", serialize(ps, new C2[]{new C2("foo"),new C2("bar"),new C2(null),null}));
220 		assertEquals("foo,bar,null,null", serialize(ps, list(new C2("foo"),new C2("bar"),new C2(null),null)));
221 		assertEquals("foo,bar,null", serialize(ps, new C3("foo","bar",null)));
222 	}
223 
224 	@Test void c11_stringType_noneFormat_3d() throws Exception {
225 		var ps = tArrayPipes(tArray(tString())).build();
226 		assertEquals("foo,bar|baz,null|null", serialize(ps, new String[][]{{"foo","bar"},{"baz",null},null}));
227 		assertEquals("foo,bar|baz,null|null", serialize(ps, list(new String[]{"foo","bar"}, new String[]{"baz",null},null)));
228 		assertEquals("foo,bar|baz,null|null", serialize(ps, list(list("foo","bar"),list("baz",null),null)));
229 		assertEquals("foo,bar|baz,null|null", serialize(ps, new Object[][]{{"foo","bar"},{"baz",null},null}));
230 		assertEquals("foo,bar|baz,null|null", serialize(ps, list(new Object[]{"foo","bar"}, new String[]{"baz",null},null)));
231 		assertEquals("foo,bar|baz,null|null", serialize(ps, list(list((Object)"foo",(Object)"bar"),list((Object)"baz",null),null)));
232 		assertEquals("foo,bar|baz,null,null|null", serialize(ps, new C2[][]{{new C2("foo"),new C2("bar")},{new C2("baz"),new C2(null),null},null}));
233 		assertEquals("foo,bar|baz,null,null|null", serialize(ps, list(new C2[]{new C2("foo"),new C2("bar")}, new C2[]{new C2("baz"),new C2(null),null},null)));
234 		assertEquals("foo,bar|baz,null,null|null", serialize(ps, list(list(new C2("foo"),new C2("bar")),list(new C2("baz"),new C2(null),null),null)));
235 		assertEquals("foo,bar|baz,null|null|null", serialize(ps, new C3[]{new C3("foo","bar"),new C3("baz",null),new C3((String)null),null}));
236 		assertEquals("foo,bar|baz,null|null|null", serialize(ps, list(new C3("foo","bar"),new C3("baz",null),new C3((String)null),null)));
237 	}
238 
239 	@Test void c12_stringType_uonKeywords_plain() throws Exception {
240 		var ps = T_STRING;
241 		// When serialized normally, the following should not be quoted.
242 		assertEquals("true", serialize(ps, "true"));
243 		assertEquals("false", serialize(ps, "false"));
244 		assertEquals("null", serialize(ps, "null"));
245 		assertEquals("null", serialize(ps, null));
246 		assertEquals("123", serialize(ps, "123"));
247 		assertEquals("1.23", serialize(ps, "1.23"));
248 	}
249 
250 	@Test void c13_stringType_uonKeywords_uon() throws Exception {
251 		var ps = T_UON;
252 		// When serialized as UON, the following should be quoted so that they're not confused with booleans or numbers.
253 		assertEquals("'true'", serialize(ps, "true"));
254 		assertEquals("'false'", serialize(ps, "false"));
255 		assertEquals("'null'", serialize(ps, "null"));
256 		assertEquals("null", serialize(ps, null));
257 		assertEquals("'123'", serialize(ps, "123"));
258 		assertEquals("'1.23'", serialize(ps, "1.23"));
259 	}
260 
261 	//-----------------------------------------------------------------------------------------------------------------
262 	// type = array
263 	//-----------------------------------------------------------------------------------------------------------------
264 
265 	public static class D {
266 		private String f;
267 		public D(String in) {
268 			this.f = in;
269 		}
270 		@Override
271 		public String toString() {
272 			return f;
273 		}
274 	}
275 
276 	@Test void d01_arrayType_collectionFormatCsv() throws Exception {
277 		var ps = T_ARRAY_CSV;
278 		assertEquals("foo,bar,null", serialize(ps, new String[]{"foo","bar",null}));
279 		assertEquals("foo,bar,null", serialize(ps, new Object[]{"foo","bar",null}));
280 		assertEquals("foo,bar,null,null", serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
281 		assertEquals("foo,bar,null", serialize(ps, list("foo","bar",null)));
282 		assertEquals("foo,bar,null", serialize(ps, list("foo","bar",null)));
283 		assertEquals("foo,bar,null,null", serialize(ps, list(new D("foo"),new D("bar"),new D(null),null)));
284 		assertEquals("foo,bar,null", serialize(ps, JsonList.of("foo","bar",null)));
285 
286 		assertEquals("foo\\,bar,null", serialize(ps, new String[]{"foo,bar",null}));
287 	}
288 
289 	@Test void d02_arrayType_collectionFormatPipes() throws Exception {
290 		var ps = T_ARRAY_PIPES;
291 		assertEquals("foo|bar|null", serialize(ps, new String[]{"foo","bar",null}));
292 		assertEquals("foo|bar|null", serialize(ps, new Object[]{"foo","bar",null}));
293 		assertEquals("foo|bar|null|null", serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
294 		assertEquals("foo|bar|null", serialize(ps, list("foo","bar",null)));
295 		assertEquals("foo|bar|null", serialize(ps, list("foo","bar",null)));
296 		assertEquals("foo|bar|null|null", serialize(ps, list(new D("foo"),new D("bar"),new D(null),null)));
297 		assertEquals("foo|bar|null", serialize(ps, JsonList.of("foo","bar",null)));
298 	}
299 
300 	@Test void d03_arrayType_collectionFormatSsv() throws Exception {
301 		var ps = T_ARRAY_SSV;
302 		assertEquals("foo bar null", serialize(ps, new String[]{"foo","bar",null}));
303 		assertEquals("foo bar null", serialize(ps, new Object[]{"foo","bar",null}));
304 		assertEquals("foo bar null null", serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
305 		assertEquals("foo bar null", serialize(ps, list("foo","bar",null)));
306 		assertEquals("foo bar null", serialize(ps, list("foo","bar",null)));
307 		assertEquals("foo bar null null", serialize(ps, list(new D("foo"),new D("bar"),new D(null),null)));
308 		assertEquals("foo bar null", serialize(ps, JsonList.of("foo","bar",null)));
309 	}
310 
311 	@Test void d04_arrayType_collectionFormatTsv() throws Exception {
312 		var ps = T_ARRAY_TSV;
313 		assertEquals("foo\tbar\tnull", serialize(ps, new String[]{"foo","bar",null}));
314 		assertEquals("foo\tbar\tnull", serialize(ps, new Object[]{"foo","bar",null}));
315 		assertEquals("foo\tbar\tnull\tnull", serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
316 		assertEquals("foo\tbar\tnull", serialize(ps, list("foo","bar",null)));
317 		assertEquals("foo\tbar\tnull", serialize(ps, list("foo","bar",null)));
318 		assertEquals("foo\tbar\tnull\tnull", serialize(ps, list(new D("foo"),new D("bar"),new D(null),null)));
319 		assertEquals("foo\tbar\tnull", serialize(ps, JsonList.of("foo","bar",null)));
320 	}
321 
322 	@Test void d05_arrayType_collectionFormatUon() throws Exception {
323 		var ps = T_ARRAY_UON;
324 		assertEquals("@(foo,bar,'null',null)", serialize(ps, new String[]{"foo","bar","null",null}));
325 		assertEquals("@(foo,bar,'null',null)", serialize(ps, new Object[]{"foo","bar","null",null}));
326 		assertEquals("@(foo,bar,'null',null)", serialize(ps, new D[]{new D("foo"),new D("bar"),new D("null"),null}));
327 		assertEquals("@(foo,bar,'null',null)", serialize(ps, list("foo","bar","null",null)));
328 		assertEquals("@(foo,bar,'null',null)", serialize(ps, list("foo","bar","null",null)));
329 		assertEquals("@(foo,bar,'null',null)", serialize(ps, list(new D("foo"),new D("bar"),new D("null"),null)));
330 		assertEquals("@(foo,bar,'null',null)", serialize(ps, JsonList.of("foo","bar","null",null)));
331 	}
332 
333 	@Test void d06a_arrayType_collectionFormatNone() throws Exception {
334 		var ps = T_ARRAY;
335 		assertEquals("foo,bar,null", serialize(ps, new String[]{"foo","bar",null}));
336 		assertEquals("foo,bar,null", serialize(ps, new Object[]{"foo","bar",null}));
337 		assertEquals("foo,bar,null,null", serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
338 		assertEquals("foo,bar,null", serialize(ps, list("foo","bar",null)));
339 		assertEquals("foo,bar,null", serialize(ps, list("foo","bar",null)));
340 		assertEquals("foo,bar,null,null", serialize(ps, list(new D("foo"),new D("bar"),new D(null),null)));
341 		assertEquals("foo,bar,null", serialize(ps, JsonList.of("foo","bar",null)));
342 	}
343 
344 	@Test void d07_arrayType_collectionFormatMulti() throws Exception {
345 		// collectionFormat=multi really shouldn't be applicable to collections of values, so just use csv.
346 		var ps = T_ARRAY_MULTI;
347 		assertEquals("foo,bar,null", serialize(ps, new String[]{"foo","bar",null}));
348 		assertEquals("foo,bar,null", serialize(ps, new Object[]{"foo","bar",null}));
349 		assertEquals("foo,bar,null,null", serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
350 		assertEquals("foo,bar,null", serialize(ps, list("foo","bar",null)));
351 		assertEquals("foo,bar,null", serialize(ps, list("foo","bar",null)));
352 		assertEquals("foo,bar,null,null", serialize(ps, list(new D("foo"),new D("bar"),new D(null),null)));
353 		assertEquals("foo,bar,null", serialize(ps, JsonList.of("foo","bar",null)));
354 	}
355 
356 	@Test void d08_arrayType_collectionFormatCsvAndPipes() throws Exception {
357 		var ps = tArrayPipes(tArrayCsv()).build();
358 		assertEquals("foo,bar|baz,null|null", serialize(ps, new String[][]{{"foo","bar"},{"baz",null},null}));
359 		assertEquals("foo,bar|baz,null|null", serialize(ps, new Object[][]{{"foo","bar"},{"baz",null},null}));
360 		assertEquals("foo,bar|baz,null,null|null", serialize(ps, new D[][]{{new D("foo"),new D("bar")},{new D("baz"),new D(null),null},null}));
361 		assertEquals("foo,bar|baz,null|null", serialize(ps, list(list("foo","bar"),list("baz",null),null)));
362 		assertEquals("foo,bar|baz,null|null", serialize(ps, list(list("foo","bar"),list("baz",null),null)));
363 		assertEquals("foo,bar|baz,null,null|null", serialize(ps, list(list(new D("foo"),new D("bar")),list(new D("baz"),new D(null),null),null)));
364 	}
365 
366 	@Test void d09_arrayType_itemsInteger() throws Exception {
367 		var ps = tArrayCsv(tInteger()).build();
368 		assertEquals("1,2", serialize(ps, new int[]{1,2}));
369 		assertEquals("1,2,null", serialize(ps, new Integer[]{1,2,null}));
370 		assertEquals("1,2,null", serialize(ps, new Object[]{1,2,null}));
371 		assertEquals("1,2,null", serialize(ps, list(1,2,null)));
372 	}
373 
374 	@Test void d10_arrayType_itemsInteger_2d() throws Exception {
375 		var ps = tArrayPipes(tArrayCsv(tInteger()).allowEmptyValue()).build();
376 		assertEquals("1,2||null", serialize(ps, new int[][]{{1,2},{},null}));
377 		assertEquals("1,2,null||null", serialize(ps, new Integer[][]{{1,2,null},{},null}));
378 		assertEquals("1,2,null||null", serialize(ps, new Object[][]{{1,2,null},{},null}));
379 		assertEquals("1,2,null||null", serialize(ps, list(list(1,2,null),list(),null)));
380 	}
381 
382 	//-----------------------------------------------------------------------------------------------------------------
383 	// type = boolean
384 	//-----------------------------------------------------------------------------------------------------------------
385 
386 	public static class E1 {
387 		private Boolean f;
388 		public E1(Boolean in) {
389 			this.f = in;
390 		}
391 		public Boolean toBoolean() {
392 			return f;
393 		}
394 	}
395 
396 	public static class E2 {
397 		private Boolean[] f;
398 		public E2(Boolean...in) {
399 			this.f = in;
400 		}
401 		public Boolean[] toBooleanArray() {
402 			return f;
403 		}
404 	}
405 
406 	@Test void e01_booleanType() throws Exception {
407 		var ps = T_BOOLEAN;
408 		assertEquals("true", serialize(ps, true));
409 		assertEquals("true", serialize(ps, "true"));
410 		assertEquals("true", serialize(ps, new E1(true)));
411 		assertEquals("false", serialize(ps, false));
412 		assertEquals("false", serialize(ps, "false"));
413 		assertEquals("false", serialize(ps, new E1(false)));
414 		assertEquals("null", serialize(ps, null));
415 		assertEquals("null", serialize(ps, "null"));
416 		assertEquals("null", serialize(ps, new E1(null)));
417 	}
418 
419 	@Test void e03_booleanType_2d() throws Exception {
420 		var ps = tArray(tBoolean()).build();
421 		assertEquals("true", serialize(ps, new boolean[]{true}));
422 		assertEquals("true,null", serialize(ps, new Boolean[]{true,null}));
423 		assertEquals("true,null", serialize(ps, list(true,null)));
424 		assertEquals("true,null", serialize(ps, new String[]{"true",null}));
425 		assertEquals("true,null", serialize(ps, list("true",null)));
426 		assertEquals("true,null", serialize(ps, new Object[]{true,null}));
427 		assertEquals("true,null", serialize(ps, list(true,null)));
428 		assertEquals("true,null,null", serialize(ps, new E1[]{new E1(true),new E1(null),null}));
429 		assertEquals("true,null,null", serialize(ps, list(new E1(true),new E1(null),null)));
430 		assertEquals("true,null", serialize(ps, new E2(true,null)));
431 	}
432 
433 	@Test void e04_booleanType_3d() throws Exception {
434 		var ps = tArrayPipes(tArray(tBoolean())).build();
435 		assertEquals("true,true|false", serialize(ps, new boolean[][]{{true,true},{false}}));
436 		assertEquals("true,true|false", serialize(ps, list(new boolean[]{true,true},new boolean[]{false})));
437 		assertEquals("true,true|false,null", serialize(ps, new Boolean[][]{{true,true},{false,null}}));
438 		assertEquals("true,true|false,null", serialize(ps, list(new Boolean[]{true,true},new Boolean[]{false,null})));
439 		assertEquals("true,true|false,null", serialize(ps, list(list(true,true),list(false,null))));
440 		assertEquals("true,true|false,null,null", serialize(ps, list(list("true","true"),list("false","null",null))));
441 		assertEquals("true,true|false,null,null", serialize(ps, list(new String[]{"true","true"},new String[]{"false","null",null})));
442 		assertEquals("true,true|false,null", serialize(ps, new Object[][]{{true,true},{false,null}}));
443 		assertEquals("true,true|false,null", serialize(ps, list(list((Object)true,(Object)true),list((Object)false,null))));
444 		assertEquals("true,true|false,null", serialize(ps, list(new Object[]{true,true},new Object[]{false,null})));
445 		assertEquals("true,true|false,null", serialize(ps, new E1[][]{{new E1(true),new E1(true)},{new E1(false),new E1(null)}}));
446 		assertEquals("true,true|false,null", serialize(ps, list(list(new E1(true),new E1(true)), list(new E1(false),new E1(null)))));
447 		assertEquals("true,true|false,null", serialize(ps, list(new E1[]{new E1(true),new E1(true)},new E1[]{new E1(false),new E1(null)})));
448 		assertEquals("true,true|false,null", serialize(ps, new E2[]{new E2(true,true),new E2(false,null)}));
449 		assertEquals("true,true|false,null", serialize(ps, list(new E2(true,true),new E2(false,null))));
450 	}
451 
452 	//-----------------------------------------------------------------------------------------------------------------
453 	// type = integer
454 	//-----------------------------------------------------------------------------------------------------------------
455 
456 	public static class F1 {
457 		private Integer f;
458 		public F1(Integer in) {
459 			this.f = in;
460 		}
461 		public Integer toInteger() {
462 			return f;
463 		}
464 	}
465 
466 	public static class F2 {
467 		private Integer[] f;
468 		public F2(Integer...in) {
469 			this.f = in;
470 		}
471 		public Integer[] toIntegerArray() {
472 			return f;
473 		}
474 	}
475 
476 	public static class F3 {
477 		private Long f;
478 		public F3(Long in) {
479 			this.f = in;
480 		}
481 		public Long toLong() {
482 			return f;
483 		}
484 	}
485 
486 	public static class F4 {
487 		private Long[] f;
488 		public F4(Long...in) {
489 			this.f = in;
490 		}
491 		public Long[] toLongArray() {
492 			return f;
493 		}
494 	}
495 
496 	@Test void f01_integerType_int32() throws Exception {
497 		var ps = T_INT32;
498 		assertEquals("1", serialize(ps, 1));
499 		assertEquals("1", serialize(ps, Integer.valueOf(1)));
500 		assertEquals("1", serialize(ps, (short)1));
501 		assertEquals("1", serialize(ps, Short.valueOf((short)1)));
502 		assertEquals("1", serialize(ps, 1L));
503 		assertEquals("1", serialize(ps, Long.valueOf(1)));
504 		assertEquals("1", serialize(ps, "1"));
505 		assertEquals("1", serialize(ps, new F1(1)));
506 		assertEquals("null", serialize(ps, null));
507 		assertEquals("null", serialize(ps, "null"));
508 	}
509 
510 	@Test void f02_integerType_int32_2d() throws Exception {
511 		var ps = tArray(tInt32()).build();
512 		assertEquals("1,2", serialize(ps, new int[]{1,2}));
513 		assertEquals("1,2,null", serialize(ps, new Integer[]{1,2,null}));
514 		assertEquals("1,2,null", serialize(ps, list(1,2,null)));
515 		assertEquals("1,2", serialize(ps, new short[]{1,2}));
516 		assertEquals("1,2,null", serialize(ps, new Short[]{1,2,null}));
517 		assertEquals("1,2,null", serialize(ps, list(Short.valueOf((short)1),Short.valueOf((short)2),null)));
518 		assertEquals("1,2", serialize(ps, new long[]{1L,2L}));
519 		assertEquals("1,2,null", serialize(ps, new Long[]{1L,2L,null}));
520 		assertEquals("1,2,null", serialize(ps, list(1L,2L,null)));
521 		assertEquals("1,2,null,null", serialize(ps, new String[]{"1","2","null",null}));
522 		assertEquals("1,2,null,null", serialize(ps, list("1","2","null",null)));
523 		assertEquals("1,2,null", serialize(ps, new Object[]{1,2,null}));
524 		assertEquals("1,2,null", serialize(ps, list(1,2,null)));
525 		assertEquals("1,2,null,null", serialize(ps, new F1[]{new F1(1),new F1(2),new F1(null),null}));
526 		assertEquals("1,2,null,null", serialize(ps, list(new F1(1),new F1(2),new F1(null),null)));
527 		assertEquals("1,2,null", serialize(ps, new F2(1,2,null)));
528 	}
529 
530 	@Test void f03_integerType_int32_3d() throws Exception {
531 		var ps = tArrayPipes(tArray(tInt32())).build();
532 		assertEquals("1,2|3|null", serialize(ps, new int[][]{{1,2},{3},null}));
533 		assertEquals("1,2|3|null", serialize(ps, list(new int[]{1,2},new int[]{3},null)));
534 		assertEquals("1,2|3,null|null", serialize(ps, new Integer[][]{{1,2},{3,null},null}));
535 		assertEquals("1,2|3,null|null", serialize(ps, list(new Integer[]{1,2},new Integer[]{3,null},null)));
536 		assertEquals("1,2|3,null|null", serialize(ps, list(list(1,2),list(3,null),null)));
537 		assertEquals("1,2|3|null", serialize(ps, new short[][]{{1,2},{3},null}));
538 		assertEquals("1,2|3|null", serialize(ps, list(new short[]{1,2},new short[]{3},null)));
539 		assertEquals("1,2|3,null|null", serialize(ps, new Short[][]{{1,2},{3,null},null}));
540 		assertEquals("1,2|3,null|null", serialize(ps, list(new Short[]{1,2},new Short[]{3,null},null)));
541 		assertEquals("1,2|3,null|null", serialize(ps, list(list(Short.valueOf((short)1),Short.valueOf((short)2)),list(Short.valueOf((short)3),null),null)));
542 		assertEquals("1,2|3|null", serialize(ps, new long[][]{{1L,2L},{3L},null}));
543 		assertEquals("1,2|3|null", serialize(ps, list(new long[]{1L,2L},new long[]{3L},null)));
544 		assertEquals("1,2|3,null|null", serialize(ps, new Long[][]{{1L,2L},{3L,null},null}));
545 		assertEquals("1,2|3,null|null", serialize(ps, list(new Long[]{1L,2L},new Long[]{3L,null},null)));
546 		assertEquals("1,2|3,null|null", serialize(ps, list(list(Long.valueOf(1),Long.valueOf(2)),list(Long.valueOf(3),null),null)));
547 		assertEquals("1,2|3,null,null|null", serialize(ps, new String[][]{{"1","2"},{"3","null",null},null}));
548 		assertEquals("1,2|3,null,null|null", serialize(ps, list(new String[]{"1","2"},new String[]{"3","null",null},null)));
549 		assertEquals("1,2|3,null,null|null", serialize(ps, list(list("1","2"),list("3","null",null),null)));
550 		assertEquals("1,2|3,null|null", serialize(ps, new Object[][]{{1,2},{3,null},null}));
551 		assertEquals("1,2|3,null|null", serialize(ps, list(new Object[]{1,2},new Object[]{3,null},null)));
552 		assertEquals("1,2|3,null|null", serialize(ps, list(list(1,2),list(3,null),null)));
553 		assertEquals("1,2|3,null,null|null", serialize(ps, new F1[][]{{new F1(1),new F1(2)},{new F1(3),new F1(null),null},null}));
554 		assertEquals("1,2|3,null,null|null", serialize(ps, list(new F1[]{new F1(1),new F1(2)},new F1[]{new F1(3),new F1(null),null},null)));
555 		assertEquals("1,2|3,null,null|null", serialize(ps, list(list(new F1(1),new F1(2)),list(new F1(3),new F1(null),null),null)));
556 		assertEquals("1,2|3,null|null", serialize(ps, new F2[]{new F2(1,2),new F2(3,null),null}));
557 		assertEquals("1,2|3,null|null", serialize(ps, list(new F2(1,2),new F2(3,null),null)));
558 	}
559 
560 	@Test void f04_integerType_int64() throws Exception {
561 		var ps = T_INT64;
562 		assertEquals("1", serialize(ps, 1));
563 		assertEquals("1", serialize(ps, Integer.valueOf(1)));
564 		assertEquals("1", serialize(ps, (short)1));
565 		assertEquals("1", serialize(ps, Short.valueOf((short)1)));
566 		assertEquals("1", serialize(ps, 1L));
567 		assertEquals("1", serialize(ps, Long.valueOf(1L)));
568 		assertEquals("1", serialize(ps, "1"));
569 		assertEquals("1", serialize(ps,  new F3(1L)));
570 		assertEquals("null", serialize(ps, null));
571 		assertEquals("null", serialize(ps, "null"));
572 	}
573 
574 	@Test void f05_integerType_int64_2d() throws Exception {
575 		var ps = tArray(tInt64()).build();
576 		assertEquals("1,2", serialize(ps, new int[]{1,2}));
577 		assertEquals("1,2,null", serialize(ps, new Integer[]{1,2,null}));
578 		assertEquals("1,2,null", serialize(ps, list(1,2,null)));
579 		assertEquals("1,2", serialize(ps, new short[]{1,2}));
580 		assertEquals("1,2,null", serialize(ps, new Short[]{1,2,null}));
581 		assertEquals("1,2,null", serialize(ps, list((short)1,(short)2,null)));
582 		assertEquals("1,2", serialize(ps, new long[]{1L,2L}));
583 		assertEquals("1,2,null", serialize(ps, new Long[]{1L,2L,null}));
584 		assertEquals("1,2,null", serialize(ps, list(1L,2L,null)));
585 		assertEquals("1,2,null,null", serialize(ps, new String[]{"1","2","null",null}));
586 		assertEquals("1,2,null,null", serialize(ps, list("1","2","null",null)));
587 		assertEquals("1,2,null", serialize(ps, new Object[]{1,2,null}));
588 		assertEquals("1,2,null", serialize(ps, list((Object)1,(Object)2,null)));
589 		assertEquals("1,2,null,null", serialize(ps, new F3[]{new F3(1L),new F3(2L),new F3(null),null}));
590 		assertEquals("1,2,null,null", serialize(ps, list(new F3(1L),new F3(2L),new F3(null),null)));
591 		assertEquals("1,2,null", serialize(ps, new F4(1L,2L,null)));
592 	}
593 
594 	@Test void f06_integerType_int64_3d() throws Exception {
595 		var ps = tArrayPipes(tArray(tInt64())).build();
596 		assertEquals("1,2|3|null", serialize(ps, new int[][]{{1,2},{3},null}));
597 		assertEquals("1,2|3|null", serialize(ps, list(new int[]{1,2},new int[]{3},null)));
598 		assertEquals("1,2|3,null|null", serialize(ps, new Integer[][]{{1,2},{3,null},null}));
599 		assertEquals("1,2|3,null|null", serialize(ps, list(new Integer[]{1,2},new Integer[]{3,null},null)));
600 		assertEquals("1,2|3,null|null", serialize(ps, list(list(1,2),list(3,null),null)));
601 		assertEquals("1,2|3|null", serialize(ps, new short[][]{{1,2},{3},null}));
602 		assertEquals("1,2|3|null", serialize(ps, list(new short[]{1,2},new short[]{3},null)));
603 		assertEquals("1,2|3,null|null", serialize(ps, new Short[][]{{1,2},{3,null},null}));
604 		assertEquals("1,2|3,null|null", serialize(ps, list(new Short[]{1,2},new Short[]{3,null},null)));
605 		assertEquals("1,2|3,null|null", serialize(ps, list(list((short)1,(short)2),list((short)3,null),null)));
606 		assertEquals("1,2|3|null", serialize(ps, new long[][]{{1L,2L},{3L},null}));
607 		assertEquals("1,2|3|null", serialize(ps, list(new long[]{1L,2L},new long[]{3L},null)));
608 		assertEquals("1,2|3,null|null", serialize(ps, new Long[][]{{1L,2L},{3L,null},null}));
609 		assertEquals("1,2|3,null|null", serialize(ps, list(new Long[]{1L,2L},new Long[]{3L,null},null)));
610 		assertEquals("1,2|3,null|null", serialize(ps, list(list(1L,2L),list(3L,null),null)));
611 		assertEquals("1,2|3,null,null|null", serialize(ps, new String[][]{{"1","2"},{"3","null",null},null}));
612 		assertEquals("1,2|3,null,null|null", serialize(ps, list(new String[]{"1","2"},new String[]{"3","null",null},null)));
613 		assertEquals("1,2|3,null,null|null", serialize(ps, list(list("1","2"),list("3","null",null),null)));
614 		assertEquals("1,2|3,null|null", serialize(ps, new Object[][]{{1,2},{3,null},null}));
615 		assertEquals("1,2|3,null|null", serialize(ps, list(new Object[]{1,2},new Object[]{3,null},null)));
616 		assertEquals("1,2|3,null|null", serialize(ps, list(list((Object)1,(Object)2),list((Object)3,null),null)));
617 		assertEquals("1,2|3,null,null|null", serialize(ps, new F3[][]{{new F3(1L),new F3(2L)},{new F3(3L),new F3(null),null},null}));
618 		assertEquals("1,2|3,null,null|null", serialize(ps, list(new F3[]{new F3(1L),new F3(2L)},new F3[]{new F3(3L),new F3(null),null},null)));
619 		assertEquals("1,2|3,null,null|null", serialize(ps, list(list(new F3(1L),new F3(2L)),list(new F3(3L),new F3(null),null),null)));
620 		assertEquals("1,2|3,null|null", serialize(ps, new F4[]{new F4(1L,2L),new F4(3L,null),null}));
621 		assertEquals("1,2|3,null|null", serialize(ps, list(new F4(1L,2L),new F4(3L,null),null)));
622 	}
623 
624 
625 	//-----------------------------------------------------------------------------------------------------------------
626 	// type = number
627 	//-----------------------------------------------------------------------------------------------------------------
628 
629 	public static class G1 {
630 		private Float f;
631 		public G1(Float in) {
632 			this.f = in;
633 		}
634 		public Float toFloat() {
635 			return f;
636 		}
637 	}
638 
639 	public static class G2 {
640 		private Float[] f;
641 		public G2(Float...in) {
642 			this.f = in;
643 		}
644 		public Float[] toFloatArray() {
645 			return f;
646 		}
647 	}
648 
649 	public static class G3 {
650 		private Double f;
651 		public G3(Double in) {
652 			this.f = in;
653 		}
654 		public Double toDouble() {
655 			return f;
656 		}
657 	}
658 
659 	public static class G4 {
660 		private Double[] f;
661 		public G4(Double...in) {
662 			this.f = in;
663 		}
664 		public Double[] toDoubleArray() {
665 			return f;
666 		}
667 	}
668 
669 	@Test void g01_numberType_float() throws Exception {
670 		var ps = T_FLOAT;
671 		assertEquals("1.0", serialize(ps, 1f));
672 		assertEquals("1.0", serialize(ps, Float.valueOf(1f)));
673 		assertEquals("1.0", serialize(ps, 1d));
674 		assertEquals("1.0", serialize(ps, Double.valueOf(1d)));
675 		assertEquals("1.0", serialize(ps, "1"));
676 		assertEquals("1.0", serialize(ps, new G1(1f)));
677 		assertEquals("null", serialize(ps, null));
678 		assertEquals("null", serialize(ps, "null"));
679 		assertEquals("null", serialize(ps, new G1(null)));
680 	}
681 
682 	@Test void g02_numberType_float_2d() throws Exception {
683 		var ps = tArray(tFloat()).build();
684 		assertEquals("1.0,2.0", serialize(ps, new float[]{1,2}));
685 		assertEquals("1.0,2.0,null", serialize(ps, new Float[]{1f,2f,null}));
686 		assertEquals("1.0,2.0,null", serialize(ps, list(1f,2f,null)));
687 		assertEquals("1.0,2.0", serialize(ps, new double[]{1,2}));
688 		assertEquals("1.0,2.0,null", serialize(ps, new Double[]{1d,2d,null}));
689 		assertEquals("1.0,2.0,null", serialize(ps, list(1d,2d,null)));
690 		assertEquals("1.0,2.0,null,null", serialize(ps, new String[]{"1","2","null",null}));
691 		assertEquals("1.0,2.0,null,null", serialize(ps, list("1","2","null",null)));
692 		assertEquals("1.0,2.0,null", serialize(ps, new Object[]{1,2,null}));
693 		assertEquals("1.0,2.0,null", serialize(ps, list((Object)1,(Object)2,null)));
694 		assertEquals("1.0,2.0,null,null", serialize(ps, new G1[]{new G1(1f),new G1(2f),new G1(null),null}));
695 		assertEquals("1.0,2.0,null,null", serialize(ps, list(new G1(1f),new G1(2f),new G1(null),null)));
696 		assertEquals("1.0,2.0,null", serialize(ps, new G2(1f,2f,null)));
697 	}
698 
699 	@Test void g03_numberType_float_3d() throws Exception {
700 		var ps = tArrayPipes(tArray(tFloat())).build();
701 		assertEquals("1.0,2.0|3.0|null", serialize(ps, new float[][]{{1,2},{3},null}));
702 		assertEquals("1.0,2.0|3.0|null", serialize(ps, list(new float[]{1,2},new float[]{3},null)));
703 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, new Float[][]{{1f,2f},{3f,null},null}));
704 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(new Float[]{1f,2f},new Float[]{3f,null}, null)));
705 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(list(1f,2f),list(3f,null),null)));
706 		assertEquals("1.0,2.0|3.0|null", serialize(ps, new double[][]{{1d,2d},{3d},null}));
707 		assertEquals("1.0,2.0|3.0|null", serialize(ps, list(new double[]{1d,2d},new double[]{3d},null)));
708 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, new Double[][]{{1d,2d},{3d,null},null}));
709 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(new Double[]{1d,2d},new Double[]{3d,null},null)));
710 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(list(1d,2d),list(3d,null),null)));
711 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, new String[][]{{"1","2"},{"3","null",null},null}));
712 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(new String[]{"1","2"},new String[]{"3","null",null},null)));
713 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(list(1d,2d),list(3f,"null",null),null)));
714 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, new Object[][]{{1d,2d},{3f,"null",null},null}));
715 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(new Object[]{1d,2d},new Object[]{3f,"null",null},null)));
716 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(list(1d,2d),list(3f,"null",null),null)));
717 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, new G1[][]{{new G1(1f),new G1(2f)},{new G1(3f),new G1(null),null},null}));
718 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(new G1[]{new G1(1f),new G1(2f)},new G1[]{new G1(3f),new G1(null),null},null)));
719 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(list(new G1(1f),new G1(2f)),list(new G1(3f),new G1(null),null),null)));
720 		assertEquals("1.0,2.0,null|null", serialize(ps, new G2[]{new G2(1f,2f,null),null}));
721 		assertEquals("1.0,2.0,null|null", serialize(ps, list(new G2(1f,2f,null),null)));
722 	}
723 
724 	@Test void g04_numberType_double() throws Exception {
725 		var ps = T_DOUBLE;
726 		assertEquals("1.0", serialize(ps, 1f));
727 		assertEquals("1.0", serialize(ps, Float.valueOf(1f)));
728 		assertEquals("1.0", serialize(ps, 1d));
729 		assertEquals("1.0", serialize(ps, Double.valueOf(1d)));
730 		assertEquals("1.0", serialize(ps, "1"));
731 		assertEquals("1.0", serialize(ps, new G3(1d)));
732 		assertEquals("null", serialize(ps, null));
733 		assertEquals("null", serialize(ps, "null"));
734 		assertEquals("null", serialize(ps, new G3(null)));
735 	}
736 
737 	@Test void g05_numberType_double_2d() throws Exception {
738 		var ps = tArray(tDouble()).build();
739 		assertEquals("1.0,2.0", serialize(ps, new float[]{1,2}));
740 		assertEquals("1.0,2.0,null", serialize(ps, new Float[]{1f,2f,null}));
741 		assertEquals("1.0,2.0,null", serialize(ps, list(1f,2f,null)));
742 		assertEquals("1.0,2.0", serialize(ps, new double[]{1,2}));
743 		assertEquals("1.0,2.0,null", serialize(ps, new Double[]{1d,2d,null}));
744 		assertEquals("1.0,2.0,null", serialize(ps, list(1d,2d,null)));
745 		assertEquals("1.0,2.0,null,null", serialize(ps, new String[]{"1","2","null",null}));
746 		assertEquals("1.0,2.0,null,null", serialize(ps, list("1","2","null",null)));
747 		assertEquals("1.0,2.0,null,null", serialize(ps, new Object[]{1d,2f,"null",null}));
748 		assertEquals("1.0,2.0,null,null", serialize(ps, list(1d,2f,"null",null)));
749 		assertEquals("1.0,2.0,null,null", serialize(ps, new G3[]{new G3(1d),new G3(2d),new G3(null),null}));
750 		assertEquals("1.0,2.0,null,null", serialize(ps, list(new G3(1d),new G3(2d),new G3(null),null)));
751 		assertEquals("1.0,2.0,null", serialize(ps, new G4(1d,2d,null)));
752 	}
753 
754 	@Test void g06_numberType_double_3d() throws Exception {
755 		var ps = tArrayPipes(tArray(tDouble())).build();
756 		assertEquals("1.0,2.0|3.0|null", serialize(ps, new float[][]{{1f,2f},{3f},null}));
757 		assertEquals("1.0,2.0|3.0|null", serialize(ps, list(new float[]{1f,2f},new float[]{3f},null)));
758 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, new Float[][]{{1f,2f},{3f,null},null}));
759 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(new Float[]{1f,2f},new Float[]{3f,null},null)));
760 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(list(1f,2f),list(3f,null),null)));
761 		assertEquals("1.0,2.0|3.0|null", serialize(ps, new double[][]{{1d,2d},{3d},null}));
762 		assertEquals("1.0,2.0|3.0|null", serialize(ps, list(new double[]{1d,2d},new double[]{3d},null)));
763 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, new Double[][]{{1d,2d},{3d,null},null}));
764 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(new Double[]{1d,2d},new Double[]{3d,null},null)));
765 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(list(1d,2d),list(3d,null),null)));
766 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, new String[][]{{"1","2"},{"3","null",null},null}));
767 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(new String[]{"1","2"},new String[]{"3","null",null},null)));
768 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(list("1","2"),list("3","null",null),null)));
769 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, new Object[][]{{1d,2d},{"3","null",null},null}));
770 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(new Object[]{1d,2d},new Object[]{"3","null",null},null)));
771 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(list(1d,2f),list(3d,"null",null),null)));
772 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, new G3[][]{{new G3(1d),new G3(2d)},{new G3(3d),new G3(null),null},null}));
773 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(new G3[]{new G3(1d),new G3(2d)},new G3[]{new G3(3d),new G3(null),null},null)));
774 		assertEquals("1.0,2.0|3.0,null,null|null", serialize(ps, list(list(new G3(1d),new G3(2d)),list(new G3(3d),new G3(null),null),null)));
775 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, new G4[]{new G4(1d,2d),new G4(3d,null),null}));
776 		assertEquals("1.0,2.0|3.0,null|null", serialize(ps, list(new G4(1d,2d),new G4(3d,null),null)));
777 	}
778 
779 	//-----------------------------------------------------------------------------------------------------------------
780 	// type = object
781 	//-----------------------------------------------------------------------------------------------------------------
782 
783 	public static class H1 {
784 		public String f1;
785 		public Integer f2;
786 		public Boolean f3;
787 		public H1(String f1, Integer f2, Boolean f3) {
788 			this.f1 = f1;
789 			this.f2 = f2;
790 			this.f3 = f3;
791 		}
792 	}
793 
794 	@Test void h01_objectType() throws Exception {
795 		var ps = tObject().allowEmptyValue().build();
796 		assertEquals("f1=1,f2=2,f3=true", serialize(ps, new H1("1",2,true)));
797 		assertEquals("", serialize(ps, new H1(null,null,null)));
798 		assertEquals("f1=1,f2=2,f3=true", serialize(ps, JsonMap.ofJson("{f1:'1',f2:2,f3:true}")));
799 		assertEquals("f1=null,f2=null,f3=null", serialize(ps, JsonMap.ofJson("{f1:null,f2:null,f3:null}")));
800 		assertEquals("null", serialize(ps, null));
801 	}
802 
803 	@Test void h02_objectType_uon() throws Exception {
804 		var ps = T_OBJECT_UON;
805 		assertEquals("(f1='1',f2=2,f3=true)", serialize(ps, new H1("1",2,true)));
806 		assertEquals("()", serialize(ps, new H1(null,null,null)));
807 		assertEquals("(f1='1',f2=2,f3=true)", serialize(ps, JsonMap.ofJson("{f1:'1',f2:2,f3:true}")));
808 		assertEquals("(f1=null,f2=null,f3=null)", serialize(ps, JsonMap.ofJson("{f1:null,f2:null,f3:null}")));
809 		assertEquals("null", serialize(ps, null));
810 	}
811 
812 	@Test void h03_objectType_2d() throws Exception {
813 		var ps = tArray(tObject().allowEmptyValue()).build();
814 		assertEquals("f1=1\\,f2=2\\,f3=true,,null", serialize(ps, new H1[]{new H1("1",2,true),new H1(null,null,null),null}));
815 		assertEquals("f1=1\\,f2=2\\,f3=true,,null", serialize(ps, list(new H1("1",2,true),new H1(null,null,null),null)));
816 		assertEquals("f1=1\\,f2=2\\,f3=true,f1=null\\,f2=null\\,f3=null,null", serialize(ps, new JsonMap[]{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null}));
817 		assertEquals("f1=1\\,f2=2\\,f3=true,f1=null\\,f2=null\\,f3=null,null", serialize(ps, list(JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null)));
818 		assertEquals("f1=1\\,f2=2\\,f3=true,f1=1\\,f2=2\\,f3=true,null", serialize(ps, new Object[]{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),null}));
819 		assertEquals("f1=1\\,f2=2\\,f3=true,f1=1\\,f2=2\\,f3=true,null", serialize(ps, list(new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),null)));
820 	}
821 
822 	@Test void h03_objectType_2d_pipes() throws Exception {
823 		var ps = tArrayPipes(tObject().allowEmptyValue()).build();
824 		assertEquals("f1=1,f2=2,f3=true||null", serialize(ps, new H1[]{new H1("1",2,true),new H1(null,null,null),null}));
825 		assertEquals("f1=1,f2=2,f3=true||null", serialize(ps, list(new H1("1",2,true),new H1(null,null,null),null)));
826 		assertEquals("f1=1,f2=2,f3=true|f1=null,f2=null,f3=null|null", serialize(ps, new JsonMap[]{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null}));
827 		assertEquals("f1=1,f2=2,f3=true|f1=null,f2=null,f3=null|null", serialize(ps, list(JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null)));
828 		assertEquals("f1=1,f2=2,f3=true|f1=1,f2=2,f3=true|null", serialize(ps, new Object[]{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),null}));
829 		assertEquals("f1=1,f2=2,f3=true|f1=1,f2=2,f3=true|null", serialize(ps, list(new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),null)));
830 	}
831 
832 	@Test void h04_objectType_2d_uon() throws Exception {
833 		var ps = tArrayUon(tObject()).build();
834 		assertEquals("@((f1='1',f2=2,f3=true),(),null)", serialize(ps, new H1[]{new H1("1",2,true),new H1(null,null,null),null}));
835 		assertEquals("@((f1='1',f2=2,f3=true),(),null)", serialize(ps, list(new H1("1",2,true),new H1(null,null,null),null)));
836 		assertEquals("@((f1='1',f2=2,f3=true),(f1=null,f2=null,f3=null),null)", serialize(ps, new JsonMap[]{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null}));
837 		assertEquals("@((f1='1',f2=2,f3=true),(f1=null,f2=null,f3=null),null)", serialize(ps, list(JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null)));
838 		assertEquals("@((f1='1',f2=2,f3=true),(f1='1',f2=2,f3=true),null)", serialize(ps, new Object[]{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),null}));
839 		assertEquals("@((f1='1',f2=2,f3=true),(f1='1',f2=2,f3=true),null)", serialize(ps, list(new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),null)));
840 	}
841 
842 	@Test void h03_objectType_3d() throws Exception {
843 		var ps = tArray(tArray(tObject().allowEmptyValue())).build();
844 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=x\\\\\\,f2=3\\\\\\,f3=false,\\,null,null", serialize(ps, new H1[][]{{new H1("1",2,true),new H1("x",3,false)},{new H1(null,null,null),null},null}));
845 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=x\\\\\\,f2=3\\\\\\,f3=false,\\,null,null", serialize(ps, list(new H1[]{new H1("1",2,true),new H1("x",3,false)},new H1[]{new H1(null,null,null),null},null)));
846 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=x\\\\\\,f2=3\\\\\\,f3=false,\\,null,null", serialize(ps, list(list(new H1("1",2,true),new H1("x",3,false)),list(new H1(null,null,null),null),null)));
847 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=x\\\\\\,f2=4\\\\\\,f3=false,f1=null\\\\\\,f2=null\\\\\\,f3=null\\,null,null", serialize(ps, new JsonMap[][]{{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")},{JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null}));
848 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=x\\\\\\,f2=4\\\\\\,f3=false,f1=null\\\\\\,f2=null\\\\\\,f3=null\\,null,null", serialize(ps, list(new JsonMap[]{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")},new JsonMap[]{JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null)));
849 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=x\\\\\\,f2=4\\\\\\,f3=false,f1=null\\\\\\,f2=null\\\\\\,f3=null\\,null,null", serialize(ps, list(list(JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")),list(JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null),null)));
850 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=1\\\\\\,f2=2\\\\\\,f3=true,\\,f1=null\\\\\\,f2=null\\\\\\,f3=null\\,null,null", serialize(ps, new Object[][]{{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")},{new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null}));
851 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=1\\\\\\,f2=2\\\\\\,f3=true,\\,f1=null\\\\\\,f2=null\\\\\\,f3=null\\,null,null", serialize(ps, list(new Object[]{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")},new Object[]{new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null)));
852 		assertEquals("f1=1\\\\\\,f2=2\\\\\\,f3=true\\,f1=1\\\\\\,f2=2\\\\\\,f3=true,\\,f1=null\\\\\\,f2=null\\\\\\,f3=null\\,null,null", serialize(ps, list(list(new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")),list(new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null),null)));
853 	}
854 
855 	@Test void h03_objectType_3d_ssvAndPipes() throws Exception {
856 		var ps = tArraySsv(tArrayPipes(tObject().allowEmptyValue())).build();
857 		assertEquals("null|null null|null null null", serialize(ps, new String[][]{{null,null},{null,null},null,null}));
858 //f1=1,f2=2,f3=true|f1=x,f2=3,f3=false null null
859 		assertEquals("f1=1,f2=2,f3=true|f1=x,f2=3,f3=false |null null", serialize(ps, new H1[][]{{new H1("1",2,true),new H1("x",3,false)},{new H1(null,null,null),null},null}));
860 		assertEquals("f1=1,f2=2,f3=true|f1=x,f2=3,f3=false |null null", serialize(ps, list(new H1[]{new H1("1",2,true),new H1("x",3,false)},new H1[]{new H1(null,null,null),null},null)));
861 		assertEquals("f1=1,f2=2,f3=true|f1=x,f2=3,f3=false |null null", serialize(ps, list(list(new H1("1",2,true),new H1("x",3,false)),list(new H1(null,null,null),null),null)));
862 		assertEquals("f1=1,f2=2,f3=true|f1=x,f2=4,f3=false f1=null,f2=null,f3=null|null null", serialize(ps, new JsonMap[][]{{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")},{JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null}));
863 		assertEquals("f1=1,f2=2,f3=true|f1=x,f2=4,f3=false f1=null,f2=null,f3=null|null null", serialize(ps, list(new JsonMap[]{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")},new JsonMap[]{JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null)));
864 		assertEquals("f1=1,f2=2,f3=true|f1=x,f2=4,f3=false f1=null,f2=null,f3=null|null null", serialize(ps, list(list(JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")),list(JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null),null)));
865 		assertEquals("f1=1,f2=2,f3=true|f1=1,f2=2,f3=true |f1=null,f2=null,f3=null|null null", serialize(ps, new Object[][]{{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")},{new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null}));
866 		assertEquals("f1=1,f2=2,f3=true|f1=1,f2=2,f3=true |f1=null,f2=null,f3=null|null null", serialize(ps, list(new Object[]{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")},new Object[]{new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null)));
867 		assertEquals("f1=1,f2=2,f3=true|f1=1,f2=2,f3=true |f1=null,f2=null,f3=null|null null", serialize(ps, list(list(new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")),list(new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null),null)));
868 	}
869 
870 	@Test void h03_objectType_3d_uon() throws Exception {
871 		var ps = tArrayUon(tArray(tObject())).build();
872 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=3,f3=false)),@((),null),null)", serialize(ps, new H1[][]{{new H1("1",2,true),new H1("x",3,false)},{new H1(null,null,null),null},null}));
873 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=3,f3=false)),@((),null),null)", serialize(ps, list(new H1[]{new H1("1",2,true),new H1("x",3,false)},new H1[]{new H1(null,null,null),null},null)));
874 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=3,f3=false)),@((),null),null)", serialize(ps, list(list(new H1("1",2,true),new H1("x",3,false)),list(new H1(null,null,null),null),null)));
875 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=4,f3=false)),@((f1=null,f2=null,f3=null),null),null)", serialize(ps, new JsonMap[][]{{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")},{JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null}));
876 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=4,f3=false)),@((f1=null,f2=null,f3=null),null),null)", serialize(ps, list(new JsonMap[]{JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")},new JsonMap[]{JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null)));
877 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1=x,f2=4,f3=false)),@((f1=null,f2=null,f3=null),null),null)", serialize(ps, list(list(JsonMap.ofJson("{f1:'1',f2:2,f3:true}"),JsonMap.ofJson("{f1:'x',f2:4,f3:false}")),list(JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null),null)));
878 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1='1',f2=2,f3=true)),@((),(f1=null,f2=null,f3=null),null),null)", serialize(ps, new Object[][]{{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")},{new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null}));
879 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1='1',f2=2,f3=true)),@((),(f1=null,f2=null,f3=null),null),null)", serialize(ps, list(new Object[]{new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")},new Object[]{new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null},null)));
880 		assertEquals("@(@((f1='1',f2=2,f3=true),(f1='1',f2=2,f3=true)),@((),(f1=null,f2=null,f3=null),null),null)", serialize(ps, list(list(new H1("1",2,true),JsonMap.ofJson("{f1:'1',f2:2,f3:true}")),list(new H1(null,null,null),JsonMap.ofJson("{f1:null,f2:null,f3:null}"),null),null)));
881 	}
882 
883 	public static class H2 {
884 		public Object f01, f02, f04, f05, f06, f07, f08, f09, f10, f11, f12, f99;
885 		public H2(Object f01, Object f02, Object f04, Object f05, Object f06, Object f07, Object f08, Object f09, Object f10, Object f11, Object f12, Object f99) {
886 			this.f01 = f01;
887 			this.f02 = f02;
888 			this.f04 = f04;
889 			this.f05 = f05;
890 			this.f06 = f06;
891 			this.f07 = f07;
892 			this.f08 = f08;
893 			this.f09 = f09;
894 			this.f10 = f10;
895 			this.f11 = f11;
896 			this.f12 = f12;
897 			this.f99 = f99;
898 		}
899 	}
900 
901 	@Test void h04_objectType_simpleProperties() throws Exception {
902 		var ps = tObject()
903 			.p("f01", tString())
904 			.p("f02", tByte())
905 			.p("f04", tDateTime())
906 			.p("f05", tBinary())
907 			.p("f06", tBinarySpaced())
908 			.p("f07", tUon())
909 			.p("f08", tInteger())
910 			.p("f09", tInt64())
911 			.p("f10", tNumber())
912 			.p("f11", tDouble())
913 			.p("f12", tBoolean())
914 			.ap(tInteger())
915 			.allowEmptyValue()
916 			.build();
917 
918 		var foob = "foo".getBytes();
919 
920 		assertEquals(
921 			"f01=foo,f02=Zm9v,f04=2012-12-21T12:34:56Z,f05=666F6F,f06=66 6F 6F,f07=foo,f08=1,f09=2,f10=1.0,f11=1.0,f12=true,f99=1",
922 			serialize(ps, new H2("foo",foob,parseIsoCalendar("2012-12-21T12:34:56Z"),foob,foob,"foo",1,2,1.0,1.0,true,1))
923 		);
924 		assertEquals("", serialize(ps, new H2(null,null,null,null,null,null,null,null,null,null,null,null)));
925 		assertEquals("null", serialize(ps, null));
926 		assertEquals(
927 			"f01=foo,f02=Zm9v,f04=2012-12-21T12:34:56Z,f05=666F6F,f06=66 6F 6F,f07=foo,f08=1,f09=2,f10=1.0,f11=1.0,f12=true,f99=1",
928 			serialize(ps, JsonMap.of("f01","foo","f02",foob,"f04",parseIsoCalendar("2012-12-21T12:34:56Z"),"f05",foob,"f06",foob,"f07","foo","f08",1,"f09",2,"f10",1.0,"f11",1.0,"f12",true,"f99",1))
929 		);
930 	}
931 
932 	@Test void h05_objectType_arrayProperties() throws Exception {
933 		var ps = tObjectUon()
934 			.p("f01", tArray(tString()))
935 			.p("f02", tArray(tByte()))
936 			.p("f04", tArray(tDateTime()))
937 			.p("f05", tArray(tBinary()))
938 			.p("f06", tArray(tBinarySpaced()))
939 			.p("f07", tArray(tUon()))
940 			.p("f08", tArray(tInteger()))
941 			.p("f09", tArray(tInt64()))
942 			.p("f10", tArray(tNumber()))
943 			.p("f11", tArray(tDouble()))
944 			.p("f12", tArray(tBoolean()))
945 			.ap(tArray(tInteger()))
946 			.build();
947 
948 		var foob = "foo".getBytes();
949 
950 		assertEquals(
951 			"(f01=@('a,b',null),f02=@(Zm9v,null),f04=@(2012-12-21T12:34:56Z,null),f05=@(666F6F,null),f06=@('66 6F 6F',null),f07=@(a,b,null),f08=@(1,2,null),f09=@(3,4,null),f10=@(1.0,2.0,null),f11=@(3.0,4.0,null),f12=@(true,false,null),f99=@(1,x,null))",
952 			serialize(ps, new H2(new String[]{"a,b",null},new byte[][]{foob,null},new Calendar[]{parseIsoCalendar("2012-12-21T12:34:56Z"),null},new byte[][]{foob,null},new byte[][]{foob,null},new String[]{"a","b",null},new Integer[]{1,2,null},new Integer[]{3,4,null},new Float[]{1f,2f,null},new Float[]{3f,4f,null},new Boolean[]{true,false,null},new Object[]{1,"x",null}))
953 		);
954 
955 	}
956 
957 	//-----------------------------------------------------------------------------------------------------------------
958 	// No-schema tests
959 	//-----------------------------------------------------------------------------------------------------------------
960 	@Test void i01a_noSchemaTests_Integer() throws Exception {
961 		for (var v : list(Integer.valueOf(1), Integer.MAX_VALUE, Integer.MIN_VALUE))
962 			assertEquals(valueOf(v), serialize((HttpPartSchema)null, v));
963 	}
964 	@Test void i01b_noSchemaTests_IntegerArray() throws Exception {
965 		assertEquals("1,2147483647,-2147483648", serialize((HttpPartSchema)null, new Integer[]{Integer.valueOf(1), Integer.MAX_VALUE, Integer.MIN_VALUE}));
966 	}
967 
968 	@Test void i02a_noSchemaTests_Short() throws Exception {
969 		for (var v : list(Short.valueOf((short)1), Short.MAX_VALUE, Short.MIN_VALUE))
970 			assertEquals(valueOf(v), serialize((HttpPartSchema)null, v));
971 	}
972 
973 	@Test void i02b_noSchemaTests_ShortArray() throws Exception {
974 		assertEquals("1,32767,-32768,null", serialize((HttpPartSchema)null, new Short[]{Short.valueOf((short)1), Short.MAX_VALUE, Short.MIN_VALUE, null}));
975 	}
976 
977 	@Test void i03a_noSchemaTests_Long() throws Exception {
978 		for (var v : list(Long.valueOf(1), Long.MAX_VALUE, Long.MIN_VALUE))
979 			assertEquals(valueOf(v), serialize((HttpPartSchema)null, v));
980 	}
981 
982 	@Test void i03b_noSchemaTests_LongArray() throws Exception {
983 		assertEquals("1,9223372036854775807,-9223372036854775808,null", serialize((HttpPartSchema)null, new Long[]{Long.valueOf(1), Long.MAX_VALUE, Long.MIN_VALUE, null}));
984 	}
985 
986 	@Test void i04a_noSchemaTests_Float() throws Exception {
987 		for (var v : list(Float.valueOf(1f), Float.MAX_VALUE, Float.MIN_VALUE))
988 			assertEquals(valueOf(v), serialize((HttpPartSchema)null, v));
989 	}
990 
991 	@Test void i04b_noSchemaTests_FloatArray() throws Exception {
992 		assertEquals("1.0,3.4028235E38,1.4E-45", serialize((HttpPartSchema)null, new Float[]{Float.valueOf(1f), Float.MAX_VALUE, Float.MIN_VALUE}));
993 	}
994 
995 	@Test void i05a_noSchemaTests_Double() throws Exception {
996 		for (var v : list(Double.valueOf(1d), Double.MAX_VALUE, Double.MIN_VALUE))
997 			assertEquals(valueOf(v), serialize((HttpPartSchema)null, v));
998 	}
999 
1000 	@Test void i05b_noSchemaTests_DoubleArray() throws Exception {
1001 		assertEquals("1.0,1.7976931348623157E308,4.9E-324", serialize((HttpPartSchema)null, new Double[]{Double.valueOf(1), Double.MAX_VALUE, Double.MIN_VALUE}));
1002 	}
1003 
1004 	@Test void i06a_noSchemaTests_Boolean() throws Exception {
1005 		for (var v : list(Boolean.TRUE, Boolean.FALSE))
1006 			assertEquals(valueOf(v), serialize((HttpPartSchema)null, v));
1007 	}
1008 
1009 	@Test void i06b_noSchemaTests_BooleanArray() throws Exception {
1010 		assertEquals("true,false,null", serialize((HttpPartSchema)null, new Boolean[]{Boolean.TRUE, Boolean.FALSE, null}));
1011 	}
1012 
1013 	@Test void i07_noSchemaTests_Null() throws Exception {
1014 		assertEquals("null", serialize((HttpPartSchema)null, null));
1015 	}
1016 
1017 	@Test void i08a_noSchemaTests_String() throws Exception {
1018 		for (var v : list("foo", ""))
1019 			assertEquals(v, serialize((HttpPartSchema)null, v));
1020 	}
1021 	@Test void i08b_noSchemaTests_StringArray() throws Exception {
1022 		assertEquals("foo,,null", serialize((HttpPartSchema)null, new String[]{"foo", "", null}));
1023 	}
1024 }