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.jsonschema;
18  
19  import static org.apache.juneau.TestUtils.*;
20  import static org.apache.juneau.jsonschema.TypeCategory.*;
21  
22  import java.util.*;
23  
24  import org.apache.juneau.*;
25  import org.apache.juneau.annotation.*;
26  import org.apache.juneau.collections.*;
27  import org.apache.juneau.reflect.*;
28  import org.apache.juneau.swap.*;
29  import org.apache.juneau.testutils.pojos.*;
30  import org.junit.jupiter.api.*;
31  
32  class JsonSchemaGeneratorTest extends TestBase {
33  
34  	//====================================================================================================
35  	// Simple objects
36  	//====================================================================================================
37  
38  	@Test void simpleObjects() throws Exception {
39  		var s = JsonSchemaGenerator.DEFAULT.getSession();
40  
41  		assertBean(s.getSchema(short.class), "type,format", "integer,int16");
42  		assertBean(s.getSchema(Short.class), "type,format", "integer,int16");
43  		assertBean(s.getSchema(int.class), "type,format", "integer,int32");
44  		assertBean(s.getSchema(Integer.class), "type,format", "integer,int32");
45  		assertBean(s.getSchema(long.class), "type,format", "integer,int64");
46  		assertBean(s.getSchema(Long.class), "type,format", "integer,int64");
47  		assertBean(s.getSchema(float.class), "type,format", "number,float");
48  		assertBean(s.getSchema(Float.class), "type,format", "number,float");
49  		assertBean(s.getSchema(double.class), "type,format", "number,double");
50  		assertBean(s.getSchema(Double.class), "type,format", "number,double");
51  		assertBean(s.getSchema(boolean.class), "type", "boolean");
52  		assertBean(s.getSchema(Boolean.class), "type", "boolean");
53  		assertBean(s.getSchema(String.class), "type", "string");
54  		assertBean(s.getSchema(StringBuilder.class), "type", "string");
55  		assertBean(s.getSchema(char.class), "type", "string");
56  		assertBean(s.getSchema(Character.class), "type", "string");
57  		assertBean(s.getSchema(TestEnumToString.class), "type,enum", "string,[one,two,three]");
58  		assertBean(s.getSchema(SimpleBean.class), "type,properties{f1{type}}", "object,{{string}}");
59  	}
60  
61  	public static class SimpleBean {
62  		public String f1;
63  	}
64  
65  	//====================================================================================================
66  	// Arrays
67  	//====================================================================================================
68  
69  	@Test void arrays1d() throws Exception {
70  		var s = JsonSchemaGenerator.DEFAULT.getSession();
71  
72  		assertBean(s.getSchema(short[].class), "type,items{type,format}", "array,{integer,int16}");
73  		assertBean(s.getSchema(Short[].class), "type,items{type,format}", "array,{integer,int16}");
74  		assertBean(s.getSchema(int[].class), "type,items{type,format}", "array,{integer,int32}");
75  		assertBean(s.getSchema(Integer[].class), "type,items{type,format}", "array,{integer,int32}");
76  		assertBean(s.getSchema(long[].class), "type,items{type,format}", "array,{integer,int64}");
77  		assertBean(s.getSchema(Long[].class), "type,items{type,format}", "array,{integer,int64}");
78  		assertBean(s.getSchema(float[].class), "type,items{type,format}", "array,{number,float}");
79  		assertBean(s.getSchema(Float[].class), "type,items{type,format}", "array,{number,float}");
80  		assertBean(s.getSchema(double[].class), "type,items{type,format}", "array,{number,double}");
81  		assertBean(s.getSchema(Double[].class), "type,items{type,format}", "array,{number,double}");
82  		assertBean(s.getSchema(boolean[].class), "type,items{type}", "array,{boolean}");
83  		assertBean(s.getSchema(Boolean[].class), "type,items{type}", "array,{boolean}");
84  		assertBean(s.getSchema(String[].class), "type,items{type}", "array,{string}");
85  		assertBean(s.getSchema(StringBuilder[].class), "type,items{type}", "array,{string}");
86  		assertBean(s.getSchema(char[].class), "type,items{type}", "array,{string}");
87  		assertBean(s.getSchema(Character[].class), "type,items{type}", "array,{string}");
88  		assertBean(s.getSchema(TestEnumToString[].class), "type,items{type,enum}", "array,{string,[one,two,three]}");
89  		assertBean(s.getSchema(SimpleBean[].class), "type,items{type,properties{f1{type}}}", "array,{object,{{string}}}");
90  	}
91  
92  	@Test void arrays2d() throws Exception {
93  		var s = JsonSchemaGenerator.DEFAULT.getSession();
94  
95  		assertBean(s.getSchema(short[][].class), "type,items{type,items{type,format}}", "array,{array,{integer,int16}}");
96  		assertBean(s.getSchema(Short[][].class), "type,items{type,items{type,format}}", "array,{array,{integer,int16}}");
97  		assertBean(s.getSchema(int[][].class), "type,items{type,items{type,format}}", "array,{array,{integer,int32}}");
98  		assertBean(s.getSchema(Integer[][].class), "type,items{type,items{type,format}}", "array,{array,{integer,int32}}");
99  		assertBean(s.getSchema(long[][].class), "type,items{type,items{type,format}}", "array,{array,{integer,int64}}");
100 		assertBean(s.getSchema(Long[][].class), "type,items{type,items{type,format}}", "array,{array,{integer,int64}}");
101 		assertBean(s.getSchema(float[][].class), "type,items{type,items{type,format}}", "array,{array,{number,float}}");
102 		assertBean(s.getSchema(Float[][].class), "type,items{type,items{type,format}}", "array,{array,{number,float}}");
103 		assertBean(s.getSchema(double[][].class), "type,items{type,items{type,format}}", "array,{array,{number,double}}");
104 		assertBean(s.getSchema(Double[][].class), "type,items{type,items{type,format}}", "array,{array,{number,double}}");
105 		assertBean(s.getSchema(boolean[][].class), "type,items{type,items{type}}", "array,{array,{boolean}}");
106 		assertBean(s.getSchema(Boolean[][].class), "type,items{type,items{type}}", "array,{array,{boolean}}");
107 		assertBean(s.getSchema(String[][].class), "type,items{type,items{type}}", "array,{array,{string}}");
108 		assertBean(s.getSchema(StringBuilder[][].class), "type,items{type,items{type}}", "array,{array,{string}}");
109 		assertBean(s.getSchema(char[][].class), "type,items{type,items{type}}", "array,{array,{string}}");
110 		assertBean(s.getSchema(Character[][].class), "type,items{type,items{type}}", "array,{array,{string}}");
111 		assertBean(s.getSchema(TestEnumToString[][].class), "type,items{type,items{type,enum}}", "array,{array,{string,[one,two,three]}}");
112 		assertBean(s.getSchema(SimpleBean[][].class), "type,items{type,items{type,properties{f1{type}}}}", "array,{array,{object,{{string}}}}");
113 	}
114 
115 	//====================================================================================================
116 	// Collections
117 	//====================================================================================================
118 
119 	@Test void simpleList() throws Exception {
120 		var s = JsonSchemaGenerator.DEFAULT.getSession();
121 		assertBean(s.getSchema(SimpleList.class), "type,items{type,format}", "array,{integer,int32}");
122 	}
123 
124 	@SuppressWarnings("serial")
125 	public static class SimpleList extends LinkedList<Integer> {}
126 
127 	@Test void simpleList2d() throws Exception {
128 		var s = JsonSchemaGenerator.DEFAULT.getSession();
129 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int32'}}}", s.getSchema(Simple2dList.class));
130 	}
131 
132 	@SuppressWarnings("serial")
133 	public static class Simple2dList extends LinkedList<LinkedList<Integer>> {}
134 
135 	//====================================================================================================
136 	// Bean collections
137 	//====================================================================================================
138 
139 	@Test void beanList() throws Exception {
140 		var s = JsonSchemaGenerator.DEFAULT.getSession();
141 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanList.class));
142 	}
143 
144 	@SuppressWarnings("serial")
145 	public static class BeanList extends LinkedList<SimpleBean> {}
146 
147 	@Test void beanList2d() throws Exception {
148 		var s = JsonSchemaGenerator.DEFAULT.getSession();
149 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}}", s.getSchema(BeanList2d.class));
150 	}
151 
152 	@SuppressWarnings("serial")
153 	public static class BeanList2d extends LinkedList<LinkedList<SimpleBean>> {}
154 
155 	//====================================================================================================
156 	// Maps
157 	//====================================================================================================
158 
159 	@Test void beanMap() throws Exception {
160 		var s = JsonSchemaGenerator.DEFAULT.getSession();
161 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanMap.class));
162 	}
163 
164 	@SuppressWarnings("serial")
165 	public static class BeanMap extends LinkedHashMap<Integer,SimpleBean> {}
166 
167 	@Test void beanMap2d() throws Exception {
168 		var s = JsonSchemaGenerator.DEFAULT.getSession();
169 		assertJson("{type:'object',additionalProperties:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}}}}", s.getSchema(BeanMap2d.class));
170 	}
171 
172 	@SuppressWarnings("serial")
173 	public static class BeanMap2d extends LinkedHashMap<Integer,LinkedHashMap<Integer,SimpleBean>> {}
174 
175 
176 	//====================================================================================================
177 	// JSONSCHEMA_useBeanDefs
178 	//====================================================================================================
179 
180 	@Test void useBeanDefs() throws Exception {
181 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
182 		assertJson("{'$ref':'#/definitions/SimpleBean'}", s.getSchema(SimpleBean.class));
183 		assertJson("{SimpleBean:{type:'object',properties:{f1:{type:'string'}}}}", s.getBeanDefs());
184 	}
185 
186 	@Test void useBeanDefs_beanList() throws Exception {
187 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
188 		assertJson("{type:'array',items:{'$ref':'#/definitions/SimpleBean'}}", s.getSchema(BeanList.class));
189 		assertJson("{SimpleBean:{type:'object',properties:{f1:{type:'string'}}}}", s.getBeanDefs());
190 	}
191 
192 	@Test void useBeanDefs_beanList2d() throws Exception {
193 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
194 		assertJson("{type:'array',items:{type:'array',items:{'$ref':'#/definitions/SimpleBean'}}}", s.getSchema(BeanList2d.class));
195 		assertJson("{SimpleBean:{type:'object',properties:{f1:{type:'string'}}}}", s.getBeanDefs());
196 	}
197 
198 	@Test void useBeanDefs_beanArray2d() throws Exception {
199 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
200 		assertJson("{type:'array',items:{type:'array',items:{'$ref':'#/definitions/SimpleBean'}}}", s.getSchema(SimpleBean[][].class));
201 		assertJson("{SimpleBean:{type:'object',properties:{f1:{type:'string'}}}}", s.getBeanDefs());
202 	}
203 
204 	//====================================================================================================
205 	// JSONSCHEMA_useBeanDefs - preload definition.
206 	//====================================================================================================
207 
208 	@Test void beanDefsPreloaded() throws Exception {
209 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
210 		s.addBeanDef("SimpleBean", new JsonMap().append("test", 123));
211 		assertJson("{'$ref':'#/definitions/SimpleBean'}", s.getSchema(SimpleBean.class));
212 		assertJson("{SimpleBean:{test:123}}", s.getBeanDefs());
213 	}
214 
215 	@Test void useBeanDefsPreloaded_beanList() throws Exception {
216 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
217 		s.addBeanDef("SimpleBean", new JsonMap().append("test", 123));
218 		assertJson("{type:'array',items:{'$ref':'#/definitions/SimpleBean'}}", s.getSchema(BeanList.class));
219 		assertJson("{SimpleBean:{test:123}}", s.getBeanDefs());
220 	}
221 
222 	@Test void useBeanDefsPreloaded_beanList2d() throws Exception {
223 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
224 		s.addBeanDef("SimpleBean", new JsonMap().append("test", 123));
225 		assertJson("{type:'array',items:{type:'array',items:{'$ref':'#/definitions/SimpleBean'}}}", s.getSchema(BeanList2d.class));
226 		assertJson("{SimpleBean:{test:123}}", s.getBeanDefs());
227 	}
228 
229 	@Test void useBeanDefsPreloaded_beanArray2d() throws Exception {
230 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().build().getSession();
231 		s.addBeanDef("SimpleBean", new JsonMap().append("test", 123));
232 		assertJson("{type:'array',items:{type:'array',items:{'$ref':'#/definitions/SimpleBean'}}}", s.getSchema(SimpleBean[][].class));
233 		assertJson("{SimpleBean:{test:123}}", s.getBeanDefs());
234 	}
235 
236 	//====================================================================================================
237 	// JSONSCHEMA_beanDefMapper
238 	//====================================================================================================
239 
240 	@Test void customBeanDefMapper() throws Exception {
241 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().beanDefMapper(CustomBeanDefMapper.class).build().getSession();
242 		assertJson("{'$ref':'#/definitions/org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean'}", s.getSchema(SimpleBean.class));
243 		assertJson("{'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean':{type:'object',properties:{f1:{type:'string'}}}}", s.getBeanDefs());
244 	}
245 
246 	public static class CustomBeanDefMapper extends BasicBeanDefMapper {
247 		@Override
248 		public String getId(ClassMeta<?> cm) {
249 			return cm.getFullName();
250 		}
251 	}
252 
253 	@Test void customBeanDefMapper_customURI() throws Exception {
254 		var s = JsonSchemaGenerator.DEFAULT.copy().useBeanDefs().beanDefMapper(CustomBeanDefMapper2.class).build().getSession();
255 		assertJson("{'$ref':'/foo/bar/org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean'}", s.getSchema(SimpleBean.class));
256 		assertJson("{'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean':{type:'object',properties:{f1:{type:'string'}}}}", s.getBeanDefs());
257 	}
258 
259 	public static class CustomBeanDefMapper2 extends BasicBeanDefMapper {
260 
261 		public CustomBeanDefMapper2() {
262 			super("/foo/bar/{0}");
263 		}
264 		@Override
265 		public String getId(ClassMeta<?> cm) {
266 			return cm.getFullName();
267 		}
268 	}
269 
270 	//====================================================================================================
271 	// JSONSCHEMA_addExamples - BEAN
272 	//====================================================================================================
273 
274 	@Test void addExample_BEAN_noBeanExample() throws Exception {
275 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
276 		assertJson("{type:'object',properties:{f1:{type:'string'}}}", s.getSchema(SimpleBean.class));
277 	}
278 
279 	@Test void addExample_BEAN_exampleMethod() throws Exception {
280 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
281 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(B1.class));
282 	}
283 
284 	@Test void addExample_BEAN_exampleMethod_wDefault() throws Exception {
285 		var b = new B1();
286 		b.f1 = "baz";
287 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).example(B1.class, b).build().getSession();
288 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'baz'}}", s.getSchema(B1.class));
289 	}
290 
291 	@Test void addExample_BEAN_exampleMethod_array2d() throws Exception {
292 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
293 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B1[][].class));
294 	}
295 
296 	public static class B1 extends SimpleBean {
297 
298 		@Example
299 		public static B1 example() {
300 			var ex = new B1();
301 			ex.f1 = "foobar";
302 			return ex;
303 		}
304 	}
305 
306 	@Test void addExample_BEAN_exampleMethod_usingConfig() throws Exception {
307 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B1cConfig.class).build().getSession();
308 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(B1c.class));
309 	}
310 
311 	@Test void addExample_BEAN_exampleMethod_wDefault_usingConfig() throws Exception {
312 		var b = new B1c();
313 		b.f1 = "baz";
314 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B1cConfig.class).example(B1c.class, b).build().getSession();
315 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'baz'}}", s.getSchema(B1c.class));
316 	}
317 
318 	@Test void addExample_BEAN_exampleMethod_array2d_usingConfig() throws Exception {
319 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B1cConfig.class).build().getSession();
320 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B1c[][].class));
321 	}
322 
323 	@Example(on="Dummy1.example")
324 	@Example(on="B1c.example")
325 	@Example(on="Dummy2.example")
326 	private static class B1cConfig {}
327 
328 	public static class B1c extends SimpleBean {
329 
330 		public static B1c example() {
331 			var ex = new B1c();
332 			ex.f1 = "foobar";
333 			return ex;
334 		}
335 	}
336 
337 	@Test void addExample_BEAN_exampleMethodOverridden_wDefault() throws Exception {
338 		var b = new B2();
339 		b.f1 = "baz";
340 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).example(B2.class, b).build().getSession();
341 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'baz'}}", s.getSchema(B2.class));
342 	}
343 
344 	@Test void addExample_BEAN_exampleMethodOverridden_array2d() throws Exception {
345 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
346 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B2[][].class));
347 	}
348 
349 	public static class B2 extends B1 {
350 
351 		@Example
352 		public static B2 example2() {
353 			var ex = new B2();
354 			ex.f1 = "foobar";
355 			return ex;
356 		}
357 	}
358 
359 	@Test void addExample_BEAN_exampleMethodOverridden_wDefault_usingConfig() throws Exception {
360 		var b = new B2c();
361 		b.f1 = "baz";
362 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B2cConfig.class).example(B2c.class, b).build().getSession();
363 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'baz'}}", s.getSchema(B2c.class));
364 	}
365 
366 	@Test void addExample_BEAN_exampleMethodOverridden_array2d_usingConfig() throws Exception {
367 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B2cConfig.class).build().getSession();
368 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B2c[][].class));
369 	}
370 
371 	@Example(on="Dummy1.example2")
372 	@Example(on="B2c.example2")
373 	@Example(on="Dummy2.example2")
374 	private static class B2cConfig {}
375 
376 	public static class B2c extends B1c {
377 
378 		public static B2c example2() {
379 			var ex = new B2c();
380 			ex.f1 = "foobar";
381 			return ex;
382 		}
383 	}
384 
385 	@Test void addExample_BEAN_exampleField() throws Exception {
386 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
387 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(B3.class));
388 	}
389 
390 	@Test void addExample_BEAN_exampleField_array2d() throws Exception {
391 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
392 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B3[][].class));
393 	}
394 
395 	public static class B3 extends SimpleBean {
396 
397 		@Example
398 		public static B3 EXAMPLE = getExample();
399 
400 		private static B3 getExample() {
401 			var ex = new B3();
402 			ex.f1 = "foobar";
403 			return ex;
404 		}
405 	}
406 
407 	@Test void addExample_BEAN_exampleField_usingConfig() throws Exception {
408 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B3cConfig.class).build().getSession();
409 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(B3c.class));
410 	}
411 
412 	@Test void addExample_BEAN_exampleField_array2d_usingConfig() throws Exception {
413 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B3cConfig.class).build().getSession();
414 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B3c[][].class));
415 	}
416 
417 	@Example(on="B3c.EXAMPLE")
418 	private static class B3cConfig {}
419 
420 	public static class B3c extends SimpleBean {
421 
422 		public static B3c EXAMPLE = getExample();
423 
424 		private static B3c getExample() {
425 			var ex = new B3c();
426 			ex.f1 = "foobar";
427 			return ex;
428 		}
429 	}
430 
431 	@Test void addExample_BEAN_exampleBeanAnnotation() throws Exception {
432 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
433 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(B4.class));
434 	}
435 
436 	@Test void addExample_BEAN_exampleBeanAnnotation_2darray() throws Exception {
437 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).build().getSession();
438 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B4[][].class));
439 	}
440 
441 	@Example("{f1:'foobar'}")
442 	public static class B4 extends SimpleBean {}
443 
444 	@Test void addExample_BEAN_exampleBeanAnnotation_usingConfig() throws Exception {
445 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B4cConfig.class).build().getSession();
446 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(B4c.class));
447 	}
448 
449 	@Test void addExample_BEAN_exampleBeanAnnotation_2darray_usingConfig() throws Exception {
450 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).applyAnnotations(B4cConfig.class).build().getSession();
451 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(B4c[][].class));
452 	}
453 
454 	@Example(on="B4c", value="{f1:'foobar'}")
455 	private static class B4cConfig {}
456 
457 	public static class B4c extends SimpleBean {}
458 
459 	@Test void addExample_BEAN_exampleBeanProperty() throws Exception {
460 		var b = new SimpleBean();
461 		b.f1 = "foobar";
462 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).example(SimpleBean.class, b).build().getSession();
463 		assertJson("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(SimpleBean.class));
464 	}
465 
466 	@Test void addExample_BEAN_exampleBeanProperty_2darray() throws Exception {
467 		var b = new SimpleBean();
468 		b.f1 = "foobar";
469 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BEAN).example(SimpleBean.class, b).build().getSession();
470 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(SimpleBean[][].class));
471 	}
472 
473 	//====================================================================================================
474 	// JSONSCHEMA_addExamples - MAP
475 	//====================================================================================================
476 
477 	@Test void addExample_MAP_noExample() throws Exception {
478 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).build().getSession();
479 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanMap.class));
480 	}
481 
482 	@Test void addExample_MAP_exampleMethod() throws Exception {
483 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).build().getSession();
484 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(C1.class));
485 	}
486 
487 	@Test void addExample_MAP_exampleMethod_wDefault() throws Exception {
488 		var b = new C1();
489 		b.put(456, B1.example());
490 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).example(C1.class, b).build().getSession();
491 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'456':{f1:'foobar'}}}", s.getSchema(C1.class));
492 	}
493 
494 	@SuppressWarnings("serial")
495 	public static class C1 extends BeanMap {
496 
497 		@Example
498 		public static C1 example() {
499 			var m = new C1();
500 			m.put(123, B1.example());
501 			return m;
502 		}
503 	}
504 
505 	@Test void addExample_MAP_exampleMethod_usingConfig() throws Exception {
506 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).applyAnnotations(C1cConfig.class).build().getSession();
507 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(C1c.class));
508 	}
509 
510 	@Test void addExample_MAP_exampleMethod_wDefault_usingConfig() throws Exception {
511 		var b = new C1c();
512 		b.put(456, B1.example());
513 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).applyAnnotations(C1cConfig.class).example(C1c.class, b).build().getSession();
514 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'456':{f1:'foobar'}}}", s.getSchema(C1c.class));
515 	}
516 
517 	@Example(on="C1c.example")
518 	private static class C1cConfig {}
519 
520 	@SuppressWarnings("serial")
521 	public static class C1c extends BeanMap {
522 
523 		public static C1c example() {
524 			var m = new C1c();
525 			m.put(123, B1.example());
526 			return m;
527 		}
528 	}
529 
530 	@Test void addExample_MAP_exampleField() throws Exception {
531 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).build().getSession();
532 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(C2.class));
533 	}
534 
535 	@Test void addExample_MAP_exampleField_array2d() throws Exception {
536 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).build().getSession();
537 		assertJson("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}}}", s.getSchema(C2[][].class));
538 	}
539 
540 	@SuppressWarnings("serial")
541 	public static class C2 extends BeanMap {
542 
543 		@Example
544 		public static C2 EXAMPLE = getExample();
545 
546 		private static C2 getExample() {
547 			var ex = new C2();
548 			ex.put(123, B1.example());
549 			return ex;
550 		}
551 	}
552 
553 	@Test void addExample_MAP_exampleField_usingConfig() throws Exception {
554 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).applyAnnotations(C2cConfig.class).build().getSession();
555 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(C2c.class));
556 	}
557 
558 	@Test void addExample_MAP_exampleField_array2d_usingConfig() throws Exception {
559 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).applyAnnotations(C2cConfig.class).build().getSession();
560 		assertJson("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}}}", s.getSchema(C2c[][].class));
561 	}
562 
563 	@Example(on="C2c.EXAMPLE")
564 	private static class C2cConfig {}
565 
566 	@SuppressWarnings("serial")
567 	public static class C2c extends BeanMap {
568 
569 		public static C2c EXAMPLE = getExample();
570 
571 		private static C2c getExample() {
572 			var ex = new C2c();
573 			ex.put(123, B1.example());
574 			return ex;
575 		}
576 	}
577 
578 	@Test void addExample_MAP_exampleBeanAnnotation() throws Exception {
579 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).build().getSession();
580 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'baz'}}}", s.getSchema(C3.class));
581 	}
582 
583 	@Test void addExample_MAP_exampleBeanAnnotation_2darray() throws Exception {
584 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).build().getSession();
585 		assertJson("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'baz'}}}}}", s.getSchema(C3[][].class));
586 	}
587 
588 	@SuppressWarnings("serial")
589 	@Example("{'123':{f1:'baz'}}")
590 	public static class C3 extends BeanMap {}
591 
592 	@Test void addExample_MAP_exampleBeanAnnotation_usingConfig() throws Exception {
593 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).applyAnnotations(C3cConfig.class).build().getSession();
594 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'baz'}}}", s.getSchema(C3c.class));
595 	}
596 
597 	@Test void addExample_MAP_exampleBeanAnnotation_2darray_usingConfig() throws Exception {
598 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).applyAnnotations(C3cConfig.class).build().getSession();
599 		assertJson("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'baz'}}}}}", s.getSchema(C3c[][].class));
600 	}
601 
602 	@Example(on="C3c", value="{'123':{f1:'baz'}}")
603 	private static class C3cConfig {}
604 
605 	@SuppressWarnings("serial")
606 	public static class C3c extends BeanMap {}
607 
608 	@Test void addExample_MAP_exampleBeanProperty() throws Exception {
609 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).example(BeanMap.class, C1.example()).build().getSession();
610 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(BeanMap.class));
611 	}
612 
613 	@Test void addExample_MAP_exampleBeanProperty_2darray() throws Exception {
614 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(MAP).example(BeanMap.class, C1.example()).build().getSession();
615 		assertJson("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}}}", s.getSchema(BeanMap[][].class));
616 	}
617 
618 	//====================================================================================================
619 	// JSONSCHEMA_addExamples - COLLECTION / ARRAY
620 	//====================================================================================================
621 
622 	@Test void addExample_COLLECTION_noExample() throws Exception {
623 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).build().getSession();
624 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanList.class));
625 	}
626 
627 	@Test void addExample_COLLECTION_exampleMethod() throws Exception {
628 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).build().getSession();
629 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(D1.class));
630 	}
631 
632 	@Test void addExample_COLLECTION_exampleMethod_wDefault() throws Exception {
633 		var b = new D1();
634 		var sb = new SimpleBean();
635 		sb.f1 = "baz";
636 		b.add(sb);
637 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).example(D1.class, b).build().getSession();
638 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'baz'}]}", s.getSchema(D1.class));
639 	}
640 
641 	@SuppressWarnings("serial")
642 	public static class D1 extends BeanList {
643 
644 		@Example
645 		public static D1 example() {
646 			var m = new D1();
647 			m.add(B1.example());
648 			return m;
649 		}
650 	}
651 
652 	@Test void addExample_COLLECTION_exampleMethod_usingConfig() throws Exception {
653 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).applyAnnotations(D1c.class).build().getSession();
654 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(D1c.class));
655 	}
656 
657 	@Test void addExample_COLLECTION_exampleMethod_wDefault_usingConfig() throws Exception {
658 		var b = new D1c();
659 		var sb = new SimpleBean();
660 		sb.f1 = "baz";
661 		b.add(sb);
662 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).applyAnnotations(D1cConfig.class).example(D1c.class, b).build().getSession();
663 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'baz'}]}", s.getSchema(D1c.class));
664 	}
665 
666 	@Example(on="D1c.example")
667 	private static class D1cConfig {}
668 
669 	@SuppressWarnings("serial")
670 	public static class D1c extends BeanList {
671 
672 		public static D1c example() {
673 			var m = new D1c();
674 			m.add(B1.example());
675 			return m;
676 		}
677 	}
678 
679 	@Test void addExample_COLLECTION_exampleField() throws Exception {
680 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).build().getSession();
681 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(D2.class));
682 	}
683 
684 	@Test void addExample_ARRAY_exampleField_array2d() throws Exception {
685 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ARRAY).build().getSession();
686 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'foobar'}]]]}", s.getSchema(D2[][].class));
687 	}
688 
689 	@SuppressWarnings("serial")
690 	public static class D2 extends BeanList {
691 
692 		@Example
693 		public static D2 EXAMPLE = getExample();
694 
695 		private static D2 getExample() {
696 			var ex = new D2();
697 			ex.add(B1.example());
698 			return ex;
699 		}
700 	}
701 
702 	@Test void addExample_COLLECTION_exampleField_usingConfig() throws Exception {
703 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).applyAnnotations(D2cConfig.class).build().getSession();
704 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(D2c.class));
705 	}
706 
707 	@Test void addExample_ARRAY_exampleField_array2d_usingConfig() throws Exception {
708 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ARRAY).applyAnnotations(D2cConfig.class).build().getSession();
709 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'foobar'}]]]}", s.getSchema(D2c[][].class));
710 	}
711 
712 	@Example(on="D2c.EXAMPLE")
713 	private static class D2cConfig {}
714 
715 	@SuppressWarnings("serial")
716 	public static class D2c extends BeanList {
717 
718 		public static D2c EXAMPLE = getExample();
719 
720 		private static D2c getExample() {
721 			var ex = new D2c();
722 			ex.add(B1.example());
723 			return ex;
724 		}
725 	}
726 
727 	@Test void addExample_COLLECTION_exampleBeanAnnotation() throws Exception {
728 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).build().getSession();
729 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'baz'}]}", s.getSchema(D3.class));
730 	}
731 
732 	@Test void addExample_ARRAY_exampleBeanAnnotation_2darray() throws Exception {
733 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ARRAY).build().getSession();
734 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'baz'}]]]}", s.getSchema(D3[][].class));
735 	}
736 
737 	@SuppressWarnings("serial")
738 	@Example("[{f1:'baz'}]")
739 	public static class D3 extends BeanList {}
740 
741 	@Test void addExample_COLLECTION_exampleBeanAnnotation_usingConfig() throws Exception {
742 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).applyAnnotations(D3cConfig.class).build().getSession();
743 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'baz'}]}", s.getSchema(D3c.class));
744 	}
745 
746 	@Test void addExample_ARRAY_exampleBeanAnnotation_2darray_usingConfig() throws Exception {
747 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ARRAY).applyAnnotations(D3cConfig.class).build().getSession();
748 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'baz'}]]]}", s.getSchema(D3c[][].class));
749 	}
750 
751 	@Example(on="D3c", value="[{f1:'baz'}]")
752 	private static class D3cConfig {}
753 
754 	@SuppressWarnings("serial")
755 	public static class D3c extends BeanList {}
756 
757 	@Test void addExample_COLLECTION_exampleBeanProperty() throws Exception {
758 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(COLLECTION).example(BeanList.class, D1.example()).build().getSession();
759 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(BeanList.class));
760 	}
761 
762 	@Test void addExample_ARRAY_exampleBeanProperty_2darray() throws Exception {
763 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ARRAY).example(BeanList.class, D1.example()).build().getSession();
764 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'foobar'}]]]}", s.getSchema(BeanList[][].class));
765 	}
766 
767 	//====================================================================================================
768 	// JSONSCHEMA_addExamples - BOOLEAN
769 	//====================================================================================================
770 	@Test void addExample_BOOLEAN() throws Exception {
771 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BOOLEAN).build().getSession();
772 		assertJson("{type:'boolean',example:true}", s.getSchema(boolean.class));
773 		assertJson("{type:'boolean',example:true}", s.getSchema(Boolean.class));
774 	}
775 
776 	@Test void addExample_BOOLEAN_wDefault() throws Exception {
777 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BOOLEAN)
778 			.example(boolean.class, false)
779 			.example(Boolean.class, false)
780 			.build().getSession();
781 		assertJson("{type:'boolean',example:false}", s.getSchema(boolean.class));
782 		assertJson("{type:'boolean',example:false}", s.getSchema(Boolean.class));
783 	}
784 
785 	@Test void addExample_BOOLEAN_2darray() throws Exception {
786 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(BOOLEAN).build().getSession();
787 		assertJson("{type:'array',items:{type:'array',items:{type:'boolean',example:true}}}", s.getSchema(boolean[][].class));
788 		assertJson("{type:'array',items:{type:'array',items:{type:'boolean',example:true}}}", s.getSchema(Boolean[][].class));
789 	}
790 
791 	//====================================================================================================
792 	// JSONSCHEMA_addExamples - NUMBER
793 	//====================================================================================================
794 	@Test void addExample_NUMBER() throws Exception {
795 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(NUMBER).build().getSession();
796 		assertJson("{type:'integer',format:'int16',example:1}", s.getSchema(short.class));
797 		assertJson("{type:'integer',format:'int16',example:1}", s.getSchema(Short.class));
798 		assertJson("{type:'integer',format:'int32',example:1}", s.getSchema(int.class));
799 		assertJson("{type:'integer',format:'int32',example:1}", s.getSchema(Integer.class));
800 		assertJson("{type:'integer',format:'int64',example:1}", s.getSchema(long.class));
801 		assertJson("{type:'integer',format:'int64',example:1}", s.getSchema(Long.class));
802 		assertJson("{type:'number',format:'float',example:1.0}", s.getSchema(float.class));
803 		assertJson("{type:'number',format:'float',example:1.0}", s.getSchema(Float.class));
804 		assertJson("{type:'number',format:'double',example:1.0}", s.getSchema(double.class));
805 		assertJson("{type:'number',format:'double',example:1.0}", s.getSchema(Double.class));
806 	}
807 
808 	@Test void addExample_NUMBER_wDefault() throws Exception {
809 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(NUMBER)
810 			.example(short.class, (short)2)
811 			.example(Short.class, (short)3)
812 			.example(int.class, 4)
813 			.example(Integer.class, 5)
814 			.example(long.class, 6L)
815 			.example(Long.class, 7L)
816 			.example(float.class, 8f)
817 			.example(Float.class, 9f)
818 			.example(double.class, 10d)
819 			.example(Double.class, 11d)
820 			.build().getSession();
821 		assertJson("{type:'integer',format:'int16',example:2}", s.getSchema(short.class));
822 		assertJson("{type:'integer',format:'int16',example:3}", s.getSchema(Short.class));
823 		assertJson("{type:'integer',format:'int32',example:4}", s.getSchema(int.class));
824 		assertJson("{type:'integer',format:'int32',example:5}", s.getSchema(Integer.class));
825 		assertJson("{type:'integer',format:'int64',example:6}", s.getSchema(long.class));
826 		assertJson("{type:'integer',format:'int64',example:7}", s.getSchema(Long.class));
827 		assertJson("{type:'number',format:'float',example:8.0}", s.getSchema(float.class));
828 		assertJson("{type:'number',format:'float',example:9.0}", s.getSchema(Float.class));
829 		assertJson("{type:'number',format:'double',example:10.0}", s.getSchema(double.class));
830 		assertJson("{type:'number',format:'double',example:11.0}", s.getSchema(Double.class));
831 	}
832 
833 	@Test void addExample_NUMBER_2darray() throws Exception {
834 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(NUMBER).build().getSession();
835 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',example:1}}}", s.getSchema(short[][].class));
836 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',example:1}}}", s.getSchema(Short[][].class));
837 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int32',example:1}}}", s.getSchema(int[][].class));
838 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int32',example:1}}}", s.getSchema(Integer[][].class));
839 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int64',example:1}}}", s.getSchema(long[][].class));
840 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int64',example:1}}}", s.getSchema(Long[][].class));
841 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'float',example:1.0}}}", s.getSchema(float[][].class));
842 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'float',example:1.0}}}", s.getSchema(Float[][].class));
843 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'double',example:1.0}}}", s.getSchema(double[][].class));
844 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'double',example:1.0}}}", s.getSchema(Double[][].class));
845 	}
846 
847 	//====================================================================================================
848 	// JSONSCHEMA_addExamples - STRING
849 	//====================================================================================================
850 
851 	@Test void addExample_STRING() throws Exception {
852 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(STRING).build().getSession();
853 		assertJson("{type:'string',example:'foo'}", s.getSchema(String.class));
854 		assertJson("{type:'string',example:'foo'}", s.getSchema(StringBuilder.class));
855 		assertJson("{type:'string',example:'a'}", s.getSchema(Character.class));
856 		assertJson("{type:'string',example:'a'}", s.getSchema(char.class));
857 	}
858 
859 	@Test void addExample_STRING_wDefault() throws Exception {
860 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(STRING)
861 			.example(StringBuilder.class, new StringBuilder("foo"))
862 			.example(Character.class, 'b')
863 			.example(char.class, 'c')
864 			.build().getSession();
865 		assertJson("{type:'string',example:'foo'}", s.getSchema(StringBuilder.class));
866 		assertJson("{type:'string',example:'b'}", s.getSchema(Character.class));
867 		assertJson("{type:'string',example:'c'}", s.getSchema(char.class));
868 	}
869 
870 	@Test void addExample_STRING_2darray() throws Exception {
871 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(STRING).build().getSession();
872 		assertJson("{type:'array',items:{type:'array',items:{type:'string',example:'foo'}}}", s.getSchema(String[][].class));
873 		assertJson("{type:'array',items:{type:'array',items:{type:'string',example:'foo'}}}", s.getSchema(StringBuilder[][].class));
874 		assertJson("{type:'array',items:{type:'array',items:{type:'string',example:'a'}}}", s.getSchema(Character[][].class));
875 		assertJson("{type:'array',items:{type:'array',items:{type:'string',example:'a'}}}", s.getSchema(char[][].class));
876 	}
877 
878 	@Test void addExample_STRING_2darray_wDefault() throws Exception {
879 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(STRING)
880 			.example(StringBuilder.class, new StringBuilder("foo"))
881 			.example(Character.class, 'b')
882 			.example(char.class, 'c')
883 			.build().getSession();
884 		assertJson("{type:'array',items:{type:'array',items:{type:'string',example:'foo'}}}", s.getSchema(StringBuilder[][].class));
885 		assertJson("{type:'array',items:{type:'array',items:{type:'string',example:'b'}}}", s.getSchema(Character[][].class));
886 		assertJson("{type:'array',items:{type:'array',items:{type:'string',example:'c'}}}", s.getSchema(char[][].class));
887 	}
888 
889 	//====================================================================================================
890 	// JSONSCHEMA_addExamples - ENUM
891 	//====================================================================================================
892 
893 	@Test void addExample_ENUM() throws Exception {
894 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ENUM).build().getSession();
895 		assertJson("{type:'string','enum':['one','two','three'],example:'one'}", s.getSchema(TestEnumToString.class));
896 	}
897 
898 	@Test void addExample_ENUM_wDefault() throws Exception {
899 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ENUM).example(TestEnumToString.class, TestEnumToString.TWO).build().getSession();
900 		assertJson("{type:'string','enum':['one','two','three'],example:'two'}", s.getSchema(TestEnumToString.class));
901 	}
902 
903 	@Test void addExample_ENUM_2darray() throws Exception {
904 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ENUM).build().getSession();
905 		assertJson("{type:'array',items:{type:'array',items:{type:'string','enum':['one','two','three'],example:'one'}}}", s.getSchema(TestEnumToString[][].class));
906 	}
907 
908 	@Test void addExample_ENUM_useEnumNames() throws Exception {
909 		var s = JsonSchemaGenerator.DEFAULT.copy().useEnumNames().addExamplesTo(ENUM).build().getSession();
910 		assertJson("{type:'string','enum':['ONE','TWO','THREE'],example:'ONE'}", s.getSchema(TestEnumToString.class));
911 	}
912 
913 	@Test void addExample_ENUM_wDefault_useEnumNames() throws Exception {
914 		var s = JsonSchemaGenerator.DEFAULT.copy().useEnumNames().addExamplesTo(ENUM).example(TestEnumToString.class, "'TWO'").build().getSession();
915 		assertJson("{type:'string','enum':['ONE','TWO','THREE'],example:'TWO'}", s.getSchema(TestEnumToString.class));
916 	}
917 
918 	@Test void addExample_ENUM_2darray_useEnumNames() throws Exception {
919 		var s = JsonSchemaGenerator.DEFAULT.copy().useEnumNames().addExamplesTo(ENUM).build().getSession();
920 		assertJson("{type:'array',items:{type:'array',items:{type:'string','enum':['ONE','TWO','THREE'],example:'ONE'}}}", s.getSchema(TestEnumToString[][].class));
921 	}
922 
923 	//====================================================================================================
924 	// JSONSCHEMA_addExamples - ANY
925 	//====================================================================================================
926 	@Test void addExample_ANY() throws Exception {
927 		var s = JsonSchemaGenerator.DEFAULT.copy().addExamplesTo(ANY).build().getSession();
928 		assertJson("{type:'object',properties:{f1:{type:'string',example:'foo'}}}", s.getSchema(SimpleBean.class));
929 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(C1.class));
930 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(D1.class));
931 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'foobar'}]]]}", s.getSchema(D2[][].class));
932 		assertJson("{type:'boolean',example:true}", s.getSchema(boolean.class));
933 		assertJson("{type:'integer',format:'int16',example:1}", s.getSchema(short.class));
934 		assertJson("{type:'integer',format:'int16',example:1}", s.getSchema(Short.class));
935 		assertJson("{type:'integer',format:'int32',example:1}", s.getSchema(int.class));
936 		assertJson("{type:'integer',format:'int32',example:1}", s.getSchema(Integer.class));
937 		assertJson("{type:'integer',format:'int64',example:1}", s.getSchema(long.class));
938 		assertJson("{type:'integer',format:'int64',example:1}", s.getSchema(Long.class));
939 		assertJson("{type:'number',format:'float',example:1.0}", s.getSchema(float.class));
940 		assertJson("{type:'number',format:'float',example:1.0}", s.getSchema(Float.class));
941 		assertJson("{type:'number',format:'double',example:1.0}", s.getSchema(double.class));
942 		assertJson("{type:'number',format:'double',example:1.0}", s.getSchema(Double.class));
943 		assertJson("{type:'string',example:'foo'}", s.getSchema(String.class));
944 		assertJson("{type:'string',example:'foo'}", s.getSchema(StringBuilder.class));
945 		assertJson("{type:'string',example:'a'}", s.getSchema(Character.class));
946 		assertJson("{type:'string',example:'a'}", s.getSchema(char.class));
947 		assertJson("{type:'string','enum':['one','two','three'],example:'one'}", s.getSchema(TestEnumToString.class));
948 	}
949 
950 	//====================================================================================================
951 	// JSONSCHEMA_addDescriptionsTo - BEAN
952 	//====================================================================================================
953 
954 	@Test void addDescription_BEAN() throws Exception {
955 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(BEAN).build().getSession();
956 		assertJson("{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean'}", s.getSchema(SimpleBean.class));
957 	}
958 
959 	@Test void addDescription_BEAN_array2d() throws Exception {
960 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(BEAN).build().getSession();
961 		assertJson("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean'}}}", s.getSchema(SimpleBean[][].class));
962 	}
963 
964 	//====================================================================================================
965 	// JSONSCHEMA_addDescriptionsTo - MAP
966 	//====================================================================================================
967 
968 	@Test void addDescription_MAP() throws Exception {
969 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(MAP).build().getSession();
970 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanMap<java.lang.Integer,org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}", s.getSchema(BeanMap.class));
971 	}
972 
973 	@Test void addDescription_MAP_2darray() throws Exception {
974 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(MAP).build().getSession();
975 		assertJson("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanMap<java.lang.Integer,org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}}}", s.getSchema(BeanMap[][].class));
976 	}
977 
978 	//====================================================================================================
979 	// JSONSCHEMA_addDescriptionsTo - COLLECTION / ARRAY
980 	//====================================================================================================
981 
982 	@Test void addDescription_COLLECTION() throws Exception {
983 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(COLLECTION).build().getSession();
984 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanList<org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}", s.getSchema(BeanList.class));
985 	}
986 
987 	@Test void addDescription_COLLECTION_2darray() throws Exception {
988 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(COLLECTION).build().getSession();
989 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanList<org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}}}", s.getSchema(BeanList[][].class));
990 	}
991 
992 	@Test void addDescription_ARRAY() throws Exception {
993 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(ARRAY).build().getSession();
994 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanList<org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>[][]'}", s.getSchema(BeanList[][].class));
995 	}
996 
997 	//====================================================================================================
998 	// JSONSCHEMA_addDescriptionsTo - BOOLEAN
999 	//====================================================================================================
1000 	@Test void addDescription_BOOLEAN() throws Exception {
1001 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(BOOLEAN).build().getSession();
1002 		assertJson("{type:'boolean',description:'boolean'}", s.getSchema(boolean.class));
1003 		assertJson("{type:'boolean',description:'java.lang.Boolean'}", s.getSchema(Boolean.class));
1004 	}
1005 
1006 	@Test void addDescription_BOOLEAN_2darray() throws Exception {
1007 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(BOOLEAN).build().getSession();
1008 		assertJson("{type:'array',items:{type:'array',items:{type:'boolean',description:'boolean'}}}", s.getSchema(boolean[][].class));
1009 		assertJson("{type:'array',items:{type:'array',items:{type:'boolean',description:'java.lang.Boolean'}}}", s.getSchema(Boolean[][].class));
1010 	}
1011 
1012 	//====================================================================================================
1013 	// JSONSCHEMA_addDescriptionsTo - NUMBER
1014 	//====================================================================================================
1015 	@Test void addDescription_NUMBER() throws Exception {
1016 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(NUMBER).build().getSession();
1017 		assertJson("{type:'integer',format:'int16',description:'short'}", s.getSchema(short.class));
1018 		assertJson("{type:'integer',format:'int16',description:'java.lang.Short'}", s.getSchema(Short.class));
1019 		assertJson("{type:'integer',format:'int32',description:'int'}", s.getSchema(int.class));
1020 		assertJson("{type:'integer',format:'int32',description:'java.lang.Integer'}", s.getSchema(Integer.class));
1021 		assertJson("{type:'integer',format:'int64',description:'long'}", s.getSchema(long.class));
1022 		assertJson("{type:'integer',format:'int64',description:'java.lang.Long'}", s.getSchema(Long.class));
1023 		assertJson("{type:'number',format:'float',description:'float'}", s.getSchema(float.class));
1024 		assertJson("{type:'number',format:'float',description:'java.lang.Float'}", s.getSchema(Float.class));
1025 		assertJson("{type:'number',format:'double',description:'double'}", s.getSchema(double.class));
1026 		assertJson("{type:'number',format:'double',description:'java.lang.Double'}", s.getSchema(Double.class));
1027 	}
1028 
1029 	@Test void addDescription_NUMBER_2darray() throws Exception {
1030 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(NUMBER).build().getSession();
1031 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',description:'short'}}}", s.getSchema(short[][].class));
1032 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',description:'java.lang.Short'}}}", s.getSchema(Short[][].class));
1033 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int32',description:'int'}}}", s.getSchema(int[][].class));
1034 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int32',description:'java.lang.Integer'}}}", s.getSchema(Integer[][].class));
1035 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int64',description:'long'}}}", s.getSchema(long[][].class));
1036 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int64',description:'java.lang.Long'}}}", s.getSchema(Long[][].class));
1037 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'float',description:'float'}}}", s.getSchema(float[][].class));
1038 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'float',description:'java.lang.Float'}}}", s.getSchema(Float[][].class));
1039 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'double',description:'double'}}}", s.getSchema(double[][].class));
1040 		assertJson("{type:'array',items:{type:'array',items:{type:'number',format:'double',description:'java.lang.Double'}}}", s.getSchema(Double[][].class));
1041 	}
1042 
1043 	//====================================================================================================
1044 	// JSONSCHEMA_addDescriptionsTo - STRING
1045 	//====================================================================================================
1046 
1047 	@Test void addDescription_STRING() throws Exception {
1048 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(STRING).build().getSession();
1049 		assertJson("{type:'string',description:'java.lang.String'}", s.getSchema(String.class));
1050 		assertJson("{type:'string',description:'java.lang.StringBuilder'}", s.getSchema(StringBuilder.class));
1051 		assertJson("{type:'string',description:'java.lang.Character'}", s.getSchema(Character.class));
1052 		assertJson("{type:'string',description:'char'}", s.getSchema(char.class));
1053 	}
1054 
1055 	@Test void addDescription_STRING_2darray() throws Exception {
1056 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(STRING).build().getSession();
1057 		assertJson("{type:'array',items:{type:'array',items:{type:'string',description:'java.lang.String'}}}", s.getSchema(String[][].class));
1058 		assertJson("{type:'array',items:{type:'array',items:{type:'string',description:'java.lang.StringBuilder'}}}", s.getSchema(StringBuilder[][].class));
1059 		assertJson("{type:'array',items:{type:'array',items:{type:'string',description:'java.lang.Character'}}}", s.getSchema(Character[][].class));
1060 		assertJson("{type:'array',items:{type:'array',items:{type:'string',description:'char'}}}", s.getSchema(char[][].class));
1061 	}
1062 
1063 	//====================================================================================================
1064 	// JSONSCHEMA_addDescriptionsTo - ENUM
1065 	//====================================================================================================
1066 
1067 	@Test void addDescription_ENUM() throws Exception {
1068 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(ENUM).build().getSession();
1069 		assertJson("{type:'string','enum':['one','two','three'],description:'org.apache.juneau.testutils.pojos.TestEnumToString'}", s.getSchema(TestEnumToString.class));
1070 	}
1071 
1072 	@Test void addDescription_ENUM_2darray() throws Exception {
1073 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(ENUM).build().getSession();
1074 		assertJson("{type:'array',items:{type:'array',items:{type:'string','enum':['one','two','three'],description:'org.apache.juneau.testutils.pojos.TestEnumToString'}}}", s.getSchema(TestEnumToString[][].class));
1075 	}
1076 
1077 	//====================================================================================================
1078 	// JSONSCHEMA_addDescriptionsTo - ANY
1079 	//====================================================================================================
1080 	@Test void addDescription_ANY() throws Exception {
1081 		var s = JsonSchemaGenerator.DEFAULT.copy().addDescriptionsTo(ANY).build().getSession();
1082 		assertJson("{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean'}", s.getSchema(SimpleBean.class));
1083 		assertJson("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanMap<java.lang.Integer,org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}", s.getSchema(BeanMap.class));
1084 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanList<org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}", s.getSchema(BeanList.class));
1085 		assertJson("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanList<org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>[][]'}", s.getSchema(BeanList[][].class));
1086 		assertJson("{type:'boolean',description:'boolean'}", s.getSchema(boolean.class));
1087 		assertJson("{type:'boolean',description:'java.lang.Boolean'}", s.getSchema(Boolean.class));
1088 		assertJson("{type:'integer',format:'int16',description:'short'}", s.getSchema(short.class));
1089 		assertJson("{type:'integer',format:'int16',description:'java.lang.Short'}", s.getSchema(Short.class));
1090 		assertJson("{type:'integer',format:'int32',description:'int'}", s.getSchema(int.class));
1091 		assertJson("{type:'integer',format:'int32',description:'java.lang.Integer'}", s.getSchema(Integer.class));
1092 		assertJson("{type:'integer',format:'int64',description:'long'}", s.getSchema(long.class));
1093 		assertJson("{type:'integer',format:'int64',description:'java.lang.Long'}", s.getSchema(Long.class));
1094 		assertJson("{type:'number',format:'float',description:'float'}", s.getSchema(float.class));
1095 		assertJson("{type:'number',format:'float',description:'java.lang.Float'}", s.getSchema(Float.class));
1096 		assertJson("{type:'number',format:'double',description:'double'}", s.getSchema(double.class));
1097 		assertJson("{type:'number',format:'double',description:'java.lang.Double'}", s.getSchema(Double.class));
1098 		assertJson("{type:'string',description:'java.lang.String'}", s.getSchema(String.class));
1099 		assertJson("{type:'string',description:'java.lang.StringBuilder'}", s.getSchema(StringBuilder.class));
1100 		assertJson("{type:'string',description:'java.lang.Character'}", s.getSchema(Character.class));
1101 		assertJson("{type:'string',description:'char'}", s.getSchema(char.class));
1102 		assertJson("{type:'string','enum':['one','two','three'],description:'org.apache.juneau.testutils.pojos.TestEnumToString'}", s.getSchema(TestEnumToString.class));
1103 	}
1104 
1105 	//====================================================================================================
1106 	// JSONSCHEMA_allowNestedExamples
1107 	//====================================================================================================
1108 
1109 	@Test void allowNestedExamples_enabled() throws Exception {
1110 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy()
1111 			.allowNestedExamples()
1112 			.example(BeanList.class, new BeanList())
1113 			.example(SimpleBean.class, new SimpleBean())
1114 			.addExamplesTo(COLLECTION,BEAN)
1115 			.build().getSession();
1116 
1117 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanList.class));
1118 	}
1119 
1120 	@Test void allowNestedExamples_disabled() throws Exception {
1121 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy()
1122 			.example(BeanList.class, new BeanList())
1123 			.example(SimpleBean.class, new SimpleBean())
1124 			.addExamplesTo(COLLECTION,BEAN)
1125 			.build().getSession();
1126 
1127 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanList.class));
1128 	}
1129 
1130 	//====================================================================================================
1131 	// JSONSCHEMA_allowNestedDescriptions
1132 	//====================================================================================================
1133 
1134 	@Test void allowNestedDescriptions_enabled() throws Exception {
1135 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy()
1136 			.allowNestedDescriptions()
1137 			.addDescriptionsTo(COLLECTION,BEAN)
1138 			.build().getSession();
1139 
1140 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean'},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanList<org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}", s.getSchema(BeanList.class));
1141 	}
1142 
1143 	@Test void allowNestedDescriptions_disabled() throws Exception {
1144 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy()
1145 			.addDescriptionsTo(COLLECTION,BEAN)
1146 			.build().getSession();
1147 
1148 		assertJson("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$BeanList<org.apache.juneau.jsonschema.JsonSchemaGeneratorTest$SimpleBean>'}", s.getSchema(BeanList.class));
1149 	}
1150 
1151 	//====================================================================================================
1152 	// Swaps
1153 	//====================================================================================================
1154 
1155 	@Test void swaps_int() throws Exception {
1156 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy()
1157 			.swaps(IntSwap.class)
1158 			.build().getSession();
1159 		assertJson("{type:'integer',format:'int32'}", s.getSchema(SimpleBean.class));
1160 		assertJson("{type:'array',items:{type:'integer',format:'int32'}}", s.getSchema(BeanList.class));
1161 		assertJson("{type:'array',items:{type:'array',items:{type:'integer',format:'int32'}}}", s.getSchema(SimpleBean[][].class));
1162 	}
1163 
1164 	public static class IntSwap extends ObjectSwap<SimpleBean,Integer> {}
1165 
1166 	//====================================================================================================
1167 	// @JsonSchema on class
1168 	//====================================================================================================
1169 
1170 	@Test void jsonSchema_onclass() throws Exception {
1171 		var s = JsonSchemaGenerator.DEFAULT.copy().build().getSession();
1172 		assertJson("{description:'baz',format:'bar',type:'foo',properties:{f1:{type:'integer',format:'int32'}}}", s.getSchema(A1.class));
1173 	}
1174 
1175 	@Schema(type="foo",format="bar",description="baz")
1176 	public static class A1 {
1177 		public int f1;
1178 	}
1179 
1180 	@Test void jsonSchema_onclass_usingConfig() throws Exception {
1181 		var s = JsonSchemaGenerator.DEFAULT.copy().applyAnnotations(A1aConfig.class).build().getSession();
1182 		assertJson("{description:'baz',format:'bar',type:'foo',properties:{f1:{type:'integer',format:'int32'}}}", s.getSchema(A1a.class));
1183 	}
1184 
1185 	@Schema(on="Dummy1",type="foo",format="bar",description="baz")
1186 	@Schema(on="A1a",type="foo",format="bar",description="baz")
1187 	@Schema(on="Dummy2",type="foo",format="bar",description="baz")
1188 	private static class A1aConfig {}
1189 
1190 	public static class A1a {
1191 		public int f1;
1192 	}
1193 
1194 	@Test void jsonSchema_onbeanfield() throws Exception {
1195 		var s = JsonSchemaGenerator.DEFAULT.copy().build().getSession();
1196 		assertJson("{type:'object',properties:{f1:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(A2.class));
1197 	}
1198 
1199 	public static class A2 {
1200 		@Schema(type="foo",format="bar",description="baz")
1201 		public int f1;
1202 	}
1203 
1204 	@Test void jsonSchema_onbeanfield_usingConfig() throws Exception {
1205 		var s = JsonSchemaGenerator.DEFAULT.copy().applyAnnotations(A2aConfig.class).build().getSession();
1206 		assertJson("{type:'object',properties:{f1:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(A2a.class));
1207 	}
1208 
1209 	@Schema(on="A2a.f1",type="foo",format="bar",description="baz")
1210 	private static class A2aConfig {}
1211 
1212 	public static class A2a {
1213 		public int f1;
1214 	}
1215 
1216 	@Test void jsonSchema_onbeangetter() throws Exception {
1217 		var s = JsonSchemaGenerator.DEFAULT.copy().build().getSession();
1218 		assertJson("{type:'object',properties:{f1:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(A3.class));
1219 	}
1220 
1221 	public static class A3 {
1222 		@Schema(type="foo",format="bar",description="baz")
1223 		public int getF1() { return 123; }
1224 	}
1225 
1226 	@Test void jsonSchema_onbeangetter_usingConfig() throws Exception {
1227 		var s = JsonSchemaGenerator.DEFAULT.copy().applyAnnotations(A3aConfig.class).build().getSession();
1228 		assertJson("{type:'object',properties:{f1:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(A3a.class));
1229 	}
1230 
1231 	@Schema(on="A3a.getF1",type="foo",format="bar",description="baz")
1232 	private static class A3aConfig {}
1233 
1234 	public static class A3a {
1235 		public int getF1() { return 123; }
1236 	}
1237 
1238 	@Test void jsonSchema_onbeansetter() throws Exception {
1239 		var s = JsonSchemaGenerator.DEFAULT.copy().build().getSession();
1240 		assertJson("{type:'object',properties:{f1:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(A4.class));
1241 	}
1242 
1243 	public static class A4 {
1244 		public int getF1() { return 123; }
1245 
1246 		@Schema(type="foo",format="bar",description="baz")
1247 		public void setF1(int v) { /* no-op */ }
1248 	}
1249 
1250 	@Test void jsonSchema_onbeansetter_usingConfig() throws Exception {
1251 		var s = JsonSchemaGenerator.DEFAULT.copy().applyAnnotations(A4aConfig.class).build().getSession();
1252 		assertJson("{type:'object',properties:{f1:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(A4a.class));
1253 	}
1254 
1255 	@Schema(on="A4a.setF1",type="foo",format="bar",description="baz")
1256 	private static class A4aConfig {}
1257 
1258 	public static class A4a {
1259 		public int getF1() { return 123; }
1260 
1261 		public void setF1(int v) { /* no-op */ }
1262 	}
1263 
1264 	//====================================================================================================
1265 	// @JsonSchema on ObjectSwap
1266 	//====================================================================================================
1267 
1268 	@Test void jsonschema_onpojoswap() throws Exception {
1269 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy()
1270 			.swaps(SwapWithAnnotation.class)
1271 			.build().getSession();
1272 		assertJson("{description:'baz',format:'bar',type:'foo'}", s.getSchema(SimpleBean.class));
1273 		assertJson("{type:'array',items:{description:'baz',format:'bar',type:'foo'}}", s.getSchema(BeanList.class));
1274 		assertJson("{type:'array',items:{type:'array',items:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(SimpleBean[][].class));
1275 	}
1276 
1277 	@Schema(type="foo",format="bar",description="baz")
1278 	public static class SwapWithAnnotation extends ObjectSwap<SimpleBean,Integer> {}
1279 
1280 	@Test void jsonschema_onpojoswap_usingConfig() throws Exception {
1281 		JsonSchemaGeneratorSession s = JsonSchemaGenerator.DEFAULT.copy().applyAnnotations(SwapWithAnnotation2Config.class)
1282 			.swaps(SwapWithAnnotation2.class)
1283 			.build().getSession();
1284 		assertJson("{description:'baz',format:'bar',type:'foo'}", s.getSchema(SimpleBean.class));
1285 		assertJson("{type:'array',items:{description:'baz',format:'bar',type:'foo'}}", s.getSchema(BeanList.class));
1286 		assertJson("{type:'array',items:{type:'array',items:{description:'baz',format:'bar',type:'foo'}}}", s.getSchema(SimpleBean[][].class));
1287 	}
1288 
1289 	@Schema(on="SwapWithAnnotation2", type="foo",format="bar",description="baz")
1290 	private static class SwapWithAnnotation2Config {}
1291 
1292 	public static class SwapWithAnnotation2 extends ObjectSwap<SimpleBean,Integer> {}
1293 
1294 	//====================================================================================================
1295 	// @JsonSchema on ObjectSwap
1296 	//====================================================================================================
1297 
1298 	@Schema(onClass=B.class,$ref="ref")
1299 	static class BConfig {}
1300 
1301 	static class B {}
1302 	static ClassInfo bConfig = ClassInfo.of(BConfig.class);
1303 
1304 	@Test void schemaOnClass_onConfig() throws Exception {
1305 		var al = AnnotationWorkList.of(bConfig.getAnnotationList());
1306 		var x = JsonSchemaGenerator.create().apply(al).build().getSession();
1307 		assertContains("$ref", r(x.getSchema(new B())));
1308 	}
1309 
1310 }