Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve name generation for Schemas of Eithers with parameterized types #3848

Merged
merged 4 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion core/src/main/scala/sttp/tapir/Schema.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
)
)
}

Expand Down
25 changes: 25 additions & 0 deletions core/src/test/scala/sttp/tapir/SchemaTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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"))
)

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this test go to sth like SchemaTest?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I added tests to SchemaTest as well. Still I think it's good keep these to make sure that the "title" field looks good now, as this was the initially reported issue.

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"
)
}
}
Loading