diff --git a/build.sbt b/build.sbt index 8fbfad6977..bb916341a7 100644 --- a/build.sbt +++ b/build.sbt @@ -94,7 +94,8 @@ lazy val commonJsSettings = Seq( botBuild := scala.sys.env.get("TRAVIS").isDefined, // batch mode decreases the amount of memory needed to compile scala.js code scalaJSOptimizerOptions := scalaJSOptimizerOptions.value.withBatchMode(botBuild.value), - doctestGenTests := Seq.empty + doctestGenTests := Seq.empty, + doctestWithDependencies := false ) lazy val commonJvmSettings = Seq( @@ -114,16 +115,18 @@ lazy val includeGeneratedSrc: Setting[_] = { lazy val catsSettings = buildSettings ++ commonSettings ++ publishSettings ++ scoverageSettings ++ javadocSettings -lazy val scalacheckVersion = "1.12.5" +lazy val scalaCheckVersion = "1.13.2" +lazy val scalaTestVersion = "3.0.0" +lazy val disciplineVersion = "0.6" lazy val disciplineDependencies = Seq( - libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalacheckVersion, - libraryDependencies += "org.typelevel" %%% "discipline" % "0.4") + libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion, + libraryDependencies += "org.typelevel" %%% "discipline" % disciplineVersion) lazy val testingDependencies = Seq( libraryDependencies += "org.typelevel" %%% "catalysts-platform" % "0.0.2", libraryDependencies += "org.typelevel" %%% "catalysts-macros" % "0.0.2" % "test", - libraryDependencies += "org.scalatest" %%% "scalatest" % "3.0.0-M8" % "test") + libraryDependencies += "org.scalatest" %%% "scalatest" % scalaTestVersion % "test") /** @@ -246,7 +249,7 @@ lazy val core = crossProject.crossType(CrossType.Pure) .settings(catsSettings:_*) .settings(sourceGenerators in Compile <+= (sourceManaged in Compile).map(Boilerplate.gen)) .settings(includeGeneratedSrc) - .settings(libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalacheckVersion % "test") + .settings(libraryDependencies += "org.scalacheck" %%% "scalacheck" % scalaCheckVersion % "test") .jsSettings(commonJsSettings:_*) .jvmSettings(commonJvmSettings:_*) diff --git a/free/src/test/scala/cats/free/FreeTTests.scala b/free/src/test/scala/cats/free/FreeTTests.scala index ded2dc284c..ee51e17536 100644 --- a/free/src/test/scala/cats/free/FreeTTests.scala +++ b/free/src/test/scala/cats/free/FreeTTests.scala @@ -8,7 +8,7 @@ import cats.laws.discipline._ import cats.tests.CatsSuite import cats.instances.option._ -import org.scalacheck.{Arbitrary, Gen} +import org.scalacheck.{Arbitrary, Gen, Cogen} class FreeTTests extends CatsSuite { @@ -165,7 +165,7 @@ object FreeTTests extends FreeTTestsInstances { def withFlatMapped = for { fDepth <- nextDepth freeDepth <- nextDepth - f <- arbFunction1[A, FreeT[F, G, A]](Arbitrary(freeTGen[F, G, A](fDepth))).arbitrary + f <- arbFunction1[A, FreeT[F, G, A]](Arbitrary(freeTGen[F, G, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary freeFGA <- freeTGen[F, G, A](freeDepth) } yield freeFGA.flatMap(f) diff --git a/free/src/test/scala/cats/free/FreeTests.scala b/free/src/test/scala/cats/free/FreeTests.scala index dcf882a425..e6988f64e8 100644 --- a/free/src/test/scala/cats/free/FreeTests.scala +++ b/free/src/test/scala/cats/free/FreeTests.scala @@ -6,7 +6,7 @@ import cats.arrow.FunctionK import cats.laws.discipline.{CartesianTests, MonadTests, SerializableTests} import cats.laws.discipline.arbitrary.catsLawsArbitraryForFn0 -import org.scalacheck.{Arbitrary, Gen} +import org.scalacheck.{Arbitrary, Gen, Cogen} import Arbitrary.arbFunction1 class FreeTests extends CatsSuite { @@ -131,7 +131,7 @@ sealed trait FreeTestsInstances { def withFlatMapped = for { fDepth <- nextDepth freeDepth <- nextDepth - f <- arbFunction1[A, Free[F, A]](Arbitrary(freeGen[F, A](fDepth))).arbitrary + f <- arbFunction1[A, Free[F, A]](Arbitrary(freeGen[F, A](fDepth)), Cogen[Unit].contramap(_ => ())).arbitrary freeFA <- freeGen[F, A](freeDepth) } yield freeFA.flatMap(f) diff --git a/js/src/test/scala/cats/tests/FutureTests.scala b/js/src/test/scala/cats/tests/FutureTests.scala index ec982d8817..e248189d34 100644 --- a/js/src/test/scala/cats/tests/FutureTests.scala +++ b/js/src/test/scala/cats/tests/FutureTests.scala @@ -10,8 +10,9 @@ import cats.tests.CatsSuite import scala.concurrent.Future import scala.concurrent.duration._ -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Arbitrary.arbitrary +import cats.laws.discipline.arbitrary._ // https://issues.scala-lang.org/browse/SI-7934 @deprecated("", "") @@ -36,7 +37,7 @@ class FutureTests extends CatsSuite { } implicit val throwableEq: Eq[Throwable] = - Eq.fromUniversalEquals + Eq[String].on(_.toString) implicit val comonad: Comonad[Future] = futureComonad(timeout) @@ -44,6 +45,12 @@ class FutureTests extends CatsSuite { implicit val nonFatalArbitrary: Arbitrary[Throwable] = Arbitrary(arbitrary[Exception].map(identity)) + // We can't block on futures in JS, so we can't create interesting + // cogen instances. This will allow the tests to run in a + // less-useful way. + implicit def cogenForFuture[A]: Cogen[Future[A]] = + Cogen[Unit].contramap(_ => ()) + checkAll("Future[Int]", MonadErrorTests[Future, Throwable].monadError[Int, Int, Int]) checkAll("Future[Int]", ComonadTests[Future].comonad[Int, Int, Int]) checkAll("Future", MonadTests[Future].monad[Int, Int, Int]) diff --git a/jvm/src/test/scala/cats/tests/FutureTests.scala b/jvm/src/test/scala/cats/tests/FutureTests.scala index af68328617..669d065500 100644 --- a/jvm/src/test/scala/cats/tests/FutureTests.scala +++ b/jvm/src/test/scala/cats/tests/FutureTests.scala @@ -3,6 +3,7 @@ package jvm package tests import cats.laws.discipline._ +import cats.laws.discipline.arbitrary._ import cats.tests.CatsSuite import scala.concurrent.{Await, Future} @@ -27,7 +28,7 @@ class FutureTests extends CatsSuite { } implicit val throwableEq: Eq[Throwable] = - Eq.fromUniversalEquals + Eq[String].on(_.toString) // Need non-fatal Throwables for Future recoverWith/handleError implicit val nonFatalArbitrary: Arbitrary[Throwable] = diff --git a/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala b/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala index 27f7f59958..f1284f68f7 100644 --- a/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala +++ b/kernel-laws/src/main/scala/cats/kernel/laws/OrderLaws.scala @@ -3,22 +3,25 @@ package laws import org.typelevel.discipline.Laws -import org.scalacheck.{Arbitrary, Prop} +import org.scalacheck.{Arbitrary, Cogen, Prop} import org.scalacheck.Prop._ import cats.kernel.instances.all._ object OrderLaws { - def apply[A: Eq: Arbitrary]: OrderLaws[A] = new OrderLaws[A] { - def Equ = Eq[A] - def Arb = implicitly[Arbitrary[A]] - } + def apply[A: Eq: Arbitrary: Cogen]: OrderLaws[A] = + new OrderLaws[A] { + def Equ = Eq[A] + def Arb = implicitly[Arbitrary[A]] + def Cog = implicitly[Cogen[A]] + } } trait OrderLaws[A] extends Laws { implicit def Equ: Eq[A] implicit def Arb: Arbitrary[A] + implicit def Cog: Cogen[A] def eqv: OrderProperties = new OrderProperties( name = "eq", diff --git a/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala b/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala index a52e56dc3d..7f0ce51018 100644 --- a/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala +++ b/kernel-laws/src/test/scala/cats/kernel/laws/LawTests.scala @@ -8,7 +8,7 @@ import cats.kernel.instances.all._ import org.typelevel.discipline.{ Laws } import org.typelevel.discipline.scalatest.Discipline -import org.scalacheck.{ Arbitrary, Gen } +import org.scalacheck.{ Arbitrary, Cogen, Gen } import Arbitrary.arbitrary import org.scalatest.FunSuite @@ -24,13 +24,28 @@ class LawTests extends FunSuite with Discipline { implicit override val generatorDrivenConfig: PropertyCheckConfiguration = PropertyCheckConfig(maxSize = PropMaxSize, minSuccessful = PropMinSuccessful) - implicit def orderLaws[A: Eq: Arbitrary] = OrderLaws[A] - implicit def groupLaws[A: Eq: Arbitrary] = GroupLaws[A] + implicit def orderLaws[A: Cogen: Eq: Arbitrary]: OrderLaws[A] = OrderLaws[A] + implicit def groupLaws[A: Cogen: Eq: Arbitrary]: GroupLaws[A] = GroupLaws[A] implicit val arbitraryBitSet: Arbitrary[BitSet] = Arbitrary(arbitrary[List[Short]].map(ns => BitSet(ns.map(_ & 0xffff): _*))) - laws[OrderLaws, Map[String, HasEq[Int]]].check(_.eqv) + // this instance is not available in scalacheck 1.13.2. + // remove this once a newer version is available. + implicit val cogenBigInt: Cogen[BigInt] = + Cogen[Long].contramap(_.toLong) + + // this instance is not available in scalacheck 1.13.2. + // remove this once a newer version is available. + implicit val cogenBigDecimal: Cogen[BigDecimal] = + Cogen[Double].contramap(_.toDouble) + + { + // needed for Cogen[Map[...]] + implicit val ohe: Ordering[HasEq[Int]] = Ordering[Int].on(_.a) + laws[OrderLaws, Map[String, HasEq[Int]]].check(_.eqv) + } + laws[OrderLaws, List[HasEq[Int]]].check(_.eqv) laws[OrderLaws, Option[HasEq[Int]]].check(_.eqv) laws[OrderLaws, Vector[HasEq[Int]]].check(_.eqv) @@ -114,6 +129,9 @@ class LawTests extends FunSuite with Discipline { implicit val arbitraryComparison: Arbitrary[Comparison] = Arbitrary(Gen.oneOf(Comparison.GreaterThan, Comparison.EqualTo, Comparison.LessThan)) + implicit val cogenComparison: Cogen[Comparison] = + Cogen[Int].contramap(_.toInt) + laws[OrderLaws, Comparison].check(_.eqv) test("comparison") { @@ -168,12 +186,16 @@ class LawTests extends FunSuite with Discipline { val order = new Random(seed).shuffle(Vector.range(0, nMax)) Order.by { (n: N) => order(n.n) } }) + implicit val cogNOrder: Cogen[Order[N]] = + Cogen[Unit].contramap(_ => ()) // The arbitrary `Eq[N]` values are created by mapping N values to random // integers. implicit val arbNEq: Arbitrary[Eq[N]] = Arbitrary(arbitrary[Int].map { seed => val mapping = new Random(seed).shuffle(Vector.range(0, nMax)) Eq.by { (n: N) => mapping(n.n) } }) + implicit val cogNEq: Cogen[Eq[N]] = + Cogen[Unit].contramap(_ => ()) // needed because currently we don't have Vector instances implicit val vectorNEq: Eq[Vector[N]] = Eq.fromUniversalEquals // The `Eq[Order[N]]` instance enumerates all possible `N` values in a @@ -210,6 +232,8 @@ class LawTests extends FunSuite with Discipline { Eq[A].on(_.a) implicit def hasEqArbitrary[A: Arbitrary]: Arbitrary[HasEq[A]] = Arbitrary(arbitrary[A].map(HasEq(_))) + implicit def hasCogen[A: Cogen]: Cogen[HasEq[A]] = + Cogen[A].contramap(_.a) } case class HasPartialOrder[A](a: A) @@ -219,6 +243,8 @@ class LawTests extends FunSuite with Discipline { PartialOrder[A].on(_.a) implicit def hasPartialOrderArbitrary[A: Arbitrary]: Arbitrary[HasPartialOrder[A]] = Arbitrary(arbitrary[A].map(HasPartialOrder(_))) + implicit def hasCogen[A: Cogen]: Cogen[HasPartialOrder[A]] = + Cogen[A].contramap(_.a) } case class LawChecker[L <: Laws](name: String, laws: L) { diff --git a/laws/src/main/scala/cats/laws/MonadCombineLaws.scala b/laws/src/main/scala/cats/laws/MonadCombineLaws.scala index a8100e381d..689466a2af 100644 --- a/laws/src/main/scala/cats/laws/MonadCombineLaws.scala +++ b/laws/src/main/scala/cats/laws/MonadCombineLaws.scala @@ -1,7 +1,7 @@ package cats package laws -import cats.syntax.all._ +// import cats.syntax.all._ /** * Laws that must be obeyed by any `MonadCombine`. @@ -9,8 +9,16 @@ import cats.syntax.all._ trait MonadCombineLaws[F[_]] extends MonadFilterLaws[F] with AlternativeLaws[F] { implicit override def F: MonadCombine[F] - def monadCombineLeftDistributivity[A, B](fa: F[A], fa2: F[A], f: A => F[B]): IsEq[F[B]] = - F.combineK(fa, fa2).flatMap(f) <-> F.combineK(fa flatMap f, fa2 flatMap f) + // the left distributivity law does not hold for things like + // MonadCombine[Option]; here's a counter-example: + // + // def f(x: Int): Option[Int] = if (x == 0) None else Some(x) + // val a = Option(0) + // val b = Option(1) + // (a <+> b).flatMap(f) != (a.flatMap(f) <+> b.flatMap(f)) + // + // def monadCombineLeftDistributivity[A, B](fa: F[A], fa2: F[A], f: A => F[B]): IsEq[F[B]] = + // F.combineK(fa, fa2).flatMap(f) <-> F.combineK(fa flatMap f, fa2 flatMap f) } object MonadCombineLaws { diff --git a/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala b/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala index 530f24cc62..8a11fc7a05 100644 --- a/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/AlternativeTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait AlternativeTests[F[_]] extends ApplicativeTests[F] with MonoidKTests[F] { @@ -16,6 +15,9 @@ trait AlternativeTests[F[_]] extends ApplicativeTests[F] with MonoidKTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala b/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala index 8116da9f03..2acdddd280 100644 --- a/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ApplicativeErrorTests.scala @@ -5,7 +5,7 @@ package discipline import cats.data.EitherT import cats.laws.discipline.CartesianTests.Isomorphisms import cats.laws.discipline.arbitrary._ -import org.scalacheck.{Arbitrary, Prop} +import org.scalacheck.{Arbitrary, Cogen, Prop} import org.scalacheck.Prop.forAll trait ApplicativeErrorTests[F[_], E] extends ApplicativeTests[F] { @@ -18,6 +18,10 @@ trait ApplicativeErrorTests[F[_], E] extends ApplicativeTests[F] { ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], ArbE: Arbitrary[E], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenE: Cogen[E], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala b/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala index 385e8b905f..60256cc9eb 100644 --- a/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ApplicativeTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait ApplicativeTests[F[_]] extends ApplyTests[F] { @@ -16,6 +15,9 @@ trait ApplicativeTests[F[_]] extends ApplyTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala b/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala index 427ecbe226..715ee64fbe 100644 --- a/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ApplyTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait ApplyTests[F[_]] extends FunctorTests[F] with CartesianTests[F] { @@ -16,6 +15,9 @@ trait ApplyTests[F[_]] extends FunctorTests[F] with CartesianTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFC: Eq[F[C]], EqFABC: Eq[F[(A, B, C)]], diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index e1ff541ab8..c9d2eb4d32 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -2,8 +2,10 @@ package cats package laws package discipline +import scala.util.{Try, Success, Failure} + import cats.data._ -import org.scalacheck.{Arbitrary, Gen} +import org.scalacheck.{Arbitrary, Cogen, Gen} import org.scalacheck.Arbitrary.{arbitrary => getArbitrary} /** @@ -11,39 +13,69 @@ import org.scalacheck.Arbitrary.{arbitrary => getArbitrary} */ object arbitrary extends ArbitraryInstances0 { - // A special function1Arbitrary for testing operations like dropWhile specifically - // in the context of Int => Boolean. Once scalacheck supports better Function1 arbitrary - // instances this can be removed. - implicit def catsLawsArbitraryForIntToBool: Arbitrary[(Int) => Boolean] = - Arbitrary( - getArbitrary[Int].map(x => - new Function1[Int, Boolean] { - def apply(i: Int): Boolean = i < x + // this instance is not available in scalacheck 1.13.2. + // remove this once a newer version is available. + implicit val catsLawsCogenForThrowable: Cogen[Throwable] = + Cogen[String].contramap(_.toString) + + // this instance is not available in scalacheck 1.13.2. + // remove this once a newer version is available. + implicit def catsLawsCogenForTry[A](implicit A: Cogen[A]): Cogen[Try[A]] = + Cogen((seed, x) => x match { + case Success(a) => A.perturb(seed, a) + case Failure(e) => Cogen[Throwable].perturb(seed, e) + }) - override def toString = s"" - })) + // this instance is not available in scalacheck 1.13.2. + // remove this once a newer version is available. + implicit def catsLawsCogenForFunction0[A](implicit A: Cogen[A]): Cogen[Function0[A]] = + A.contramap(_()) implicit def catsLawsArbitraryForConst[A, B](implicit A: Arbitrary[A]): Arbitrary[Const[A, B]] = Arbitrary(A.arbitrary.map(Const[A, B])) + implicit def catsLawsCogenForConst[A, B](implicit A: Cogen[A]): Cogen[Const[A, B]] = + A.contramap(_.getConst) + implicit def catsLawsArbitraryForOneAnd[F[_], A](implicit A: Arbitrary[A], F: Arbitrary[F[A]]): Arbitrary[OneAnd[F, A]] = Arbitrary(F.arbitrary.flatMap(fa => A.arbitrary.map(a => OneAnd(a, fa)))) + implicit def catsLawsCogenForOneAnd[F[_], A](implicit A: Cogen[A], F: Cogen[F[A]]): Cogen[OneAnd[F, A]] = + Cogen((seed, x) => F.perturb(A.perturb(seed, x.head), x.tail)) + implicit def catsLawsArbitraryForNonEmptyVector[A](implicit A: Arbitrary[A]): Arbitrary[NonEmptyVector[A]] = Arbitrary(implicitly[Arbitrary[Vector[A]]].arbitrary.flatMap(fa => A.arbitrary.map(a => NonEmptyVector(a, fa)))) + implicit def catsLawsCogenForNonEmptyVector[A](implicit A: Cogen[A]): Cogen[NonEmptyVector[A]] = + Cogen[Vector[A]].contramap(_.toVector) + implicit def catsLawsArbitraryForNonEmptyList[A](implicit A: Arbitrary[A]): Arbitrary[NonEmptyList[A]] = Arbitrary(implicitly[Arbitrary[List[A]]].arbitrary.flatMap(fa => A.arbitrary.map(a => NonEmptyList(a, fa)))) + implicit def catsLawsCogenForNonEmptyList[A](implicit A: Cogen[A]): Cogen[NonEmptyList[A]] = + Cogen[List[A]].contramap(_.toList) + implicit def catsLawsArbitraryForEitherT[F[_], A, B](implicit F: Arbitrary[F[Either[A, B]]]): Arbitrary[EitherT[F, A, B]] = Arbitrary(F.arbitrary.map(EitherT(_))) + implicit def catsLawsCogenForEitherT[F[_], A, B](implicit F: Cogen[F[Either[A, B]]]): Cogen[EitherT[F, A, B]] = + F.contramap(_.value) + implicit def catsLawsArbitraryForValidated[A, B](implicit A: Arbitrary[A], B: Arbitrary[B]): Arbitrary[Validated[A, B]] = Arbitrary(Gen.oneOf(A.arbitrary.map(Validated.invalid), B.arbitrary.map(Validated.valid))) + implicit def catsLawsCogenForValidated[A, B](implicit A: Cogen[A], B: Cogen[B]): Cogen[Validated[A, B]] = + Cogen((seed, x) => x.fold(A.perturb(seed, _), B.perturb(seed, _))) + implicit def catsLawsArbitraryForIor[A, B](implicit A: Arbitrary[A], B: Arbitrary[B]): Arbitrary[A Ior B] = Arbitrary(Gen.oneOf(A.arbitrary.map(Ior.left), B.arbitrary.map(Ior.right), for { a <- A.arbitrary; b <- B.arbitrary } yield Ior.both(a, b))) + implicit def catsLawsCogenForIor[A, B](implicit A: Cogen[A], B: Cogen[B]): Cogen[A Ior B] = + Cogen((seed, x) => x.fold( + A.perturb(seed, _), + B.perturb(seed, _), + (a, b) => A.perturb(B.perturb(seed, b), a))) + implicit def catsLawsArbitraryForKleisli[F[_], A, B](implicit F: Arbitrary[F[B]]): Arbitrary[Kleisli[F, A, B]] = Arbitrary(F.arbitrary.map(fb => Kleisli[F, A, B](_ => fb))) @@ -53,15 +85,24 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsArbitraryForOptionT[F[_], A](implicit F: Arbitrary[F[Option[A]]]): Arbitrary[OptionT[F, A]] = Arbitrary(F.arbitrary.map(OptionT.apply)) + implicit def catsLawsCogenForOptionT[F[_], A](implicit F: Cogen[F[Option[A]]]): Cogen[OptionT[F, A]] = + F.contramap(_.value) + implicit def catsLawsArbitraryForIdT[F[_], A](implicit F: Arbitrary[F[A]]): Arbitrary[IdT[F, A]] = Arbitrary(F.arbitrary.map(IdT.apply)) + implicit def catsLawsCogenForIdT[F[_], A](implicit F: Cogen[F[A]]): Cogen[IdT[F, A]] = + F.contramap(_.value) + implicit def catsLawsArbitraryForEval[A: Arbitrary]: Arbitrary[Eval[A]] = Arbitrary(Gen.oneOf( getArbitrary[A].map(Eval.now(_)), getArbitrary[A].map(Eval.later(_)), getArbitrary[A].map(Eval.always(_)))) + implicit def catsLawsCogenForEval[A: Cogen]: Cogen[Eval[A]] = + Cogen[A].contramap(_.value) + implicit def catsLawsArbitraryForProd[F[_], G[_], A](implicit F: Arbitrary[F[A]], G: Arbitrary[G[A]]): Arbitrary[Prod[F, G, A]] = Arbitrary(F.arbitrary.flatMap(fa => G.arbitrary.map(ga => Prod[F, G, A](fa, ga)))) @@ -74,6 +115,9 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsArbitraryForWriter[L:Arbitrary, V:Arbitrary]: Arbitrary[Writer[L, V]] = catsLawsArbitraryForWriterT[Id, L, V] + implicit def catsLawsCogenForWriter[L: Cogen, V: Cogen]: Cogen[Writer[L, V]] = + Cogen[(L, V)].contramap(_.run) + // until this is provided by scalacheck implicit def catsLawsArbitraryForPartialFunction[A, B](implicit F: Arbitrary[A => Option[B]]): Arbitrary[PartialFunction[A, B]] = Arbitrary(F.arbitrary.map(Function.unlift)) @@ -83,6 +127,9 @@ object arbitrary extends ArbitraryInstances0 { F.arbitrary.map(Coproduct.leftc[F, G, A]), G.arbitrary.map(Coproduct.rightc[F, G, A]))) + implicit def catsLawsCogenForCoproduct[F[_], G[_], A](implicit F: Cogen[F[A]], G: Cogen[G[A]]): Cogen[Coproduct[F, G, A]] = + Cogen((seed, x) => x.run.fold(F.perturb(seed, _), G.perturb(seed, _))) + implicit def catsLawsArbitraryForShow[A: Arbitrary]: Arbitrary[Show[A]] = Arbitrary(Show.fromToString[A]) @@ -112,4 +159,7 @@ object arbitrary extends ArbitraryInstances0 { private[discipline] sealed trait ArbitraryInstances0 { implicit def catsLawsArbitraryForWriterT[F[_], L, V](implicit F: Arbitrary[F[(L, V)]]): Arbitrary[WriterT[F, L, V]] = Arbitrary(F.arbitrary.map(WriterT(_))) + + implicit def catsLawsCogenForWriterT[F[_], L, V](implicit F: Cogen[F[(L, V)]]): Cogen[WriterT[F, L, V]] = + F.contramap(_.run) } diff --git a/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala b/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala index 60b246d594..0a133a106a 100644 --- a/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ArrowTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.arrow.Arrow -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait ArrowTests[F[_, _]] extends CategoryTests[F] with SplitTests[F] with StrongTests[F] { @@ -16,6 +15,11 @@ trait ArrowTests[F[_, _]] extends CategoryTests[F] with SplitTests[F] with Stron ArbFCD: Arbitrary[F[C, D]], ArbFDE: Arbitrary[F[D, E]], ArbFEG: Arbitrary[F[E, G]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenD: Cogen[D], + CogenE: Cogen[E], EqFAA: Eq[F[A, A]], EqFAB: Eq[F[A, B]], EqFAC: Eq[F[A, C]], diff --git a/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala b/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala index ec594702b8..2e391109f1 100644 --- a/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/BifoldableTests.scala @@ -2,7 +2,7 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop._ import org.typelevel.discipline.Laws @@ -10,7 +10,9 @@ trait BifoldableTests[F[_, _]] extends Laws { def laws: BifoldableLaws[F] def bifoldable[A: Arbitrary, B: Arbitrary, C: Arbitrary: Monoid: Eq](implicit - ArbFAB: Arbitrary[F[A, B]] + ArbFAB: Arbitrary[F[A, B]], + CogenA: Cogen[A], + CogenB: Cogen[B] ): RuleSet = new DefaultRuleSet( name = "bifoldable", diff --git a/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala b/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala index fb9f545dda..81621771fd 100644 --- a/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/BimonadTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait BimonadTests[F[_]] extends MonadTests[F] with ComonadTests[F] { @@ -17,6 +16,11 @@ trait BimonadTests[F[_]] extends MonadTests[F] with ComonadTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenFA: Cogen[F[A]], + CogenFB: Cogen[F[B]], EqFFFA: Eq[F[F[A]]], EqFFA: Eq[F[F[F[A]]]], EqFA: Eq[F[A]], diff --git a/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala b/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala index 8b3f9297f3..706077f7a9 100644 --- a/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/BitraverseTests.scala @@ -2,7 +2,7 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop.forAll trait BitraverseTests[F[_, _]] extends BifoldableTests[F] with BifunctorTests[F] { @@ -22,6 +22,11 @@ trait BitraverseTests[F[_, _]] extends BifoldableTests[F] with BifunctorTests[F] ArbC: Arbitrary[C], ArbE: Arbitrary[E], ArbH: Arbitrary[H], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenD: Cogen[D], + CogenE: Cogen[E], EqFAB: Eq[F[A, B]], EqFAD: Eq[F[A, D]], EqFAH: Eq[F[A, H]], diff --git a/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala b/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala index 887a2cb9d1..91b05182cb 100644 --- a/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/CoflatMapTests.scala @@ -2,8 +2,7 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ import org.typelevel.discipline.Laws @@ -12,6 +11,11 @@ trait CoflatMapTests[F[_]] extends Laws with FunctorTests[F] { def coflatMap[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenFA: Cogen[F[A]], + CogenFB: Cogen[F[B]], EqFA: Eq[F[A]], EqFC: Eq[F[C]], EqFFA: Eq[F[F[A]]], diff --git a/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala b/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala index b57e1c4add..d3b5aa405c 100644 --- a/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ComonadTests.scala @@ -2,8 +2,7 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait ComonadTests[F[_]] extends CoflatMapTests[F] { @@ -12,6 +11,11 @@ trait ComonadTests[F[_]] extends CoflatMapTests[F] { def comonad[A: Arbitrary: Eq, B: Arbitrary: Eq, C: Arbitrary: Eq](implicit ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenFA: Cogen[F[A]], + CogenFB: Cogen[F[B]], EqFA: Eq[F[A]], EqFFA: Eq[F[F[A]]], EqFFFA: Eq[F[F[F[A]]]], diff --git a/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala b/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala index 94a4d45021..88937b7835 100644 --- a/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ContravariantTests.scala @@ -3,7 +3,7 @@ package laws package discipline import cats.functor.Contravariant -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop._ trait ContravariantTests[F[_]] extends InvariantTests[F] { @@ -11,6 +11,9 @@ trait ContravariantTests[F[_]] extends InvariantTests[F] { def contravariant[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFC: Eq[F[C]] ): RuleSet = { diff --git a/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala b/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala index c8586d9347..5eae4b7fba 100644 --- a/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FlatMapTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait FlatMapTests[F[_]] extends ApplyTests[F] { @@ -16,6 +15,9 @@ trait FlatMapTests[F[_]] extends ApplyTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala b/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala index a2d656205d..a3b5a16f2b 100644 --- a/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FoldableTests.scala @@ -2,7 +2,7 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop._ import org.typelevel.discipline.Laws @@ -12,6 +12,7 @@ trait FoldableTests[F[_]] extends Laws { def foldable[A: Arbitrary, B: Arbitrary](implicit ArbFA: Arbitrary[F[A]], B: Monoid[B], + CogenA: Cogen[A], EqB: Eq[B] ): RuleSet = { new DefaultRuleSet( diff --git a/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala index 86ab17723e..813e1c6fd0 100644 --- a/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FunctorFilterTests.scala @@ -2,20 +2,22 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait FunctorFilterTests[F[_]] extends FunctorTests[F] { def laws: FunctorFilterLaws[F] def functorFilter[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit - ArbFA: Arbitrary[F[A]], - ArbAOB: Arbitrary[A => Option[B]], - ArbBOC: Arbitrary[B => Option[C]], - ArbAB: Arbitrary[A => C], - EqFA: Eq[F[A]], - EqFC: Eq[F[C]] + ArbFA: Arbitrary[F[A]], + ArbAOB: Arbitrary[A => Option[B]], + ArbBOC: Arbitrary[B => Option[C]], + ArbAB: Arbitrary[A => C], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + EqFA: Eq[F[A]], + EqFC: Eq[F[C]] ): RuleSet = { new DefaultRuleSet( name = "functorFilter", diff --git a/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala b/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala index 231d9b9fd9..c2a9542a08 100644 --- a/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/FunctorTests.scala @@ -2,8 +2,7 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait FunctorTests[F[_]] extends InvariantTests[F] { @@ -11,6 +10,9 @@ trait FunctorTests[F[_]] extends InvariantTests[F] { def functor[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFC: Eq[F[C]] ): RuleSet = { diff --git a/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala b/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala index 1bdaf07803..0d44206d47 100644 --- a/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/InvariantMonoidalTests.scala @@ -3,7 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop._ trait InvariantMonoidalTests[F[_]] extends InvariantTests[F] with CartesianTests[F] { @@ -13,6 +13,9 @@ trait InvariantMonoidalTests[F[_]] extends InvariantTests[F] with CartesianTests ArbFA: Arbitrary[F[A]], ArbFB: Arbitrary[F[B]], ArbFC: Arbitrary[F[C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFABC: Eq[F[(A, (B, C))]], EqFABC2: Eq[F[(A, B, C)]], iso: Isomorphisms[F], diff --git a/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala b/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala index 36a7b8b29a..3497fc5082 100644 --- a/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/InvariantTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.functor.Invariant -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ import org.typelevel.discipline.Laws @@ -13,6 +12,9 @@ trait InvariantTests[F[_]] extends Laws { def invariant[A: Arbitrary, B: Arbitrary, C: Arbitrary](implicit ArbFA: Arbitrary[F[A]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFC: Eq[F[C]] ): RuleSet = { diff --git a/laws/src/main/scala/cats/laws/discipline/MonadCombineTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadCombineTests.scala index be6ec6ed11..429df09dd3 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadCombineTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadCombineTests.scala @@ -3,9 +3,8 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop -import Prop._ +import org.scalacheck.{Arbitrary, Cogen, Prop} +// import Prop._ trait MonadCombineTests[F[_]] extends MonadFilterTests[F] with AlternativeTests[F] { def laws: MonadCombineLaws[F] @@ -16,6 +15,9 @@ trait MonadCombineTests[F[_]] extends MonadFilterTests[F] with AlternativeTests[ ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], @@ -26,9 +28,10 @@ trait MonadCombineTests[F[_]] extends MonadFilterTests[F] with AlternativeTests[ def name: String = "monadCombine" def bases: Seq[(String, RuleSet)] = Nil def parents: Seq[RuleSet] = Seq(monadFilter[A, B, C], alternative[A, B, C]) - def props: Seq[(String, Prop)] = Seq( - "monadCombine left distributivity" -> forAll(laws.monadCombineLeftDistributivity[A, B] _) - ) + def props: Seq[(String, Prop)] = Nil + // def props: Seq[(String, Prop)] = Seq( + // "monadCombine left distributivity" -> forAll(laws.monadCombineLeftDistributivity[A, B] _) + // ) } } } diff --git a/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala index 74bca14988..b8e3fa84c7 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadErrorTests.scala @@ -4,7 +4,7 @@ package discipline import cats.data.EitherT import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Prop} +import org.scalacheck.{Arbitrary, Cogen, Prop} import org.scalacheck.Prop.forAll trait MonadErrorTests[F[_], E] extends ApplicativeErrorTests[F, E] with MonadTests[F] { @@ -17,6 +17,10 @@ trait MonadErrorTests[F[_], E] extends ApplicativeErrorTests[F, E] with MonadTes ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], ArbE: Arbitrary[E], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenE: Cogen[E], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/MonadFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadFilterTests.scala index bfdb555fd6..3f2daa11ea 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadFilterTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadFilterTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait MonadFilterTests[F[_]] extends MonadTests[F] with FunctorFilterTests[F] { @@ -16,6 +15,9 @@ trait MonadFilterTests[F[_]] extends MonadTests[F] with FunctorFilterTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/MonadReaderTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadReaderTests.scala index 10f2507816..5c8266dd27 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadReaderTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadReaderTests.scala @@ -3,7 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Prop} +import org.scalacheck.{Arbitrary, Cogen, Prop} import org.scalacheck.Prop.forAll trait MonadReaderTests[F[_], R] extends MonadTests[F] { @@ -16,6 +16,10 @@ trait MonadReaderTests[F[_], R] extends MonadTests[F] { ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], ArbR: Arbitrary[R], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenR: Cogen[R], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/MonadStateTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadStateTests.scala index c27d93d7ac..22e83829b4 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadStateTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadStateTests.scala @@ -3,7 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.{Arbitrary, Prop} +import org.scalacheck.{Arbitrary, Cogen, Prop} import org.scalacheck.Prop.forAll trait MonadStateTests[F[_], S] extends MonadTests[F] { @@ -18,6 +18,9 @@ trait MonadStateTests[F[_], S] extends MonadTests[F] { ArbS: Arbitrary[S], ArbFS: Arbitrary[F[S]], ArbFUnit: Arbitrary[F[Unit]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/MonadTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadTests.scala index 50e6a56039..076fc3e79a 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait MonadTests[F[_]] extends ApplicativeTests[F] with FlatMapTests[F] { @@ -16,6 +15,9 @@ trait MonadTests[F[_]] extends ApplicativeTests[F] with FlatMapTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFB: Eq[F[B]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/MonadWriterTests.scala b/laws/src/main/scala/cats/laws/discipline/MonadWriterTests.scala index e3f92eb563..85a91436e0 100644 --- a/laws/src/main/scala/cats/laws/discipline/MonadWriterTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/MonadWriterTests.scala @@ -3,7 +3,7 @@ package laws package discipline import cats.laws.discipline.CartesianTests.Isomorphisms -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop.forAll trait MonadWriterTests[F[_], W] extends MonadTests[F] { @@ -15,6 +15,9 @@ trait MonadWriterTests[F[_], W] extends MonadTests[F] { ArbFC: Arbitrary[F[C]], ArbFAtoB: Arbitrary[F[A => B]], ArbFBtoC: Arbitrary[F[B => C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], EqFA: Eq[F[A]], EqFAW: Eq[F[(W, A)]], EqFB: Eq[F[B]], diff --git a/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala b/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala index 3a5d4a5a4e..957c92f917 100644 --- a/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ProfunctorTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.functor.Profunctor -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ import org.typelevel.discipline.Laws @@ -14,6 +13,11 @@ trait ProfunctorTests[F[_, _]] extends Laws { def profunctor[A: Arbitrary, B: Arbitrary, C: Arbitrary, D: Arbitrary, E: Arbitrary, G: Arbitrary](implicit ArbFAB: Arbitrary[F[A, B]], ArbFCD: Arbitrary[F[C, D]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenD: Cogen[D], + CogenE: Cogen[E], EqFAB: Eq[F[A, B]], EqFAD: Eq[F[A, D]], EqFAG: Eq[F[A, G]] diff --git a/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala b/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala index 4f7db2d858..cae5bf2730 100644 --- a/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/ReducibleTests.scala @@ -2,7 +2,7 @@ package cats package laws package discipline -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Prop.forAll trait ReducibleTests[F[_]] extends FoldableTests[F] { @@ -12,9 +12,10 @@ trait ReducibleTests[F[_]] extends FoldableTests[F] { ArbFA: Arbitrary[F[A]], ArbFGA: Arbitrary[F[G[A]]], ArbGB: Arbitrary[G[B]], - B: Monoid[B], + CogenA: Cogen[A], EqG: Eq[G[Unit]], - EqB: Eq[B] + EqB: Eq[B], + MonoidB: Monoid[B] ): RuleSet = new DefaultRuleSet( name = "reducible", diff --git a/laws/src/main/scala/cats/laws/discipline/StrongTests.scala b/laws/src/main/scala/cats/laws/discipline/StrongTests.scala index dc07d961e4..7b20c09946 100644 --- a/laws/src/main/scala/cats/laws/discipline/StrongTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/StrongTests.scala @@ -3,8 +3,7 @@ package laws package discipline import cats.functor.Strong -import org.scalacheck.Arbitrary -import org.scalacheck.Prop +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait StrongTests[F[_, _]] extends ProfunctorTests[F] { @@ -14,6 +13,11 @@ trait StrongTests[F[_, _]] extends ProfunctorTests[F] { ArbFAB: Arbitrary[F[A, B]], ArbFBC: Arbitrary[F[B, C]], ArbFCD: Arbitrary[F[C, D]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], + CogenD: Cogen[D], + CogenE: Cogen[E], EqFAB: Eq[F[A, B]], EqFAD: Eq[F[A, D]], EqFAG: Eq[F[A, G]], diff --git a/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala b/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala index f1e717e1bf..0ef525483b 100644 --- a/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/TraverseFilterTests.scala @@ -2,7 +2,7 @@ package cats package laws package discipline -import org.scalacheck.{Prop, Arbitrary} +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ trait TraverseFilterTests[F[_]] extends TraverseTests[F] with FunctorFilterTests[F] { @@ -15,6 +15,9 @@ trait TraverseFilterTests[F[_]] extends TraverseTests[F] with FunctorFilterTests ArbYC: Arbitrary[Y[C]], ArbAXOB: Arbitrary[A => X[Option[B]]], ArbBYOC: Arbitrary[B => Y[Option[C]]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], M: Monoid[M], EqFA: Eq[F[A]], EqFC: Eq[F[C]], diff --git a/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala b/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala index 14496b396c..447ab090cf 100644 --- a/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala +++ b/laws/src/main/scala/cats/laws/discipline/TraverseTests.scala @@ -2,7 +2,7 @@ package cats package laws package discipline -import org.scalacheck.{Prop, Arbitrary} +import org.scalacheck.{Arbitrary, Cogen, Prop} import Prop._ @@ -14,6 +14,9 @@ trait TraverseTests[F[_]] extends FunctorTests[F] with FoldableTests[F] { ArbXB: Arbitrary[X[B]], ArbYB: Arbitrary[Y[B]], ArbYC: Arbitrary[Y[C]], + CogenA: Cogen[A], + CogenB: Cogen[B], + CogenC: Cogen[C], M: Monoid[M], EqFA: Eq[F[A]], EqFC: Eq[F[C]], diff --git a/tests/src/test/scala/cats/tests/CatsSuite.scala b/tests/src/test/scala/cats/tests/CatsSuite.scala index 8341ef36c6..2909a55b86 100644 --- a/tests/src/test/scala/cats/tests/CatsSuite.scala +++ b/tests/src/test/scala/cats/tests/CatsSuite.scala @@ -7,15 +7,10 @@ import cats.instances.AllInstances import cats.syntax.{AllSyntax, EqOps} import org.scalactic.anyvals.{PosZDouble, PosInt, PosZInt} -import org.scalatest.{FunSuite, Matchers} +import org.scalatest.{FunSuite, FunSuiteLike, Matchers} import org.scalatest.prop.{Configuration, GeneratorDrivenPropertyChecks} import org.typelevel.discipline.scalatest.Discipline -import org.scalacheck.{Arbitrary, Gen} -import org.scalacheck.Arbitrary.arbitrary - -import scala.util.{Failure, Success, Try} - trait TestSettings extends Configuration with Matchers { lazy val checkConfiguration: PropertyCheckConfiguration = @@ -35,7 +30,15 @@ trait TestSettings extends Configuration with Matchers { * An opinionated stack of traits to improve consistency and reduce * boilerplate in Cats tests. */ -trait CatsSuite extends FunSuite with Matchers with GeneratorDrivenPropertyChecks with Discipline with TestSettings with AllInstances with AllSyntax with TestInstances with StrictCatsEquality { +trait CatsSuite extends FunSuite + with Matchers + with GeneratorDrivenPropertyChecks + with Discipline + with TestSettings + with AllInstances + with AllSyntax + with StrictCatsEquality { self: FunSuiteLike => + implicit override val generatorDrivenConfig: PropertyCheckConfiguration = checkConfiguration @@ -52,11 +55,3 @@ trait SlowCatsSuite extends CatsSuite { implicit override val generatorDrivenConfig: PropertyCheckConfiguration = slowCheckConfiguration } - -sealed trait TestInstances { - // To be replaced by https://github.com/rickynils/scalacheck/pull/170 - implicit def arbitraryTry[A: Arbitrary]: Arbitrary[Try[A]] = - Arbitrary(Gen.oneOf( - arbitrary[A].map(Success(_)), - arbitrary[Throwable].map(Failure(_)))) -} diff --git a/tests/src/test/scala/cats/tests/ConstTests.scala b/tests/src/test/scala/cats/tests/ConstTests.scala index 117c51d2c1..792676ffb2 100644 --- a/tests/src/test/scala/cats/tests/ConstTests.scala +++ b/tests/src/test/scala/cats/tests/ConstTests.scala @@ -6,7 +6,7 @@ import cats.kernel.laws.{GroupLaws, OrderLaws} import cats.data.{Const, NonEmptyList} import cats.functor.Contravariant import cats.laws.discipline._ -import cats.laws.discipline.arbitrary.{catsLawsArbitraryForConst, catsLawsArbitraryForNonEmptyList} +import cats.laws.discipline.arbitrary._ class ConstTests extends CatsSuite { diff --git a/tests/src/test/scala/cats/tests/EvalTests.scala b/tests/src/test/scala/cats/tests/EvalTests.scala index 308f56cee7..d7c4100253 100644 --- a/tests/src/test/scala/cats/tests/EvalTests.scala +++ b/tests/src/test/scala/cats/tests/EvalTests.scala @@ -45,6 +45,7 @@ class EvalTests extends CatsSuite { spin ^= result.## } spooky.counter should === (numEvals) + () } (0 to 2).foreach(n => nTimes(n, numCalls(n))) } diff --git a/tests/src/test/scala/cats/tests/Helpers.scala b/tests/src/test/scala/cats/tests/Helpers.scala index ed88d386b2..85cb8e7d00 100644 --- a/tests/src/test/scala/cats/tests/Helpers.scala +++ b/tests/src/test/scala/cats/tests/Helpers.scala @@ -1,7 +1,7 @@ package cats package tests -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import Arbitrary.arbitrary import cats.kernel.{ CommutativeSemigroup, CommutativeMonoid, CommutativeGroup } @@ -23,22 +23,25 @@ import cats.kernel.{ Band, Semilattice, BoundedSemilattice } */ object Helpers { - abstract class Arb[E](f: Int => E) { + abstract class N { def n: Int } + + abstract class Arb[E <: N](f: Int => E) { implicit val earb: Arbitrary[E] = Arbitrary(arbitrary[Int].map(f)) + implicit val ccog: Cogen[E] = Cogen[Int].contramap(_.n) } trait Q[E] { implicit val eeq: Eq[E] = Eq.fromUniversalEquals } - abstract class Companion[E](f: Int => E) extends Arb[E](f) with Q[E] + abstract class Companion[E <: N](f: Int => E) extends Arb[E](f) with Q[E] // Eq - case class Eqed(n: Int) + case class Eqed(n: Int) extends N object Eqed extends Companion(new Eqed(_)) // PartialOrder - case class POrd(n: Int) + case class POrd(n: Int) extends N object POrd extends Arb(new POrd(_)) { implicit object O extends PartialOrder[POrd] { def partialCompare(x: POrd, y: POrd): Double = @@ -49,7 +52,7 @@ object Helpers { } // Order - case class Ord(n: Int) + case class Ord(n: Int) extends N object Ord extends Arb(new Ord(_)) { implicit object O extends Order[Ord] { def compare(x: Ord, y: Ord): Int = x.n compare y.n @@ -57,7 +60,7 @@ object Helpers { } // Band - case class Bnd(n: Int) + case class Bnd(n: Int) extends N object Bnd extends Companion(new Bnd(_)) { implicit object Alg extends Band[Bnd] { def combine(x: Bnd, y: Bnd): Bnd = Bnd(x.n & y.n) @@ -65,7 +68,7 @@ object Helpers { } // Semilattice - case class SL(n: Int) + case class SL(n: Int) extends N object SL extends Companion(new SL(_)) { implicit object Alg extends Semilattice[SL] { def combine(x: SL, y: SL): SL = SL(x.n & y.n) @@ -73,7 +76,7 @@ object Helpers { } // BoundedSemilattice - case class BSL(n: Int) + case class BSL(n: Int) extends N object BSL extends Companion(new BSL(_)) { implicit object Alg extends BoundedSemilattice[BSL] { def empty: BSL = BSL(0) @@ -82,7 +85,7 @@ object Helpers { } // Semigroup - case class Semi(n: Int) + case class Semi(n: Int) extends N object Semi extends Companion(new Semi(_)) { implicit object Alg extends Semigroup[Semi] { def combine(x: Semi, y: Semi): Semi = Semi(x.n ^ y.n) @@ -90,7 +93,7 @@ object Helpers { } // CommutativeSemigroup - case class CSemi(n: Int) + case class CSemi(n: Int) extends N object CSemi extends Companion(new CSemi(_)) { implicit object Alg extends CommutativeSemigroup[CSemi] { def combine(x: CSemi, y: CSemi): CSemi = CSemi(x.n ^ y.n) @@ -98,7 +101,7 @@ object Helpers { } // Monoid - case class Mono(n: Int) + case class Mono(n: Int) extends N object Mono extends Companion(new Mono(_)) { implicit object Alg extends Monoid[Mono] { def empty: Mono = Mono(Int.MaxValue) @@ -107,7 +110,7 @@ object Helpers { } // CommutativeMonoid - case class CMono(n: Int) + case class CMono(n: Int) extends N object CMono extends Companion(new CMono(_)) { implicit object Alg extends CommutativeMonoid[CMono] { def empty: CMono = CMono(Int.MaxValue) @@ -116,7 +119,7 @@ object Helpers { } // Group - case class Grp(n: Int) + case class Grp(n: Int) extends N object Grp extends Companion(new Grp(_)) { implicit object Alg extends Group[Grp] { def empty: Grp = Grp(0) @@ -126,7 +129,7 @@ object Helpers { } // CommutativeGroup - case class CGrp(n: Int) + case class CGrp(n: Int) extends N object CGrp extends Companion(new CGrp(_)) { implicit object Alg extends CommutativeGroup[CGrp] { def empty: CGrp = CGrp(0) diff --git a/tests/src/test/scala/cats/tests/ListWrapper.scala b/tests/src/test/scala/cats/tests/ListWrapper.scala index 4c2dad7efa..7bf02bfccb 100644 --- a/tests/src/test/scala/cats/tests/ListWrapper.scala +++ b/tests/src/test/scala/cats/tests/ListWrapper.scala @@ -4,7 +4,7 @@ package tests import cats.functor.Invariant import cats.instances.list._ -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} import org.scalacheck.Arbitrary.arbitrary /** This data type exists purely for testing. @@ -25,7 +25,7 @@ import org.scalacheck.Arbitrary.arbitrary * By providing this data type, we can have implicit search pick up * a specific type class instance by asking for it explicitly in a block. * Note that ListWrapper has no type class instances in implicit scope, - * save for ones related to testing (e.g. Eq and Arbitrary). + * save for ones related to testing (e.g. Eq, Arbitrary, Cogen). * * {{{ * { @@ -113,5 +113,9 @@ object ListWrapper { implicit def listWrapperArbitrary[A: Arbitrary]: Arbitrary[ListWrapper[A]] = Arbitrary(arbitrary[List[A]].map(ListWrapper.apply)) - implicit def listWrapperEq[A: Eq]: Eq[ListWrapper[A]] = Eq.by(_.list) + implicit def listWrapperCogen[A: Cogen]: Cogen[ListWrapper[A]] = + Cogen[List[A]].contramap(_.list) + + implicit def listWrapperEq[A: Eq]: Eq[ListWrapper[A]] = + Eq.by(_.list) } diff --git a/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala b/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala index 604318ae14..a2f6b78401 100644 --- a/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala +++ b/tests/src/test/scala/cats/tests/MonadRecInstancesTests.scala @@ -20,6 +20,7 @@ class MonadRecInstancesTests extends CatsSuite { val n = 50000 val res = M.tailRecM(0)(i => M.pure(if (i < n) Either.left(i + 1) else Either.right(i))) res should === (M.pure(n)) + () } test("tailRecM stack-safety for Cokleisli[Option, Int, ?]") { diff --git a/tests/src/test/scala/cats/tests/NonEmptyListTests.scala b/tests/src/test/scala/cats/tests/NonEmptyListTests.scala index 09eb06ffb8..024c58b626 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyListTests.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyListTests.scala @@ -117,7 +117,10 @@ class NonEmptyListTests extends CatsSuite { test("reduceRight consistent with foldRight") { forAll { (nel: NonEmptyList[Int], f: (Int, Eval[Int]) => Eval[Int]) => - nel.reduceRight(f).value should === (nel.tail.foldRight(nel.head)((a, b) => f(a, Now(b)).value)) + val got = nel.reduceRight(f).value + val last :: rev = nel.toList.reverse + val expected = rev.reverse.foldRight(last)((a, b) => f(a, Now(b)).value) + got should === (expected) } } @@ -144,10 +147,12 @@ class NonEmptyListTests extends CatsSuite { test("reduceRightToOption consistent with foldRight + Option") { forAll { (nel: NonEmptyList[Int], f: Int => String, g: (Int, Eval[String]) => Eval[String]) => - val expected = nel.tail.foldRight(Option(f(nel.head))) { (i, opt) => + val got = nel.reduceRightToOption(f)(g).value + val last :: rev = nel.toList.reverse + val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } - nel.reduceRightToOption(f)(g).value should === (expected) + got should === (expected) } } diff --git a/tests/src/test/scala/cats/tests/NonEmptyVectorTests.scala b/tests/src/test/scala/cats/tests/NonEmptyVectorTests.scala index 729aeba973..53c4feacb9 100644 --- a/tests/src/test/scala/cats/tests/NonEmptyVectorTests.scala +++ b/tests/src/test/scala/cats/tests/NonEmptyVectorTests.scala @@ -127,9 +127,15 @@ class NonEmptyVectorTests extends CatsSuite { } } + def excise[A](as: Vector[A]): (Vector[A], A) = + (as.slice(0, as.size - 1), as.last) + test("reduceRight consistent with foldRight") { forAll { (nonEmptyVector: NonEmptyVector[Int], f: (Int, Eval[Int]) => Eval[Int]) => - nonEmptyVector.reduceRight(f).value should === (nonEmptyVector.tail.foldRight(nonEmptyVector.head)((a, b) => f(a, Now(b)).value)) + val got = nonEmptyVector.reduceRight(f).value + val (first, last) = excise(nonEmptyVector.toVector) + val expected = first.foldRight(last)((a, b) => f(a, Now(b)).value) + got should === (expected) } } @@ -156,7 +162,8 @@ class NonEmptyVectorTests extends CatsSuite { test("reduceRightToOption consistent with foldRight + Option") { forAll { (nonEmptyVector: NonEmptyVector[Int], f: Int => String, g: (Int, Eval[String]) => Eval[String]) => - val expected = nonEmptyVector.tail.foldRight(Option(f(nonEmptyVector.head))) { (i, opt) => + val (first, last) = excise(nonEmptyVector.toVector) + val expected = first.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } nonEmptyVector.reduceRightToOption(f)(g).value should === (expected) diff --git a/tests/src/test/scala/cats/tests/OneAndTests.scala b/tests/src/test/scala/cats/tests/OneAndTests.scala index 79d8ec4004..f3a7b26f61 100644 --- a/tests/src/test/scala/cats/tests/OneAndTests.scala +++ b/tests/src/test/scala/cats/tests/OneAndTests.scala @@ -135,7 +135,10 @@ class OneAndTests extends CatsSuite { test("reduceRight consistent with foldRight") { forAll { (nel: NonEmptyStream[Int], f: (Int, Eval[Int]) => Eval[Int]) => - nel.reduceRight(f).value should === (nel.tail.foldRight(nel.head)((a, b) => f(a, Now(b)).value)) + val got = nel.reduceRight(f).value + val last :: rev = nel.unwrap.toList.reverse + val expected = rev.reverse.foldRight(last)((a, b) => f(a, Now(b)).value) + got should === (expected) } } @@ -162,10 +165,12 @@ class OneAndTests extends CatsSuite { test("reduceRightToOption consistent with foldRight + Option") { forAll { (nel: NonEmptyStream[Int], f: Int => String, g: (Int, Eval[String]) => Eval[String]) => - val expected = nel.tail.foldRight(Option(f(nel.head))) { (i, opt) => + val got = nel.reduceRightToOption(f)(g).value + val last :: rev = nel.unwrap.toList.reverse + val expected = rev.reverse.foldRight(Option(f(last))) { (i, opt) => opt.map(s => g(i, Now(s)).value) } - nel.reduceRightToOption(f)(g).value should === (expected) + got should === (expected) } } } diff --git a/tests/src/test/scala/cats/tests/StateTTests.scala b/tests/src/test/scala/cats/tests/StateTTests.scala index 18fb0bb410..34ebcddc6f 100644 --- a/tests/src/test/scala/cats/tests/StateTTests.scala +++ b/tests/src/test/scala/cats/tests/StateTTests.scala @@ -6,7 +6,7 @@ import cats.kernel.instances.tuple._ import cats.laws.discipline._ import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ -import org.scalacheck.Arbitrary +import org.scalacheck.{Arbitrary, Cogen} class StateTTests extends CatsSuite { import StateTTests._ @@ -226,7 +226,7 @@ object StateTTests extends StateTTestsInstances { implicit def stateEq[S:Eq:Arbitrary, A:Eq]: Eq[State[S, A]] = stateTEq[Eval, S, A] - implicit def stateArbitrary[S: Arbitrary, A: Arbitrary]: Arbitrary[State[S, A]] = + implicit def stateArbitrary[S: Arbitrary: Cogen, A: Arbitrary]: Arbitrary[State[S, A]] = stateTArbitrary[Eval, S, A] val add1: State[Int, Int] = State(n => (n + 1, n)) diff --git a/tests/src/test/scala/cats/tests/TryTests.scala b/tests/src/test/scala/cats/tests/TryTests.scala index 074fda6880..3548372aa4 100644 --- a/tests/src/test/scala/cats/tests/TryTests.scala +++ b/tests/src/test/scala/cats/tests/TryTests.scala @@ -3,6 +3,7 @@ package tests import cats.laws.{ApplicativeLaws, CoflatMapLaws, FlatMapLaws, MonadLaws} import cats.laws.discipline._ +import cats.laws.discipline.arbitrary._ import scala.util.{Success, Try}