diff --git a/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala b/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala index 1802b449bd..6420ea6533 100644 --- a/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala +++ b/free/src/test/scala/cats/free/FreeInvariantMonoidalSuite.scala @@ -3,10 +3,11 @@ package tests import cats.arrow.FunctionK import cats.free.FreeInvariantMonoidal -import cats.laws.discipline.{InvariantMonoidalTests, SerializableTests} +import cats.laws.discipline.{InvariantMonoidalTests, MiniInt, SerializableTests} +import cats.laws.discipline.arbitrary._ import cats.laws.discipline.SemigroupalTests.Isomorphisms import org.scalacheck.{Arbitrary, Gen} -import cats.tests.CsvCodecInvariantMonoidalSuite._ +import cats.tests.BinCodecInvariantMonoidalSuite._ class FreeInvariantMonoidalSuite extends CatsSuite { implicit def freeInvariantMonoidalArbitrary[F[_], A](implicit F: Arbitrary[F[A]], @@ -25,24 +26,25 @@ class FreeInvariantMonoidalSuite extends CatsSuite { } } - implicit val isoFreeCsvCodec = Isomorphisms.invariant[FreeInvariantMonoidal[CsvCodec, ?]] + implicit val isoFreeBinCodec = Isomorphisms.invariant[FreeInvariantMonoidal[BinCodec, ?]] - checkAll("FreeInvariantMonoidal[CsvCodec, ?]", - InvariantMonoidalTests[FreeInvariantMonoidal[CsvCodec, ?]].invariantMonoidal[Int, Int, Int]) - checkAll("InvariantMonoidal[FreeInvariantMonoidal[CsvCodec, ?]]", - SerializableTests.serializable(InvariantMonoidal[FreeInvariantMonoidal[CsvCodec, ?]])) + checkAll("FreeInvariantMonoidal[BinCodec, ?]", + InvariantMonoidalTests[FreeInvariantMonoidal[BinCodec, ?]].invariantMonoidal[MiniInt, Boolean, Boolean]) + checkAll("InvariantMonoidal[FreeInvariantMonoidal[BinCodec, ?]]", + SerializableTests.serializable(InvariantMonoidal[FreeInvariantMonoidal[BinCodec, ?]])) test("FreeInvariantMonoidal#fold") { - val n = 2 - val i1 = numericSystemCodec(8) - val i2 = InvariantMonoidal[CsvCodec].point(n) - val iExpr = i1.product(i2.imap(_ * 2)(_ / 2)) + forAll { i1: BinCodec[MiniInt] => + val n = MiniInt.unsafeFromInt(2) + val i2 = InvariantMonoidal[BinCodec].point(n) + val iExpr = i1.product(i2.imap(_ * n)(_ / n)) - val f1 = FreeInvariantMonoidal.lift[CsvCodec, Int](i1) - val f2 = FreeInvariantMonoidal.pure[CsvCodec, Int](n) - val fExpr = f1.product(f2.imap(_ * 2)(_ / 2)) + val f1 = FreeInvariantMonoidal.lift[BinCodec, MiniInt](i1) + val f2 = FreeInvariantMonoidal.pure[BinCodec, MiniInt](n) + val fExpr = f1.product(f2.imap(_ * n)(_ / n)) - fExpr.fold should ===(iExpr) + fExpr.fold should ===(iExpr) + } } implicit val idIsInvariantMonoidal: InvariantMonoidal[Id] = new InvariantMonoidal[Id] { diff --git a/free/src/test/scala/cats/free/FreeTSuite.scala b/free/src/test/scala/cats/free/FreeTSuite.scala index 7224a7a837..29b62cc99e 100644 --- a/free/src/test/scala/cats/free/FreeTSuite.scala +++ b/free/src/test/scala/cats/free/FreeTSuite.scala @@ -5,7 +5,6 @@ import cats._ import cats.arrow.FunctionK import cats.data._ import cats.laws.discipline._ -import cats.laws.discipline.arbitrary._ import cats.tests.CatsSuite import cats.instances.option._ import org.scalacheck.{Arbitrary, Cogen, Gen} @@ -247,7 +246,7 @@ trait FreeTSuiteInstances { import cats.tests.IndexedStateTSuite._ import SemigroupalTests._ - type IntState[A] = State[Int, A] + type IntState[A] = State[MiniInt, A] type FreeTOption[A] = FreeT[Option, Option, A] type FreeTState[A] = FreeT[IntState, IntState, A] @@ -261,16 +260,6 @@ trait FreeTSuiteInstances { override def map[A, B](fa: JustFunctor[A])(f: A => B): JustFunctor[B] = JustFunctor(f(fa.a)) } - implicit val intEq: Eq[Int] = new Eq[Int] { - def eqv(a: Int, b: Int) = a == b - } - - implicit def evalEq[A: Eq]: Eq[Eval[A]] = Eval.catsEqForEval[A] - - implicit def intStateEq[A: Eq]: Eq[IntState[A]] = stateEq[Int, A] - - implicit def intStateArb[A: Arbitrary]: Arbitrary[IntState[A]] = catsLawArbitraryForState[Int, A] - implicit def freeTOptionEq[A](implicit A: Eq[A], OM: Monad[Option]): Eq[FreeTOption[A]] = new Eq[FreeTOption[A]] { def eqv(a: FreeTOption[A], b: FreeTOption[A]) = Eq[Option[A]].eqv(a.runM(identity), b.runM(identity)) } diff --git a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala index 664dc28477..fa99582c5e 100644 --- a/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala +++ b/laws/src/main/scala/cats/laws/discipline/Arbitrary.scala @@ -349,6 +349,11 @@ object arbitrary extends ArbitraryInstances0 { implicit def catsLawsCogenForChain[A](implicit A: Cogen[A]): Cogen[Chain[A]] = Cogen[List[A]].contramap(_.toList) + implicit val catsLawsCogenForMiniInt: Cogen[MiniInt] = + Cogen[Int].contramap(_.toInt) + + implicit val catsLawsArbitraryForMiniInt: Arbitrary[MiniInt] = + Arbitrary(Gen.oneOf(MiniInt.allValues)) } sealed private[discipline] trait ArbitraryInstances0 { diff --git a/laws/src/main/scala/cats/laws/discipline/Eq.scala b/laws/src/main/scala/cats/laws/discipline/Eq.scala index feb05bd692..c6bd200676 100644 --- a/laws/src/main/scala/cats/laws/discipline/Eq.scala +++ b/laws/src/main/scala/cats/laws/discipline/Eq.scala @@ -10,16 +10,117 @@ import cats.data.AndThen import cats.instances.boolean._ import cats.instances.int._ import cats.instances.string._ +import cats.instances.tuple._ import cats.kernel._ import cats.syntax.eq._ import org.scalacheck.Arbitrary -object eq { +object eq extends DisciplineBinCompatEqInstances { + + implicit def catsLawsEqForFn1Exhaustive[A, B](implicit A: ExhaustiveCheck[A], B: Eq[B]): Eq[A => B] = + Eq.instance((f, g) => A.allValues.forall(a => B.eqv(f(a), g(a)))) + + implicit def catsLawsEqForFn2BinCompat[A, B, C](implicit ev: Eq[((A, B)) => C]): Eq[(A, B) => C] = + Eq.by((_: (A, B) => C).tupled) + + implicit def catsLawsEqForAndThenBinCompat[A, B](implicit eqAB: Eq[A => B]): Eq[AndThen[A, B]] = + Eq.by[AndThen[A, B], A => B](identity) + + implicit def catsLawsEqForShowBinCompat[A](implicit ev: Eq[A => String]): Eq[Show[A]] = + Eq.by[Show[A], A => String](showA => a => showA.show(a)) + + implicit def catsLawsEqForEqBinCompt[A](implicit ev: Eq[(A, A) => Boolean]): Eq[Eq[A]] = + Eq.by[Eq[A], (A, A) => Boolean](e => (a1, a2) => e.eqv(a1, a2)) + + implicit def catsLawsEqForEquivBinCompat[A](implicit ev: Eq[(A, A) => Boolean]): Eq[Equiv[A]] = + Eq.by[Equiv[A], (A, A) => Boolean](e => (a1, a2) => e.equiv(a1, a2)) + + implicit def catsLawsEqForPartialOrderBinCompat[A](implicit ev: Eq[(A, A) => Option[Int]]): Eq[PartialOrder[A]] = + Eq.by[PartialOrder[A], (A, A) => Option[Int]](o => (a1, a2) => o.tryCompare(a1, a2)) + + implicit def catsLawsEqForPartialOrderingBinCompat[A]( + implicit ev: Eq[(A, A) => Option[Int]] + ): Eq[PartialOrdering[A]] = + Eq.by[PartialOrdering[A], (A, A) => Option[Int]]((o: PartialOrdering[A]) => (a1, a2) => o.tryCompare(a1, a2)) + + implicit def catsLawsEqForOrderBinCompat[A](implicit ev: Eq[(A, A) => Int]): Eq[Order[A]] = + Eq.by[Order[A], (A, A) => Int](o => (a1, a2) => o.compare(a1, a2)) + + implicit def catsLawsEqForOrderingBinCompat[A](implicit ev: Eq[(A, A) => Int]): Eq[Ordering[A]] = + Eq.by[Ordering[A], (A, A) => Int](o => (a1, a2) => o.compare(a1, a2)) + + implicit def catsLawsEqForHashBinCompat[A](implicit ev: Eq[A => Int]): Eq[Hash[A]] = + Eq.by[Hash[A], A => Int](h => a => h.hash(a)) + + implicit def catsLawsEqForSemigroupBinCompat[A](implicit ev: Eq[(A, A) => A]): Eq[Semigroup[A]] = + Eq.by[Semigroup[A], (A, A) => A](s => (a1, a2) => s.combine(a1, a2)) + + implicit def catsLawsEqForCommutativeSemigroupBinCompat[A](implicit eqA: Eq[A], + ev: Eq[(A, A) => (A, A)]): Eq[CommutativeSemigroup[A]] = + Eq.by[CommutativeSemigroup[A], (A, A) => (A, A)](s => (x, y) => (s.combine(x, y), s.combine(y, x))) + + implicit def catsLawsEqForBandBinCompat[A](implicit ev: Eq[(A, A) => (A, A)]): Eq[Band[A]] = + Eq.by[Band[A], (A, A) => (A, A)]( + f => (x, y) => (f.combine(x, y), f.combine(f.combine(x, y), y)) + ) + + implicit def catsLawsEqForGroupBinCompat[A](implicit ev1: Eq[(A, A) => (A, Boolean)], eqA: Eq[A]): Eq[Group[A]] = + Eq.by[Group[A], (A, A) => (A, Boolean)]( + f => + (x, y) => + ( + f.combine(x, y), + f.combine(f.inverse(x), x) === f.empty && f.combine(x, f.inverse(x)) === f.empty && + f.combine(f.inverse(y), y) === f.empty && f.combine(y, f.inverse(y)) === f.empty && + f.inverse(f.empty) == f.empty + ) + ) + + implicit def catsLawsEqForMonoid[A](implicit eqSA: Eq[Semigroup[A]], eqA: Eq[A]): Eq[Monoid[A]] = new Eq[Monoid[A]] { + def eqv(f: Monoid[A], g: Monoid[A]): Boolean = + eqSA.eqv(f, g) && eqA.eqv(f.empty, g.empty) + } + + implicit def catsLawsEqForSemilattice[A](implicit eqBA: Eq[Band[A]], + eqCA: Eq[CommutativeSemigroup[A]], + eqA: Eq[A]): Eq[Semilattice[A]] = + Eq.instance((f, g) => eqBA.eqv(f, g) && eqCA.eqv(f, g)) + + implicit def catsLawsEqForCommutativeMonoid[A](implicit eqSA: Eq[CommutativeSemigroup[A]], + eqMA: Eq[Monoid[A]], + eqA: Eq[A]): Eq[CommutativeMonoid[A]] = + Eq.instance((f, g) => eqSA.eqv(f, g) && eqMA.eqv(f, g)) + + implicit def catsLawsEqForBoundedSemilattice[A](implicit eqSA: Eq[Semilattice[A]], + eqCA: Eq[CommutativeMonoid[A]], + eqA: Eq[A]): Eq[BoundedSemilattice[A]] = + Eq.instance((f, g) => eqSA.eqv(f, g) && eqCA.eqv(f, g)) + + implicit def catsLawsEqForCommutativeGroup[A](implicit eqMA: Eq[CommutativeMonoid[A]], + eqGA: Eq[Group[A]], + eqA: Eq[A]): Eq[CommutativeGroup[A]] = + Eq.instance((f, g) => eqMA.eqv(f, g) && eqGA.eqv(f, g)) + + implicit def catsLawsEqForRepresentableStore[F[_]: Representable, S, A](implicit eqFA: Eq[F[A]], + eqS: Eq[S]): Eq[RepresentableStore[F, S, A]] = + Eq.instance((s1, s2) => eqFA.eqv(s1.fa, s2.fa) && eqS.eqv(s1.index, s2.index)) +} + +/** + * These instances are questionable and can lead to false positives. For the sake of compatibility, + * they haven't been removed, but they should be considered to be deprecated, and we put them in a + * lower implicit scope priority. + */ +private[discipline] trait DisciplineBinCompatEqInstances { /** - * Create an approximation of Eq[A => B] by generating 100 values for A + * Create an approximation of Eq[A => B] by generating random values for A * and comparing the application of the two functions. */ + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForFn1Exhaustive instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForFn1[A, B](implicit A: Arbitrary[A], B: Eq[B]): Eq[A => B] = new Eq[A => B] { val sampleCnt: Int = if (Platform.isJvm) 50 else 30 @@ -32,37 +133,43 @@ object eq { } } - /** `Eq[AndThen]` instance, built by piggybacking on [[catsLawsEqForFn1]]. */ - implicit def catsLawsEqForAndThen[A, B](implicit A: Arbitrary[A], B: Eq[B]): Eq[AndThen[A, B]] = - Eq.instance(catsLawsEqForFn1[A, B].eqv(_, _)) - /** - * Create an approximation of Eq[(A, B) => C] by generating 100 values for A and B + * Create an approximation of Eq[(A, B) => C] by generating random values for A and B * and comparing the application of the two functions. */ + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForFn2BinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForFn2[A, B, C](implicit A: Arbitrary[A], B: Arbitrary[B], C: Eq[C]): Eq[(A, B) => C] = - new Eq[(A, B) => C] { - val sampleCnt: Int = if (Platform.isJvm) 50 else 5 - - def eqv(f: (A, B) => C, g: (A, B) => C): Boolean = { - val samples = List.fill(sampleCnt)((A.arbitrary.sample, B.arbitrary.sample)).collect { - case (Some(a), Some(b)) => (a, b) - case _ => sys.error("Could not generate arbitrary values to compare two functions") - } - samples.forall { case (a, b) => C.eqv(f(a, b), g(a, b)) } - } - } + Eq.by((_: (A, B) => C).tupled)(catsLawsEqForFn1) + + /** `Eq[AndThen]` instance, built by piggybacking on [[catsLawsEqForFn1]]. */ + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForAndThenBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) + implicit def catsLawsEqForAndThen[A, B](implicit A: Arbitrary[A], B: Eq[B]): Eq[AndThen[A, B]] = + Eq.instance(catsLawsEqForFn1[A, B].eqv(_, _)) /** Create an approximation of Eq[Show[A]] by using catsLawsEqForFn1[A, String] */ + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForShowBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForShow[A: Arbitrary]: Eq[Show[A]] = Eq.by[Show[A], A => String] { showInstance => (a: A) => showInstance.show(a) - } + }(catsLawsEqForFn1) /** * Create an approximate Eq instance for some type A, by comparing * the behavior of `f(x, b)` and `f(y, b)` across many `b` samples. */ + @deprecated( + "This method is problematic and will most likely be removed in a future version of Cats. You may want to use an approach based on catsLawsEqForFn1Exhaustive instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) def sampledEq[A, B: Arbitrary, C: Eq](samples: Int)(f: (A, B) => C): Eq[A] = new Eq[A] { val gen = Arbitrary.arbitrary[B] @@ -76,23 +183,47 @@ object eq { } } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForEqBinCompt instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForEq[A](implicit arbA: Arbitrary[(A, A)]): Eq[Eq[A]] = sampledEq[Eq[A], (A, A), Boolean](100) { case (e, (l, r)) => e.eqv(l, r) } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForEquivBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForEquiv[A](implicit arbA: Arbitrary[(A, A)]): Eq[Equiv[A]] = sampledEq[Equiv[A], (A, A), Boolean](100) { case (e, (l, r)) => e.equiv(l, r) } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForPartialOrderBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForPartialOrder[A](implicit arbA: Arbitrary[(A, A)], optIntEq: Eq[Option[Int]]): Eq[PartialOrder[A]] = sampledEq[PartialOrder[A], (A, A), Option[Int]](100) { case (p, (l, r)) => p.tryCompare(l, r) } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForPartialOrderingBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForPartialOrdering[A](implicit arbA: Arbitrary[(A, A)], optIntEq: Eq[Option[Int]]): Eq[PartialOrdering[A]] = sampledEq[PartialOrdering[A], (A, A), Option[Int]](100) { case (p, (l, r)) => p.tryCompare(l, r) } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForOrderBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForOrder[A](implicit arbA: Arbitrary[(A, A)]): Eq[Order[A]] = sampledEq[Order[A], (A, A), Int](100) { case (p, (l, r)) => p.compare(l, r) } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForOrderingBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForOrdering[A](implicit arbA: Arbitrary[(A, A)]): Eq[Ordering[A]] = sampledEq[Ordering[A], (A, A), Int](100) { case (p, (l, r)) => p.compare(l, r) } @@ -100,6 +231,10 @@ object eq { * Creates an approximation of Eq[Hash[A]] by generating 100 values for A * and comparing the application of the two hash functions. */ + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForHashBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForHash[A](implicit arbA: Arbitrary[A]): Eq[Hash[A]] = new Eq[Hash[A]] { def eqv(f: Hash[A], g: Hash[A]): Boolean = { val samples = List.fill(100)(arbA.arbitrary.sample).collect { @@ -116,11 +251,19 @@ object eq { * Create an approximation of Eq[Semigroup[A]] by generating values for A * and comparing the application of the two combine functions. */ + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForSemigroupBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForSemigroup[A](implicit arbAA: Arbitrary[(A, A)], eqA: Eq[A]): Eq[Semigroup[A]] = { val instance: Eq[((A, A)) => A] = catsLawsEqForFn1[(A, A), A] Eq.by[Semigroup[A], ((A, A)) => A](f => Function.tupled((x, y) => f.combine(x, y)))(instance) } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForCommutativeSemigroupBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForCommutativeSemigroup[A](implicit arbAA: Arbitrary[(A, A)], eqA: Eq[A]): Eq[CommutativeSemigroup[A]] = { implicit val eqABool: Eq[(A, Boolean)] = Eq.instance { @@ -132,6 +275,10 @@ object eq { )(catsLawsEqForFn1[(A, A), (A, Boolean)]) } + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForBandBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForBand[A](implicit arbAA: Arbitrary[(A, A)], eqSA: Eq[Semigroup[A]], eqA: Eq[A]): Eq[Band[A]] = @@ -139,26 +286,10 @@ object eq { f => Function.tupled((x, y) => f.combine(x, y) === f.combine(f.combine(x, y), y)) )(catsLawsEqForFn1[(A, A), Boolean]) - implicit def catsLawsEqForMonoid[A](implicit eqSA: Eq[Semigroup[A]], eqA: Eq[A]): Eq[Monoid[A]] = new Eq[Monoid[A]] { - def eqv(f: Monoid[A], g: Monoid[A]): Boolean = - eqSA.eqv(f, g) && eqA.eqv(f.empty, g.empty) - } - - implicit def catsLawsEqForSemilattice[A](implicit eqBA: Eq[Band[A]], - eqCA: Eq[CommutativeSemigroup[A]], - eqA: Eq[A]): Eq[Semilattice[A]] = - Eq.instance((f, g) => eqBA.eqv(f, g) && eqCA.eqv(f, g)) - - implicit def catsLawsEqForCommutativeMonoid[A](implicit eqSA: Eq[CommutativeSemigroup[A]], - eqMA: Eq[Monoid[A]], - eqA: Eq[A]): Eq[CommutativeMonoid[A]] = - Eq.instance((f, g) => eqSA.eqv(f, g) && eqMA.eqv(f, g)) - - implicit def catsLawsEqForBoundedSemilattice[A](implicit eqSA: Eq[Semilattice[A]], - eqCA: Eq[CommutativeMonoid[A]], - eqA: Eq[A]): Eq[BoundedSemilattice[A]] = - Eq.instance((f, g) => eqSA.eqv(f, g) && eqCA.eqv(f, g)) - + @deprecated( + "This instance is problematic and will most likely be removed in a future version of Cats. Use catsLawsEqForGroupBinCompat instead. See https://github.com/typelevel/cats/pull/2577 for more information.", + "1.7" + ) implicit def catsLawsEqForGroup[A](implicit arbAA: Arbitrary[(A, A)], eqMA: Eq[Monoid[A]], eqA: Eq[A]): Eq[Group[A]] = { @@ -181,13 +312,4 @@ object eq { Eq.instance((f, g) => eqMA.eqv(f, g) && inverseEq.eqv(f, g)) } - - implicit def catsLawsEqForCommutativeGroup[A](implicit eqMA: Eq[CommutativeMonoid[A]], - eqGA: Eq[Group[A]], - eqA: Eq[A]): Eq[CommutativeGroup[A]] = - Eq.instance((f, g) => eqMA.eqv(f, g) && eqGA.eqv(f, g)) - - implicit def catsLawsEqForRepresentableStore[F[_]: Representable, S, A](implicit eqFA: Eq[F[A]], - eqS: Eq[S]): Eq[RepresentableStore[F, S, A]] = - Eq.instance((s1, s2) => eqFA.eqv(s1.fa, s2.fa) && eqS.eqv(s1.index, s2.index)) } diff --git a/laws/src/main/scala/cats/laws/discipline/ExhaustiveCheck.scala b/laws/src/main/scala/cats/laws/discipline/ExhaustiveCheck.scala new file mode 100644 index 0000000000..f5446c6f1c --- /dev/null +++ b/laws/src/main/scala/cats/laws/discipline/ExhaustiveCheck.scala @@ -0,0 +1,62 @@ +package cats +package laws +package discipline + +/** + * An `ExhuastiveCheck[A]` instance can be used similarly to a Scalacheck + * `Gen[A]` instance, but differs in that it generates a `Stream` of the entire + * domain of values as opposed to generating a random sampling of values. + */ +trait ExhaustiveCheck[A] extends Serializable { self => + def allValues: Stream[A] +} + +object ExhaustiveCheck { + def apply[A](implicit A: ExhaustiveCheck[A]): ExhaustiveCheck[A] = A + + def instance[A](values: Stream[A]): ExhaustiveCheck[A] = new ExhaustiveCheck[A] { + val allValues: Stream[A] = values + } + + implicit val catsLawsExhaustiveCheckForBoolean: ExhaustiveCheck[Boolean] = + instance(Stream(false, true)) + + implicit val catsLawsExhaustiveCheckForSetBoolean: ExhaustiveCheck[Set[Boolean]] = + forSet[Boolean] + + /** + * Warning: the domain of (A, B) is the cross-product of the domain of `A` and the domain of `B`. + */ + implicit def catsLawsExhaustiveCheckForTuple2[A, B](implicit A: ExhaustiveCheck[A], + B: ExhaustiveCheck[B]): ExhaustiveCheck[(A, B)] = + instance(A.allValues.flatMap(a => B.allValues.map(b => (a, b)))) + + /** + * Warning: the domain of (A, B, C) is the cross-product of the 3 domains. + */ + implicit def catsLawsExhaustiveCheckForTuple3[A, B, C](implicit A: ExhaustiveCheck[A], + B: ExhaustiveCheck[B], + C: ExhaustiveCheck[C]): ExhaustiveCheck[(A, B, C)] = + instance( + for { + a <- A.allValues + b <- B.allValues + c <- C.allValues + } yield (a, b, c) + ) + + implicit def catsLawsExhaustiveCheckForEither[A, B](implicit A: ExhaustiveCheck[A], + B: ExhaustiveCheck[B]): ExhaustiveCheck[Either[A, B]] = + instance(A.allValues.map(Left(_)) ++ B.allValues.map(Right(_))) + + implicit def catsLawsExhaustiveCheckForOption[A](implicit A: ExhaustiveCheck[A]): ExhaustiveCheck[Option[A]] = + instance(Stream.cons(None, A.allValues.map(Some(_)))) + + /** + * Creates an `ExhaustiveCheck[Set[A]]` given an `ExhaustiveCheck[A]` by computing the powerset of + * values. Note that if there are `n` elements in the domain of `A` there will be `2^n` elements + * in the domain of `Set[A]`, so use this only on small domains. + */ + def forSet[A](implicit A: ExhaustiveCheck[A]): ExhaustiveCheck[Set[A]] = + instance(A.allValues.toSet.subsets.toStream) +} diff --git a/laws/src/main/scala/cats/laws/discipline/MiniInt.scala b/laws/src/main/scala/cats/laws/discipline/MiniInt.scala new file mode 100644 index 0000000000..bc193ab6c4 --- /dev/null +++ b/laws/src/main/scala/cats/laws/discipline/MiniInt.scala @@ -0,0 +1,79 @@ +package cats +package laws +package discipline + +import cats.kernel.{BoundedSemilattice, CommutativeGroup, CommutativeMonoid} +import cats.instances.int._ + +/** + * Similar to `Int`, but with a much smaller domain. The exact range of [[MiniInt]] may be tuned from time to time, so + * consumers of this type should avoid depending on its exact range. + * + * `MiniInt` has integer overflow characteristics similar to `Int` (but with a smaller radix), meaning that its addition + * and multiplication are commutative and associative. + */ +final class MiniInt private (val intBits: Int) extends AnyVal with Serializable { + import MiniInt._ + + def unary_- : MiniInt = this * negativeOne + + def toInt: Int = intBits << intShift >> intShift + + def +(o: MiniInt): MiniInt = wrapped(intBits + o.intBits) + def *(o: MiniInt): MiniInt = wrapped(intBits * o.intBits) + def |(o: MiniInt): MiniInt = wrapped(intBits | o.intBits) + def /(o: MiniInt): MiniInt = wrapped(intBits / o.intBits) + + override def toString: String = s"MiniInt(toInt=$toInt, intBits=$intBits)" +} + +object MiniInt { + val bitCount: Int = 4 + val minIntValue: Int = -8 + val maxIntValue: Int = 7 + private val intShift: Int = 28 + val minValue: MiniInt = unsafeFromInt(minIntValue) + val maxValue: MiniInt = unsafeFromInt(maxIntValue) + val zero: MiniInt = unsafeFromInt(0) + val one: MiniInt = unsafeFromInt(1) + val negativeOne: MiniInt = unsafeFromInt(-1) + + def isInDomain(i: Int): Boolean = i >= minIntValue && i <= maxIntValue + + def fromInt(i: Int): Option[MiniInt] = if (isInDomain(i)) Some(unsafeFromInt(i)) else None + + def wrapped(intBits: Int): MiniInt = new MiniInt(intBits & (-1 >>> intShift)) + + def unsafeFromInt(i: Int): MiniInt = + if (isInDomain(i)) { + new MiniInt(i << intShift >>> intShift) + } else throw new IllegalArgumentException(s"Expected value between $minIntValue and $maxIntValue but got $i") + + val allValues: Stream[MiniInt] = (minIntValue to maxIntValue).map(unsafeFromInt).toStream + + implicit val catsLawsEqInstancesForMiniInt: Order[MiniInt] with Hash[MiniInt] = new Order[MiniInt] + with Hash[MiniInt] { + def hash(x: MiniInt): Int = Hash[Int].hash(x.intBits) + + def compare(x: MiniInt, y: MiniInt): Int = Order[Int].compare(x.toInt, y.toInt) + } + + implicit val catsLawsExhuastiveCheckForMiniInt: ExhaustiveCheck[MiniInt] = + ExhaustiveCheck.instance(allValues) + + val miniIntAddition: CommutativeGroup[MiniInt] = new CommutativeGroup[MiniInt] { + val empty = MiniInt.zero + def combine(x: MiniInt, y: MiniInt): MiniInt = x + y + def inverse(x: MiniInt): MiniInt = -x + } + + val miniIntMultiplication: CommutativeMonoid[MiniInt] = new CommutativeMonoid[MiniInt] { + val empty = MiniInt.one + def combine(x: MiniInt, y: MiniInt): MiniInt = x * y + } + + val miniIntOr: BoundedSemilattice[MiniInt] = new BoundedSemilattice[MiniInt] { + val empty = MiniInt.zero + def combine(x: MiniInt, y: MiniInt): MiniInt = x | y + } +} diff --git a/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala b/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala index ee50130e75..c62233ed22 100644 --- a/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala +++ b/tests/src/test/scala/cats/tests/AlgebraInvariantSuite.scala @@ -4,66 +4,160 @@ package tests import cats.Invariant import cats.kernel._ import cats.kernel.laws.discipline.{SemigroupTests, MonoidTests, GroupTests, _} -import cats.laws.discipline.{InvariantMonoidalTests, InvariantSemigroupalTests, InvariantTests, SerializableTests} +import cats.laws.discipline.{ + InvariantMonoidalTests, + InvariantSemigroupalTests, + InvariantTests, + MiniInt, + SerializableTests +} +import MiniInt._ import cats.laws.discipline.eq._ +import cats.laws.discipline.arbitrary._ import org.scalacheck.{Arbitrary, Gen} class AlgebraInvariantSuite extends CatsSuite { + // working around https://github.com/typelevel/cats/issues/2701 + implicit private val eqSetBooleanTuple: Eq[(Set[Boolean], Set[Boolean])] = Eq.fromUniversalEquals + implicit private val eqSetBooleanBooleanTuple: Eq[(Set[Boolean], Boolean)] = Eq.fromUniversalEquals + + // https://github.com/typelevel/cats/issues/2725 + implicit private def commutativeMonoidForSemigroup[A]( + implicit csA: CommutativeSemigroup[A] + ): CommutativeMonoid[Option[A]] = + new CommutativeMonoid[Option[A]] { + def empty: Option[A] = None + def combine(x: Option[A], y: Option[A]): Option[A] = (x, y) match { + case (None, r) => r + case (l, None) => l + case (Some(l), Some(r)) => Some(csA.combine(l, r)) + } + } + + private def leftOptionMonoid[A]: Monoid[Option[A]] = + new Monoid[Option[A]] { + def empty: Option[A] = None + def combine(x: Option[A], y: Option[A]): Option[A] = x + } + + private def rightOptionMonoid[A]: Monoid[Option[A]] = + new Monoid[Option[A]] { + def empty: Option[A] = None + def combine(x: Option[A], y: Option[A]): Option[A] = y + } + + private val boundedSemilatticeMiniInt: BoundedSemilattice[MiniInt] = new BoundedSemilattice[MiniInt] { + def empty: MiniInt = MiniInt.zero + def combine(x: MiniInt, y: MiniInt): MiniInt = x | y + } + + private val genBoundedSemilatticeMiniInt: Gen[BoundedSemilattice[MiniInt]] = + Gen.const(miniIntOr) - val intMultiplication: CommutativeMonoid[Int] = new CommutativeMonoid[Int] { - val empty = 1 - def combine(x: Int, y: Int): Int = x * y + private val genCommutativeGroupInt: Gen[CommutativeGroup[Int]] = + Gen.const(implicitly[CommutativeGroup[Int]]) + + private val miniIntMultiplication: CommutativeMonoid[MiniInt] = new CommutativeMonoid[MiniInt] { + val empty = MiniInt.one + def combine(x: MiniInt, y: MiniInt): MiniInt = x * y } - val maxInt: Monoid[Int] = new Monoid[Int] { - val empty = Int.MinValue - def combine(x: Int, y: Int): Int = if (x > y) x else y + private val maxMiniInt: CommutativeMonoid[MiniInt] = new CommutativeMonoid[MiniInt] { + val empty = MiniInt.minValue + def combine(x: MiniInt, y: MiniInt): MiniInt = if (x > y) x else y } - val genMonoidInt: Gen[Monoid[Int]] = - Gen.oneOf(implicitly[Monoid[Int]], intMultiplication, maxInt) + private val genMonoidMiniInt: Gen[Monoid[MiniInt]] = + Gen.oneOf(miniIntAddition, miniIntMultiplication, maxMiniInt) - val genCommutativeMonoidInt: Gen[CommutativeMonoid[Int]] = - Gen.oneOf(implicitly[CommutativeMonoid[Int]], intMultiplication) + private val genMonoidOptionMiniInt: Gen[Monoid[Option[MiniInt]]] = + Gen.oneOf( + commutativeMonoidForSemigroup(miniIntAddition), + commutativeMonoidForSemigroup(miniIntMultiplication), + commutativeMonoidForSemigroup(maxMiniInt), + leftOptionMonoid[MiniInt], + rightOptionMonoid[MiniInt] + ) - val genBoundedSemilatticeSetInt: Gen[BoundedSemilattice[Set[Int]]] = - Gen.const(implicitly[BoundedSemilattice[Set[Int]]]) + private val genCommutativeMonoidMiniInt: Gen[CommutativeMonoid[MiniInt]] = + Gen.oneOf(miniIntAddition, miniIntMultiplication, maxMiniInt) - val genCommutativeGroupInt: Gen[CommutativeGroup[Int]] = - Gen.const(implicitly[CommutativeGroup[Int]]) + private val genCommutativeGroupMiniInt: Gen[CommutativeGroup[MiniInt]] = + Gen.const(miniIntAddition) + + implicit private val arbMonoidOptionMiniInt: Arbitrary[Monoid[Option[MiniInt]]] = + Arbitrary(genMonoidOptionMiniInt) + + implicit private val arbSemigroupOptionMiniInt: Arbitrary[Semigroup[Option[MiniInt]]] = + Arbitrary(genMonoidOptionMiniInt) + + implicit private val arbSemigroupMiniInt: Arbitrary[Semigroup[MiniInt]] = + Arbitrary(genMonoidMiniInt) + + implicit private val arbCommutativeMonoidMiniInt: Arbitrary[CommutativeMonoid[MiniInt]] = + Arbitrary(genCommutativeMonoidMiniInt) + + implicit private val arbCommutativeSemigroupMiniInt: Arbitrary[CommutativeSemigroup[MiniInt]] = + Arbitrary(genCommutativeMonoidMiniInt) - implicit val arbMonoidInt: Arbitrary[Monoid[Int]] = - Arbitrary(genMonoidInt) + implicit private val arbGroupMiniInt: Arbitrary[Group[MiniInt]] = + Arbitrary(genCommutativeGroupMiniInt) - implicit val arbSemigroupInt: Arbitrary[Semigroup[Int]] = - Arbitrary(genMonoidInt) + implicit private val arbCommutativeGroupMiniInt: Arbitrary[CommutativeGroup[MiniInt]] = + Arbitrary(genCommutativeGroupMiniInt) - implicit val arbCommutativeMonoidInt: Arbitrary[CommutativeMonoid[Int]] = - Arbitrary(genCommutativeMonoidInt) + private val boolAnd: CommutativeMonoid[Boolean] = new CommutativeMonoid[Boolean] { + val empty = true + def combine(x: Boolean, y: Boolean): Boolean = x && y + } + + private val boolOr: CommutativeMonoid[Boolean] = new CommutativeMonoid[Boolean] { + val empty = false + def combine(x: Boolean, y: Boolean): Boolean = x || y + } + + private val genMonoidOptionBoolean: Gen[Monoid[Option[Boolean]]] = + Gen.oneOf(commutativeMonoidForSemigroup(boolAnd), + commutativeMonoidForSemigroup(boolOr), + leftOptionMonoid[Boolean], + rightOptionMonoid[Boolean]) + + implicit private val arbMonoidOptionBoolean: Arbitrary[Monoid[Option[Boolean]]] = + Arbitrary(genMonoidOptionBoolean) + + implicit private val arbSemibroupOptionBoolean: Arbitrary[Semigroup[Option[Boolean]]] = + Arbitrary(genMonoidOptionBoolean) - implicit val arbCommutativeSemigroupInt: Arbitrary[CommutativeSemigroup[Int]] = - Arbitrary(genCommutativeMonoidInt) + private val genCommutativeMonoidBoolean: Gen[CommutativeMonoid[Boolean]] = + Gen.oneOf(boolAnd, boolOr) - implicit val arbBandSetInt: Arbitrary[Band[Set[Int]]] = - Arbitrary(genBoundedSemilatticeSetInt) + implicit private val arbCommutativeMonoidBoolean: Arbitrary[CommutativeMonoid[Boolean]] = + Arbitrary(genCommutativeMonoidBoolean) - implicit val arbSemilatticeSetInt: Arbitrary[Semilattice[Set[Int]]] = - Arbitrary(genBoundedSemilatticeSetInt) + implicit private val arbCommutativeSemigroupBoolean: Arbitrary[CommutativeSemigroup[Boolean]] = + Arbitrary(genCommutativeMonoidBoolean) - implicit val arbBoundedSemilatticeSetInt: Arbitrary[BoundedSemilattice[Set[Int]]] = - Arbitrary(genBoundedSemilatticeSetInt) + implicit private val arbBandSetMiniInt: Arbitrary[Band[MiniInt]] = + Arbitrary(genBoundedSemilatticeMiniInt) - implicit val arbGroupInt: Arbitrary[Group[Int]] = + implicit private val arbSemilatticeSetMiniInt: Arbitrary[Semilattice[MiniInt]] = + Arbitrary(genBoundedSemilatticeMiniInt) + + implicit private val arbBoundedSemilatticeSetMiniInt: Arbitrary[BoundedSemilattice[MiniInt]] = + Arbitrary(genBoundedSemilatticeMiniInt) + + implicit private val arbGroupInt: Arbitrary[Group[Int]] = Arbitrary(genCommutativeGroupInt) - implicit val arbCommutativeGroupInt: Arbitrary[CommutativeGroup[Int]] = + implicit private val arbCommutativeGroupInt: Arbitrary[CommutativeGroup[Int]] = Arbitrary(genCommutativeGroupInt) checkAll("InvariantMonoidal[Semigroup]", SemigroupTests[Int](InvariantMonoidal[Semigroup].point(0)).semigroup) checkAll("InvariantMonoidal[CommutativeSemigroup]", CommutativeSemigroupTests[Int](InvariantMonoidal[CommutativeSemigroup].point(0)).commutativeSemigroup) - checkAll("InvariantSemigroupal[Monoid]", InvariantSemigroupalTests[Monoid].invariantSemigroupal[Int, Int, Int]) + checkAll("InvariantSemigroupal[Monoid]", + InvariantSemigroupalTests[Monoid].invariantSemigroupal[Option[MiniInt], Option[Boolean], Option[Boolean]]) { val S: Semigroup[Int] = Semigroup[Int].imap(identity)(identity) @@ -100,6 +194,10 @@ class AlgebraInvariantSuite extends CatsSuite { checkAll("CommutativeMonoid[Int]", CommutativeMonoidTests[Int](S).commutativeMonoid) } + { + checkAll("CommutativeMonoid[MiniInt]", CommutativeMonoidTests[MiniInt](miniIntAddition).commutativeMonoid) + } + { val S: CommutativeGroup[Int] = CommutativeGroup[Int].imap(identity)(identity) checkAll("CommutativeGroup[Int]", CommutativeGroupTests[Int](S).commutativeGroup) @@ -120,38 +218,45 @@ class AlgebraInvariantSuite extends CatsSuite { checkAll("BoundedSemilattice[Set[Int]]", BoundedSemilatticeTests[Set[Int]](S).boundedSemilattice) } - checkAll("Invariant[Semigroup]", InvariantTests[Semigroup].invariant[Int, Int, Int]) + checkAll("Invariant[Semigroup]", InvariantTests[Semigroup].invariant[MiniInt, Boolean, Boolean]) checkAll("Invariant[Semigroup]", SerializableTests.serializable(Invariant[Semigroup])) - checkAll("Invariant[CommutativeSemigroup]", InvariantTests[CommutativeSemigroup].invariant[Int, Int, Int]) + checkAll("Invariant[CommutativeSemigroup]", InvariantTests[CommutativeSemigroup].invariant[MiniInt, Boolean, Boolean]) checkAll("Invariant[CommutativeSemigroup]", SerializableTests.serializable(Invariant[CommutativeSemigroup])) - checkAll("Invariant[Band]", InvariantTests[Band].invariant[Set[Int], Set[Int], Set[Int]]) + checkAll("Invariant[Band]", InvariantTests[Band].invariant[MiniInt, Set[Boolean], Set[Boolean]]) checkAll("Invariant[Band]", SerializableTests.serializable(Invariant[Band])) - checkAll("Invariant[Monoid]", InvariantTests[Monoid].invariant[Int, Int, Int]) + checkAll("Invariant[Monoid]", InvariantTests[Monoid].invariant[Option[MiniInt], Boolean, Boolean]) checkAll("Invariant[Monoid]", SerializableTests.serializable(Invariant[Monoid])) - checkAll("Invariant[Semilattice]", InvariantTests[Semilattice].invariant[Set[Int], Set[Int], Set[Int]]) + Eq[Band[Set[Boolean]]] + cats.laws.discipline.ExhaustiveCheck[Set[Boolean]] + Eq[(Set[Boolean], Boolean)] + Eq[(Set[Boolean], Set[Boolean] => (Set[Boolean], Boolean))] + Eq[CommutativeSemigroup[Set[Boolean]]] + checkAll("Invariant[Semilattice]", InvariantTests[Semilattice].invariant[MiniInt, Set[Boolean], Set[Boolean]]) checkAll("Invariant[Semilattice]", SerializableTests.serializable(Invariant[Semilattice])) - checkAll("Invariant[CommutativeMonoid]", InvariantTests[CommutativeMonoid].invariant[Int, Int, Int]) + checkAll("Invariant[CommutativeMonoid]", InvariantTests[CommutativeMonoid].invariant[MiniInt, Boolean, Boolean]) checkAll("Invariant[CommutativeMonoid]", SerializableTests.serializable(Invariant[CommutativeMonoid])) - checkAll("Invariant[BoundedSemilattice]", InvariantTests[BoundedSemilattice].invariant[Set[Int], Set[Int], Set[Int]]) + checkAll("Invariant[BoundedSemilattice]", + InvariantTests[BoundedSemilattice].invariant[MiniInt, Set[Boolean], Set[Boolean]]) checkAll("Invariant[BoundedSemilattice]", SerializableTests.serializable(Invariant[BoundedSemilattice])) - checkAll("Invariant[Group]", InvariantTests[Group].invariant[Int, Int, Int]) + checkAll("Invariant[Group]", InvariantTests[Group].invariant[MiniInt, Boolean, Boolean]) checkAll("Invariant[Group]", SerializableTests.serializable(Invariant[Group])) - checkAll("Invariant[CommutativeGroup]", InvariantTests[CommutativeGroup].invariant[Int, Int, Int]) + checkAll("Invariant[CommutativeGroup]", InvariantTests[CommutativeGroup].invariant[MiniInt, Boolean, Boolean]) checkAll("Invariant[CommutativeGroup]", SerializableTests.serializable(Invariant[CommutativeGroup])) - checkAll("InvariantMonoidal[Semigroup]", InvariantMonoidalTests[Semigroup].invariantMonoidal[Int, Int, Int]) + checkAll("InvariantMonoidal[Semigroup]", + InvariantMonoidalTests[Semigroup].invariantMonoidal[Option[MiniInt], Option[Boolean], Option[Boolean]]) checkAll("InvariantMonoidal[Semigroup]", SerializableTests.serializable(InvariantMonoidal[Semigroup])) checkAll("InvariantMonoidal[CommutativeSemigroup]", - InvariantMonoidalTests[CommutativeSemigroup].invariantMonoidal[Int, Int, Int]) + InvariantMonoidalTests[CommutativeSemigroup].invariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("InvariantMonoidal[CommutativeSemigroup]", SerializableTests.serializable(InvariantMonoidal[CommutativeSemigroup])) diff --git a/tests/src/test/scala/cats/tests/AndThenSuite.scala b/tests/src/test/scala/cats/tests/AndThenSuite.scala index 60f9509eca..1c8c950956 100644 --- a/tests/src/test/scala/cats/tests/AndThenSuite.scala +++ b/tests/src/test/scala/cats/tests/AndThenSuite.scala @@ -10,32 +10,31 @@ import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ class AndThenSuite extends CatsSuite { - { - implicit val iso = SemigroupalTests.Isomorphisms.invariant[AndThen[Int, ?]] - checkAll("AndThen[Int, Int]", SemigroupalTests[AndThen[Int, ?]].semigroupal[Int, Int, Int]) - checkAll("Semigroupal[AndThen[Int, ?]]", SerializableTests.serializable(Semigroupal[AndThen[Int, ?]])) - } + checkAll("AndThen[MiniInt, Int]", SemigroupalTests[AndThen[MiniInt, ?]].semigroupal[Int, Int, Int]) + checkAll("Semigroupal[AndThen[Int, ?]]", SerializableTests.serializable(Semigroupal[AndThen[Int, ?]])) { implicit val iso = SemigroupalTests.Isomorphisms.invariant[AndThen[?, Int]] - checkAll("AndThen[Int, Int]", ContravariantMonoidalTests[AndThen[?, Int]].contravariantMonoidal[Int, Int, Int]) + checkAll("AndThen[?, Int]", + ContravariantMonoidalTests[AndThen[?, Int]].contravariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("ContravariantMonoidal[AndThen[?, Int]]", SerializableTests.serializable(ContravariantMonoidal[AndThen[?, Int]])) } - checkAll("AndThen[Int, Int]", MonadTests[AndThen[Int, ?]].monad[Int, Int, Int]) + checkAll("AndThen[MiniInt, Int]", MonadTests[AndThen[MiniInt, ?]].monad[Int, Int, Int]) checkAll("Monad[AndThen[Int, ?]]", SerializableTests.serializable(Monad[AndThen[Int, ?]])) - checkAll("AndThen[Int, Int]", CommutativeArrowTests[AndThen].commutativeArrow[Int, Int, Int, Int, Int, Int]) + checkAll("AndThen", + CommutativeArrowTests[AndThen].commutativeArrow[MiniInt, Boolean, Boolean, Boolean, Boolean, Boolean]) checkAll("Arrow[AndThen]", SerializableTests.serializable(CommutativeArrow[AndThen])) - checkAll("AndThen[Int, Int]", ChoiceTests[AndThen].choice[Int, Int, Int, Int]) + checkAll("AndThen", ChoiceTests[AndThen].choice[MiniInt, Boolean, Int, Int]) checkAll("Choice[AndThen]", SerializableTests.serializable(Choice[AndThen])) - checkAll("AndThen[Int, Int]", ArrowChoiceTests[AndThen].arrowChoice[Int, Int, Int, Int, Int, Int]) + checkAll("AndThen", ArrowChoiceTests[AndThen].arrowChoice[MiniInt, Boolean, Boolean, Boolean, Boolean, Boolean]) checkAll("ArrowChoice[AndThen]", SerializableTests.serializable(ArrowChoice[AndThen])) - checkAll("AndThen[Int, Int]", ContravariantTests[AndThen[?, Int]].contravariant[Int, Int, Int]) + checkAll("AndThen[?, Int]", ContravariantTests[AndThen[?, Int]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[AndThen[?, Int]]", SerializableTests.serializable(Contravariant[AndThen[?, Int]])) test("compose a chain of functions with andThen") { diff --git a/tests/src/test/scala/cats/tests/BinCodecInvariantMonoidalSuite.scala b/tests/src/test/scala/cats/tests/BinCodecInvariantMonoidalSuite.scala new file mode 100644 index 0000000000..2e6390c48e --- /dev/null +++ b/tests/src/test/scala/cats/tests/BinCodecInvariantMonoidalSuite.scala @@ -0,0 +1,173 @@ +package cats +package tests + +import cats.laws.discipline.eq._ +import cats.laws.discipline.arbitrary._ +import cats.laws.discipline.{ExhaustiveCheck, InvariantMonoidalTests, MiniInt, SerializableTests} +import cats.implicits._ +import cats.Eq +import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests} +import org.scalacheck.{Arbitrary, Gen} + +object BinCodecInvariantMonoidalSuite { + final case class MiniList[+A] private (val toList: List[A]) extends AnyVal { + import MiniList.truncated + + /** + * Returns a new MiniList with a modified underlying List. Note that this truncates the returned List to ensure that + * it fits into the allowable MiniInt range. + */ + def mod[B](f: List[A] => List[B]): MiniList[B] = truncated(f(toList)) + + /** + * Append a `MiniList`. + * + * Note: this will trim the resulting list to respect the maximum list length. + */ + def ++[AA >: A](o: MiniList[AA]): MiniList[AA] = mod(_ ++ o.toList) + } + + object MiniList { + val maxLength: Int = 6 + + val nil: MiniList[Nothing] = MiniList(Nil) + def empty[A]: MiniList[A] = nil + + def truncated[A](l: List[A]): MiniList[A] = MiniList(l.take(maxLength)) + + def unsafe[A](l: List[A]): MiniList[A] = { + val inputLength = l.size + if (inputLength > maxLength) + throw new IllegalArgumentException( + s"MiniList.unsafe called with list of size $inputLength, but $maxLength is the maximum allowed size." + ) + else MiniList(l) + } + + def one[A](a: A): MiniList[A] = MiniList(a :: Nil) + + implicit def eqForMiniList[A: Eq]: Eq[MiniList[A]] = Eq.by(_.toList) + + implicit val exhaustiveCheckForMiniListBoolean: ExhaustiveCheck[MiniList[Boolean]] = + ExhaustiveCheck.instance( + for { + length <- (0 to maxLength).toStream + boolList <- List(false, true).replicateA(length).toStream + } yield MiniList.unsafe(boolList) + ) + } + + /** A small amount of binary bits */ + type Bin = MiniList[Boolean] + + /** + * Type class to read and write objects of type A to binary. + * + * Obeys `forAll { (c: BinCodec[A], a: A) => c.read(c.writes(a)) == (Some(a), List())`, + * under the assumtion that `imap(f, g)` is always called with `f` and `g` such that + * `forAll { (a: A) => g(f(a)) == a }`. + */ + trait BinCodec[A] extends Serializable { self => + + /** Reads the first value of a Bin, returning an optional value of type `A` and the remaining Bin. */ + def read(s: Bin): (Option[A], Bin) + + /** Writes a value of type `A` to Bin format. */ + def write(a: A): Bin + } + + object BinCodec { + // In tut/invariantmonoidal.md pure, product and imap are defined in + // their own trait to be introduced one by one, + trait CCPure { + def unit: BinCodec[Unit] = new BinCodec[Unit] { + def read(s: Bin): (Option[Unit], Bin) = (Some(()), s) + def write(a: Unit): Bin = MiniList.empty + } + } + + trait CCProduct { + def product[A, B](fa: BinCodec[A], fb: BinCodec[B]): BinCodec[(A, B)] = + new BinCodec[(A, B)] { + def read(s: Bin): (Option[(A, B)], Bin) = { + val (a1, s1) = fa.read(s) + val (a2, s2) = fb.read(s1) + ((a1, a2).mapN(_ -> _), s2) + } + + def write(a: (A, B)): Bin = + fa.write(a._1) ++ fb.write(a._2) + } + } + + trait CCImap { + def imap[A, B](fa: BinCodec[A])(f: A => B)(g: B => A): BinCodec[B] = + new BinCodec[B] { + def read(s: Bin): (Option[B], Bin) = { + val (a1, s1) = fa.read(s) + (a1.map(f), s1) + } + + def write(a: B): Bin = + fa.write(g(a)) + } + } + + implicit val binCodecIsInvariantMonoidal: InvariantMonoidal[BinCodec] = + new InvariantMonoidal[BinCodec] with CCPure with CCProduct with CCImap + } + + def genBinCodecForExhaustive[A](implicit exA: ExhaustiveCheck[A]): Gen[BinCodec[A]] = + for { + bitCount <- Gen.oneOf(1, 2, 3) + shuffleSeed <- Gen.choose(Long.MinValue, Long.MaxValue) + } yield { + val binValues: Stream[Bin] = Stream(false, true).replicateA(bitCount).map(MiniList.unsafe(_)) + val pairs: List[(A, Bin)] = new scala.util.Random(seed = shuffleSeed).shuffle(exA.allValues).toList.zip(binValues) + val aToBin: Map[A, Bin] = pairs.toMap + val binToA: Map[Bin, A] = pairs.map(_.swap).toMap + + new BinCodec[A] { + def read(s: Bin): (Option[A], Bin) = + (binToA.get(s.mod(_.take(bitCount))), s.mod(_.drop(bitCount))) + + def write(a: A): Bin = + aToBin.getOrElse(a, MiniList.empty) + + override def toString: String = s"BinCodec($pairs)" + } + } + + implicit val arbMiniIntCodec: Arbitrary[BinCodec[MiniInt]] = + Arbitrary(genBinCodecForExhaustive[MiniInt]) + + implicit val arbBooleanCodec: Arbitrary[BinCodec[Boolean]] = + Arbitrary(genBinCodecForExhaustive[Boolean]) + + implicit def binCodecsEq[A: Eq: ExhaustiveCheck]: Eq[BinCodec[A]] = { + val writeEq: Eq[BinCodec[A]] = Eq.by[BinCodec[A], A => Bin](_.write) + + val readEq: Eq[BinCodec[A]] = Eq.by[BinCodec[A], Bin => (Option[A], Bin)](_.read) + Eq.and(writeEq, readEq) + } +} + +class BinCodecInvariantMonoidalSuite extends CatsSuite { + // Eveything is defined in a companion object to be serializable. + import BinCodecInvariantMonoidalSuite._ + + checkAll("InvariantMonoidal[BinCodec]", InvariantMonoidalTests[BinCodec].invariantMonoidal[MiniInt, MiniInt, MiniInt]) + checkAll("InvariantMonoidal[BinCodec]", SerializableTests.serializable(InvariantMonoidal[BinCodec])) + + { + implicit val miniIntMonoid: Monoid[MiniInt] = MiniInt.miniIntAddition + implicit val binMonoid = InvariantMonoidal.monoid[BinCodec, MiniInt] + checkAll("InvariantMonoidal[BinCodec].monoid", MonoidTests[BinCodec[MiniInt]].monoid) + } + + { + implicit val miniIntSemigroup: Semigroup[MiniInt] = MiniInt.miniIntAddition + implicit val binSemigroup = InvariantSemigroupal.semigroup[BinCodec, MiniInt] + checkAll("InvariantSemigroupal[BinCodec].semigroup", SemigroupTests[BinCodec[MiniInt]].semigroup) + } +} diff --git a/tests/src/test/scala/cats/tests/BinestedSuite.scala b/tests/src/test/scala/cats/tests/BinestedSuite.scala index 88e5caa860..8580b07412 100644 --- a/tests/src/test/scala/cats/tests/BinestedSuite.scala +++ b/tests/src/test/scala/cats/tests/BinestedSuite.scala @@ -28,13 +28,17 @@ class BinestedSuite extends CatsSuite { { // Profunctor + Functor + Functor = Profunctor - implicit val instance = ListWrapper.functor + implicit val instance = OptionWrapper.functor + Eq[OptionWrapper[MiniInt] => Option[Int]] + checkAll( + "Binested[Function1, OptionWrapper, Option, ?, ?]", + ProfunctorTests[Binested[Function1, OptionWrapper, Option, ?, ?]] + .profunctor[MiniInt, Int, Int, String, String, String] + ) checkAll( - "Binested[Function1, ListWrapper, Option, ?, ?]", - ProfunctorTests[Binested[Function1, ListWrapper, Option, ?, ?]].profunctor[Int, Int, Int, String, String, String] + "Profunctor[Binested[Function1, OptionWrapper, Option, ?, ?]]", + SerializableTests.serializable(Profunctor[Binested[Function1, OptionWrapper, Option, ?, ?]]) ) - checkAll("Profunctor[Binested[Function1, ListWrapper, Option, ?, ?]]", - SerializableTests.serializable(Profunctor[Binested[Function1, ListWrapper, Option, ?, ?]])) } { diff --git a/tests/src/test/scala/cats/tests/CategorySuite.scala b/tests/src/test/scala/cats/tests/CategorySuite.scala index 5eb98a484b..0f6c62ffb9 100644 --- a/tests/src/test/scala/cats/tests/CategorySuite.scala +++ b/tests/src/test/scala/cats/tests/CategorySuite.scala @@ -4,15 +4,16 @@ package tests import cats.kernel.laws.discipline.MonoidTests import cats.arrow.Category -import cats.laws.discipline.{MonoidKTests, SerializableTests} -import cats.laws.discipline.eq.catsLawsEqForFn1 +import cats.laws.discipline.{MiniInt, MonoidKTests, SerializableTests} +import cats.laws.discipline.eq.catsLawsEqForFn1Exhaustive +import cats.laws.discipline.arbitrary.{catsLawsArbitraryForMiniInt, catsLawsCogenForMiniInt} class CategorySuite extends CatsSuite { val functionCategory = Category[Function1] - checkAll("Category[Function1].algebraK", MonoidKTests[Endo](functionCategory.algebraK).monoidK[Int]) + checkAll("Category[Function1].algebraK", MonoidKTests[Endo](functionCategory.algebraK).monoidK[MiniInt]) checkAll("Category[Function1].algebraK", SerializableTests.serializable(functionCategory.algebraK)) - val functionAlgebra = functionCategory.algebra[Int] - checkAll("Category[Function1].algebra[Int]", MonoidTests[Endo[Int]](functionAlgebra).monoid) + val functionAlgebra = functionCategory.algebra[MiniInt] + checkAll("Category[Function1].algebra[MiniInt]", MonoidTests[Endo[MiniInt]](functionAlgebra).monoid) } diff --git a/tests/src/test/scala/cats/tests/CokleisliSuite.scala b/tests/src/test/scala/cats/tests/CokleisliSuite.scala index 57e3520c0b..1d8b58baa5 100644 --- a/tests/src/test/scala/cats/tests/CokleisliSuite.scala +++ b/tests/src/test/scala/cats/tests/CokleisliSuite.scala @@ -7,7 +7,6 @@ import cats.data.{Cokleisli, NonEmptyList} import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ -import org.scalacheck.Arbitrary class CokleisliSuite extends SlowCatsSuite { @@ -15,54 +14,56 @@ class CokleisliSuite extends SlowCatsSuite { slowCheckConfiguration.copy(sizeRange = slowCheckConfiguration.sizeRange.min(5), minSuccessful = slowCheckConfiguration.minSuccessful.min(20)) - implicit def cokleisliEq[F[_], A, B](implicit A: Arbitrary[F[A]], FB: Eq[B]): Eq[Cokleisli[F, A, B]] = + implicit def cokleisliEq[F[_], A, B](implicit ev: Eq[F[A] => B]): Eq[Cokleisli[F, A, B]] = Eq.by[Cokleisli[F, A, B], F[A] => B](_.run) - def cokleisliEqE[F[_], A](implicit A: Arbitrary[F[A]], FA: Eq[A]): Eq[Cokleisli[F, A, A]] = - Eq.by[Cokleisli[F, A, A], F[A] => A](_.run) - implicit val iso = SemigroupalTests.Isomorphisms.invariant[Cokleisli[Option, Int, ?]] - checkAll("Cokleisli[Option, Int, Int]", SemigroupalTests[Cokleisli[Option, Int, ?]].semigroupal[Int, Int, Int]) + checkAll("Cokleisli[Option, MiniInt, Int]", + SemigroupalTests[Cokleisli[Option, MiniInt, ?]].semigroupal[Int, Int, Int]) checkAll("Semigroupal[Cokleisli[Option, Int, ?]]", SerializableTests.serializable(Semigroupal[Cokleisli[Option, Int, ?]])) - checkAll("Cokleisli[Option, Int, Int]", MonadTests[Cokleisli[Option, Int, ?]].monad[Int, Int, Int]) + checkAll("Cokleisli[Option, MiniInt, Int]", MonadTests[Cokleisli[Option, MiniInt, ?]].monad[Int, Int, Int]) checkAll("Monad[Cokleisli[Option, Int, ?]]", SerializableTests.serializable(Monad[Cokleisli[Option, Int, ?]])) - checkAll("Cokleisli[Option, Int, Int]", - ProfunctorTests[Cokleisli[Option, ?, ?]].profunctor[Int, Int, Int, Int, Int, Int]) + checkAll("Cokleisli[Option, MiniInt, Int]", + ProfunctorTests[Cokleisli[Option, ?, ?]].profunctor[MiniInt, Int, Int, Int, Int, Int]) checkAll("Profunctor[Cokleisli[Option, ?, ?]]", SerializableTests.serializable(Profunctor[Cokleisli[Option, ?, ?]])) - checkAll("Cokleisli[Option, Int, Int]", ContravariantTests[Cokleisli[Option, ?, Int]].contravariant[Int, Int, Int]) - checkAll("Contravariant[Cokleisli[Option, ?, Int]]", + checkAll("Cokleisli[Option, MiniInt, MiniInt]", + ContravariantTests[Cokleisli[Option, ?, MiniInt]].contravariant[MiniInt, MiniInt, MiniInt]) + checkAll("Contravariant[Cokleisli[Option, ?, MiniInt]]", SerializableTests.serializable(Contravariant[Cokleisli[Option, ?, Int]])) - checkAll("Cokleisli[NonEmptyList, Int, Int]", MonoidKTests[λ[α => Cokleisli[NonEmptyList, α, α]]].monoidK[Int]) + checkAll("Cokleisli[(Boolean, ?), MiniInt, MiniInt]", + MonoidKTests[λ[α => Cokleisli[(Boolean, ?), α, α]]].monoidK[MiniInt]) checkAll("MonoidK[λ[α => Cokleisli[NonEmptyList, α, α]]]", SerializableTests.serializable(MonoidK[λ[α => Cokleisli[NonEmptyList, α, α]]])) - checkAll("Cokleisli[List, Int, Int]", SemigroupKTests[λ[α => Cokleisli[List, α, α]]].semigroupK[Int]) + checkAll("Cokleisli[Option, MiniInt, MiniInt]", SemigroupKTests[λ[α => Cokleisli[Option, α, α]]].semigroupK[MiniInt]) checkAll("SemigroupK[λ[α => Cokleisli[List, α, α]]]", SerializableTests.serializable(SemigroupK[λ[α => Cokleisli[List, α, α]]])) - checkAll("Cokleisli[NonEmptyList, Int, Int]", - ArrowTests[Cokleisli[NonEmptyList, ?, ?]].arrow[Int, Int, Int, Int, Int, Int]) + checkAll("Cokleisli[(Boolean, ?), MiniInt, MiniInt]", + ArrowTests[Cokleisli[(Boolean, ?), ?, ?]].arrow[MiniInt, MiniInt, MiniInt, MiniInt, MiniInt, MiniInt]) checkAll("Arrow[Cokleisli[NonEmptyList, ?, ?]]", SerializableTests.serializable(Arrow[Cokleisli[NonEmptyList, ?, ?]])) { - implicit def cokleisliIdEq[A, B](implicit A: Arbitrary[A], FB: Eq[B]): Eq[Cokleisli[Id, A, B]] = + implicit def cokleisliIdEq[A, B](implicit evidence: Eq[A => B]): Eq[Cokleisli[Id, A, B]] = Eq.by[Cokleisli[Id, A, B], A => B](_.run) - checkAll("Cokleisli[Id, Int, Int]", - CommutativeArrowTests[Cokleisli[Id, ?, ?]].commutativeArrow[Int, Int, Int, Int, Int, Int]) + checkAll( + "Cokleisli[Id, MiniInt, MiniInt]", + CommutativeArrowTests[Cokleisli[Id, ?, ?]].commutativeArrow[MiniInt, MiniInt, MiniInt, MiniInt, MiniInt, MiniInt] + ) checkAll("CommutativeArrow[Cokleisli[Id, ?, ?]]", SerializableTests.serializable(CommutativeArrow[Cokleisli[Id, ?, ?]])) } test("contramapValue with Id consistent with lmap") { - forAll { (c: Cokleisli[Id, Int, Long], f: Char => Int) => - c.contramapValue[Char](f) should ===(c.lmap(f)) + forAll { (c: Cokleisli[Id, Int, Long], f: MiniInt => Int) => + c.contramapValue[MiniInt](f) should ===(c.lmap(f)) } } } diff --git a/tests/src/test/scala/cats/tests/ComposeSuite.scala b/tests/src/test/scala/cats/tests/ComposeSuite.scala index 1c6ca48343..07bad67dc5 100644 --- a/tests/src/test/scala/cats/tests/ComposeSuite.scala +++ b/tests/src/test/scala/cats/tests/ComposeSuite.scala @@ -3,17 +3,18 @@ package tests import cats.kernel.laws.discipline.SemigroupTests import cats.arrow.Compose -import cats.laws.discipline.{SemigroupKTests, SerializableTests} -import cats.laws.discipline.eq.catsLawsEqForFn1 +import cats.laws.discipline.{MiniInt, SemigroupKTests, SerializableTests} +import cats.laws.discipline.eq.catsLawsEqForFn1Exhaustive +import cats.laws.discipline.arbitrary._ class ComposeSuite extends CatsSuite { val functionCompose = Compose[Function1] - checkAll("Compose[Function1].algebraK", SemigroupKTests[Endo](functionCompose.algebraK).semigroupK[Int]) + checkAll("Compose[Function1].algebraK", SemigroupKTests[Endo](functionCompose.algebraK).semigroupK[MiniInt]) checkAll("Compose[Function1].algebraK", SerializableTests.serializable(functionCompose.algebraK)) - val functionAlgebra = functionCompose.algebra[Int] - checkAll("Compose[Function1].algebra[Int]", SemigroupTests[Endo[Int]](functionAlgebra).semigroup) + val functionAlgebra = functionCompose.algebra[MiniInt] + checkAll("Compose[Function1].algebra[MiniInt]", SemigroupTests[Endo[MiniInt]](functionAlgebra).semigroup) test("syntax") { (((_: Int) + 1) <<< ((_: Int) / 2))(2) should be(2) diff --git a/tests/src/test/scala/cats/tests/ContravariantSuite.scala b/tests/src/test/scala/cats/tests/ContravariantSuite.scala index 189005977f..e515a4ac41 100644 --- a/tests/src/test/scala/cats/tests/ContravariantSuite.scala +++ b/tests/src/test/scala/cats/tests/ContravariantSuite.scala @@ -3,10 +3,11 @@ package tests import cats.data.Const import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests} -import cats.laws.discipline.ContravariantMonoidalTests +import cats.laws.discipline.{ContravariantMonoidalTests, ExhaustiveCheck, MiniInt} import org.scalactic.CanEqual import org.scalacheck.{Arbitrary, Cogen} import cats.laws.discipline.eq._ +import cats.laws.discipline.arbitrary._ class ContravariantSuite extends CatsSuite { @@ -33,22 +34,22 @@ class ContravariantSuite extends CatsSuite { Predicate(x => fa.run(f(x))) } - implicit def eqPredicate[A: Arbitrary]: Eq[Predicate[A]] = + implicit def eqPredicate[A: ExhaustiveCheck]: Eq[Predicate[A]] = Eq.by[Predicate[A], A => Boolean](_.run) implicit def arbPredicate[A: Cogen]: Arbitrary[Predicate[A]] = Arbitrary(implicitly[Arbitrary[A => Boolean]].arbitrary.map(f => Predicate(f))) checkAll("ContravariantMonoidal[Predicate]", - ContravariantMonoidalTests[Predicate].contravariantMonoidal[Int, Int, Int]) + ContravariantMonoidalTests[Predicate].contravariantMonoidal[Boolean, Boolean, Boolean]) { - implicit val predicateMonoid = ContravariantMonoidal.monoid[Predicate, Int] - checkAll("ContravariantMonoidal[Predicate].monoid", MonoidTests[Predicate[Int]].monoid) + implicit val predicateMonoid = ContravariantMonoidal.monoid[Predicate, MiniInt] + checkAll("ContravariantMonoidal[Predicate].monoid", MonoidTests[Predicate[MiniInt]].monoid) } { - implicit val predicateSemigroup = ContravariantSemigroupal.semigroup[Predicate, Int] - checkAll("ContravariantSemigroupal[Predicate].semigroup", SemigroupTests[Predicate[Int]].semigroup) + implicit val predicateSemigroup = ContravariantSemigroupal.semigroup[Predicate, MiniInt] + checkAll("ContravariantSemigroupal[Predicate].semigroup", SemigroupTests[Predicate[MiniInt]].semigroup) } } diff --git a/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalSuite.scala b/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalSuite.scala deleted file mode 100644 index b828cacb0a..0000000000 --- a/tests/src/test/scala/cats/tests/CsvCodecInvariantMonoidalSuite.scala +++ /dev/null @@ -1,108 +0,0 @@ -package cats -package tests - -import cats.laws.discipline.eq.catsLawsEqForFn1 -import cats.laws.discipline.{InvariantMonoidalTests, SerializableTests} -import cats.instances.all._ -import cats.syntax.apply._ -import cats.Eq -import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests} -import org.scalacheck.{Arbitrary, Gen} - -object CsvCodecInvariantMonoidalSuite { - type CSV = List[String] - - /** - * Type class to read and write objects of type A to CSV. - * - * Obeys `forAll { (c: CsvCodec[A], a: A) => c.read(c.writes(a)) == (Some(a), List())`, - * under the assumtion that `imap(f, g)` is always called with `f` and `g` such that - * `forAll { (a: A) => g(f(a)) == a }`. - */ - trait CsvCodec[A] extends Serializable { self => - - /** Reads the first value of a CSV, returning an optional value of type `A` and the remaining CSV. */ - def read(s: CSV): (Option[A], CSV) - - /** Writes a value of type `A` to CSV format. */ - def write(a: A): CSV - } - - object CsvCodec { - // In tut/invariantmonoidal.md pure, product and imap are defined in - // their own trait to be introduced one by one, - trait CCPure { - def unit: CsvCodec[Unit] = new CsvCodec[Unit] { - def read(s: CSV): (Option[Unit], CSV) = (Some(()), s) - def write(a: Unit): CSV = List.empty - } - } - - trait CCProduct { - def product[A, B](fa: CsvCodec[A], fb: CsvCodec[B]): CsvCodec[(A, B)] = - new CsvCodec[(A, B)] { - def read(s: CSV): (Option[(A, B)], CSV) = { - val (a1, s1) = fa.read(s) - val (a2, s2) = fb.read(s1) - ((a1, a2).mapN(_ -> _), s2) - } - - def write(a: (A, B)): CSV = - fa.write(a._1) ++ fb.write(a._2) - } - } - - trait CCImap { - def imap[A, B](fa: CsvCodec[A])(f: A => B)(g: B => A): CsvCodec[B] = - new CsvCodec[B] { - def read(s: CSV): (Option[B], CSV) = { - val (a1, s1) = fa.read(s) - (a1.map(f), s1) - } - - def write(a: B): CSV = - fa.write(g(a)) - } - } - - implicit val csvCodecIsInvariantMonoidal: InvariantMonoidal[CsvCodec] = - new InvariantMonoidal[CsvCodec] with CCPure with CCProduct with CCImap - } - - def numericSystemCodec(base: Int): CsvCodec[Int] = - new CsvCodec[Int] { - def read(s: CSV): (Option[Int], CSV) = - (s.headOption.flatMap(head => scala.util.Try(Integer.parseInt(head, base)).toOption), s.drop(1)) - - def write(a: Int): CSV = - List(Integer.toString(a, base)) - } - - implicit val arbNumericSystemCodec: Arbitrary[CsvCodec[Int]] = - Arbitrary(Gen.choose(2, 16).map(numericSystemCodec)) - - implicit def csvCodecsEq[A](implicit a: Arbitrary[A], e: Eq[A]): Eq[CsvCodec[A]] = { - val writeEq: Eq[CsvCodec[A]] = Eq.by[CsvCodec[A], A => CSV](_.write)(catsLawsEqForFn1[A, CSV]) - val readEq: Eq[CsvCodec[A]] = - Eq.by[CsvCodec[A], CSV => (Option[A], CSV)](_.read)(catsLawsEqForFn1[CSV, (Option[A], CSV)]) - Eq.and(writeEq, readEq) - } -} - -class CsvCodecInvariantMonoidalSuite extends CatsSuite { - // Eveything is defined in a companion object to be serializable. - import CsvCodecInvariantMonoidalSuite._ - - checkAll("InvariantMonoidal[CsvCodec]", InvariantMonoidalTests[CsvCodec].invariantMonoidal[Int, Int, Int]) - checkAll("InvariantMonoidal[CsvCodec]", SerializableTests.serializable(InvariantMonoidal[CsvCodec])) - - { - implicit val csvMonoid = InvariantMonoidal.monoid[CsvCodec, Int] - checkAll("InvariantMonoidal[CsvCodec].monoid", MonoidTests[CsvCodec[Int]].monoid) - } - - { - implicit val csvSemigroup = InvariantSemigroupal.semigroup[CsvCodec, Int] - checkAll("InvariantSemigroupal[CsvCodec].semigroup", SemigroupTests[CsvCodec[Int]].semigroup) - } -} diff --git a/tests/src/test/scala/cats/tests/EitherKSuite.scala b/tests/src/test/scala/cats/tests/EitherKSuite.scala index 04b63260ca..32734c9432 100644 --- a/tests/src/test/scala/cats/tests/EitherKSuite.scala +++ b/tests/src/test/scala/cats/tests/EitherKSuite.scala @@ -32,7 +32,7 @@ class EitherKSuite extends CatsSuite { checkAll("EitherK[Option, Option, Int]", EqTests[EitherK[Option, Option, Int]].eqv) checkAll("Eq[EitherK[Option, Option, Int]]", SerializableTests.serializable(Eq[EitherK[Option, Option, Int]])) - checkAll("EitherK[Show, Show, ?]", ContravariantTests[EitherK[Show, Show, ?]].contravariant[Int, Int, Int]) + checkAll("EitherK[Show, Show, ?]", ContravariantTests[EitherK[Show, Show, ?]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[EitherK[Show, Show, ?]]", SerializableTests.serializable(Contravariant[EitherK[Show, Show, ?]])) diff --git a/tests/src/test/scala/cats/tests/EqSuite.scala b/tests/src/test/scala/cats/tests/EqSuite.scala index 91c16adf16..6898df5828 100644 --- a/tests/src/test/scala/cats/tests/EqSuite.scala +++ b/tests/src/test/scala/cats/tests/EqSuite.scala @@ -2,7 +2,7 @@ package cats package tests import cats.kernel.laws.discipline.SerializableTests -import cats.laws.discipline.ContravariantMonoidalTests +import cats.laws.discipline.{ContravariantMonoidalTests, MiniInt} import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ @@ -12,7 +12,7 @@ class EqSuite extends CatsSuite { Semigroupal[Eq] ContravariantSemigroupal[Eq] - checkAll("Eq[Int]", ContravariantMonoidalTests[Eq].contravariantMonoidal[Int, Int, Int]) + checkAll("Eq", ContravariantMonoidalTests[Eq].contravariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("ContravariantMonoidal[Eq]", SerializableTests.serializable(ContravariantMonoidal[Eq])) } diff --git a/tests/src/test/scala/cats/tests/EquivSuite.scala b/tests/src/test/scala/cats/tests/EquivSuite.scala index 62bf7d5fc7..a443441e42 100644 --- a/tests/src/test/scala/cats/tests/EquivSuite.scala +++ b/tests/src/test/scala/cats/tests/EquivSuite.scala @@ -13,8 +13,9 @@ class EquivSuite extends CatsSuite { ContravariantSemigroupal[Equiv] ContravariantMonoidal[Equiv] - checkAll("Contravariant[Equiv]", ContravariantTests[Equiv].contravariant[Int, Int, Int]) - checkAll("Semigroupal[Equiv]", SemigroupalTests[Equiv].semigroupal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Equiv]", ContravariantMonoidalTests[Equiv].contravariantMonoidal[Int, Int, Int]) + checkAll("Contravariant[Equiv]", ContravariantTests[Equiv].contravariant[MiniInt, Int, Boolean]) + checkAll("Semigroupal[Equiv]", SemigroupalTests[Equiv].semigroupal[MiniInt, Boolean, Boolean]) + checkAll("ContravariantMonoidal[Equiv]", + ContravariantMonoidalTests[Equiv].contravariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("ContravariantMonoidal[Equiv]", SerializableTests.serializable(ContravariantMonoidal[Equiv])) } diff --git a/tests/src/test/scala/cats/tests/FuncSuite.scala b/tests/src/test/scala/cats/tests/FuncSuite.scala index 47402b3449..3188a9a25b 100644 --- a/tests/src/test/scala/cats/tests/FuncSuite.scala +++ b/tests/src/test/scala/cats/tests/FuncSuite.scala @@ -6,48 +6,49 @@ import Func.appFunc import cats.Contravariant import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ -import org.scalacheck.Arbitrary class FuncSuite extends CatsSuite { import cats.laws.discipline.eq._ - implicit def funcEq[F[_], A, B](implicit A: Arbitrary[A], FB: Eq[F[B]]): Eq[Func[F, A, B]] = + implicit def funcEq[F[_], A, B](implicit ev: Eq[A => F[B]]): Eq[Func[F, A, B]] = Eq.by[Func[F, A, B], A => F[B]](_.run) - implicit def appFuncEq[F[_], A, B](implicit A: Arbitrary[A], FB: Eq[F[B]]): Eq[AppFunc[F, A, B]] = + implicit def appFuncEq[F[_], A, B](implicit ev: Eq[A => F[B]]): Eq[AppFunc[F, A, B]] = Eq.by[AppFunc[F, A, B], A => F[B]](_.run) implicit val iso = SemigroupalTests.Isomorphisms.invariant[Func[Option, Int, ?]] - checkAll("Func[Option, Int, Int]", SemigroupalTests[Func[Option, Int, ?]].semigroupal[Int, Int, Int]) + checkAll("Func[Option, MiniInt, Int]", SemigroupalTests[Func[Option, MiniInt, ?]].semigroupal[Int, Int, Int]) checkAll("Semigroupal[Func[Option, Int, ?]]", SerializableTests.serializable(Semigroupal[Func[Option, Int, ?]])) { implicit val catsDataApplicativeForFunc = Func.catsDataApplicativeForFunc[Option, Int] - checkAll("Func[Option, Int, Int]", ApplicativeTests[Func[Option, Int, ?]].applicative[Int, Int, Int]) + checkAll("Func[Option, MiniInt, Int]", ApplicativeTests[Func[Option, MiniInt, ?]].applicative[Int, Int, Int]) checkAll("Applicative[Func[Option, Int, ?]]", SerializableTests.serializable(Applicative[Func[Option, Int, ?]])) } { - implicit val catsDataApplyForFunc = Func.catsDataApplyForFunc[Option, Int] - checkAll("Func[Option, Int, Int]", ApplyTests[Func[Option, Int, ?]].apply[Int, Int, Int]) + implicit val catsDataApplyForFunc = Func.catsDataApplyForFunc[Option, MiniInt] + checkAll("Func[Option, MiniInt, Int]", ApplyTests[Func[Option, MiniInt, ?]].apply[Int, Int, Int]) checkAll("Apply[Func[Option, Int, ?]]", SerializableTests.serializable(Apply[Func[Option, Int, ?]])) } { implicit val catsDataFunctorForFunc = Func.catsDataFunctorForFunc[Option, Int] - checkAll("Func[Option, Int, Int]", FunctorTests[Func[Option, Int, ?]].functor[Int, Int, Int]) + checkAll("Func[Option, MiniInt, Int]", FunctorTests[Func[Option, MiniInt, ?]].functor[Int, Int, Int]) checkAll("Functor[Func[Option, Int, ?]]", SerializableTests.serializable(Functor[Func[Option, Int, ?]])) } { - implicit val funcContravariant = Func.catsDataContravariantForFunc[Show, Int] - checkAll("Func[Show, Int, Int]", ContravariantTests[Func[Show, ?, Int]].contravariant[Int, Int, Int]) + implicit val funcContravariant = Func.catsDataContravariantForFunc[Show, MiniInt] + checkAll("Func[Show, MiniInt, MiniInt]", + ContravariantTests[Func[Show, ?, MiniInt]].contravariant[MiniInt, MiniInt, MiniInt]) checkAll("Contravariant[Func[Show, ?, Int]]", SerializableTests.serializable(Contravariant[Func[Show, ?, Int]])) } { implicit val appFuncApp = AppFunc.appFuncApplicative[Option, Int] implicit val iso = SemigroupalTests.Isomorphisms.invariant[AppFunc[Option, Int, ?]] - checkAll("AppFunc[Option, Int, Int]", ApplicativeTests[AppFunc[Option, Int, ?]].applicative[Int, Int, Int]) + checkAll("AppFunc[Option, MiniInt, MiniInt]", + ApplicativeTests[AppFunc[Option, MiniInt, ?]].applicative[MiniInt, MiniInt, MiniInt]) checkAll("Applicative[AppFunc[Option, Int, ?]]", SerializableTests.serializable(Applicative[AppFunc[Option, Int, ?]])) } diff --git a/tests/src/test/scala/cats/tests/FunctionSuite.scala b/tests/src/test/scala/cats/tests/FunctionSuite.scala index c1167cab94..e261826c6b 100644 --- a/tests/src/test/scala/cats/tests/FunctionSuite.scala +++ b/tests/src/test/scala/cats/tests/FunctionSuite.scala @@ -34,39 +34,41 @@ class FunctionSuite extends CatsSuite { checkAll("Function0[Int]", DeferTests[Function0].defer[Int]) checkAll("Defer[Function0[Int]]", SerializableTests.serializable(Defer[Function0])) - checkAll("Function1[Int, Int]", DeferTests[Function1[Int, ?]].defer[Int]) + checkAll("Function1[MiniInt, Int]", DeferTests[Function1[MiniInt, ?]].defer[Int]) checkAll("Defer[Function1[Int, Int]]", SerializableTests.serializable(Defer[Function1[Int, ?]])) checkAll("Function0[Int]", BimonadTests[Function0].bimonad[Int, Int, Int]) checkAll("Bimonad[Function0]", SerializableTests.serializable(Bimonad[Function0])) - implicit val iso = SemigroupalTests.Isomorphisms.invariant[Function1[Int, ?]] - checkAll("Function1[Int, Int]", SemigroupalTests[Function1[Int, ?]].semigroupal[Int, Int, Int]) + implicit val iso = SemigroupalTests.Isomorphisms.invariant[Function1[MiniInt, ?]] + checkAll("Function1[MiniInt, Int]", SemigroupalTests[Function1[MiniInt, ?]].semigroupal[Int, Int, Int]) // TODO: make an binary compatible way to do this //checkAll("Function1[Int => ?]", DeferTests[Function1[Int, ?]].defer[Int]) checkAll("Semigroupal[Function1[Int, ?]]", SerializableTests.serializable(Semigroupal[Function1[Int, ?]])) - checkAll("Function1[Int, Int]", MonadTests[Int => ?].monad[Int, Int, Int]) + checkAll("Function1[MiniInt, Int]", MonadTests[MiniInt => ?].monad[Int, Int, Int]) checkAll("Monad[Int => ?]", SerializableTests.serializable(Monad[Int => ?])) - checkAll("Function1[Int, Int]", CommutativeArrowTests[Function1].commutativeArrow[Int, Int, Int, Int, Int, Int]) + checkAll("Function1[MiniInt, MiniInt]", + CommutativeArrowTests[Function1].commutativeArrow[MiniInt, MiniInt, MiniInt, MiniInt, MiniInt, MiniInt]) checkAll("Arrow[Function1]", SerializableTests.serializable(CommutativeArrow[Function1])) - checkAll("Function1[Int, Int]", ChoiceTests[Function1].choice[Int, Int, Int, Int]) + checkAll("Function1", ChoiceTests[Function1].choice[MiniInt, Boolean, Int, Long]) checkAll("Choice[Function1]", SerializableTests.serializable(Choice[Function1])) - checkAll("Function1[Int, Int]", ArrowChoiceTests[Function1].arrowChoice[Int, Int, Int, Int, Int, Int]) + checkAll("Function1", ArrowChoiceTests[Function1].arrowChoice[MiniInt, MiniInt, MiniInt, MiniInt, MiniInt, MiniInt]) checkAll("ArrowChoice[Function1]", SerializableTests.serializable(ArrowChoice[Function1])) - checkAll("Function1[Int, Int]", ContravariantTests[? => Int].contravariant[Int, Int, Int]) + checkAll("Function1", ContravariantTests[? => MiniInt].contravariant[MiniInt, MiniInt, MiniInt]) checkAll("Contravariant[? => Int]", SerializableTests.serializable(Contravariant[? => Int])) - checkAll("Function1[Int, Int]", MonoidKTests[λ[α => α => α]].monoidK[Int]) + checkAll("Function1", MonoidKTests[λ[α => α => α]].monoidK[MiniInt]) checkAll("MonoidK[λ[α => α => α]", SerializableTests.serializable(catsStdMonoidKForFunction1)) - checkAll("Function1[Int, Int]", DistributiveTests[Int => ?].distributive[Int, Int, Int, Id, Function1[Int, ?]]) + checkAll("Function1[MiniInt, ?]", + DistributiveTests[MiniInt => ?].distributive[Int, Int, Int, Id, Function1[MiniInt, ?]]) checkAll("Distributive[Int => ?]", SerializableTests.serializable(Distributive[Int => ?])) // law checks for the various Function0-related instances @@ -92,8 +94,8 @@ class FunctionSuite extends CatsSuite { // Test for Arrow applicative Applicative[String => ?] - checkAll("Function1[String, ?]", - ApplicativeTests[Function1[String, ?]](Applicative.catsApplicativeForArrow[Function1, String]) + checkAll("Function1[MiniInt, ?]", + ApplicativeTests[Function1[MiniInt, ?]](Applicative.catsApplicativeForArrow[Function1, MiniInt]) .applicative[Int, Int, Int]) // serialization tests for the various Function0-related instances @@ -112,18 +114,19 @@ class FunctionSuite extends CatsSuite { checkAll("Function0", SerializableTests.serializable(Distributive[Function0])) // law checks for the various Function1-related instances - checkAll("Function1[String, Semi]", SemigroupTests[Function1[String, Semi]].semigroup) - checkAll("Function1[String, CSemi]", CommutativeSemigroupTests[Function1[String, CSemi]].commutativeSemigroup) - checkAll("Function1[String, Bnd]", BandTests[Function1[String, Bnd]].band) - checkAll("Function1[String, SL]", SemilatticeTests[Function1[String, SL]].semilattice) - checkAll("Function1[String, BSL]", BoundedSemilatticeTests[Function1[String, BSL]].boundedSemilattice) - checkAll("Function1[String, Mono]", MonoidTests[Function1[String, Mono]].monoid) - checkAll("Function1[String, CMono]", CommutativeMonoidTests[Function1[String, CMono]].commutativeMonoid) - checkAll("Function1[String, Grp]", GroupTests[Function1[String, Grp]].group) - checkAll("Function1[String, CGrp]", CommutativeGroupTests[Function1[String, CGrp]].commutativeGroup) + checkAll("Function1[MiniInt, Semi]", SemigroupTests[Function1[MiniInt, Semi]].semigroup) + checkAll("Function1[MiniInt, CSemi]", CommutativeSemigroupTests[Function1[MiniInt, CSemi]].commutativeSemigroup) + checkAll("Function1[MiniInt, Bnd]", BandTests[Function1[MiniInt, Bnd]].band) + checkAll("Function1[MiniInt, SL]", SemilatticeTests[Function1[MiniInt, SL]].semilattice) + checkAll("Function1[MiniInt, BSL]", BoundedSemilatticeTests[Function1[MiniInt, BSL]].boundedSemilattice) + checkAll("Function1[MiniInt, Mono]", MonoidTests[Function1[MiniInt, Mono]].monoid) + checkAll("Function1[MiniInt, CMono]", CommutativeMonoidTests[Function1[MiniInt, CMono]].commutativeMonoid) + checkAll("Function1[MiniInt, Grp]", GroupTests[Function1[MiniInt, Grp]].group) + checkAll("Function1[MiniInt, CGrp]", CommutativeGroupTests[Function1[MiniInt, CGrp]].commutativeGroup) // Isos for ContravariantMonoidal implicit val isoCodomain = SemigroupalTests.Isomorphisms.invariant[Function1[?, Long]] - checkAll("Function1[?, Monoid]", ContravariantMonoidalTests[Function1[?, Long]].contravariantMonoidal[Int, Int, Int]) + checkAll("Function1[?, Monoid]", + ContravariantMonoidalTests[Function1[?, Long]].contravariantMonoidal[MiniInt, MiniInt, MiniInt]) // serialization tests for the various Function1-related instances checkAll("Semigroup[String => Semi]", SerializableTests.serializable(Semigroup[String => Semi])) diff --git a/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala b/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala index d03fa4f278..b2d258ea05 100644 --- a/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala +++ b/tests/src/test/scala/cats/tests/IndexedReaderWriterStateTSuite.scala @@ -52,13 +52,13 @@ class ReaderWriterStateTSuite extends CatsSuite { } test("ReaderWriterState.pure, ReaderWriterStateT.pure and IndexedReaderWriterStateT.pure are consistent") { - forAll { (value: Int) => + forAll { (context: String, value: Int) => val rws: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterState.pure(value) val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.pure(value) val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.pure(value) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, value) should ===(rwst.run(context, value)) + rwst.run(context, value) should ===(irwst.run(context, value)) } } @@ -70,131 +70,131 @@ class ReaderWriterStateTSuite extends CatsSuite { } test("ReaderWriterState.get, ReaderWriterStateT.get and IndexedReaderWriterStateT.get are consistent") { - forAll { (initial: Int) => + forAll { (context: String, initial: Int) => val rws: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterState.get val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.get val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.get - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.get and instance get are consistent") { - forAll { (initial: Int) => + forAll { (context: String, initial: Int) => val singleton = ReaderWriterState.get[String, String, Int] val instance = ReaderWriterState.pure[String, String, Int, Unit](()).get - singleton should ===(instance) + singleton.run(context, initial) should ===(instance.run(context, initial)) } } test("ReaderWriterState.inspect and instance inspect are consistent") { - forAll { (initial: Int) => + forAll { (context: String, initial: Int) => val singleton = ReaderWriterState.inspect[String, String, Int, String](_.toString) val instance = ReaderWriterState.pure[String, String, Int, Unit](()).inspect(_.toString) - singleton should ===(instance) + singleton.run(context, initial) should ===(instance.run(context, initial)) } } test("ReaderWriterState.inspect, ReaderWriterStateT.inspect and IndexedReaderWriterStateT.inspect are consistent") { - forAll { (f: Int => Int) => + forAll { (context: String, initial: Int, f: Int => Int) => val rws: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterState.inspect(f) val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.inspect(f) val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.inspect(f) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.inspect, ReaderWriterStateT.inspectF and IndexedReaderWriterStateT.inspectF are consistent") { - forAll { (f: Int => Int) => + forAll { (context: String, initial: Int, f: Int => Int) => val rws: ReaderWriterState[String, String, Int, Int] = ReaderWriterState.inspect(f) val rwst: ReaderWriterState[String, String, Int, Int] = ReaderWriterStateT.inspectF(f.andThen(Eval.now)) val irwst: ReaderWriterState[String, String, Int, Int] = IndexedReaderWriterStateT.inspectF(f.andThen(Eval.now)) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.modify, ReaderWriterStateT.modify and IndexedReaderWriterStateT.modify are consistent") { - forAll { (f: Int => Int) => + forAll { (context: String, initial: Int, f: Int => Int) => val rws: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterState.modify(f) val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.modify(f) val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.modify(f) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.modify, ReaderWriterStateT.modifyF and IndexedReaderWriterStateT.modifyF are consistent") { - forAll { (f: Int => Int) => + forAll { (context: String, initial: Int, f: Int => Int) => val rws: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterState.modify(f) val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.modifyF(f.andThen(Eval.now)) val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.modifyF(f.andThen(Eval.now)) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.pure, ReaderWriterStateT.liftF and IndexedReaderWriterStateT.liftF are consistent") { - forAll { (value: Int) => + forAll { (context: String, initial: Int, value: Int) => val rws: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterState.pure(value) val rwst: ReaderWriterState[String, Vector[String], Int, Int] = ReaderWriterStateT.liftF(Eval.now(value)) val irwst: ReaderWriterState[String, Vector[String], Int, Int] = IndexedReaderWriterStateT.liftF(Eval.now(value)) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.set, ReaderWriterStateT.set and IndexedReaderWriterStateT.set are consistent") { - forAll { (next: Int) => + forAll { (context: String, initial: Int, next: Int) => val rws: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterState.set(next) val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.set(next) val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.set(next) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.set, ReaderWriterStateT.setF and IndexedReaderWriterStateT.setF are consistent") { - forAll { (next: Int) => + forAll { (context: String, initial: Int, next: Int) => val rws: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterState.set(next) val rwst: ReaderWriterState[String, Vector[String], Int, Unit] = ReaderWriterStateT.setF(Eval.now(next)) val irwst: ReaderWriterState[String, Vector[String], Int, Unit] = IndexedReaderWriterStateT.setF(Eval.now(next)) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.tell, ReaderWriterStateT.tell and IndexedReaderWriterStateT.tell are consistent") { - forAll { (log: String) => + forAll { (context: String, initial: Int, log: String) => val rws: ReaderWriterState[String, String, Int, Unit] = ReaderWriterState.tell(log) val rwst: ReaderWriterState[String, String, Int, Unit] = ReaderWriterStateT.tell(log) val irwst: ReaderWriterState[String, String, Int, Unit] = IndexedReaderWriterStateT.tell(log) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } test("ReaderWriterState.tell, ReaderWriterStateT.tellF and IndexedReaderWriterStateT.tellF are consistent") { - forAll { (log: String) => + forAll { (context: String, initial: Int, log: String) => val rws: ReaderWriterState[String, String, Int, Unit] = ReaderWriterState.tell(log) val rwst: ReaderWriterState[String, String, Int, Unit] = ReaderWriterStateT.tellF(Eval.now(log)) val irwst: ReaderWriterState[String, String, Int, Unit] = IndexedReaderWriterStateT.tellF(Eval.now(log)) - rws should ===(rwst) - rwst should ===(irwst) + rws.run(context, initial) should ===(rwst.run(context, initial)) + rwst.run(context, initial) should ===(irwst.run(context, initial)) } } @@ -236,7 +236,7 @@ class ReaderWriterStateTSuite extends CatsSuite { test("reset on pure is a noop") { forAll { (c: String, s: Int, a: Int) => val pure = ReaderWriterState.pure[String, String, Int, Int](a) - pure.reset should ===(pure) + pure.reset.run(c, s) should ===(pure.run(c, s)) } } @@ -316,15 +316,17 @@ class ReaderWriterStateTSuite extends CatsSuite { IndexedReaderWriterStateT.catsDataFunctorForIRWST(ListWrapper.functor) ) - checkAll("IndexedReaderWriterStateT[Eval, String, String, Int, String, ?]", - DeferTests[IndexedReaderWriterStateT[Eval, String, String, Int, String, ?]].defer[Int]) + checkAll( + "IndexedReaderWriterStateT[Eval, Boolean, String, MiniInt, String, ?]", + DeferTests[IndexedReaderWriterStateT[Eval, Boolean, String, MiniInt, String, ?]].defer[Int] + ) { implicit val F: Monad[ListWrapper] = ListWrapper.monad checkAll( - "IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", - FunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]].functor[Int, Int, Int] + "IndexedReaderWriterStateT[ListWrapper, Boolean, String, MiniInt, String, ?]", + FunctorTests[IndexedReaderWriterStateT[ListWrapper, Boolean, String, MiniInt, String, ?]].functor[Int, Int, Int] ) checkAll( "Functor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, ?]]", @@ -332,9 +334,9 @@ class ReaderWriterStateTSuite extends CatsSuite { ) checkAll( - "IndexedReaderWriterStateT[ListWrapper, String, String, String, Int, Int]", - ContravariantTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]] - .contravariant[String, String, String] + "IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]", + ContravariantTests[IndexedReaderWriterStateT[ListWrapper, Boolean, String, ?, Int, Int]] + .contravariant[MiniInt, String, Boolean] ) checkAll( "Contravariant[IndexedReaderWriterStateT[ListWrapper, String, String, ?, Int, Int]]", @@ -342,9 +344,9 @@ class ReaderWriterStateTSuite extends CatsSuite { ) checkAll( - "IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", - ProfunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]] - .profunctor[Int, Int, Int, String, String, String] + "IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]", + ProfunctorTests[IndexedReaderWriterStateT[ListWrapper, Boolean, String, ?, ?, Int]] + .profunctor[MiniInt, Int, Int, String, String, String] ) checkAll( "Profunctor[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]", @@ -352,9 +354,9 @@ class ReaderWriterStateTSuite extends CatsSuite { ) checkAll( - "IndexedReaderWriterStateT[ListWrapper, String, String, Int, String, Int]", - StrongTests[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]] - .strong[Int, Int, Int, String, String, String] + "IndexedReaderWriterStateT[ListWrapper, Boolean, String, ?, ?, Int]", + StrongTests[IndexedReaderWriterStateT[ListWrapper, Boolean, String, ?, ?, Int]] + .strong[MiniInt, Int, Boolean, Boolean, Boolean, String] ) checkAll( "Strong[IndexedReaderWriterStateT[ListWrapper, String, String, ?, ?, Int]]", @@ -362,9 +364,9 @@ class ReaderWriterStateTSuite extends CatsSuite { ) checkAll( - "IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, String]", - BifunctorTests[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]] - .bifunctor[Int, Int, Int, String, String, String] + "IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]", + BifunctorTests[IndexedReaderWriterStateT[ListWrapper, Boolean, String, MiniInt, ?, ?]] + .bifunctor[Int, Int, Boolean, String, String, String] ) checkAll( "Bifunctor[IndexedReaderWriterStateT[ListWrapper, String, String, Int, ?, ?]]", @@ -375,13 +377,13 @@ class ReaderWriterStateTSuite extends CatsSuite { { implicit val G: Monad[ListWrapper] = ListWrapper.monad - val SA = IRWST.catsDataAlternativeForIRWST[ListWrapper, String, String, Int](ListWrapper.monad, - ListWrapper.alternative, - Monoid[String]) + val SA = IRWST.catsDataAlternativeForIRWST[ListWrapper, Boolean, String, MiniInt](ListWrapper.monad, + ListWrapper.alternative, + Monoid[String]) checkAll( - "IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, Int]", - AlternativeTests[IRWST[ListWrapper, String, String, Int, Int, ?]](SA).alternative[Int, Int, Int] + "IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, ?]", + AlternativeTests[IRWST[ListWrapper, Boolean, String, MiniInt, MiniInt, ?]](SA).alternative[Int, Int, Int] ) checkAll("Alternative[IndexedReaderWriterStateT[ListWrapper, String, String, Int, Int, ?]]", SerializableTests.serializable(SA)) @@ -390,8 +392,10 @@ class ReaderWriterStateTSuite extends CatsSuite { { implicit val LWM: Monad[ListWrapper] = ListWrapper.monad - checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - MonadTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?]].monad[Int, Int, Int]) + checkAll( + "ReaderWriterStateT[ListWrapper, Boolean, String, MiniInt, MiniInt, ?]", + MonadTests[ReaderWriterStateT[ListWrapper, Boolean, String, MiniInt, ?]].monad[Int, Int, Int] + ) checkAll( "Monad[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]", SerializableTests.serializable(Monad[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]) @@ -399,12 +403,14 @@ class ReaderWriterStateTSuite extends CatsSuite { } { - implicit val iso = SemigroupalTests.Isomorphisms.invariant[ReaderWriterStateT[Option, String, String, Int, ?]] - implicit val eqEitherTFA: Eq[EitherT[ReaderWriterStateT[Option, String, String, Int, ?], Unit, Int]] = - EitherT.catsDataEqForEitherT[ReaderWriterStateT[Option, String, String, Int, ?], Unit, Int] + implicit val iso = SemigroupalTests.Isomorphisms.invariant[ReaderWriterStateT[Option, Boolean, String, MiniInt, ?]] + implicit val eqEitherTFA: Eq[EitherT[ReaderWriterStateT[Option, Boolean, String, MiniInt, ?], Unit, Int]] = + EitherT.catsDataEqForEitherT[ReaderWriterStateT[Option, Boolean, String, MiniInt, ?], Unit, Int] - checkAll("ReaderWriterStateT[Option, String, String, Int, Int]", - MonadErrorTests[ReaderWriterStateT[Option, String, String, Int, ?], Unit].monadError[Int, Int, Int]) + checkAll( + "ReaderWriterStateT[Option, Boolean, String, MiniIntInt, ?]", + MonadErrorTests[ReaderWriterStateT[Option, Boolean, String, MiniInt, ?], Unit].monadError[Int, Int, Int] + ) checkAll( "MonadError[ReaderWriterStateT[Option, String, String, Int, ?], Unit]", SerializableTests.serializable(MonadError[ReaderWriterStateT[Option, String, String, Int, ?], Unit]) @@ -415,8 +421,10 @@ class ReaderWriterStateTSuite extends CatsSuite { implicit val F: Monad[ListWrapper] = ListWrapper.monad implicit val S: SemigroupK[ListWrapper] = ListWrapper.semigroupK - checkAll("ReaderWriterStateT[ListWrapper, String, String, Int, Int]", - SemigroupKTests[ReaderWriterStateT[ListWrapper, String, String, Int, ?]].semigroupK[Int]) + checkAll( + "ReaderWriterStateT[ListWrapper, Boolean, String, MiniInt, ?]", + SemigroupKTests[ReaderWriterStateT[ListWrapper, Boolean, String, MiniInt, ?]].semigroupK[Int] + ) checkAll( "SemigroupK[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]", SerializableTests.serializable(SemigroupK[ReaderWriterStateT[ListWrapper, String, String, Int, ?]]) @@ -442,9 +450,9 @@ object ReaderWriterStateTSuite { } } - implicit def IRWSTEq[F[_], E, L, SA, SB, A](implicit SA: Arbitrary[SA], + implicit def IRWSTEq[F[_], E, L, SA, SB, A](implicit SA: ExhaustiveCheck[SA], SB: Arbitrary[SB], - E: Arbitrary[E], + E: ExhaustiveCheck[E], FLSB: Eq[F[(L, SB, A)]], F: Monad[F]): Eq[IndexedReaderWriterStateT[F, E, L, SA, SB, A]] = Eq.by[IndexedReaderWriterStateT[F, E, L, SA, SB, A], (E, SA) => F[(L, SB, A)]] { state => (e, s) => diff --git a/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala b/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala index a26b4f4f4c..801ef01990 100644 --- a/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala +++ b/tests/src/test/scala/cats/tests/IndexedStateTSuite.scala @@ -9,7 +9,6 @@ import cats.kernel.instances.tuple._ import cats.laws.discipline._ import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ -import org.scalacheck.Arbitrary class IndexedStateTSuite extends CatsSuite { @@ -166,7 +165,7 @@ class IndexedStateTSuite extends CatsSuite { } test("flatMap and flatMapF consistent") { - forAll { (stateT: StateT[Option, Long, Int], f: Int => Option[Int]) => + forAll { (stateT: StateT[Option, MiniInt, Int], f: Int => Option[Int]) => stateT.flatMap(a => StateT(s => f(a).map(b => (s, b)))) should ===(stateT.flatMapF(f)) } } @@ -178,7 +177,7 @@ class IndexedStateTSuite extends CatsSuite { } test("modify identity is a noop") { - forAll { (f: StateT[List, Long, Int]) => + forAll { (f: StateT[List, MiniInt, Int]) => f.modify(identity) should ===(f) } } @@ -196,9 +195,9 @@ class IndexedStateTSuite extends CatsSuite { } test("State.modify equivalent to get then set") { - forAll { (f: Long => Long) => + forAll { (f: MiniInt => MiniInt) => val s1 = for { - l <- State.get[Long] + l <- State.get[MiniInt] _ <- State.set(f(l)) } yield () @@ -232,14 +231,14 @@ class IndexedStateTSuite extends CatsSuite { } test(".get equivalent to flatMap with State.get") { - forAll { (s: State[Long, Int]) => + forAll { (s: State[MiniInt, Int]) => s.get should ===(s.flatMap(_ => State.get)) } } test("StateT#transformS with identity is identity") { - forAll { (s: StateT[List, Long, Int]) => - s.transformS[Long](identity, (s, i) => i) should ===(s) + forAll { (s: StateT[List, MiniInt, Int]) => + s.transformS[MiniInt](identity, (s, i) => i) should ===(s) } } @@ -342,15 +341,15 @@ class IndexedStateTSuite extends CatsSuite { Profunctor[IndexedStateT[ListWrapper, ?, ?, String]] } - checkAll("IndexedStateT[Eval, String, String, ?]", DeferTests[IndexedStateT[Eval, String, String, ?]].defer[Int]) + checkAll("IndexedStateT[Eval, MiniInt, String, ?]", DeferTests[IndexedStateT[Eval, MiniInt, String, ?]].defer[Int]) { // F needs a Monad to do Eq on StateT implicit val F: Monad[ListWrapper] = ListWrapper.monad implicit val FS: Functor[IndexedStateT[ListWrapper, String, Int, ?]] = IndexedStateT.catsDataFunctorForIndexedStateT - checkAll("IndexedStateT[ListWrapper, String, Int, Int]", - FunctorTests[IndexedStateT[ListWrapper, String, Int, ?]].functor[Int, Int, Int]) + checkAll("IndexedStateT[ListWrapper, MiniInt, Int, Int]", + FunctorTests[IndexedStateT[ListWrapper, MiniInt, Int, ?]].functor[Int, Int, Int]) checkAll("Functor[IndexedStateT[ListWrapper, Int, ?]]", SerializableTests.serializable(Functor[IndexedStateT[ListWrapper, String, Int, ?]])) @@ -361,10 +360,10 @@ class IndexedStateTSuite extends CatsSuite { implicit val F0 = ListWrapper.monad implicit val FF = ListWrapper.functorFilter - checkAll("IndexedStateT[ListWrapper, String, Int, ?]", - FunctorFilterTests[IndexedStateT[ListWrapper, String, Int, ?]].functorFilter[Int, Int, Int]) - checkAll("FunctorFilter[IndexedStateT[ListWrapper, String, Int, ?]]", - SerializableTests.serializable(FunctorFilter[IndexedStateT[ListWrapper, String, Int, ?]])) + checkAll("IndexedStateT[ListWrapper, MiniInt, Int, ?]", + FunctorFilterTests[IndexedStateT[ListWrapper, MiniInt, Int, ?]].functorFilter[Int, Int, Int]) + checkAll("FunctorFilter[IndexedStateT[ListWrapper, MiniInt, Int, ?]]", + SerializableTests.serializable(FunctorFilter[IndexedStateT[ListWrapper, MiniInt, Int, ?]])) FunctorFilter[IndexedStateT[ListWrapper, String, Int, ?]] } @@ -374,8 +373,8 @@ class IndexedStateTSuite extends CatsSuite { implicit val FS: Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]] = IndexedStateT.catsDataContravariantForIndexedStateT - checkAll("IndexedStateT[ListWrapper, Int, Int, Int]", - ContravariantTests[IndexedStateT[ListWrapper, ?, Int, Int]].contravariant[Int, Int, Int]) + checkAll("IndexedStateT[ListWrapper, ?, Int, Boolean]", + ContravariantTests[IndexedStateT[ListWrapper, ?, Int, Int]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]]", SerializableTests.serializable(Contravariant[IndexedStateT[ListWrapper, ?, Int, Int]])) @@ -386,8 +385,8 @@ class IndexedStateTSuite extends CatsSuite { implicit val F: Monad[ListWrapper] = ListWrapper.monad implicit val FS: Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]] = IndexedStateT.catsDataBifunctorForIndexedStateT - checkAll("IndexedStateT[ListWrapper, Int, String, Int]", - BifunctorTests[IndexedStateT[ListWrapper, Int, ?, ?]].bifunctor[String, String, String, Int, Int, Int]) + checkAll("IndexedStateT[ListWrapper, MiniInt, String, Int]", + BifunctorTests[IndexedStateT[ListWrapper, MiniInt, ?, ?]].bifunctor[String, String, String, Int, Int, Int]) checkAll("Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]]", SerializableTests.serializable(Bifunctor[IndexedStateT[ListWrapper, Int, ?, ?]])) @@ -400,7 +399,7 @@ class IndexedStateTSuite extends CatsSuite { IndexedStateT.catsDataProfunctorForIndexedStateT checkAll("IndexedStateT[ListWrapper, String, Int, Int]", - ProfunctorTests[IndexedStateT[ListWrapper, ?, ?, Int]].profunctor[String, String, String, Int, Int, Int]) + ProfunctorTests[IndexedStateT[ListWrapper, ?, ?, Int]].profunctor[MiniInt, String, String, Int, Int, Int]) checkAll("Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]]", SerializableTests.serializable(Profunctor[IndexedStateT[ListWrapper, ?, ?, Int]])) @@ -411,8 +410,8 @@ class IndexedStateTSuite extends CatsSuite { implicit val F: Monad[ListWrapper] = ListWrapper.monad implicit val FS: Strong[IndexedStateT[ListWrapper, ?, ?, Int]] = IndexedStateT.catsDataStrongForIndexedStateT - checkAll("IndexedStateT[ListWrapper, String, Int, Int]", - StrongTests[IndexedStateT[ListWrapper, ?, ?, Int]].strong[String, String, String, Int, Int, Int]) + checkAll("IndexedStateT[ListWrapper, ?, ?, Int]", + StrongTests[IndexedStateT[ListWrapper, ?, ?, Int]].strong[MiniInt, Int, Boolean, Boolean, Boolean, String]) checkAll("Strong[IndexedStateT[ListWrapper, ?, ?, Int]]", SerializableTests.serializable(Strong[IndexedStateT[ListWrapper, ?, ?, Int]])) @@ -423,9 +422,9 @@ class IndexedStateTSuite extends CatsSuite { // F has a Monad implicit val F = ListWrapper.monad - checkAll("IndexedStateT[ListWrapper, Int, Int]", - MonadTests[IndexedStateT[ListWrapper, Int, Int, ?]].monad[Int, Int, Int]) - checkAll("Monad[StateT[ListWrapper, Int, ?]]", + checkAll("IndexedStateT[ListWrapper, MiniInt, Int, ?]", + MonadTests[IndexedStateT[ListWrapper, MiniInt, MiniInt, ?]].monad[Int, Int, Int]) + checkAll("Monad[IndexedStateT[ListWrapper, Int, Int, ?]]", SerializableTests.serializable(Monad[IndexedStateT[ListWrapper, Int, Int, ?]])) Monad[IndexedStateT[ListWrapper, Int, Int, ?]] @@ -440,8 +439,8 @@ class IndexedStateTSuite extends CatsSuite { implicit val F = ListWrapper.monad implicit val S = ListWrapper.semigroupK - checkAll("IndexedStateT[ListWrapper, Int, Int]", - SemigroupKTests[IndexedStateT[ListWrapper, Int, Int, ?]].semigroupK[Int]) + checkAll("IndexedStateT[ListWrapper, MiniInt, Int, ?]", + SemigroupKTests[IndexedStateT[ListWrapper, MiniInt, Int, ?]].semigroupK[Int]) checkAll("SemigroupK[IndexedStateT[ListWrapper, Int, ?]]", SerializableTests.serializable(SemigroupK[IndexedStateT[ListWrapper, String, Int, ?]])) } @@ -451,10 +450,11 @@ class IndexedStateTSuite extends CatsSuite { implicit val G = ListWrapper.monad implicit val F = ListWrapper.alternative val SA = - IndexedStateT.catsDataAlternativeForIndexedStateT[ListWrapper, Int](ListWrapper.monad, ListWrapper.alternative) + IndexedStateT + .catsDataAlternativeForIndexedStateT[ListWrapper, MiniInt](ListWrapper.monad, ListWrapper.alternative) - checkAll("IndexedStateT[ListWrapper, Int, Int, Int]", - AlternativeTests[IndexedStateT[ListWrapper, Int, Int, ?]](SA).alternative[Int, Int, Int]) + checkAll("IndexedStateT[ListWrapper, MiniInt, Int, Int]", + AlternativeTests[IndexedStateT[ListWrapper, MiniInt, MiniInt, ?]](SA).alternative[Int, Int, Int]) checkAll("Alternative[IndexedStateT[ListWrapper, Int, Int, ?]]", SerializableTests.serializable(SA)) Monad[IndexedStateT[ListWrapper, Int, Int, ?]] @@ -468,19 +468,20 @@ class IndexedStateTSuite extends CatsSuite { } { - implicit val iso = SemigroupalTests.Isomorphisms.invariant[State[Long, ?]] + implicit val iso = SemigroupalTests.Isomorphisms.invariant[State[MiniInt, ?]] - checkAll("State[Long, ?]", MonadTests[State[Long, ?]].monad[Int, Int, Int]) + checkAll("State[MiniInt, ?]", MonadTests[State[MiniInt, ?]].monad[Int, Int, Int]) checkAll("Monad[State[Long, ?]]", SerializableTests.serializable(Monad[State[Long, ?]])) } { // F has a MonadError - implicit val iso = SemigroupalTests.Isomorphisms.invariant[StateT[Option, Int, ?]] - implicit val eqEitherTFA: Eq[EitherT[StateT[Option, Int, ?], Unit, Int]] = - EitherT.catsDataEqForEitherT[StateT[Option, Int, ?], Unit, Int] + implicit val iso = SemigroupalTests.Isomorphisms.invariant[StateT[Option, MiniInt, ?]] + implicit val eqEitherTFA: Eq[EitherT[StateT[Option, MiniInt, ?], Unit, Int]] = + EitherT.catsDataEqForEitherT[StateT[Option, MiniInt, ?], Unit, Int] - checkAll("StateT[Option, Int, Int]", MonadErrorTests[StateT[Option, Int, ?], Unit].monadError[Int, Int, Int]) + checkAll("StateT[Option, MiniInt, Int]", + MonadErrorTests[StateT[Option, MiniInt, ?], Unit].monadError[Int, Int, Int]) checkAll("MonadError[StateT[Option, Int, ?], Unit]", SerializableTests.serializable(MonadError[StateT[Option, Int, ?], Unit])) } @@ -488,7 +489,7 @@ class IndexedStateTSuite extends CatsSuite { } object IndexedStateTSuite extends IndexedStateTSuiteInstances { - implicit def stateEq[S: Eq: Arbitrary, A: Eq]: Eq[State[S, A]] = + implicit def stateEq[S: Eq: ExhaustiveCheck, A: Eq]: Eq[State[S, A]] = indexedStateTEq[Eval, S, S, A] val add1: State[Int, Int] = State(n => (n + 1, n)) @@ -496,7 +497,7 @@ object IndexedStateTSuite extends IndexedStateTSuiteInstances { sealed trait IndexedStateTSuiteInstances { - implicit def indexedStateTEq[F[_], SA, SB, A](implicit SA: Arbitrary[SA], + implicit def indexedStateTEq[F[_], SA, SB, A](implicit SA: ExhaustiveCheck[SA], FSB: Eq[F[(SB, A)]], F: FlatMap[F]): Eq[IndexedStateT[F, SA, SB, A]] = Eq.by[IndexedStateT[F, SA, SB, A], SA => F[(SB, A)]](state => s => state.run(s)) diff --git a/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala b/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala index 0619e7d5d2..420bb4116e 100644 --- a/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala +++ b/tests/src/test/scala/cats/tests/KernelContravariantSuite.scala @@ -10,27 +10,27 @@ class KernelContravariantSuite extends CatsSuite { Contravariant[Eq] Semigroupal[Eq] ContravariantSemigroupal[Eq] - checkAll("Contravariant[Eq]", ContravariantTests[Eq].contravariant[Int, Int, Int]) - checkAll("Semigroupal[Eq]", SemigroupalTests[Eq].semigroupal[Int, Int, Int]) + checkAll("Contravariant[Eq]", ContravariantTests[Eq].contravariant[MiniInt, Int, Boolean]) + checkAll("Semigroupal[Eq]", SemigroupalTests[Eq].semigroupal[MiniInt, Boolean, Boolean]) checkAll("Contravariant[Eq]", SerializableTests.serializable(Contravariant[Eq])) Invariant[PartialOrder] Contravariant[PartialOrder] Semigroupal[PartialOrder] ContravariantSemigroupal[PartialOrder] - checkAll("Contravariant[PartialOrder]", ContravariantTests[PartialOrder].contravariant[Int, Int, Int]) - checkAll("Semigroupal[PartialOrder]", SemigroupalTests[PartialOrder].semigroupal[Int, Int, Int]) + checkAll("Contravariant[PartialOrder]", ContravariantTests[PartialOrder].contravariant[MiniInt, Int, Boolean]) + checkAll("Semigroupal[PartialOrder]", SemigroupalTests[PartialOrder].semigroupal[MiniInt, Boolean, Boolean]) checkAll("Contravariant[PartialOrder]", SerializableTests.serializable(Contravariant[PartialOrder])) Invariant[Order] Contravariant[Order] Semigroupal[Order] ContravariantSemigroupal[Order] - checkAll("Contravariant[Order]", ContravariantTests[Order].contravariant[Int, Int, Int]) - checkAll("Semigroupal[Order]", SemigroupalTests[Order].semigroupal[Int, Int, Int]) + checkAll("Contravariant[Order]", ContravariantTests[Order].contravariant[MiniInt, Int, Boolean]) + checkAll("Semigroupal[Order]", SemigroupalTests[Order].semigroupal[MiniInt, Boolean, Boolean]) checkAll("Contravariant[Order]", SerializableTests.serializable(Contravariant[Order])) Contravariant[Hash] - checkAll("Contravariant[Hash]", ContravariantTests[Hash].contravariant[Int, Int, Int]) + checkAll("Contravariant[Hash]", ContravariantTests[Hash].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[Hash]", SerializableTests.serializable(Contravariant[Hash])) } diff --git a/tests/src/test/scala/cats/tests/KleisliSuite.scala b/tests/src/test/scala/cats/tests/KleisliSuite.scala index f2f79300b4..b5c4965b84 100644 --- a/tests/src/test/scala/cats/tests/KleisliSuite.scala +++ b/tests/src/test/scala/cats/tests/KleisliSuite.scala @@ -7,197 +7,148 @@ import cats.data.{Const, EitherT, Kleisli, Reader, ReaderT} import cats.laws.discipline._ import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ -import org.scalacheck.Arbitrary import cats.kernel.laws.discipline.{MonoidTests, SemigroupTests} import cats.laws.discipline.{DeferTests, MonoidKTests, SemigroupKTests} import Helpers.CSemi import catalysts.Platform class KleisliSuite extends CatsSuite { - implicit def kleisliEq[F[_], A, B](implicit A: Arbitrary[A], FB: Eq[F[B]]): Eq[Kleisli[F, A, B]] = + implicit def kleisliEq[F[_], A, B](implicit ev: Eq[A => F[B]]): Eq[Kleisli[F, A, B]] = Eq.by[Kleisli[F, A, B], A => F[B]](_.run) - implicit def readerEq[A, B](implicit A: Arbitrary[A], FB: Eq[Id[B]]): Eq[Reader[A, B]] = + implicit def readerEq[A, B](implicit ev: Eq[A => B]): Eq[Reader[A, B]] = kleisliEq - implicit val eitherTEq = EitherT.catsDataEqForEitherT[Kleisli[Option, Int, ?], Unit, Int] - implicit val eitherTEq2 = EitherT.catsDataEqForEitherT[Reader[Int, ?], Unit, Int] + implicit val eitherTEq = EitherT.catsDataEqForEitherT[Kleisli[Option, MiniInt, ?], Unit, Int] + implicit val eitherTEq2 = EitherT.catsDataEqForEitherT[Reader[MiniInt, ?], Unit, Int] implicit val iso = SemigroupalTests.Isomorphisms.invariant[Kleisli[Option, Int, ?]] implicit val iso2 = SemigroupalTests.Isomorphisms.invariant[Reader[Int, ?]] { - implicit val instance: ApplicativeError[Kleisli[Option, Int, ?], Unit] = - Kleisli.catsDataApplicativeErrorForKleisli[Option, Unit, Int](cats.instances.option.catsStdInstancesForOption) - checkAll("Kleisli[Option, Int, Int] with Unit", - ApplicativeErrorTests[Kleisli[Option, Int, ?], Unit](instance).applicativeError[Int, Int, Int]) + implicit val instance: ApplicativeError[Kleisli[Option, MiniInt, ?], Unit] = + Kleisli.catsDataApplicativeErrorForKleisli[Option, Unit, MiniInt](cats.instances.option.catsStdInstancesForOption) + checkAll("Kleisli[Option, MinInt, ?] with Unit", + ApplicativeErrorTests[Kleisli[Option, MiniInt, ?], Unit](instance).applicativeError[Int, Int, Int]) checkAll("ApplicativeError[Kleisli[Option, Int, Int], Unit]", SerializableTests.serializable(instance)) } - checkAll("Kleisli[Eval, Int, ?]", DeferTests[Kleisli[Eval, Int, ?]].defer[Int]) - checkAll("Kleisli[Option, Int, Int] with Unit", - MonadErrorTests[Kleisli[Option, Int, ?], Unit].monadError[Int, Int, Int]) + checkAll("Kleisli[Eval, MiniInt, ?]", DeferTests[Kleisli[Eval, MiniInt, ?]].defer[Int]) + checkAll("Kleisli[Option, MiniInt, ?] with Unit", + MonadErrorTests[Kleisli[Option, MiniInt, ?], Unit].monadError[Int, Int, Int]) checkAll("MonadError[Kleisli[Option, Int, Int], Unit]", SerializableTests.serializable(MonadError[Kleisli[Option, Int, ?], Unit])) - checkAll("Kleisli[Option, Int, Int]", SemigroupalTests[Kleisli[Option, Int, ?]].semigroupal[Int, Int, Int]) + checkAll("Kleisli[Option, MiniInt, ?]", SemigroupalTests[Kleisli[Option, MiniInt, ?]].semigroupal[Int, Int, Int]) checkAll("Semigroupal[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Semigroupal[Kleisli[Option, Int, ?]])) - checkAll("Kleisli[(CSemi, ?), Int, ?]", - CommutativeFlatMapTests[Kleisli[(CSemi, ?), Int, ?]].commutativeFlatMap[Int, Int, Int]) + checkAll("Kleisli[(CSemi, ?), MiniInt, ?]", + CommutativeFlatMapTests[Kleisli[(CSemi, ?), MiniInt, ?]].commutativeFlatMap[Int, Int, Int]) checkAll("CommutativeFlatMap[Kleisli[(CSemi, ?), Int, ?]]", SerializableTests.serializable(CommutativeFlatMap[Kleisli[(CSemi, ?), Int, ?]])) - checkAll("Kleisli[Option, Int, ?]", CommutativeMonadTests[Kleisli[Option, Int, ?]].commutativeMonad[Int, Int, Int]) + checkAll("Kleisli[Option, MiniInt, ?]", + CommutativeMonadTests[Kleisli[Option, MiniInt, ?]].commutativeMonad[Int, Int, Int]) checkAll("CommutativeMonad[Kleisli[Option, Int, ?]]", SerializableTests.serializable(CommutativeMonad[Kleisli[Option, Int, ?]])) - checkAll("Kleisli[Id, Int, ?]", CommutativeMonadTests[Kleisli[Id, Int, ?]].commutativeMonad[Int, Int, Int]) + checkAll("Kleisli[Id, MiniInt, ?]", CommutativeMonadTests[Kleisli[Id, MiniInt, ?]].commutativeMonad[Int, Int, Int]) checkAll("CommutativeMonad[Kleisli[Id, Int, ?]]", SerializableTests.serializable(CommutativeMonad[Kleisli[Id, Int, ?]])) - { - implicit val catsDataArrowForKleisli = Kleisli.catsDataArrowChoiceForKleisli[List] - checkAll("Kleisli[List, Int, Int]", ArrowTests[Kleisli[List, ?, ?]].arrow[Int, Int, Int, Int, Int, Int]) - checkAll("Arrow[Kleisli[List, ?, ?]]", SerializableTests.serializable(Arrow[Kleisli[List, ?, ?]])) - } + checkAll("Kleisli[List, ?, ?]", + ArrowTests[Kleisli[List, ?, ?]].arrow[MiniInt, MiniInt, MiniInt, MiniInt, MiniInt, Boolean]) + checkAll("Arrow[Kleisli[List, ?, ?]]", SerializableTests.serializable(Arrow[Kleisli[List, ?, ?]])) - { - implicit val catsDataArrowChoiceForKleisli = Kleisli.catsDataArrowChoiceForKleisli[List] - checkAll("Kleisli[List, Int, Int]", ArrowChoiceTests[Kleisli[List, ?, ?]].arrowChoice[Int, Int, Int, Int, Int, Int]) - checkAll("ArrowChoice[Kleisli[List, ?, ?]]", SerializableTests.serializable(ArrowChoice[Kleisli[List, ?, ?]])) - } + checkAll("Kleisli[List, ?, ?]", + ArrowChoiceTests[Kleisli[List, ?, ?]].arrowChoice[MiniInt, MiniInt, MiniInt, MiniInt, MiniInt, Boolean]) + checkAll("ArrowChoice[Kleisli[List, ?, ?]]", SerializableTests.serializable(ArrowChoice[Kleisli[List, ?, ?]])) - { - implicit val catsDataCommutativeArrowForKleisli = Kleisli.catsDataCommutativeArrowForKleisli[Option] - checkAll("Kleisli[Option, Int, Int]", - CommutativeArrowTests[Kleisli[Option, ?, ?]].commutativeArrow[Int, Int, Int, Int, Int, Int]) - checkAll("CommutativeArrow[Kleisli[Option, ?, ?]]", - SerializableTests.serializable(CommutativeArrow[Kleisli[Option, ?, ?]])) - } + checkAll("Kleisli[Option, Int, Int]", + CommutativeArrowTests[Kleisli[Option, ?, ?]] + .commutativeArrow[MiniInt, MiniInt, MiniInt, MiniInt, MiniInt, Boolean]) + checkAll("CommutativeArrow[Kleisli[Option, ?, ?]]", + SerializableTests.serializable(CommutativeArrow[Kleisli[Option, ?, ?]])) - { - implicit val catsDataChoiceForKleisli = Kleisli.catsDataChoiceForKleisli[Option] - checkAll("Kleisli[Option, Int, Int]", ChoiceTests[Kleisli[Option, ?, ?]].choice[Int, Int, Int, Int]) - checkAll("Choice[Kleisli[Option, ?, ?]]", SerializableTests.serializable(Choice[Kleisli[Option, ?, ?]])) - } + checkAll("Kleisli[Option, ?, ?]", ChoiceTests[Kleisli[Option, ?, ?]].choice[MiniInt, Boolean, Int, Int]) + checkAll("Choice[Kleisli[Option, ?, ?]]", SerializableTests.serializable(Choice[Kleisli[Option, ?, ?]])) - { - implicit val catsDataMonadForKleisli = Kleisli.catsDataMonadForKleisli[Option, Int] - checkAll("Kleisli[Option, Int, Int]", MonadTests[Kleisli[Option, Int, ?]].monad[Int, Int, Int]) - checkAll("Monad[Kleisli[Option, ?, ?], Int]", SerializableTests.serializable(Monad[Kleisli[Option, Int, ?]])) - } + checkAll("Kleisli[Option, MiniInt, ?]", MonadTests[Kleisli[Option, MiniInt, ?]].monad[Int, Int, Int]) + checkAll("Monad[Kleisli[Option, ?, ?], Int]", SerializableTests.serializable(Monad[Kleisli[Option, Int, ?]])) - { - implicit val catsDataMonadForReader = Kleisli.catsDataMonadForKleisliId[Int] - checkAll("Reader[Int, Int]", MonadTests[Reader[Int, ?]].monad[Int, Int, Int]) - checkAll("Monad[Reader[?, ?], Int]", SerializableTests.serializable(Monad[Reader[Int, ?]])) - } + checkAll("Reader[MiniInt, ?]", MonadTests[Reader[MiniInt, ?]].monad[Int, Int, Int]) + checkAll("Monad[Reader[?, ?], Int]", SerializableTests.serializable(Monad[Reader[Int, ?]])) - { - implicit val catsDataStrongForKleisli = Kleisli.catsDataStrongForKleisli[Option] - checkAll("Kleisli[Option, Int, Int]", StrongTests[Kleisli[Option, ?, ?]].strong[Int, Int, Int, Int, Int, Int]) - checkAll("Strong[Kleisli[Option, ?, ?]]", SerializableTests.serializable(Strong[Kleisli[Option, ?, ?]])) - } + checkAll("Kleisli[Option, ?, ?]", + StrongTests[Kleisli[Option, ?, ?]].strong[MiniInt, Boolean, Boolean, Boolean, Boolean, Int]) + checkAll("Strong[Kleisli[Option, ?, ?]]", SerializableTests.serializable(Strong[Kleisli[Option, ?, ?]])) - { - implicit val catsDataFlatMapForKleisli = Kleisli.catsDataFlatMapForKleisli[Option, Int] - checkAll("Kleisli[Option, Int, Int]", FlatMapTests[Kleisli[Option, Int, ?]].flatMap[Int, Int, Int]) - checkAll("FlatMap[Kleisli[Option, Int, ?]]", SerializableTests.serializable(FlatMap[Kleisli[Option, Int, ?]])) - } + checkAll("Kleisli[Option, MiniInt, Int]", FlatMapTests[Kleisli[Option, MiniInt, ?]].flatMap[Int, Int, Int]) + checkAll("FlatMap[Kleisli[Option, Int, ?]]", SerializableTests.serializable(FlatMap[Kleisli[Option, Int, ?]])) - { - implicit val catsDataAlternativeForKleisli = Kleisli.catsDataAlternativeForKleisli[Option, Int] - checkAll("Kleisli[Option, Int, Int]", AlternativeTests[Kleisli[Option, Int, ?]].alternative[Int, Int, Int]) - checkAll("Alternative[Kleisli[Option, Int, ?]]", - SerializableTests.serializable(Alternative[Kleisli[Option, Int, ?]])) - } + checkAll("Kleisli[Option, MiniInt, ?]", AlternativeTests[Kleisli[Option, MiniInt, ?]].alternative[Int, Int, Int]) + checkAll("Alternative[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Alternative[Kleisli[Option, Int, ?]])) - { - implicit val catsDataContravariantMonoidalForKleisli = - Kleisli.catsDataContravariantMonoidalForKleisli[Const[String, ?], Int] - checkAll("Kleisli[Const[String, ?], Int, Int]", - ContravariantMonoidalTests[Kleisli[Const[String, ?], Int, ?]].contravariantMonoidal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Kleisli[Option, Int, ?]]", - SerializableTests.serializable(ContravariantMonoidal[Kleisli[Const[String, ?], Int, ?]])) - } + checkAll("Kleisli[Const[String, ?], MiniInt, ?]", + ContravariantMonoidalTests[Kleisli[Const[String, ?], MiniInt, ?]].contravariantMonoidal[Int, Int, Int]) + checkAll("ContravariantMonoidal[Kleisli[Option, Int, ?]]", + SerializableTests.serializable(ContravariantMonoidal[Kleisli[Const[String, ?], Int, ?]])) - { - implicit val catsDataApplicativeForKleisli = Kleisli.catsDataApplicativeForKleisli[Option, Int] - checkAll("Kleisli[Option, Int, Int]", ApplicativeTests[Kleisli[Option, Int, ?]].applicative[Int, Int, Int]) - checkAll("Applicative[Kleisli[Option, Int, ?]]", - SerializableTests.serializable(Applicative[Kleisli[Option, Int, ?]])) - } + checkAll("Kleisli[Option, MiniInt, Int]", ApplicativeTests[Kleisli[Option, MiniInt, ?]].applicative[Int, Int, Int]) + checkAll("Applicative[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Applicative[Kleisli[Option, Int, ?]])) - { - implicit val catsDataApplyForKleisli = Kleisli.catsDataApplyForKleisli[Option, Int] - checkAll("Kleisli[Option, Int, Int]", ApplyTests[Kleisli[Option, Int, ?]].apply[Int, Int, Int]) - checkAll("Apply[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Apply[Kleisli[Option, Int, ?]])) - } + checkAll("Kleisli[Option, MiniInt, Int]", ApplyTests[Kleisli[Option, MiniInt, ?]].apply[Int, Int, Int]) + checkAll("Apply[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Apply[Kleisli[Option, Int, ?]])) - { - implicit val catsDataFunctorForKleisli = Kleisli.catsDataFunctorForKleisli[Option, Int] - checkAll("Kleisli[Option, Int, Int]", FunctorTests[Kleisli[Option, Int, ?]].functor[Int, Int, Int]) - checkAll("Functor[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Functor[Kleisli[Option, Int, ?]])) - } + checkAll("Kleisli[Option, MiniInt, Int]", FunctorTests[Kleisli[Option, MiniInt, ?]].functor[Int, Int, Int]) + checkAll("Functor[Kleisli[Option, Int, ?]]", SerializableTests.serializable(Functor[Kleisli[Option, Int, ?]])) { implicit val FF = ListWrapper.functorFilter - checkAll("Kleisli[ListWrapper, Int, ?]", - FunctorFilterTests[Kleisli[ListWrapper, Int, ?]].functorFilter[Int, Int, Int]) - checkAll("FunctorFilter[Kleisli[ListWrapper, Int, ?]]", - SerializableTests.serializable(FunctorFilter[Kleisli[ListWrapper, Int, ?]])) + checkAll("Kleisli[ListWrapper, MiniInt, ?]", + FunctorFilterTests[Kleisli[ListWrapper, MiniInt, ?]].functorFilter[Int, Int, Int]) + checkAll("FunctorFilter[Kleisli[ListWrapper, MiniInt, ?]]", + SerializableTests.serializable(FunctorFilter[Kleisli[ListWrapper, MiniInt, ?]])) FunctorFilter[ReaderT[ListWrapper, Int, ?]] } - { - checkAll("Kleisli[Function0, Int, ?]", - DistributiveTests[Kleisli[Function0, Int, ?]].distributive[Int, Int, Int, Option, Id]) - checkAll("Distributive[Kleisli[Function0, Int, ?]]", - SerializableTests.serializable(Distributive[Kleisli[Function0, Int, ?]])) - } + checkAll("Kleisli[Function0, MiniInt, ?]", + DistributiveTests[Kleisli[Function0, MiniInt, ?]].distributive[Int, Int, Int, Option, Id]) + checkAll("Distributive[Kleisli[Function0, Int, ?]]", + SerializableTests.serializable(Distributive[Kleisli[Function0, Int, ?]])) - { - implicit val catsDataMonoidForKleisli = Kleisli.catsDataMonoidForKleisli[Option, Int, String] - checkAll("Kleisli[Option, Int, String]", MonoidTests[Kleisli[Option, Int, String]].monoid) - checkAll("Monoid[Kleisli[Option, Int, String]]", SerializableTests.serializable(catsDataMonoidForKleisli)) - } + checkAll("Kleisli[Option, MiniInt, String]", MonoidTests[Kleisli[Option, MiniInt, String]].monoid) + checkAll("Monoid[Kleisli[Option, Int, String]]", SerializableTests.serializable(Monoid[Kleisli[Option, Int, String]])) - { - implicit val catsDataSemigroupForKleisli = Kleisli.catsDataSemigroupForKleisli[Option, Int, String] - checkAll("Kleisli[Option, Int, String]", SemigroupTests[Kleisli[Option, Int, String]].semigroup) - checkAll("Semigroup[Kleisli[Option, Int, String]]", SerializableTests.serializable(catsDataSemigroupForKleisli)) - } + checkAll("Kleisli[Option, MiniInt, String]", SemigroupTests[Kleisli[Option, MiniInt, String]].semigroup) + checkAll("Semigroup[Kleisli[Option, Int, String]]", + SerializableTests.serializable(Semigroup[Kleisli[Option, Int, String]])) { implicit val catsDataMonoidKForKleisli = Kleisli.endoMonoidK[Option] - checkAll("Kleisli[Option, Int, Int]", MonoidKTests[λ[α => Kleisli[Option, α, α]]].monoidK[Int]) + checkAll("Kleisli[Option, MiniInt, MiniInt]", MonoidKTests[λ[α => Kleisli[Option, α, α]]].monoidK[MiniInt]) checkAll("MonoidK[λ[α => Kleisli[Option, α, α]]]", SerializableTests.serializable(catsDataMonoidKForKleisli)) } { implicit val catsDataSemigroupKForKleisli = Kleisli.endoSemigroupK[Option] - checkAll("Kleisli[Option, Int, Int]", SemigroupKTests[λ[α => Kleisli[Option, α, α]]].semigroupK[Int]) - checkAll("SemigroupK[λ[α => Kleisli[Option, α, α]]]", SerializableTests.serializable(catsDataSemigroupKForKleisli)) + checkAll("Kleisli[Option, MiniInt, MiniInt]", SemigroupKTests[λ[α => Kleisli[Option, α, α]]].semigroupK[MiniInt]) + checkAll("SemigroupK[λ[α => Kleisli[Option, α, α]]]", + SerializableTests.serializable(SemigroupK[λ[α => Kleisli[Option, α, α]]])) } - { - implicit val semigroupk = Kleisli.catsDataSemigroupKForKleisli[Option, String] - checkAll("Kleisli[Option, String, Int]", SemigroupKTests[Kleisli[Option, String, ?]].semigroupK[Int]) - checkAll("SemigroupK[Kleisli[Option, String, ?]]", SerializableTests.serializable(semigroupk)) - } + checkAll("Kleisli[Option, MiniInt, Int]", SemigroupKTests[Kleisli[Option, MiniInt, ?]].semigroupK[Int]) + checkAll("SemigroupK[Kleisli[Option, String, ?]]", + SerializableTests.serializable(SemigroupK[Kleisli[Option, String, ?]])) - { - implicit val monoidk = Kleisli.catsDataMonoidKForKleisli[Option, String] - checkAll("Kleisli[Option, String, Int]", MonoidKTests[Kleisli[Option, String, ?]].monoidK[Int]) - checkAll("MonoidK[Kleisli[Option, String, ?]]", SerializableTests.serializable(monoidk)) - } + checkAll("Kleisli[Option, MiniInt, ?]", MonoidKTests[Kleisli[Option, MiniInt, ?]].monoidK[Int]) + checkAll("MonoidK[Kleisli[Option, String, ?]]", SerializableTests.serializable(MonoidK[Kleisli[Option, String, ?]])) - checkAll("Reader[Int, Int]", FunctorTests[Reader[Int, ?]].functor[Int, Int, Int]) + checkAll("Reader[MiniInt, Int]", FunctorTests[Reader[MiniInt, ?]].functor[Int, Int, Int]) - checkAll("Kleisli[Option, ?, Int]", ContravariantTests[Kleisli[Option, ?, Int]].contravariant[Int, Int, Int]) + checkAll("Kleisli[Option, ?, Int]", ContravariantTests[Kleisli[Option, ?, Int]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[Kleisli[Option, ?, Int]]", SerializableTests.serializable(Contravariant[Kleisli[Option, ?, Int]])) diff --git a/tests/src/test/scala/cats/tests/MiniIntSuite.scala b/tests/src/test/scala/cats/tests/MiniIntSuite.scala new file mode 100644 index 0000000000..a63d690931 --- /dev/null +++ b/tests/src/test/scala/cats/tests/MiniIntSuite.scala @@ -0,0 +1,48 @@ +package cats +package tests + +import cats.laws.discipline.MiniInt +import MiniInt._ +import cats.laws.discipline.arbitrary._ +import cats.kernel.{BoundedSemilattice, CommutativeGroup, CommutativeMonoid} +import cats.kernel.laws.discipline._ + +import org.scalacheck.Gen + +class MiniIntSuite extends CatsSuite { + checkAll("MiniInt", OrderTests[MiniInt].order) + checkAll("Order[MiniInt]", SerializableTests.serializable(Order[MiniInt])) + + checkAll("MiniInt", HashTests[MiniInt].hash) + checkAll("Hash[MiniInt]", SerializableTests.serializable(Hash[MiniInt])) + + { + implicit val g: CommutativeGroup[MiniInt] = miniIntAddition + checkAll("MiniInt addition", CommutativeGroupTests[MiniInt].commutativeGroup) + checkAll("CommutativeGroup[MiniInt] addition", SerializableTests.serializable(miniIntAddition)) + } + + { + implicit val m: CommutativeMonoid[MiniInt] = miniIntMultiplication + checkAll("MiniInt addition", CommutativeMonoidTests[MiniInt].commutativeMonoid) + checkAll("CommutativeMonoid[MiniInt] multiplication", SerializableTests.serializable(miniIntMultiplication)) + } + + { + implicit val b: BoundedSemilattice[MiniInt] = miniIntOr + checkAll("MiniInt |", BoundedSemilatticeTests[MiniInt].boundedSemilattice) + checkAll("BoundedSemilattice[MiniInt] |", SerializableTests.serializable(miniIntOr)) + } + + test("int roundtrip") { + forAll { i: MiniInt => + MiniInt.fromInt(i.toInt) should ===(Some(i)) + } + } + + test("int bounds") { + forAll(Gen.chooseNum(MiniInt.minIntValue, MiniInt.maxIntValue)) { i: Int => + MiniInt.fromInt(i).map(_.toInt) should ===(Some(i)) + } + } +} diff --git a/tests/src/test/scala/cats/tests/NestedSuite.scala b/tests/src/test/scala/cats/tests/NestedSuite.scala index a35c423072..5864f1e3e1 100644 --- a/tests/src/test/scala/cats/tests/NestedSuite.scala +++ b/tests/src/test/scala/cats/tests/NestedSuite.scala @@ -7,7 +7,7 @@ import cats.data._ import cats.laws.discipline._ import cats.laws.discipline.SemigroupalTests.Isomorphisms._ import cats.laws.discipline.arbitrary._ -import cats.laws.discipline.eq.catsLawsEqForShow +import cats.laws.discipline.eq._ class NestedSuite extends CatsSuite { // we have a lot of generated lists of lists in these tests. We have to tell @@ -59,8 +59,8 @@ class NestedSuite extends CatsSuite { { // Invariant + Contravariant = Invariant val instance = Nested.catsDataInvariantForNestedContravariant(ListWrapper.invariant, Contravariant[Show]) - checkAll("Nested[ListWrapper, Show]", - InvariantTests[Nested[ListWrapper, Show, ?]](instance).invariant[Int, Int, Int]) + checkAll("Nested[ListWrapper, Show, ?]", + InvariantTests[Nested[ListWrapper, Show, ?]](instance).invariant[MiniInt, Int, Boolean]) checkAll("Invariant[Nested[ListWrapper, Show, ?]]", SerializableTests.serializable(instance)) } @@ -74,7 +74,8 @@ class NestedSuite extends CatsSuite { { // Covariant + contravariant functor composition - checkAll("Nested[Option, Show, ?]", ContravariantTests[Nested[Option, Show, ?]].contravariant[Int, Int, Int]) + checkAll("Nested[Option, Show, ?]", + ContravariantTests[Nested[Option, Show, ?]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[Nested[Option, Show, ?]]", SerializableTests.serializable(Contravariant[Nested[Option, Show, ?]])) } @@ -106,7 +107,8 @@ class NestedSuite extends CatsSuite { { // Contravariant + Functor = Contravariant - checkAll("Nested[Show, Option, ?]", ContravariantTests[Nested[Show, Option, ?]].contravariant[Int, Int, Int]) + checkAll("Nested[Show, Option, ?]", + ContravariantTests[Nested[Show, Option, ?]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[Nested[Show, Option, ?]]", SerializableTests.serializable(Contravariant[Nested[Show, Option, ?]])) } @@ -223,8 +225,10 @@ class NestedSuite extends CatsSuite { { import cats.laws.discipline.eq._ //Distributive composition - checkAll("Nested[Function1[Int, ?], Function0, ?]", - DistributiveTests[Nested[Function1[Int, ?], Function0, ?]].distributive[Int, Int, Int, Option, Function0]) + checkAll( + "Nested[Function1[MiniInt, ?], Function0, ?]", + DistributiveTests[Nested[Function1[MiniInt, ?], Function0, ?]].distributive[Int, Int, Int, Option, Function0] + ) checkAll("Distributive[Nested[Function1[Int,?], Function0, ?]]", SerializableTests.serializable(Distributive[Nested[Function1[Int, ?], Function0, ?]])) } diff --git a/tests/src/test/scala/cats/tests/OpSuite.scala b/tests/src/test/scala/cats/tests/OpSuite.scala index 0b2e4ed358..6766ae1911 100644 --- a/tests/src/test/scala/cats/tests/OpSuite.scala +++ b/tests/src/test/scala/cats/tests/OpSuite.scala @@ -10,14 +10,14 @@ import cats.kernel.laws.discipline.EqTests class OpSuite extends CatsSuite { { - implicit val catsKernelEqForOp = Op.catsKernelEqForOp[Function1, Char, Int] - checkAll("Op[Function1, Char, Int]", EqTests[Op[Function1, Char, Int]].eqv) - checkAll("Eq[Op[Function1, Char, Int]]", SerializableTests.serializable(Eq[Op[Function1, Char, Int]])) + implicit val catsKernelEqForOp = Op.catsKernelEqForOp[Function1, Int, MiniInt] + checkAll("Op[Function1, Int, MiniInt]", EqTests[Op[Function1, Int, MiniInt]].eqv) + checkAll("Eq[Op[Function1, Int, MiniInt]]", SerializableTests.serializable(Eq[Op[Function1, Int, MiniInt]])) } { implicit val catsDataCategoryForOp = Op.catsDataCategoryForOp[Function1] - checkAll("Op[Function1, Char, Int]", CategoryTests[Op[Function1, ?, ?]].category[Char, Int, Char, Int]) + checkAll("Op[Function1, ?, ?]", CategoryTests[Op[Function1, ?, ?]].category[Char, MiniInt, Char, Boolean]) checkAll("Category[Op[Function1, ?, ?]]", SerializableTests.serializable(Category[Op[Function1, ?, ?]])) } @@ -28,7 +28,7 @@ class OpSuite extends CatsSuite { // Arr is Function1 Category[Op[Function1, ?, ?]] Compose[Op[Function1, ?, ?]] - Eq[Op[Function1, Char, Int]] + Eq[Op[Function1, Char, MiniInt]] // Arr is Kleisli[Option, ?, ?] Category[Op[Kleisli[Option, ?, ?], ?, ?]] diff --git a/tests/src/test/scala/cats/tests/OptionTSuite.scala b/tests/src/test/scala/cats/tests/OptionTSuite.scala index 6edb9ef5d2..2a4173ad32 100644 --- a/tests/src/test/scala/cats/tests/OptionTSuite.scala +++ b/tests/src/test/scala/cats/tests/OptionTSuite.scala @@ -85,7 +85,7 @@ class OptionTSuite extends CatsSuite { Contravariant[Show] Contravariant[OptionT[Show, ?]] - checkAll("OptionT[Show, ?]", ContravariantTests[OptionT[Show, ?]].contravariant[Int, Int, Int]) + checkAll("OptionT[Show, ?]", ContravariantTests[OptionT[Show, ?]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[OptionT[Show, ?]]", SerializableTests.serializable(Contravariant[OptionT[Show, ?]])) } diff --git a/tests/src/test/scala/cats/tests/OptionWrapper.scala b/tests/src/test/scala/cats/tests/OptionWrapper.scala new file mode 100644 index 0000000000..540890007f --- /dev/null +++ b/tests/src/test/scala/cats/tests/OptionWrapper.scala @@ -0,0 +1,29 @@ +package cats +package tests + +import cats.laws.discipline.ExhaustiveCheck + +import org.scalacheck.{Arbitrary, Cogen}, Arbitrary.arbitrary + +/** + * Similar to [[ListWrapper]], but using `Option` instead of `List` limits the size of the structure, which can be + * useful for limiting the space of test values to generate. + */ +final case class OptionWrapper[A](option: Option[A]) extends AnyVal + +object OptionWrapper { + val functor: Functor[OptionWrapper] = new Functor[OptionWrapper] { + def map[A, B](fa: OptionWrapper[A])(f: A => B) = OptionWrapper(fa.option.map(f)) + } + + implicit def optionWrapperArbitrary[A: Arbitrary]: Arbitrary[OptionWrapper[A]] = + Arbitrary(arbitrary[Option[A]].map(OptionWrapper.apply)) + + implicit def optionWrapperCogen[A: Cogen]: Cogen[OptionWrapper[A]] = + Cogen[Option[A]].contramap(_.option) + + implicit def catsLawsExhaustiveCheckForOptionWrapper[A]( + implicit A: ExhaustiveCheck[A] + ): ExhaustiveCheck[OptionWrapper[A]] = + ExhaustiveCheck.instance(ExhaustiveCheck[Option[A]].allValues.map(OptionWrapper(_))) +} diff --git a/tests/src/test/scala/cats/tests/OrderSuite.scala b/tests/src/test/scala/cats/tests/OrderSuite.scala index 44f4e3c925..7da7b97024 100644 --- a/tests/src/test/scala/cats/tests/OrderSuite.scala +++ b/tests/src/test/scala/cats/tests/OrderSuite.scala @@ -3,7 +3,7 @@ package tests import Helpers.Ord import cats.kernel.laws.discipline.{OrderTests, SerializableTests} -import cats.laws.discipline.ContravariantMonoidalTests +import cats.laws.discipline.{ContravariantMonoidalTests, MiniInt} import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ @@ -19,7 +19,7 @@ class OrderSuite extends CatsSuite { checkAll("Float", OrderTests[Float].order) checkAll("Long", OrderTests[Long].order) - checkAll("Order", ContravariantMonoidalTests[Order].contravariantMonoidal[Int, Int, Int]) + checkAll("Order", ContravariantMonoidalTests[Order].contravariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("ContravariantMonoidal[Order]", SerializableTests.serializable(ContravariantMonoidal[Order])) test("order ops syntax") { diff --git a/tests/src/test/scala/cats/tests/OrderingSuite.scala b/tests/src/test/scala/cats/tests/OrderingSuite.scala index 1996e01b64..5298040f80 100644 --- a/tests/src/test/scala/cats/tests/OrderingSuite.scala +++ b/tests/src/test/scala/cats/tests/OrderingSuite.scala @@ -13,8 +13,9 @@ class OrderingSuite extends CatsSuite { ContravariantSemigroupal[Ordering] ContravariantMonoidal[Ordering] - checkAll("Contravariant[Ordering]", ContravariantTests[Ordering].contravariant[Int, Int, Int]) - checkAll("Semigroupal[Ordering]", SemigroupalTests[Ordering].semigroupal[Int, Int, Int]) - checkAll("ContravariantMonoidal[Ordering]", ContravariantMonoidalTests[Ordering].contravariantMonoidal[Int, Int, Int]) + checkAll("Contravariant[Ordering]", ContravariantTests[Ordering].contravariant[MiniInt, Int, Boolean]) + checkAll("Semigroupal[Ordering]", SemigroupalTests[Ordering].semigroupal[MiniInt, Boolean, Boolean]) + checkAll("ContravariantMonoidal[Ordering]", + ContravariantMonoidalTests[Ordering].contravariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("ContravariantMonoidal[Ordering]", SerializableTests.serializable(ContravariantMonoidal[Ordering])) } diff --git a/tests/src/test/scala/cats/tests/ParallelSuite.scala b/tests/src/test/scala/cats/tests/ParallelSuite.scala index f99728ac68..bdb7a8593e 100644 --- a/tests/src/test/scala/cats/tests/ParallelSuite.scala +++ b/tests/src/test/scala/cats/tests/ParallelSuite.scala @@ -6,10 +6,9 @@ import cats.data.NonEmptyList.ZipNonEmptyList import cats.data.NonEmptyVector.ZipNonEmptyVector import cats.data._ import org.scalatest.FunSuite -import cats.laws.discipline.{ApplicativeErrorTests, NonEmptyParallelTests, ParallelTests, SerializableTests} +import cats.laws.discipline.{ApplicativeErrorTests, MiniInt, NonEmptyParallelTests, ParallelTests, SerializableTests} import cats.laws.discipline.eq._ import cats.laws.discipline.arbitrary._ -import org.scalacheck.Arbitrary import org.typelevel.discipline.scalatest.Discipline import scala.collection.immutable.SortedSet @@ -353,12 +352,13 @@ class ParallelSuite extends CatsSuite with ApplicativeErrorForEitherTest { SerializableTests.serializable(Parallel[Either[String, ?], Validated[String, ?]])) { - implicit def kleisliEq[F[_], A, B](implicit A: Arbitrary[A], FB: Eq[F[B]]): Eq[Kleisli[F, A, B]] = + implicit def kleisliEq[F[_], A, B](implicit ev: Eq[A => F[B]]): Eq[Kleisli[F, A, B]] = Eq.by[Kleisli[F, A, B], A => F[B]](_.run) checkAll( - "Parallel[KlesliT[M, ?], Nested[F, Option, ?]]", - ParallelTests[Kleisli[Either[String, ?], Int, ?], Kleisli[Validated[String, ?], Int, ?]].parallel[Int, String] + "Parallel[KlesliT[M, A, ?], Kleisli[F, A, ?]]", + ParallelTests[Kleisli[Either[String, ?], MiniInt, ?], Kleisli[Validated[String, ?], MiniInt, ?]] + .parallel[Int, String] ) } diff --git a/tests/src/test/scala/cats/tests/PartialOrderSuite.scala b/tests/src/test/scala/cats/tests/PartialOrderSuite.scala index a2b5fdf730..4b8d8e4359 100644 --- a/tests/src/test/scala/cats/tests/PartialOrderSuite.scala +++ b/tests/src/test/scala/cats/tests/PartialOrderSuite.scala @@ -3,7 +3,7 @@ package tests import Helpers.POrd import cats.kernel.laws.discipline.SerializableTests -import cats.laws.discipline.ContravariantMonoidalTests +import cats.laws.discipline.{ContravariantMonoidalTests, MiniInt} import org.scalatest.Assertion import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ @@ -22,7 +22,7 @@ class PartialOrderSuite extends CatsSuite { Contravariant[PartialOrder] } - checkAll("PartialOrder[Int]", ContravariantMonoidalTests[PartialOrder].contravariantMonoidal[Int, Int, Int]) + checkAll("PartialOrder", ContravariantMonoidalTests[PartialOrder].contravariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("ContravariantMonoidal[PartialOrder]", SerializableTests.serializable(ContravariantMonoidal[PartialOrder])) test("companion object syntax") { diff --git a/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala b/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala index 631f297537..fa5f3a9991 100644 --- a/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala +++ b/tests/src/test/scala/cats/tests/PartialOrderingSuite.scala @@ -12,11 +12,12 @@ class PartialOrderingSuite extends CatsSuite { Semigroupal[PartialOrdering] ContravariantSemigroupal[PartialOrdering] - checkAll("Contravariant[PartialOrdering]", ContravariantTests[PartialOrdering].contravariant[Int, Int, Int]) - checkAll("Semigroupal[PartialOrdering]", SemigroupalTests[PartialOrdering].semigroupal[Int, Int, Int]) + checkAll("Contravariant[PartialOrdering]", ContravariantTests[PartialOrdering].contravariant[MiniInt, Int, Boolean]) + checkAll("Semigroupal[PartialOrdering]", SemigroupalTests[PartialOrdering].semigroupal[MiniInt, Boolean, Boolean]) checkAll("Contravariant[PartialOrdering]", SerializableTests.serializable(Contravariant[PartialOrdering])) - checkAll("PartialOrdering[Int]", ContravariantMonoidalTests[PartialOrdering].contravariantMonoidal[Int, Int, Int]) + checkAll("PartialOrdering[Int]", + ContravariantMonoidalTests[PartialOrdering].contravariantMonoidal[MiniInt, Boolean, Boolean]) checkAll("ContravariantMonoidal[PartialOrdering]", SerializableTests.serializable(ContravariantMonoidal[PartialOrdering])) } diff --git a/tests/src/test/scala/cats/tests/RepresentableSuite.scala b/tests/src/test/scala/cats/tests/RepresentableSuite.scala index c29196f13b..c114c2e006 100644 --- a/tests/src/test/scala/cats/tests/RepresentableSuite.scala +++ b/tests/src/test/scala/cats/tests/RepresentableSuite.scala @@ -3,7 +3,7 @@ package cats.tests import cats.laws.discipline.SemigroupalTests.Isomorphisms import cats.laws.discipline.arbitrary._ import cats.laws.discipline.eq._ -import cats.laws.discipline.{BimonadTests, MonadTests, RepresentableTests, SerializableTests} +import cats.laws.discipline.{BimonadTests, MiniInt, MonadTests, RepresentableTests, SerializableTests} import cats.{Bimonad, Eq, Eval, Id, Representable} import org.scalacheck.Arbitrary import cats.data.Kleisli @@ -15,7 +15,7 @@ class RepresentableSuite extends CatsSuite { checkAll("Id[String] <-> Unit => String", RepresentableTests[Id, Unit].representable[String]) checkAll("Representable[Id]", SerializableTests.serializable(Representable[Id])) - checkAll("String => Int <-> String => Int", RepresentableTests[String => ?, String].representable[Int]) + checkAll("MiniInt => Int <-> MiniInt => Int", RepresentableTests[MiniInt => ?, MiniInt].representable[Int]) checkAll("Representable[String => ?]", SerializableTests.serializable(Representable[String => ?])) checkAll("Pair[String, String] <-> Boolean => String", RepresentableTests[Pair, Boolean].representable[String]) @@ -25,26 +25,26 @@ class RepresentableSuite extends CatsSuite { checkAll("Representable[Eval]", SerializableTests.serializable(Representable[Eval])) { - implicit val representableKleisliPair = Kleisli.catsDataRepresentableForKleisli[Pair, Boolean, String] + implicit val representableKleisliPair = Kleisli.catsDataRepresentableForKleisli[Pair, Boolean, MiniInt] - implicit def kleisliEq[F[_], A, B](implicit A: Arbitrary[A], FB: Eq[F[B]]): Eq[Kleisli[F, A, B]] = + implicit def kleisliEq[F[_], A, B](implicit ev: Eq[A => F[B]]): Eq[Kleisli[F, A, B]] = Eq.by[Kleisli[F, A, B], A => F[B]](_.run) checkAll( - "Kleisli[Pair, String, Int] <-> (String, Boolean) => Int", + "Kleisli[Pair, MiniInt, Int] <-> (MiniInt, Boolean) => Int", // Have to summon all implicits using 'implicitly' otherwise we get a diverging implicits error - RepresentableTests[Kleisli[Pair, String, ?], (String, Boolean)].representable[Int]( + RepresentableTests[Kleisli[Pair, MiniInt, ?], (MiniInt, Boolean)].representable[Int]( implicitly[Arbitrary[Int]], - implicitly[Arbitrary[Kleisli[Pair, String, Int]]], - implicitly[Arbitrary[(String, Boolean)]], - implicitly[Arbitrary[((String, Boolean)) => Int]], - implicitly[Eq[Kleisli[Pair, String, Int]]], + implicitly[Arbitrary[Kleisli[Pair, MiniInt, Int]]], + implicitly[Arbitrary[(MiniInt, Boolean)]], + implicitly[Arbitrary[((MiniInt, Boolean)) => Int]], + implicitly[Eq[Kleisli[Pair, MiniInt, Int]]], implicitly[Eq[Int]] ) ) - checkAll("Representable[Kleisli[Pair, String, ?]]", - SerializableTests.serializable(Representable[Kleisli[Pair, String, ?]])) + checkAll("Representable[Kleisli[Pair, MiniInt, ?]]", + SerializableTests.serializable(Representable[Kleisli[Pair, MiniInt, ?]])) } { @@ -61,11 +61,11 @@ class RepresentableSuite extends CatsSuite { { //the monadInstance below made a conflict to resolve this one. - implicit val isoFun1: Isomorphisms[String => ?] = Isomorphisms.invariant[String => ?] - - implicit val monadInstance = Representable.monad[String => ?] - checkAll("String => ?", MonadTests[String => ?].monad[String, String, String]) + // TODO ceedubs is this needed? + implicit val isoFun1: Isomorphisms[MiniInt => ?] = Isomorphisms.invariant[MiniInt => ?] + implicit val monadInstance = Representable.monad[MiniInt => ?] + checkAll("MiniInt => ?", MonadTests[MiniInt => ?].monad[String, String, String]) } // Syntax tests. If it compiles is "passes" diff --git a/tests/src/test/scala/cats/tests/ShowSuite.scala b/tests/src/test/scala/cats/tests/ShowSuite.scala index 0f70850121..347d519db4 100644 --- a/tests/src/test/scala/cats/tests/ShowSuite.scala +++ b/tests/src/test/scala/cats/tests/ShowSuite.scala @@ -5,14 +5,14 @@ import java.util.concurrent.TimeUnit import cats.Show.ContravariantShow import cats.laws.discipline.arbitrary._ -import cats.laws.discipline.{ContravariantTests, SerializableTests} +import cats.laws.discipline.{ContravariantTests, MiniInt, SerializableTests} import cats.laws.discipline.eq._ import org.scalatest.FunSuite import scala.concurrent.duration.{Duration, FiniteDuration} class ShowSuite extends CatsSuite { - checkAll("Contravariant[Show]", ContravariantTests[Show].contravariant[Int, Int, Int]) + checkAll("Contravariant[Show]", ContravariantTests[Show].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[Show]", SerializableTests.serializable(Contravariant[Show])) sealed trait TimeOfDay diff --git a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala index bf9e7be506..64b9f02a54 100644 --- a/tests/src/test/scala/cats/tests/Tuple2KSuite.scala +++ b/tests/src/test/scala/cats/tests/Tuple2KSuite.scala @@ -19,8 +19,8 @@ class Tuple2KSuite extends CatsSuite { checkAll("Alternative[Tuple2K[Option, List, Int]]", SerializableTests.serializable(Alternative[λ[α => Tuple2K[Option, List, α]]])) - checkAll("Tuple2K[Show, Order, Int]", - ContravariantTests[λ[α => Tuple2K[Show, Order, α]]].contravariant[Int, Int, Int]) + checkAll("Tuple2K[Show, Order, MiniInt]", + ContravariantTests[λ[α => Tuple2K[Show, Order, α]]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[Tuple2K[Show, Order, Int]]", SerializableTests.serializable(Contravariant[λ[α => Tuple2K[Show, Order, α]]])) diff --git a/tests/src/test/scala/cats/tests/WriterTSuite.scala b/tests/src/test/scala/cats/tests/WriterTSuite.scala index 2862c193a4..e739b82f41 100644 --- a/tests/src/test/scala/cats/tests/WriterTSuite.scala +++ b/tests/src/test/scala/cats/tests/WriterTSuite.scala @@ -21,7 +21,8 @@ class WriterTSuite extends CatsSuite { checkAll("WriterT[List, Int, Int]", EqTests[WriterT[List, Int, Int]].eqv) checkAll("Eq[WriterT[List, Int, Int]]", SerializableTests.serializable(Eq[WriterT[List, Int, Int]])) - checkAll("WriterT[Show, Int, Int]", ContravariantTests[WriterT[Show, Int, ?]].contravariant[Int, Int, Int]) + checkAll("WriterT[Show, MiniInt, ?]", + ContravariantTests[WriterT[Show, MiniInt, ?]].contravariant[MiniInt, Int, Boolean]) checkAll("Contravariant[WriterT[Show, Int, Int]]", SerializableTests.serializable(Contravariant[WriterT[Show, Int, ?]]))