From aa8c55e21508a704bccb0177cee8a27ee3f21b16 Mon Sep 17 00:00:00 2001 From: seveneves Date: Fri, 26 Jul 2024 23:02:33 +0200 Subject: [PATCH 1/6] Support comparison of Schema generated from Tapir's Schema via `TapirSchemaToJsonSchema` `TapirSchemaToJsonSchema` generates JsonSchema specification `http://json-schema.org/draft/2020-12/schema#` and uses `#/$defs/` prefixes to locate reference to schemas stored in `Schema.$defs` field. This change adds support for both `#/$defs/` and `#/components/schemas/` and the choice is made by the user of `SchemaComparator` via the following helper methods * `SchemaResolver.components` * `SchemaResolver.defsSchemas` Closes #172 and #170 --- .../apispec/validation/SchemaComparator.scala | 83 ++----------------- .../apispec/validation/SchemaResolver.scala | 75 +++++++++++++++++ .../validation/SchemaComparatorTest.scala | 12 +-- 3 files changed, 90 insertions(+), 80 deletions(-) create mode 100644 apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala diff --git a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala index d931c5b..13be7c2 100644 --- a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala +++ b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala @@ -6,10 +6,6 @@ import scala.annotation.tailrec import scala.collection.immutable.ListMap import scala.collection.mutable -object SchemaComparator { - final val RefPrefix = "#/components/schemas/" -} - /** * Utility for comparing schemas for compatibility. * See [[compare]] for more details. @@ -17,16 +13,14 @@ object SchemaComparator { * Since this class contains a cache of comparison results, * it is meant to be reused between multiple schema comparisons. * - * @param writerNamedSchemas named schemas which may be referred to by the writer schema - * @param readerNamedSchemas named schemas which may be referred to by the reader schema + * @param writerSchemaResolver can resolve named schemas which may be referred to by the writer schema + * @param readerSchemaResolver can resolve named schemas which may be referred to by the reader schema */ class SchemaComparator( - writerNamedSchemas: Map[String, Schema], - readerNamedSchemas: Map[String, Schema] + writerSchemaResolver: SchemaResolver, + readerSchemaResolver: SchemaResolver ) { - import SchemaComparator._ - private val issuesCache = new mutable.HashMap[(Schema, Schema), List[SchemaCompatibilityIssue]] private val identicalityCache = new mutable.HashMap[(Schema, Schema), Boolean] @@ -65,54 +59,13 @@ class SchemaComparator( * @return a list of incompatibilities between the schemas */ def compare(writerSchema: SchemaLike, readerSchema: SchemaLike): List[SchemaCompatibilityIssue] = { - val normalizedWriterSchema = normalize(writerSchema, writerNamedSchemas) - val normalizedReaderSchema = normalize(readerSchema, readerNamedSchemas) + val normalizedWriterSchema = writerSchemaResolver.resolveAndNormalize(writerSchema) + val normalizedReaderSchema = readerSchemaResolver.resolveAndNormalize(readerSchema) computeCached(issuesCache, (normalizedWriterSchema, normalizedReaderSchema), Nil) { compareNormalized(normalizedWriterSchema, normalizedReaderSchema) } } - // translate AnySchema to Schema, remove annotations and resolve references - @tailrec private def normalize(schema: SchemaLike, named: Map[String, Schema]): Schema = schema match { - case AnySchema.Anything => Schema.Empty - case AnySchema.Nothing => Schema.Nothing - case s: Schema => deannotate(s) match { - case s@ReferenceSchema(LocalRef(name)) => - def noSchema: Nothing = - throw new NoSuchElementException(s"could not resolve schema reference ${s.$ref.get}") - - normalize(named.getOrElse(name, noSchema), named) - case s => s - } - } - - private object LocalRef { - def unapply(ref: String): Option[String] = - if (ref.startsWith(RefPrefix)) Some(ref.stripPrefix(RefPrefix)) - else None - } - - /** Matches a schema that is a pure reference to one of the component schemas */ - private object ReferenceSchema { - def unapply(schema: Schema): Option[String] = - schema.$ref.filter(ref => schema == Schema($ref = Some(ref))) - } - - // strip fields which do not affect schema comparison - private def deannotate(schema: Schema): Schema = - schema.copy( - $comment = None, - title = None, - description = None, - default = None, - deprecated = None, - readOnly = None, - writeOnly = None, - examples = None, - externalDocs = None, - extensions = ListMap.empty - ) - private def compareNormalized(writerSchema: Schema, readerSchema: Schema): List[SchemaCompatibilityIssue] = if (writerSchema == Schema.Nothing || readerSchema == Schema.Empty) { Nil @@ -145,8 +98,8 @@ class SchemaComparator( propIssues } else if (isDiscriminatedUnionSchema(writerSchema) && isDiscriminatedUnionSchema(readerSchema)) { - val writerMapping = discriminatorMapping(writerSchema) - val readerMapping = discriminatorMapping(readerSchema) + val writerMapping = writerSchemaResolver.discriminatorMapping(writerSchema) + val readerMapping = readerSchemaResolver.discriminatorMapping(readerSchema) val variantIssues: List[SchemaCompatibilityIssue] = (writerMapping.keySet intersect readerMapping.keySet).toList.flatMap { tag => @@ -234,7 +187,7 @@ class SchemaComparator( private def identical(writerSchema: Schema, readerSchema: Schema): Boolean = (writerSchema eq readerSchema) || computeCached(identicalityCache, (writerSchema, readerSchema), true) { def identicalSubschema(writerSubschema: SchemaLike, readerSubschema: SchemaLike): Boolean = - identical(normalize(writerSubschema, writerNamedSchemas), normalize(readerSubschema, readerNamedSchemas)) + identical(writerSchemaResolver.resolveAndNormalize(writerSubschema), readerSchemaResolver.resolveAndNormalize(readerSubschema)) def identicalSubschemaMap[K](writerSubschemas: ListMap[K, SchemaLike], readerSubschemas: ListMap[K, SchemaLike]): Boolean = (writerSubschemas.keySet ++ readerSubschemas.keySet).forall { key => @@ -358,24 +311,6 @@ class SchemaComparator( private def isDiscriminatedUnionSchema(s: Schema): Boolean = s.discriminator.nonEmpty && isUnionSchema(s) - /** - * Returns a mapping from discriminator values to schemas associated with them. - * All the schemas in the result are references (local or non-local). - */ - private def discriminatorMapping(schema: Schema): ListMap[String, Schema] = { - // schema reference -> overridden discriminator value - val explicitDiscValueByRef = schema.discriminator.flatMap(_.mapping).getOrElse(ListMap.empty).map(_.swap) - // assuming that schema is valid and every reference in disc.mapping is also an element of oneOf/anyOf - ListMap.empty ++ (schema.oneOf ++ schema.anyOf).collect { - case s@ReferenceSchema(ref) => - val discValue = explicitDiscValueByRef.getOrElse(ref, ref match { - case LocalRef(name) => name - case _ => throw new NoSuchElementException(s"no discriminator value specified for non-local reference $ref") - }) - discValue -> s - } - } - private def getTypes(schema: Schema): Option[List[SchemaType]] = schema match { case Schema.Empty => Some(SchemaType.Values) case Schema.Nothing => Some(Nil) diff --git a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala new file mode 100644 index 0000000..c4f381b --- /dev/null +++ b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala @@ -0,0 +1,75 @@ +package sttp.apispec.validation + +import sttp.apispec.{AnySchema, Schema, SchemaLike} + +import scala.annotation.tailrec +import scala.collection.immutable.ListMap + +class SchemaResolver(schemas: Map[String, Schema], referencePrefix: String) { + + def discriminatorMapping(schema: Schema): ListMap[String, Schema] = { + // schema reference -> overridden discriminator value + val explicitDiscValueByRef = schema.discriminator.flatMap(_.mapping).getOrElse(ListMap.empty).map(_.swap) + // assuming that schema is valid and every reference in disc.mapping is also an element of oneOf/anyOf + ListMap.empty ++ (schema.oneOf ++ schema.anyOf).collect { case s @ ReferenceSchema(ref) => + val discValue = explicitDiscValueByRef.getOrElse( + ref, + ref match { + case Reference(name) => name + case _ => throw new NoSuchElementException(s"no discriminator value specified for non-local reference $ref") + } + ) + discValue -> s + } + } + + @tailrec final def resolveAndNormalize(schema: SchemaLike): Schema = schema match { + case AnySchema.Anything => Schema.Empty + case AnySchema.Nothing => Schema.Nothing + case s @ ReferenceSchema(Reference(name)) => + resolveAndNormalize( + schemas.getOrElse(name, throw new NoSuchElementException(s"could not resolve schema reference ${s.$ref.get}")) + ) + case s: Schema => normalize(s) + } + + private object ReferenceSchema { + def unapply(schema: Schema): Option[String] = + schema.$ref.filter(ref => schema == Schema($ref = Some(ref))) + } + + private object Reference { + def unapply(ref: String): Option[String] = Option(ref) + .filter(_.startsWith(referencePrefix)) + .map(_.stripPrefix(referencePrefix)) + } + + private def normalize(schema: Schema): Schema = + schema.copy( + $comment = None, + $defs = None, + $schema = None, + title = None, + description = None, + default = None, + deprecated = None, + readOnly = None, + writeOnly = None, + examples = None, + externalDocs = None, + extensions = ListMap.empty + ) +} + +object SchemaResolver { + val ComponentsRefPrefix = "#/components/schemas/" + + val DefsRefPrefix = "#/$defs/" + + def components(schemas: Map[String, Schema]): SchemaResolver = new SchemaResolver(schemas, ComponentsRefPrefix) + + def defsSchemas(schema: Schema): SchemaResolver = new SchemaResolver( + schema.$defs.getOrElse(Map.empty).collect { case (name, s: Schema) => name -> s }, + DefsRefPrefix + ) +} diff --git a/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala b/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala index 912eac0..a3d9301 100644 --- a/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala +++ b/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala @@ -2,7 +2,6 @@ package sttp.apispec.validation import org.scalatest.funsuite.AnyFunSuite import sttp.apispec._ -import sttp.apispec.validation.SchemaComparator.RefPrefix import scala.collection.immutable.ListMap @@ -108,10 +107,11 @@ class SchemaComparatorTest extends AnyFunSuite { ) private def ref(name: String): Schema = - Schema.referenceTo(SchemaComparator.RefPrefix, name) + Schema.referenceTo(SchemaResolver.ComponentsRefPrefix, name) private def compare(writerSchema: Schema, readerSchema: Schema): List[SchemaCompatibilityIssue] = - new SchemaComparator(writerSchemas, readerSchemas).compare(writerSchema, readerSchema) + new SchemaComparator(SchemaResolver.components(writerSchemas), SchemaResolver.components(readerSchemas)) + .compare(writerSchema, readerSchema) test("ignoring annotations") { assert(compare( @@ -481,11 +481,11 @@ class SchemaComparatorTest extends AnyFunSuite { assert(compare( Schema( oneOf = List(ref("Foo"), ref("Bar")), - discriminator = Some(Discriminator("type", Some(ListMap("WFoo" -> s"${RefPrefix}Foo")))) + discriminator = Some(Discriminator("type", Some(ListMap("WFoo" -> s"${SchemaResolver.ComponentsRefPrefix}Foo")))) ), Schema( oneOf = List(ref("Foo"), ref("Bar"), ref("Baz")), - discriminator = Some(Discriminator("type", Some(ListMap("RBar" -> s"${RefPrefix}Bar")))) + discriminator = Some(Discriminator("type", Some(ListMap("RBar" -> s"${SchemaResolver.ComponentsRefPrefix}Bar")))) ), ) == List( UnsupportedDiscriminatorValues(List("WFoo", "Bar")) @@ -496,7 +496,7 @@ class SchemaComparatorTest extends AnyFunSuite { assert(compare( Schema( oneOf = List(ref("Foo"), ref("Bar")), - discriminator = Some(Discriminator("type", Some(ListMap("Baz" -> s"${RefPrefix}Bar")))) + discriminator = Some(Discriminator("type", Some(ListMap("Baz" -> s"${SchemaResolver.ComponentsRefPrefix}Bar")))) ), Schema( oneOf = List(ref("Foo"), ref("Baz")), From e6568be9b15dd4c420e4a55d683e6fa306c0670d Mon Sep 17 00:00:00 2001 From: seveneves Date: Sun, 28 Jul 2024 09:21:28 +0200 Subject: [PATCH 2/6] Add a second constructor to support compatibility --- .../scala/sttp/apispec/validation/SchemaComparator.scala | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala index 13be7c2..fac8086 100644 --- a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala +++ b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala @@ -21,6 +21,11 @@ class SchemaComparator( readerSchemaResolver: SchemaResolver ) { + def this( + writerNamedSchemas: Map[String, Schema], + readerNamedSchemas: Map[String, Schema] + ) = this(SchemaResolver.components(writerNamedSchemas), SchemaResolver.components(readerNamedSchemas)) + private val issuesCache = new mutable.HashMap[(Schema, Schema), List[SchemaCompatibilityIssue]] private val identicalityCache = new mutable.HashMap[(Schema, Schema), Boolean] From b50e1f4e026e4509c6067866a9b2b5e970a74336 Mon Sep 17 00:00:00 2001 From: seveneves Date: Wed, 7 Aug 2024 12:58:17 +0300 Subject: [PATCH 3/6] Support both "#/components/schemas/" and "#/$defs/" in a single `SchemaResolver` --- .../apispec/validation/SchemaResolver.scala | 27 ++++++++++--------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala index c4f381b..2af4b92 100644 --- a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala +++ b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala @@ -5,7 +5,7 @@ import sttp.apispec.{AnySchema, Schema, SchemaLike} import scala.annotation.tailrec import scala.collection.immutable.ListMap -class SchemaResolver(schemas: Map[String, Schema], referencePrefix: String) { +class SchemaResolver(schemas: Map[String, Schema]) { def discriminatorMapping(schema: Schema): ListMap[String, Schema] = { // schema reference -> overridden discriminator value @@ -15,7 +15,7 @@ class SchemaResolver(schemas: Map[String, Schema], referencePrefix: String) { val discValue = explicitDiscValueByRef.getOrElse( ref, ref match { - case Reference(name) => name + case SchemaResolver.Reference(name) => name case _ => throw new NoSuchElementException(s"no discriminator value specified for non-local reference $ref") } ) @@ -26,7 +26,7 @@ class SchemaResolver(schemas: Map[String, Schema], referencePrefix: String) { @tailrec final def resolveAndNormalize(schema: SchemaLike): Schema = schema match { case AnySchema.Anything => Schema.Empty case AnySchema.Nothing => Schema.Nothing - case s @ ReferenceSchema(Reference(name)) => + case s @ ReferenceSchema(SchemaResolver.Reference(name)) => resolveAndNormalize( schemas.getOrElse(name, throw new NoSuchElementException(s"could not resolve schema reference ${s.$ref.get}")) ) @@ -38,12 +38,6 @@ class SchemaResolver(schemas: Map[String, Schema], referencePrefix: String) { schema.$ref.filter(ref => schema == Schema($ref = Some(ref))) } - private object Reference { - def unapply(ref: String): Option[String] = Option(ref) - .filter(_.startsWith(referencePrefix)) - .map(_.stripPrefix(referencePrefix)) - } - private def normalize(schema: Schema): Schema = schema.copy( $comment = None, @@ -66,10 +60,17 @@ object SchemaResolver { val DefsRefPrefix = "#/$defs/" - def components(schemas: Map[String, Schema]): SchemaResolver = new SchemaResolver(schemas, ComponentsRefPrefix) + private val Reference = new References(ComponentsRefPrefix, DefsRefPrefix) + + private class References(prefix: String*) { + def unapply(ref: String): Option[String] = prefix.flatMap { p => + Option(ref).filter(_.startsWith(p)).map(_.stripPrefix(p)) + }.headOption + } + + def components(schemas: Map[String, Schema]): SchemaResolver = new SchemaResolver(schemas) - def defsSchemas(schema: Schema): SchemaResolver = new SchemaResolver( - schema.$defs.getOrElse(Map.empty).collect { case (name, s: Schema) => name -> s }, - DefsRefPrefix + def defs(schema: Schema): SchemaResolver = new SchemaResolver( + schema.$defs.getOrElse(Map.empty).collect { case (name, s: Schema) => name -> s } ) } From 86fa82ad101570f0274b961daa4b58be0863fd21 Mon Sep 17 00:00:00 2001 From: seveneves Date: Wed, 7 Aug 2024 13:00:36 +0300 Subject: [PATCH 4/6] Rename to apply --- .../main/scala/sttp/apispec/validation/SchemaResolver.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala index 2af4b92..f071170 100644 --- a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala +++ b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaResolver.scala @@ -68,9 +68,9 @@ object SchemaResolver { }.headOption } - def components(schemas: Map[String, Schema]): SchemaResolver = new SchemaResolver(schemas) + def apply(schemas: Map[String, Schema]): SchemaResolver = new SchemaResolver(schemas) - def defs(schema: Schema): SchemaResolver = new SchemaResolver( + def apply(schema: Schema): SchemaResolver = new SchemaResolver( schema.$defs.getOrElse(Map.empty).collect { case (name, s: Schema) => name -> s } ) } From c88ce940d9cbe377c8c1c7dcecca123568c6831b Mon Sep 17 00:00:00 2001 From: seveneves Date: Wed, 7 Aug 2024 13:04:04 +0300 Subject: [PATCH 5/6] Fix compilation --- .../main/scala/sttp/apispec/validation/SchemaComparator.scala | 2 +- .../scala/sttp/apispec/validation/SchemaComparatorTest.scala | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala index fac8086..deefb55 100644 --- a/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala +++ b/apispec-model/src/main/scala/sttp/apispec/validation/SchemaComparator.scala @@ -24,7 +24,7 @@ class SchemaComparator( def this( writerNamedSchemas: Map[String, Schema], readerNamedSchemas: Map[String, Schema] - ) = this(SchemaResolver.components(writerNamedSchemas), SchemaResolver.components(readerNamedSchemas)) + ) = this(SchemaResolver(writerNamedSchemas), SchemaResolver(readerNamedSchemas)) private val issuesCache = new mutable.HashMap[(Schema, Schema), List[SchemaCompatibilityIssue]] private val identicalityCache = new mutable.HashMap[(Schema, Schema), Boolean] diff --git a/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala b/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala index a3d9301..848c014 100644 --- a/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala +++ b/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala @@ -110,7 +110,7 @@ class SchemaComparatorTest extends AnyFunSuite { Schema.referenceTo(SchemaResolver.ComponentsRefPrefix, name) private def compare(writerSchema: Schema, readerSchema: Schema): List[SchemaCompatibilityIssue] = - new SchemaComparator(SchemaResolver.components(writerSchemas), SchemaResolver.components(readerSchemas)) + new SchemaComparator(writerSchemas, readerSchemas) .compare(writerSchema, readerSchema) test("ignoring annotations") { From 02d61a1769a5c1edf9a6d29cdf44ddf46455b36d Mon Sep 17 00:00:00 2001 From: seveneves Date: Wed, 7 Aug 2024 14:31:06 +0300 Subject: [PATCH 6/6] Add test for both "#/components/schemas/" and "#/$defs/" --- .../validation/ComponentsSchemaComparatorTest.scala | 3 +++ .../apispec/validation/DefsSchemaComparatorTest.scala | 3 +++ .../apispec/validation/SchemaComparatorTest.scala | 11 ++++++----- 3 files changed, 12 insertions(+), 5 deletions(-) create mode 100644 apispec-model/src/test/scala/sttp/apispec/validation/ComponentsSchemaComparatorTest.scala create mode 100644 apispec-model/src/test/scala/sttp/apispec/validation/DefsSchemaComparatorTest.scala diff --git a/apispec-model/src/test/scala/sttp/apispec/validation/ComponentsSchemaComparatorTest.scala b/apispec-model/src/test/scala/sttp/apispec/validation/ComponentsSchemaComparatorTest.scala new file mode 100644 index 0000000..0ba8b17 --- /dev/null +++ b/apispec-model/src/test/scala/sttp/apispec/validation/ComponentsSchemaComparatorTest.scala @@ -0,0 +1,3 @@ +package sttp.apispec.validation + +class ComponentsSchemaComparatorTest extends SchemaComparatorTest(SchemaResolver.ComponentsRefPrefix) diff --git a/apispec-model/src/test/scala/sttp/apispec/validation/DefsSchemaComparatorTest.scala b/apispec-model/src/test/scala/sttp/apispec/validation/DefsSchemaComparatorTest.scala new file mode 100644 index 0000000..6357389 --- /dev/null +++ b/apispec-model/src/test/scala/sttp/apispec/validation/DefsSchemaComparatorTest.scala @@ -0,0 +1,3 @@ +package sttp.apispec.validation + +class DefsSchemaComparatorTest extends SchemaComparatorTest(SchemaResolver.DefsRefPrefix) diff --git a/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala b/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala index 848c014..8c0394d 100644 --- a/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala +++ b/apispec-model/src/test/scala/sttp/apispec/validation/SchemaComparatorTest.scala @@ -5,7 +5,8 @@ import sttp.apispec._ import scala.collection.immutable.ListMap -class SchemaComparatorTest extends AnyFunSuite { +abstract class SchemaComparatorTest(referencePrefix: String) extends AnyFunSuite { + private val stringSchema = Schema(SchemaType.String) private val integerSchema = Schema(SchemaType.Integer) private val numberSchema = Schema(SchemaType.Number) @@ -107,7 +108,7 @@ class SchemaComparatorTest extends AnyFunSuite { ) private def ref(name: String): Schema = - Schema.referenceTo(SchemaResolver.ComponentsRefPrefix, name) + Schema.referenceTo(referencePrefix, name) private def compare(writerSchema: Schema, readerSchema: Schema): List[SchemaCompatibilityIssue] = new SchemaComparator(writerSchemas, readerSchemas) @@ -481,11 +482,11 @@ class SchemaComparatorTest extends AnyFunSuite { assert(compare( Schema( oneOf = List(ref("Foo"), ref("Bar")), - discriminator = Some(Discriminator("type", Some(ListMap("WFoo" -> s"${SchemaResolver.ComponentsRefPrefix}Foo")))) + discriminator = Some(Discriminator("type", Some(ListMap("WFoo" -> s"${referencePrefix}Foo")))) ), Schema( oneOf = List(ref("Foo"), ref("Bar"), ref("Baz")), - discriminator = Some(Discriminator("type", Some(ListMap("RBar" -> s"${SchemaResolver.ComponentsRefPrefix}Bar")))) + discriminator = Some(Discriminator("type", Some(ListMap("RBar" -> s"${referencePrefix}Bar")))) ), ) == List( UnsupportedDiscriminatorValues(List("WFoo", "Bar")) @@ -496,7 +497,7 @@ class SchemaComparatorTest extends AnyFunSuite { assert(compare( Schema( oneOf = List(ref("Foo"), ref("Bar")), - discriminator = Some(Discriminator("type", Some(ListMap("Baz" -> s"${SchemaResolver.ComponentsRefPrefix}Bar")))) + discriminator = Some(Discriminator("type", Some(ListMap("Baz" -> s"${referencePrefix}Bar")))) ), Schema( oneOf = List(ref("Foo"), ref("Baz")),