11package io.github.optimumcode.json.schema.base
22
33import com.eygraber.uri.Uri
4+ import io.github.optimumcode.json.schema.ErrorCollector
45import io.github.optimumcode.json.schema.JsonSchema
6+ import io.kotest.assertions.assertSoftly
57import io.kotest.assertions.throwables.shouldNotThrowAny
68import io.kotest.assertions.throwables.shouldThrow
79import io.kotest.assertions.withClue
810import io.kotest.core.spec.style.FunSpec
911import io.kotest.matchers.shouldBe
12+ import kotlinx.serialization.json.JsonPrimitive
13+ import kotlinx.serialization.json.buildJsonArray
14+ import kotlinx.serialization.json.buildJsonObject
1015
1116internal const val KEY = " \$ "
1217
@@ -261,5 +266,88 @@ class JsonSchemaTest : FunSpec() {
261266 }.message shouldBe " unsupported schema type $it "
262267 }
263268 }
269+
270+ test(" \$ dynamicRef is resolved every time" ) {
271+ val schema = JsonSchema .fromDefinition(
272+ """
273+ {
274+ "${KEY } schema": "https://json-schema.org/draft/2020-12/schema",
275+ "${KEY } id": "https://test.json-schema.org/dynamic-ref-with-multiple-paths/main",
276+ "if": {
277+ "properties": {
278+ "kindOfList": { "const": "numbers" }
279+ },
280+ "required": ["kindOfList"]
281+ },
282+ "then": { "${KEY } ref": "numberList" },
283+ "else": { "${KEY } ref": "stringList" },
284+
285+ "${KEY } defs": {
286+ "genericList": {
287+ "${KEY } id": "genericList",
288+ "properties": {
289+ "list": {
290+ "items": { "${KEY } dynamicRef": "#itemType" }
291+ }
292+ },
293+ "${KEY } defs": {
294+ "defaultItemType": {
295+ "${KEY } comment": "Only needed to satisfy bookending requirement",
296+ "${KEY } dynamicAnchor": "itemType"
297+ }
298+ }
299+ },
300+ "numberList": {
301+ "${KEY } id": "numberList",
302+ "${KEY } defs": {
303+ "itemType": {
304+ "${KEY } dynamicAnchor": "itemType",
305+ "type": "number"
306+ }
307+ },
308+ "${KEY } ref": "genericList"
309+ },
310+ "stringList": {
311+ "${KEY } id": "stringList",
312+ "${KEY } defs": {
313+ "itemType": {
314+ "${KEY } dynamicAnchor": "itemType",
315+ "type": "string"
316+ }
317+ },
318+ "${KEY } ref": "genericList"
319+ }
320+ }
321+ }
322+ """ .trimIndent(),
323+ )
324+ val numberList = buildJsonObject {
325+ put(" kindOfList" , JsonPrimitive (" numbers" ))
326+ put(
327+ " list" ,
328+ buildJsonArray {
329+ add(JsonPrimitive (42 ))
330+ },
331+ )
332+ }
333+ val stringsList = buildJsonObject {
334+ put(" kindOfList" , JsonPrimitive (" strings" ))
335+ put(
336+ " list" ,
337+ buildJsonArray {
338+ add(JsonPrimitive (" test" ))
339+ },
340+ )
341+ }
342+
343+ assertSoftly {
344+ withClue(" resolves into list of numbers" ) {
345+ schema.validate(numberList, ErrorCollector .EMPTY ) shouldBe true
346+ }
347+ withClue(" resolves into list of strings" ) {
348+ schema.validate(stringsList, ErrorCollector .EMPTY ) shouldBe true
349+ }
350+ }
351+ }
264352 }
265353}
0 commit comments