diff --git a/core/src/main/scala/sttp/tapir/Schema.scala b/core/src/main/scala/sttp/tapir/Schema.scala index fbede53bd2..0400486ad2 100644 --- a/core/src/main/scala/sttp/tapir/Schema.scala +++ b/core/src/main/scala/sttp/tapir/Schema.scala @@ -316,7 +316,10 @@ object Schema extends LowPrioritySchema with SchemaCompanionMacros { for { na <- sa.name nb <- sb.name - } yield Schema.SName("Either", List(na.show, nb.show)) + } yield Schema.SName( + "Either", + (na.fullName :: na.typeParameterShortNames) ++ (nb.fullName :: nb.typeParameterShortNames) + ) ) } diff --git a/core/src/test/scala/sttp/tapir/SchemaTest.scala b/core/src/test/scala/sttp/tapir/SchemaTest.scala index 7154d03aed..8158835d7e 100644 --- a/core/src/test/scala/sttp/tapir/SchemaTest.scala +++ b/core/src/test/scala/sttp/tapir/SchemaTest.scala @@ -5,6 +5,7 @@ import org.scalatest.flatspec.AnyFlatSpec import org.scalatest.matchers.should.Matchers import sttp.tapir.Schema.SName import sttp.tapir.TestUtil.field +import javax.swing.plaf.ListUI class SchemaTest extends AnyFlatSpec with Matchers { it should "modify basic schema" in { @@ -203,4 +204,28 @@ class SchemaTest extends AnyFlatSpec with Matchers { implicitly[Schema[Option[Double]]].format shouldBe Some("double") } + case class SomeValueString[A](value: String, v2: A) + final case class SomeValueInt(value: Int) + final case class Node[A](values: List[A]) + it should "generate correct names for Eithers with parameterized types" in { + + import sttp.tapir.generic.auto._ + + implicitly[Schema[Either[Int, Int]]].name shouldBe None + implicitly[Schema[Either[SomeValueInt, Int]]].name shouldBe None + implicitly[Schema[Either[SomeValueInt, SomeValueInt]]].name shouldBe Some( + SName("Either", List("sttp.tapir.SchemaTest.SomeValueInt", "sttp.tapir.SchemaTest.SomeValueInt")) + ) + implicitly[Schema[Either[SomeValueInt, Node[SomeValueString[Boolean]]]]].name shouldBe Some( + SName("Either", List("sttp.tapir.SchemaTest.SomeValueInt", "sttp.tapir.SchemaTest.Node", "sttp.tapir.SchemaTest.SomeValueString", "scala.Boolean")) + ) + implicitly[Schema[Either[SomeValueInt, Node[String]]]].name shouldBe Some( + SName("Either", List("sttp.tapir.SchemaTest.SomeValueInt", "sttp.tapir.SchemaTest.Node", "java.lang.String")) + ) + implicitly[Schema[Either[Node[Boolean], SomeValueInt]]].name shouldBe Some( + SName("Either", List("sttp.tapir.SchemaTest.Node", "scala.Boolean", "sttp.tapir.SchemaTest.SomeValueInt")) + ) + + } + } diff --git a/docs/apispec-docs/src/test/scala/sttp/tapir/docs/apispec/schema/TapirSchemaToJsonSchemaTest.scala b/docs/apispec-docs/src/test/scala/sttp/tapir/docs/apispec/schema/TapirSchemaToJsonSchemaTest.scala index 03ce3459bc..6a8f4a1051 100644 --- a/docs/apispec-docs/src/test/scala/sttp/tapir/docs/apispec/schema/TapirSchemaToJsonSchemaTest.scala +++ b/docs/apispec-docs/src/test/scala/sttp/tapir/docs/apispec/schema/TapirSchemaToJsonSchemaTest.scala @@ -118,4 +118,26 @@ class JsonSchemasTest extends AnyFlatSpec with Matchers with OptionValues with E // then result.asJson.deepDropNullValues shouldBe json"""{"$$schema":"http://json-schema.org/draft-04/schema#","title":"Parent","required":["innerChildField"],"type":"object","properties":{"innerChildField":{"$$ref":"#/$$defs/Child"}},"$$defs":{"Child":{"title":"MyChild","type":"object","properties":{"childName":{"type":["string","null"]}}}}}""" } + + it should "Generate correct names for Eithers with parameterized types" in { + case class SomeValueString[A](value: String, v2: A) + final case class SomeValueInt(value: Int) + + final case class Node[A](values: List[A]) + + TapirSchemaToJsonSchema(implicitly[Schema[Either[Int, Int]]], true).title shouldBe None + TapirSchemaToJsonSchema(implicitly[Schema[Either[SomeValueInt, Int]]], true).title shouldBe None + TapirSchemaToJsonSchema(implicitly[Schema[Either[SomeValueInt, SomeValueInt]]], true).title shouldBe Some( + "Either_SomeValueInt_SomeValueInt" + ) + TapirSchemaToJsonSchema(implicitly[Schema[Either[SomeValueInt, Node[SomeValueString[Boolean]]]]], true).title shouldBe Some( + "Either_SomeValueInt_Node_SomeValueString_Boolean" + ) + TapirSchemaToJsonSchema(implicitly[Schema[Either[SomeValueInt, Node[String]]]], true).title shouldBe Some( + "Either_SomeValueInt_Node_String" + ) + TapirSchemaToJsonSchema(implicitly[Schema[Either[Node[Boolean], SomeValueInt]]], true).title shouldBe Some( + "Either_Node_Boolean_SomeValueInt" + ) + } }