1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.juneau.bean.swagger;
18
19 import static org.apache.juneau.TestUtils.*;
20 import static org.apache.juneau.bean.swagger.SwaggerBuilder.*;
21 import static org.junit.jupiter.api.Assertions.*;
22
23 import java.net.*;
24 import java.util.*;
25
26 import org.apache.juneau.*;
27 import org.apache.juneau.collections.*;
28 import org.junit.jupiter.api.*;
29
30
31
32
33 class SchemaInfo_Test extends TestBase {
34
35 @Nested class A_basicTests extends TestBase {
36
37 private static final BeanTester<SchemaInfo> TESTER =
38 testBean(
39 bean()
40 .setAdditionalProperties(schemaInfo().setType("a"))
41 .setAllOf(set(schemaInfo().setType("b")))
42 .setDefault("c")
43 .setDescription("d")
44 .setDiscriminator("e")
45 .setEnum(set("f"))
46 .setExample("g")
47 .setExclusiveMaximum(true)
48 .setExclusiveMinimum(true)
49 .setExternalDocs(externalDocumentation().setUrl(URI.create("h")))
50 .setFormat("i")
51 .setItems(items().setType("j"))
52 .setMaximum(1)
53 .setMaxItems(2)
54 .setMaxLength(3)
55 .setMaxProperties(4)
56 .setMinimum(5)
57 .setMinItems(6)
58 .setMinLength(7)
59 .setMinProperties(8)
60 .setMultipleOf(9)
61 .setPattern("k")
62 .setProperties(map("x1", schemaInfo().setType("x2")))
63 .setReadOnly(true)
64 .setRef("l")
65 .setRequired(true)
66 .setRequiredProperties("m")
67 .setTitle("n")
68 .setType("o")
69 .setUniqueItems(true)
70 .setXml(xml().setName("p"))
71 )
72 .props("additionalProperties{type},allOf{#{type}},default,description,discriminator,enum,example,exclusiveMaximum,exclusiveMinimum,externalDocs{url},format,items{type},maximum,maxItems,maxLength,maxProperties,minimum,minItems,minLength,minProperties,multipleOf,pattern,properties{x1{type}},readOnly,ref,required,requiredProperties,title,type,uniqueItems,xml{name}")
73 .vals("{a},{[{b}]},c,d,e,[f],g,true,true,{h},i,{j},1,2,3,4,5,6,7,8,9,k,{{x2}},true,l,true,[m],n,o,true,{p}")
74 .json("{'$ref':'l',additionalProperties:{type:'a'},allOf:[{type:'b'}],'default':'c',description:'d',discriminator:'e','enum':['f'],example:'g',exclusiveMaximum:true,exclusiveMinimum:true,externalDocs:{url:'h'},format:'i',items:{type:'j'},maxItems:2,maxLength:3,maxProperties:4,maximum:1,minItems:6,minLength:7,minProperties:8,minimum:5,multipleOf:9,pattern:'k',properties:{x1:{type:'x2'}},readOnly:true,required:true,requiredProperties:['m'],title:'n',type:'o',uniqueItems:true,xml:{name:'p'}}")
75 .string("{'$ref':'l','additionalProperties':{'type':'a'},'allOf':[{'type':'b'}],'default':'c','description':'d','discriminator':'e','enum':['f'],'example':'g','exclusiveMaximum':true,'exclusiveMinimum':true,'externalDocs':{'url':'h'},'format':'i','items':{'type':'j'},'maxItems':2,'maxLength':3,'maxProperties':4,'maximum':1,'minItems':6,'minLength':7,'minProperties':8,'minimum':5,'multipleOf':9,'pattern':'k','properties':{'x1':{'type':'x2'}},'readOnly':true,'required':true,'requiredProperties':['m'],'title':'n','type':'o','uniqueItems':true,'xml':{'name':'p'}}".replace('\'', '"'))
76 ;
77
78 @Test void a01_gettersAndSetters() {
79 TESTER.assertGettersAndSetters();
80 }
81
82 @Test void a02_copy() {
83 TESTER.assertCopy();
84 }
85
86 @Test void a03_toJson() {
87 TESTER.assertToJson();
88 }
89
90 @Test void a04_fromJson() {
91 TESTER.assertFromJson();
92 }
93
94 @Test void a05_roundTrip() {
95 TESTER.assertRoundTrip();
96 }
97
98 @Test void a06_toString() {
99 TESTER.assertToString();
100 }
101
102 @Test void a07_keySet() {
103 assertList(TESTER.bean().keySet(), "$ref", "additionalProperties", "allOf", "default", "description", "discriminator", "enum", "example", "exclusiveMaximum", "exclusiveMinimum", "externalDocs", "format", "items", "maxItems", "maxLength", "maxProperties", "maximum", "minItems", "minLength", "minProperties", "minimum", "multipleOf", "pattern", "properties", "readOnly", "required", "requiredProperties", "title", "type", "uniqueItems", "xml");
104 }
105
106 @Test void a08_addMethods() {
107 var x = bean()
108 .addEnum("a1")
109 .setAllOf(schemaInfo().setTitle("a1"))
110 .addAllOf(schemaInfo().setTitle("a2"))
111 ;
112
113 assertNotNull(x);
114 assertNotNull(x.getEnum());
115 assertNotNull(x.getAllOf());
116 }
117
118 @Test void a09_asMap() {
119 assertBean(
120 bean()
121 .setDescription("a")
122 .setTitle("b")
123 .setType("c")
124 .set("x1", "x1a")
125 .asMap(),
126 "description,title,type,x1",
127 "a,b,c,x1a"
128 );
129 }
130
131 @Test void a10_extraKeys() {
132 var x = bean().set("x1", "x1a").set("x2", "x2a");
133 assertList(x.extraKeys(), "x1", "x2");
134 assertEmpty(bean().extraKeys());
135 }
136
137 @Test void a11_strictMode() {
138 assertThrows(RuntimeException.class, () -> bean().strict().set("foo", "bar"));
139 assertDoesNotThrow(() -> bean().set("foo", "bar"));
140
141 assertFalse(bean().isStrict());
142 assertTrue(bean().strict().isStrict());
143 assertFalse(bean().strict(false).isStrict());
144 }
145
146 @Test void a12_collectionSetters() {
147 var x = bean()
148 .setAllOf(list(schemaInfo().setType("a"), schemaInfo().setType("b")))
149 .setEnum(list("c", "d"))
150 .setRequiredProperties(list("e", "f"));
151
152 assertBean(x,
153 "allOf{#{type}},enum,requiredProperties",
154 "{[{a},{b}]},[c,d],[e,f]"
155 );
156 }
157
158 @Test void a13_varargAdders() {
159 var x = bean()
160 .addAllOf(schemaInfo().setType("a1"))
161 .addAllOf(schemaInfo().setType("a2"))
162 .addEnum("b1")
163 .addEnum("b2")
164 .addRequiredProperties("c1")
165 .addRequiredProperties("c2");
166
167 assertBean(x,
168 "allOf{#{type}},enum,requiredProperties",
169 "{[{a1},{a2}]},[b1,b2],[c1,c2]"
170 );
171 }
172
173 @Test void a14_collectionAdders() {
174
175
176
177 var x = bean()
178 .addAllOf(list(schemaInfo().setType("a1")))
179 .addAllOf(list(schemaInfo().setType("a2")))
180 .addEnum(list("b1"))
181 .addEnum(list("b2"))
182 .addRequiredProperties(list("c1"))
183 .addRequiredProperties(list("c2"));
184
185 assertBean(x,
186 "allOf{#{type}},enum,requiredProperties",
187 "{[{a1},{a2}]},[b1,b2],[c1,c2]"
188 );
189 }
190 }
191
192 @Nested class B_emptyTests extends TestBase {
193
194 private static final BeanTester<SchemaInfo> TESTER =
195 testBean(bean())
196 .props("description,title,type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,discriminator,readOnly,xml,externalDocs,example,required,properties,additionalProperties,allOf")
197 .vals("<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>,<null>")
198 .json("{}")
199 .string("{}")
200 ;
201
202 @Test void b01_gettersAndSetters() {
203 TESTER.assertGettersAndSetters();
204 }
205
206 @Test void b02_copy() {
207 TESTER.assertCopy();
208 }
209
210 @Test void b03_toJson() {
211 TESTER.assertToJson();
212 }
213
214 @Test void b04_fromJson() {
215 TESTER.assertFromJson();
216 }
217
218 @Test void b05_roundTrip() {
219 TESTER.assertRoundTrip();
220 }
221
222 @Test void b06_toString() {
223 TESTER.assertToString();
224 }
225
226 @Test void b07_keySet() {
227 assertEmpty(TESTER.bean().keySet());
228 }
229
230 @Test void b08_nullParameters() {
231 var x = bean();
232 assertThrows(IllegalArgumentException.class, () -> x.get(null, String.class));
233 assertThrows(IllegalArgumentException.class, () -> x.set(null, "value"));
234 }
235 }
236
237 @Nested class C_extraProperties extends TestBase {
238
239 private static final BeanTester<SchemaInfo> TESTER =
240 testBean(
241 bean()
242 .set("additionalProperties", schemaInfo().setType("a"))
243 .set("allOf", set(schemaInfo().setType("b")))
244 .set("default", "c")
245 .set("description", "d")
246 .set("discriminator", "e")
247 .set("enum", set("f"))
248 .set("example", "g")
249 .set("exclusiveMaximum", true)
250 .set("exclusiveMinimum", true)
251 .set("externalDocs", externalDocumentation().setUrl(URI.create("h")))
252 .set("format", "i")
253 .set("items", items().setType("j"))
254 .set("maximum", 1)
255 .set("maxItems", 2)
256 .set("maxLength", 3)
257 .set("maxProperties", 4)
258 .set("minimum", 5)
259 .set("minItems", 6)
260 .set("minLength", 7)
261 .set("minProperties", 8)
262 .set("multipleOf", 9)
263 .set("pattern", "k")
264 .set("properties", map("x1", schemaInfo().setType("x2")))
265 .set("readOnly", true)
266 .set("$ref", "l")
267 .set("required", true)
268 .set("requiredProperties", set("m"))
269 .set("title", "n")
270 .set("type", "o")
271 .set("uniqueItems", true)
272 .set("xml", xml().setName("p"))
273 .set("x1", "x1a")
274 .set("x2", null)
275 )
276 .props("additionalProperties{type},allOf,default,description,discriminator,enum,example,exclusiveMaximum,exclusiveMinimum,externalDocs{url},format,items{type},maximum,maxItems,maxLength,maxProperties,minimum,minItems,minLength,minProperties,multipleOf,pattern,properties{x1{type}},readOnly,ref,required,requiredProperties,title,type,uniqueItems,xml{name},x1,x2")
277 .vals("{a},[{\"type\":\"b\"}],c,d,e,[f],g,true,true,{h},i,{j},1,2,3,4,5,6,7,8,9,k,{{x2}},true,l,true,[m],n,o,true,{p},x1a,<null>")
278 .json("{'$ref':'l',additionalProperties:{type:'a'},allOf:[{type:'b'}],'default':'c',description:'d',discriminator:'e','enum':['f'],example:'g',exclusiveMaximum:true,exclusiveMinimum:true,externalDocs:{url:'h'},format:'i',items:{type:'j'},maxItems:2,maxLength:3,maxProperties:4,maximum:1,minItems:6,minLength:7,minProperties:8,minimum:5,multipleOf:9,pattern:'k',properties:{x1:{type:'x2'}},readOnly:true,required:true,requiredProperties:['m'],title:'n',type:'o',uniqueItems:true,x1:'x1a',xml:{name:'p'}}")
279 .string("{'$ref':'l','additionalProperties':{'type':'a'},'allOf':[{'type':'b'}],'default':'c','description':'d','discriminator':'e','enum':['f'],'example':'g','exclusiveMaximum':true,'exclusiveMinimum':true,'externalDocs':{'url':'h'},'format':'i','items':{'type':'j'},'maxItems':2,'maxLength':3,'maxProperties':4,'maximum':1,'minItems':6,'minLength':7,'minProperties':8,'minimum':5,'multipleOf':9,'pattern':'k','properties':{'x1':{'type':'x2'}},'readOnly':true,'required':true,'requiredProperties':['m'],'title':'n','type':'o','uniqueItems':true,'x1':'x1a','xml':{'name':'p'}}".replace('\'', '"'))
280 ;
281
282 @Test void c01_gettersAndSetters() {
283 TESTER.assertGettersAndSetters();
284 }
285
286 @Test void c02_copy() {
287 TESTER.assertCopy();
288 }
289
290 @Test void c03_toJson() {
291 TESTER.assertToJson();
292 }
293
294 @Test void c04_fromJson() {
295 TESTER.assertFromJson();
296 }
297
298 @Test void c05_roundTrip() {
299 TESTER.assertRoundTrip();
300 }
301
302 @Test void c06_toString() {
303 TESTER.assertToString();
304 }
305
306 @Test void c07_keySet() {
307 assertList(TESTER.bean().keySet(), "$ref", "additionalProperties", "allOf", "default", "description", "discriminator", "enum", "example", "exclusiveMaximum", "exclusiveMinimum", "externalDocs", "format", "items", "maxItems", "maxLength", "maxProperties", "maximum", "minItems", "minLength", "minProperties", "minimum", "multipleOf", "pattern", "properties", "readOnly", "required", "requiredProperties", "title", "type", "uniqueItems", "x1", "x2", "xml");
308 }
309
310 @Test void c08_get() {
311 assertMapped(
312 TESTER.bean(), (obj,prop) -> obj.get(prop, Object.class),
313 "additionalProperties{type},allOf{#{type}},default,description,discriminator,enum,example,exclusiveMaximum,exclusiveMinimum,externalDocs{url},format,items{type},maximum,maxItems,maxLength,maxProperties,minimum,minItems,minLength,minProperties,multipleOf,pattern,properties{x1{type}},readOnly,$ref,required,requiredProperties,title,type,uniqueItems,xml{name},x1,x2",
314 "{a},{[{b}]},c,d,e,[f],g,true,true,{h},i,{j},1,2,3,4,5,6,7,8,9,k,{{x2}},true,l,true,[m],n,o,true,{p},x1a,<null>"
315 );
316 }
317
318 @Test void c09_getTypes() {
319 assertMapped(
320 TESTER.bean(), (obj,prop) -> simpleClassNameOf(obj.get(prop, Object.class)),
321 "additionalProperties,allOf,default,description,discriminator,enum,example,exclusiveMaximum,exclusiveMinimum,externalDocs,format,items,maximum,maxItems,maxLength,maxProperties,minimum,minItems,minLength,minProperties,multipleOf,pattern,properties,readOnly,$ref,required,requiredProperties,title,type,uniqueItems,xml,x1,x2",
322 "SchemaInfo,LinkedHashSet,String,String,String,LinkedHashSet,String,Boolean,Boolean,ExternalDocumentation,String,Items,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,Integer,String,LinkedHashMap,Boolean,String,Boolean,LinkedHashSet,String,String,Boolean,Xml,String,<null>"
323 );
324 }
325
326 @Test void c10_nullPropertyValue() {
327 assertThrows(IllegalArgumentException.class, ()->bean().get(null));
328 assertThrows(IllegalArgumentException.class, ()->bean().get(null, String.class));
329 assertThrows(IllegalArgumentException.class, ()->bean().set(null, "a"));
330 }
331 }
332
333 @Nested class D_refs extends TestBase {
334
335 @Test void d01_resolveRefs_basic() {
336 var swagger = swagger()
337 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"))
338 .addDefinition("Pets", JsonMap.of("type", "array", "items", JsonMap.of("$ref", "#/definitions/Pet")));
339
340 assertBean(
341 schemaInfo().setRef("#/definitions/Pet").resolveRefs(swagger, new ArrayDeque<>(), 10),
342 "type,title",
343 "object,Pet"
344 );
345 }
346
347 @Test void d02_resolveRefs_nested() {
348 var swagger = swagger()
349 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"))
350 .addDefinition("Pets", JsonMap.of("type", "array", "items", JsonMap.of("$ref", "#/definitions/Pet")));
351
352 assertBean(
353 schemaInfo().setRef("#/definitions/Pets").resolveRefs(swagger, new ArrayDeque<>(), 10),
354 "type,items{type,title}",
355 "array,{object,Pet}"
356 );
357 }
358
359 @Test void d03_resolveRefs_maxDepth() {
360 var swagger = swagger()
361 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"))
362 .addDefinition("Pets", JsonMap.of("type", "array", "items", JsonMap.of("$ref", "#/definitions/Pet")));
363
364 assertBean(
365 schemaInfo().setRef("#/definitions/Pets").resolveRefs(swagger, new ArrayDeque<>(), 1),
366 "type,items{ref}",
367 "array,{#/definitions/Pet}"
368 );
369 }
370
371 @Test void d04_resolveRefs_circular() {
372 var swagger = swagger()
373 .addDefinition("A", JsonMap.of("type", "object", "title", "A", "properties", JsonMap.of("b", JsonMap.of("$ref", "#/definitions/B"))))
374 .addDefinition("B", JsonMap.of("type", "object", "title", "B", "properties", JsonMap.of("a", JsonMap.of("$ref", "#/definitions/A"))));
375
376 assertBean(
377 schemaInfo().setRef("#/definitions/A").resolveRefs(swagger, new ArrayDeque<>(), 10),
378 "type,title,properties{b{type,title,properties{a{ref}}}}",
379 "object,A,{{object,B,{{#/definitions/A}}}}"
380 );
381 }
382
383 @Test void d05_resolveRefs_properties() {
384 var swagger = swagger()
385 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
386
387 assertBean(
388 schemaInfo().setType("object").addProperty("pet", schemaInfo().setRef("#/definitions/Pet")).resolveRefs(swagger, new ArrayDeque<>(), 10),
389 "type,properties{pet{type,title}}",
390 "object,{{object,Pet}}"
391 );
392 }
393
394 @Test void d06_resolveRefs_additionalProperties() {
395 var swagger = swagger()
396 .addDefinition("Pet", JsonMap.of("type", "object", "title", "Pet"));
397
398 assertBean(
399 schemaInfo().setType("object").setAdditionalProperties(schemaInfo().setRef("#/definitions/Pet")).resolveRefs(swagger, new ArrayDeque<>(), 10),
400 "type,additionalProperties{type,title}",
401 "object,{object,Pet}"
402 );
403 }
404 }
405
406
407
408
409
410
411 private static SchemaInfo bean() {
412 return schemaInfo();
413 }
414
415 }