From 05c5fe816ea3b487e47dac855826b121c72a87e0 Mon Sep 17 00:00:00 2001 From: matwojcik Date: Wed, 22 Jul 2020 11:35:15 +0200 Subject: [PATCH 1/3] Add map and functor instance for Example --- build.sbt | 5 ++++- .../src/main/scala/sttp/tapir/EndpointIO.scala | 4 +++- .../tapir/integ/cats/ExampleInstances.scala | 10 ++++++++++ .../sttp/tapir/integ/cats/instances.scala | 3 +++ .../integ/cats/ExampleFunctorLawSpec.scala | 18 ++++++++++++++++++ .../tapir/integ/cats/TapirCodecCatsTest.scala | 5 +++-- 6 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 integrations/cats/src/main/scala/sttp/tapir/integ/cats/ExampleInstances.scala create mode 100644 integrations/cats/src/main/scala/sttp/tapir/integ/cats/instances.scala create mode 100644 integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala diff --git a/build.sbt b/build.sbt index c7186a5b6d..572fbe143a 100644 --- a/build.sbt +++ b/build.sbt @@ -126,7 +126,10 @@ lazy val cats: Project = (project in file("integrations/cats")) libraryDependencies ++= Seq( "org.typelevel" %% "cats-core" % "2.1.1", scalaTest % Test, - scalaCheck % Test + scalaCheck % Test, + "org.typelevel" %% "discipline-scalatest" % "1.0.1" % Test, + "org.typelevel" %% "cats-laws" % "2.1.1" % Test, + "com.github.alexarchambault" %% "scalacheck-shapeless_1.14" % "1.2.5" % Test ) ) .dependsOn(core) diff --git a/core/src/main/scala/sttp/tapir/EndpointIO.scala b/core/src/main/scala/sttp/tapir/EndpointIO.scala index 24c9b31d6a..0487f80c92 100644 --- a/core/src/main/scala/sttp/tapir/EndpointIO.scala +++ b/core/src/main/scala/sttp/tapir/EndpointIO.scala @@ -421,7 +421,9 @@ object EndpointIO { // - case class Example[+T](value: T, name: Option[String], summary: Option[String]) + case class Example[+T](value: T, name: Option[String], summary: Option[String]) { + def map[B](f: T => B): Example[B] = Example(f(value), name = name, summary = summary) + } object Example { def of[T](t: T, name: Option[String] = None, summary: Option[String] = None): Example[T] = Example(t, name, summary) diff --git a/integrations/cats/src/main/scala/sttp/tapir/integ/cats/ExampleInstances.scala b/integrations/cats/src/main/scala/sttp/tapir/integ/cats/ExampleInstances.scala new file mode 100644 index 0000000000..cb529dd35f --- /dev/null +++ b/integrations/cats/src/main/scala/sttp/tapir/integ/cats/ExampleInstances.scala @@ -0,0 +1,10 @@ +package sttp.tapir.integ.cats + +import cats.Functor +import sttp.tapir.EndpointIO.Example + +trait ExampleInstances { + implicit val exampleFunctor: Functor[Example] = new Functor[Example] { + override def map[A, B](example: Example[A])(f: A => B): Example[B] = example.map(f) + } +} diff --git a/integrations/cats/src/main/scala/sttp/tapir/integ/cats/instances.scala b/integrations/cats/src/main/scala/sttp/tapir/integ/cats/instances.scala new file mode 100644 index 0000000000..5f3d91d41c --- /dev/null +++ b/integrations/cats/src/main/scala/sttp/tapir/integ/cats/instances.scala @@ -0,0 +1,3 @@ +package sttp.tapir.integ.cats + +object instances extends ExampleInstances diff --git a/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala new file mode 100644 index 0000000000..60b8b8dbae --- /dev/null +++ b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala @@ -0,0 +1,18 @@ +package sttp.tapir.integ.cats + +import cats.Eq +import cats.implicits._ +import cats.laws.discipline.FunctorTests +import org.scalatest.funsuite.AnyFunSuite +import org.scalatestplus.scalacheck.Checkers +import org.typelevel.discipline.scalatest.FunSuiteDiscipline +import sttp.tapir.EndpointIO.Example +import sttp.tapir.integ.cats.instances._ +import org.scalacheck.ScalacheckShapeless._ + +class ExampleFunctorLawSpec extends AnyFunSuite with FunSuiteDiscipline with Checkers { + implicit def eqTree[A: Eq]: Eq[Example[A]] = Eq.fromUniversalEquals + + checkAll("Example.FunctorLaws", FunctorTests[Example].functor[Int, Int, String]) +} + diff --git a/integrations/cats/src/test/scala/sttp/tapir/integ/cats/TapirCodecCatsTest.scala b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/TapirCodecCatsTest.scala index a7e47299b5..d951c7dcaa 100644 --- a/integrations/cats/src/test/scala/sttp/tapir/integ/cats/TapirCodecCatsTest.scala +++ b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/TapirCodecCatsTest.scala @@ -2,7 +2,8 @@ package sttp.tapir.integ.cats import cats.data.{NonEmptyChain, NonEmptyList, NonEmptySet} import org.scalacheck.{Arbitrary, Gen} -import org.scalatest.{FlatSpec, Matchers} +import org.scalatest.flatspec.AnyFlatSpec +import org.scalatest.matchers.should.Matchers import org.scalatestplus.scalacheck.Checkers import org.scalacheck.Arbitrary.arbString import sttp.tapir.SchemaType.{SArray, SString} @@ -12,7 +13,7 @@ import codec._ import scala.collection.immutable.SortedSet -class TapirCodecCatsTest extends FlatSpec with Matchers with Checkers { +class TapirCodecCatsTest extends AnyFlatSpec with Matchers with Checkers { case class Test(value: String) it should "find schema for cats collections" in { From 8fce3df7fba7aa5ac892bdc5ee2b2beb90dd379f Mon Sep 17 00:00:00 2001 From: matwojcik Date: Wed, 22 Jul 2020 13:13:51 +0200 Subject: [PATCH 2/3] Remove shapeless dependency, changed map to use copy --- build.sbt | 3 +-- core/src/main/scala/sttp/tapir/EndpointIO.scala | 2 +- .../sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala | 10 +++++++++- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/build.sbt b/build.sbt index 572fbe143a..a887eeb188 100644 --- a/build.sbt +++ b/build.sbt @@ -128,8 +128,7 @@ lazy val cats: Project = (project in file("integrations/cats")) scalaTest % Test, scalaCheck % Test, "org.typelevel" %% "discipline-scalatest" % "1.0.1" % Test, - "org.typelevel" %% "cats-laws" % "2.1.1" % Test, - "com.github.alexarchambault" %% "scalacheck-shapeless_1.14" % "1.2.5" % Test + "org.typelevel" %% "cats-laws" % "2.1.1" % Test ) ) .dependsOn(core) diff --git a/core/src/main/scala/sttp/tapir/EndpointIO.scala b/core/src/main/scala/sttp/tapir/EndpointIO.scala index 0487f80c92..9062e66c54 100644 --- a/core/src/main/scala/sttp/tapir/EndpointIO.scala +++ b/core/src/main/scala/sttp/tapir/EndpointIO.scala @@ -422,7 +422,7 @@ object EndpointIO { // case class Example[+T](value: T, name: Option[String], summary: Option[String]) { - def map[B](f: T => B): Example[B] = Example(f(value), name = name, summary = summary) + def map[B](f: T => B): Example[B] = copy(value = f(value)) } object Example { diff --git a/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala index 60b8b8dbae..c0f361cc03 100644 --- a/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala +++ b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala @@ -3,16 +3,24 @@ package sttp.tapir.integ.cats import cats.Eq import cats.implicits._ import cats.laws.discipline.FunctorTests +import org.scalacheck.Arbitrary import org.scalatest.funsuite.AnyFunSuite import org.scalatestplus.scalacheck.Checkers import org.typelevel.discipline.scalatest.FunSuiteDiscipline import sttp.tapir.EndpointIO.Example import sttp.tapir.integ.cats.instances._ -import org.scalacheck.ScalacheckShapeless._ class ExampleFunctorLawSpec extends AnyFunSuite with FunSuiteDiscipline with Checkers { implicit def eqTree[A: Eq]: Eq[Example[A]] = Eq.fromUniversalEquals + implicit def exampleArbitrary[T: Arbitrary]: Arbitrary[Example[T]] = Arbitrary { + for { + t <- Arbitrary.arbitrary[T] + name <- Arbitrary.arbitrary[Option[String]] + summary <- Arbitrary.arbitrary[Option[String]] + } yield Example(t, name, summary) + } + checkAll("Example.FunctorLaws", FunctorTests[Example].functor[Int, Int, String]) } From 12374f78630079089199d613087194d8204cb56a Mon Sep 17 00:00:00 2001 From: matwojcik Date: Wed, 22 Jul 2020 13:27:02 +0200 Subject: [PATCH 3/3] Fix Eq --- .../scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala index c0f361cc03..8f24dd3d7d 100644 --- a/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala +++ b/integrations/cats/src/test/scala/sttp/tapir/integ/cats/ExampleFunctorLawSpec.scala @@ -1,7 +1,6 @@ package sttp.tapir.integ.cats import cats.Eq -import cats.implicits._ import cats.laws.discipline.FunctorTests import org.scalacheck.Arbitrary import org.scalatest.funsuite.AnyFunSuite @@ -10,8 +9,8 @@ import org.typelevel.discipline.scalatest.FunSuiteDiscipline import sttp.tapir.EndpointIO.Example import sttp.tapir.integ.cats.instances._ -class ExampleFunctorLawSpec extends AnyFunSuite with FunSuiteDiscipline with Checkers { - implicit def eqTree[A: Eq]: Eq[Example[A]] = Eq.fromUniversalEquals +class ExampleFunctorLawSpec extends AnyFunSuite with FunSuiteDiscipline with Checkers { + implicit def exampleEq[A]: Eq[Example[A]] = Eq.fromUniversalEquals implicit def exampleArbitrary[T: Arbitrary]: Arbitrary[Example[T]] = Arbitrary { for {