1+ package org.openapijsonschematools.client.schemas
2+
3+ import org.openapijsonschematools.client.configurations.JsonSchemaKeywordFlags
4+ import org.openapijsonschematools.client.configurations.SchemaConfiguration
5+ import org.openapijsonschematools.client.exceptions.ValidationException
6+ import org.openapijsonschematools.client.schemas.validation.FrozenList
7+ import org.openapijsonschematools.client.schemas.validation.JsonSchema
8+ import org.openapijsonschematools.client.schemas.validation.JsonSchemaInfo
9+ import org.openapijsonschematools.client.schemas.validation.ListSchemaValidator
10+ import org.openapijsonschematools.client.schemas.validation.PathToSchemasMap
11+ import org.openapijsonschematools.client.schemas.validation.ValidationMetadata
12+ import kotlin.test.Test
13+ import kotlin.test.assertEquals
14+ import kotlin.test.assertFailsWith
15+
16+ class ArrayTypeSchemaTest {
17+ sealed interface ArrayWithItemsSchemaBoxed
18+
19+ data class ArrayWithItemsSchemaBoxedList (val data : FrozenList <String >) : ArrayWithItemsSchemaBoxed
20+ class ArrayWithItemsSchema : JsonSchema <ArrayWithItemsSchemaBoxed >(
21+ JsonSchemaInfo ()
22+ .type(setOf(List ::class.java))
23+ .items(StringJsonSchema .StringJsonSchema1 ::class.java)
24+ ), ListSchemaValidator<FrozenList<String>, ArrayWithItemsSchemaBoxedList> {
25+ override fun getNewInstance (
26+ arg : List <* >,
27+ pathToItem : List <Any >,
28+ pathToSchemas : PathToSchemasMap
29+ ): FrozenList <String > {
30+ val items: MutableList <String > = ArrayList ()
31+ var i = 0
32+ for (item in arg) {
33+ val itemPathToItem: MutableList <Any > = ArrayList (pathToItem)
34+ itemPathToItem.add(i)
35+ val schemas = pathToSchemas[itemPathToItem]
36+ ? : throw RuntimeException (" Validation result is invalid, schemas must exist for a pathToItem" )
37+ val itemSchema = schemas.entries.iterator().next().key
38+ val castItem = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas) as ? String
39+ ? : throw RuntimeException (" Instantiated type of item is invalid" )
40+ items.add(castItem)
41+ i + = 1
42+ }
43+ return FrozenList (items)
44+ }
45+
46+ @Throws(ValidationException ::class )
47+ override fun validate (arg : List <* >, configuration : SchemaConfiguration ? ): FrozenList <String > {
48+ val pathSet: MutableSet <List <Any >> = HashSet ()
49+ val pathToItem = listOf<Any >(" args[0" )
50+ val castArg: List <* > = castToAllowedTypes(arg, pathToItem, pathSet)
51+ val usedConfiguration = configuration ? : SchemaConfiguration (JsonSchemaKeywordFlags .Builder ().build())
52+ val validationMetadata =
53+ ValidationMetadata (pathToItem, usedConfiguration, PathToSchemasMap (), LinkedHashSet ())
54+ val pathToSchemasMap = getPathToSchemas(this , castArg, validationMetadata, pathSet)
55+ return getNewInstance(castArg, validationMetadata.pathToItem, pathToSchemasMap)
56+ }
57+
58+ @Throws(ValidationException ::class )
59+ override fun validateAndBox (arg : List <* >, configuration : SchemaConfiguration ? ): ArrayWithItemsSchemaBoxedList {
60+ return ArrayWithItemsSchemaBoxedList (validate(arg, configuration))
61+ }
62+
63+ override fun getNewInstance (arg : Any? , pathToItem : List <Any >, pathToSchemas : PathToSchemasMap ): Any? {
64+ if (arg is List <* >) {
65+ return getNewInstance(arg, pathToItem, pathToSchemas)
66+ }
67+ throw RuntimeException (" Invalid input type=$javaClass . It can't be instantiated by this schema" )
68+ }
69+
70+ @Throws(ValidationException ::class )
71+ override fun validate (arg : Any? , configuration : SchemaConfiguration ? ): Any? {
72+ if (arg is List <* >) {
73+ return validate(arg as List <* >? , configuration)
74+ }
75+ throw ValidationException (" Invalid input type=$javaClass . It can't be validated by this schema" )
76+ }
77+
78+ @Throws(ValidationException ::class )
79+ override fun validateAndBox (arg : Any? , configuration : SchemaConfiguration ? ): ArrayWithItemsSchemaBoxed {
80+ if (arg is List <* >) {
81+ return ArrayWithItemsSchemaBoxedList (validate(arg, configuration))
82+ }
83+ throw ValidationException (" Invalid input type=$javaClass . It can't be validated by this schema" )
84+ }
85+ }
86+
87+ class ArrayWithOutputClsSchemaList (m : FrozenList <String >) : FrozenList<String?>(m) {
88+ companion object {
89+ @Throws(ValidationException ::class )
90+ fun of (arg : List <String >, configuration : SchemaConfiguration ? ): ArrayWithOutputClsSchemaList {
91+ return ArrayWithOutputClsSchema ().validate(arg, configuration)
92+ }
93+ }
94+ }
95+
96+ interface ArrayWithOutputClsSchemaBoxed
97+
98+ data class ArrayWithOutputClsSchemaBoxedList (val data : ArrayWithOutputClsSchemaList ) :
99+ ArrayWithOutputClsSchemaBoxed
100+
101+ class ArrayWithOutputClsSchema : JsonSchema <ArrayWithOutputClsSchemaBoxed >(
102+ JsonSchemaInfo ()
103+ .type(setOf(List ::class.java))
104+ .items(StringJsonSchema .StringJsonSchema1 ::class.java)
105+ ), ListSchemaValidator<ArrayWithOutputClsSchemaList, ArrayWithOutputClsSchemaBoxedList> {
106+ override fun getNewInstance (
107+ arg : List <* >,
108+ pathToItem : List <Any >,
109+ pathToSchemas : PathToSchemasMap
110+ ): ArrayWithOutputClsSchemaList {
111+ val items: MutableList <String > = ArrayList ()
112+ var i = 0
113+ for (item in arg) {
114+ val itemPathToItem: MutableList <Any > = ArrayList (pathToItem)
115+ itemPathToItem.add(i)
116+ val schemas = pathToSchemas[itemPathToItem]
117+ ? : throw RuntimeException (" Validation result is invalid, schemas must exist for a pathToItem" )
118+ val itemSchema = schemas.entries.iterator().next().key
119+ val castItem = itemSchema.getNewInstance(item, itemPathToItem, pathToSchemas) as ? String
120+ ? : throw RuntimeException (" Instantiated type of item is invalid" )
121+ items.add(castItem)
122+ i + = 1
123+ }
124+ val newInstanceItems = FrozenList (items)
125+ return ArrayWithOutputClsSchemaList (newInstanceItems)
126+ }
127+
128+ @Throws(ValidationException ::class )
129+ override fun validate (arg : List <* >, configuration : SchemaConfiguration ? ): ArrayWithOutputClsSchemaList {
130+ val pathSet: MutableSet <List <Any >> = HashSet ()
131+ val pathToItem = listOf<Any >(" args[0" )
132+ val castArg: List <* > = castToAllowedTypes(arg, pathToItem, pathSet)
133+ val usedConfiguration = configuration ? : SchemaConfiguration (JsonSchemaKeywordFlags .Builder ().build())
134+ val validationMetadata =
135+ ValidationMetadata (pathToItem, usedConfiguration, PathToSchemasMap (), LinkedHashSet ())
136+ val pathToSchemasMap = getPathToSchemas(this , castArg, validationMetadata, pathSet)
137+ return getNewInstance(castArg, validationMetadata.pathToItem, pathToSchemasMap)
138+ }
139+
140+ @Throws(ValidationException ::class )
141+ override fun validateAndBox (
142+ arg : List <* >,
143+ configuration : SchemaConfiguration ?
144+ ): ArrayWithOutputClsSchemaBoxedList {
145+ return ArrayWithOutputClsSchemaBoxedList (validate(arg, configuration))
146+ }
147+
148+ override fun getNewInstance (arg : Any? , pathToItem : List <Any >, pathToSchemas : PathToSchemasMap ): Any? {
149+ if (arg is List <* >) {
150+ return getNewInstance(arg, pathToItem, pathToSchemas)
151+ }
152+ throw RuntimeException (" Invalid input type=$javaClass . It can't be instantiated by this schema" )
153+ }
154+
155+ @Throws(ValidationException ::class )
156+ override fun validate (arg : Any? , configuration : SchemaConfiguration ? ): Any? {
157+ if (arg is List <* >) {
158+ return validate(arg as List <* >? , configuration)
159+ }
160+ throw ValidationException (" Invalid input type=$javaClass . It can't be validated by this schema" )
161+ }
162+
163+ @Throws(ValidationException ::class )
164+ override fun validateAndBox (arg : Any? , configuration : SchemaConfiguration ? ): ArrayWithOutputClsSchemaBoxed {
165+ if (arg is List <* >) {
166+ return ArrayWithOutputClsSchemaBoxedList (validate(arg, configuration))
167+ }
168+ throw ValidationException (" Invalid input type=$javaClass . It can't be validated by this schema" )
169+ }
170+ }
171+
172+ @Test
173+ fun testExceptionThrownForInvalidType () {
174+ assertFailsWith<ValidationException >(
175+ block = {
176+ JsonSchema .validate(
177+ ArrayWithItemsSchema (),
178+ null ,
179+ validationMetadata
180+ )
181+ }
182+ )
183+ }
184+
185+ @Test
186+ @Throws(ValidationException ::class )
187+ fun testValidateArrayWithItemsSchema () {
188+ // list with only item works
189+ var inList: List <String > = listOf (" abc" )
190+ var validatedValue: FrozenList <String > = ArrayWithItemsSchema ().validate(inList, configuration)
191+ var outList: List <Any ?> = listOf (" abc" )
192+ assertEquals(validatedValue, outList)
193+
194+ // list with no items works
195+ inList = listOf ()
196+ validatedValue = ArrayWithItemsSchema ().validate(inList, configuration)
197+ outList = listOf ()
198+ assertEquals(validatedValue, outList)
199+
200+ // invalid item type fails
201+ val intList = listOf (1 )
202+ assertFailsWith<ValidationException >(
203+ block = {
204+ JsonSchema .validate(
205+ ArrayWithItemsSchema (),
206+ intList,
207+ validationMetadata
208+ )
209+ }
210+ )
211+ }
212+
213+ @Test
214+ @Throws(ValidationException ::class )
215+ fun testValidateArrayWithOutputClsSchema () {
216+ // list with only item works
217+ var inList: List <String > = listOf (" abc" )
218+ var validatedValue = ArrayWithOutputClsSchema ().validate(inList, configuration)
219+ var outList: List <Any ?> = listOf (" abc" )
220+ assertEquals(validatedValue, outList)
221+
222+ // list with no items works
223+ inList = listOf ()
224+ validatedValue = ArrayWithOutputClsSchema ().validate(inList, configuration)
225+ outList = listOf ()
226+ assertEquals(validatedValue, outList)
227+
228+ // invalid item type fails
229+ val intList = listOf (1 )
230+ assertFailsWith<ValidationException >(
231+ block = {
232+ JsonSchema .validate(
233+ ArrayWithOutputClsSchema (),
234+ intList,
235+ validationMetadata
236+ )
237+ }
238+ )
239+ }
240+
241+ companion object {
242+ val configuration = SchemaConfiguration (JsonSchemaKeywordFlags .Builder ().build())
243+ val validationMetadata = ValidationMetadata (
244+ listOf (" args[0" ),
245+ configuration,
246+ PathToSchemasMap (),
247+ LinkedHashSet ()
248+ )
249+ }
250+ }
0 commit comments