diff --git a/core/src/test/scala-3/cats/derived/ContravariantSuite.scala b/core/src/test/scala-3/cats/derived/ContravariantSuite.scala index bab1bac8..bcf5084c 100644 --- a/core/src/test/scala-3/cats/derived/ContravariantSuite.scala +++ b/core/src/test/scala-3/cats/derived/ContravariantSuite.scala @@ -50,6 +50,10 @@ class ContravariantSuite extends KittensSuite: s"$context.Contravariant[ListSnocF]", contravariantTests[ListSnocF].contravariant[MiniInt, String, Boolean] ) + checkAll( + s"$context.Contravariant[EnumK1Contra]", + contravariantTests[EnumK1Contra].contravariant[MiniInt, String, Boolean] + ) checkAll( s"$context.Contravariant is Serializable", SerializableTests.serializable(summonInline[Contravariant[TreePred]]) @@ -96,6 +100,7 @@ object ContravariantSuite: // given Contravariant[InterleavedPred] = semiauto.contravariant given Contravariant[AndCharPred] = semiauto.contravariant given Contravariant[ListSnocF] = semiauto.contravariant + given Contravariant[EnumK1Contra] = semiauto.contravariant case class Single[A](value: A => Unit) derives Contravariant diff --git a/core/src/test/scala-3/cats/derived/FoldableSuite.scala b/core/src/test/scala-3/cats/derived/FoldableSuite.scala index ff03f9af..0b748f3a 100644 --- a/core/src/test/scala-3/cats/derived/FoldableSuite.scala +++ b/core/src/test/scala-3/cats/derived/FoldableSuite.scala @@ -38,6 +38,7 @@ class FoldableSuite extends KittensSuite: checkAll(s"$context.Foldable[AndChar]", foldableTests[AndChar].foldable[Int, Long]) checkAll(s"$context.Foldable[Interleaved]", foldableTests[Interleaved].foldable[Int, Long]) checkAll(s"$context.Foldable[BoxNel]", foldableTests[BoxNel].foldable[Int, Long]) + checkAll(s"$context.Foldable[EnumK1]", foldableTests[EnumK1].foldable[Int, Long]) checkAll(s"$context.Foldable is Serializable", SerializableTests.serializable(summonInline[Foldable[Tree]])) locally { @@ -69,6 +70,7 @@ object FoldableSuite: given Foldable[AndChar] = semiauto.foldable given Foldable[Interleaved] = semiauto.foldable given Foldable[BoxNel] = semiauto.foldable + given Foldable[EnumK1] = semiauto.foldable final case class Nel[+A](head: A, tail: List[A]) object Nel: diff --git a/core/src/test/scala-3/cats/derived/FunctorSuite.scala b/core/src/test/scala-3/cats/derived/FunctorSuite.scala index 952d96f6..c4d64abe 100644 --- a/core/src/test/scala-3/cats/derived/FunctorSuite.scala +++ b/core/src/test/scala-3/cats/derived/FunctorSuite.scala @@ -40,6 +40,7 @@ class FunctorSuite extends KittensSuite: checkAll(s"$context.Functor[AndChar]", functorTests[AndChar].functor[Int, String, Long]) checkAll(s"$context.Functor[Interleaved]", functorTests[Interleaved].functor[Int, String, Long]) checkAll(s"$context.Functor[NestedPred]", functorTests[NestedPred].functor[Boolean, Int, Boolean]) + checkAll(s"$context.Functor[EnumK1]", functorTests[EnumK1].functor[Boolean, Int, Boolean]) checkAll(s"$context.Functor is Serializable", SerializableTests.serializable(summonInline[Functor[Tree]])) locally { @@ -72,6 +73,7 @@ object FunctorSuite: given Functor[AndChar] = semiauto.functor given Functor[Interleaved] = semiauto.functor given Functor[NestedPred] = semiauto.functor + given Functor[EnumK1] = semiauto.functor case class Single[A](value: A) derives Functor diff --git a/core/src/test/scala-3/cats/derived/HashSuite.scala b/core/src/test/scala-3/cats/derived/HashSuite.scala index 7c9ca162..d222fbb7 100644 --- a/core/src/test/scala-3/cats/derived/HashSuite.scala +++ b/core/src/test/scala-3/cats/derived/HashSuite.scala @@ -21,6 +21,7 @@ class HashSuite extends KittensSuite: // checkAll(s"$context.Hash[Interleaved[Int]]", hashTests[Interleaved[Int]].hash) checkAll(s"$context.Hash[Tree[Int]]", hashTests[Tree[Int]].hash) checkAll(s"$context.Hash[Recursive]", hashTests[Recursive].hash) + checkAll(s"$context.Hash[EnumK0]", hashTests[EnumK0].hash) checkAll(s"$context.Hash is Serializable", SerializableTests.serializable(summonInline[Hash[Inner]])) locally { @@ -45,5 +46,6 @@ object HashSuite: given Hash[Interleaved[Int]] = semiauto.hash given Hash[Tree[Int]] = semiauto.hash given Hash[Recursive] = semiauto.hash + given Hash[EnumK0] = semiauto.hash end HashSuite diff --git a/core/src/test/scala-3/cats/derived/InvariantSuite.scala b/core/src/test/scala-3/cats/derived/InvariantSuite.scala index 7b932269..5a99b794 100644 --- a/core/src/test/scala-3/cats/derived/InvariantSuite.scala +++ b/core/src/test/scala-3/cats/derived/InvariantSuite.scala @@ -39,6 +39,7 @@ class InvariantSuite extends KittensSuite: checkAll(s"$context.Invariant[AndCharF]", invariantTests[AndCharF].invariant[MiniInt, String, Boolean]) checkAll(s"$context.Invariant[ListSnoc", invariantTests[ListSnoc].invariant[MiniInt, String, Boolean]) checkAll(s"$context.Invariant[Bivariant]", invariantTests[Bivariant].invariant[MiniInt, String, Boolean]) + checkAll(s"$context.Invariant[EnumK1Inv]", invariantTests[EnumK1Inv].invariant[MiniInt, String, Boolean]) checkAll(s"$context.Invariant is Serializable", SerializableTests.serializable(summonInline[Invariant[TreeF]])) // TODO /~https://github.com/typelevel/kittens/issues/476 @@ -88,6 +89,7 @@ object InvariantSuite: given Invariant[ListSnoc] = semiauto.invariant given Invariant[Bivariant] = semiauto.invariant given Invariant[IList] = semiauto.invariant + given Invariant[EnumK1Inv] = semiauto.invariant case class Single[A](value: A) derives Invariant diff --git a/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala b/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala index 845fd965..b8a37cf4 100644 --- a/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala +++ b/core/src/test/scala-3/cats/derived/NonEmptyTraverseSuite.scala @@ -57,6 +57,10 @@ class NonEmptyTraverseSuite extends KittensSuite: s"$context.NonEmptyTraverse[Interleaved]", nonEmptyTraverseTests[Interleaved].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option] ) + checkAll( + s"$context.NonEmptyTraverse[EnumK1]", + nonEmptyTraverseTests[EnumK1].nonEmptyTraverse[Option, Int, Int, Int, Int, Option, Option] + ) checkAll( s"$context.NonEmptyTraverse is Serializable", SerializableTests.serializable(summonInline[NonEmptyTraverse[Tree]]) @@ -88,5 +92,6 @@ object NonEmptyTraverseSuite: given NonEmptyTraverse[NelAndOne] = semiauto.nonEmptyTraverse given NonEmptyTraverse[VecAndNel] = semiauto.nonEmptyTraverse given NonEmptyTraverse[Interleaved] = semiauto.nonEmptyTraverse + given NonEmptyTraverse[EnumK1] = semiauto.nonEmptyTraverse end NonEmptyTraverseSuite diff --git a/core/src/test/scala-3/cats/derived/OrderSuite.scala b/core/src/test/scala-3/cats/derived/OrderSuite.scala index 39dee289..e0b7c031 100644 --- a/core/src/test/scala-3/cats/derived/OrderSuite.scala +++ b/core/src/test/scala-3/cats/derived/OrderSuite.scala @@ -34,6 +34,7 @@ class OrderSuite extends KittensSuite { checkAll(s"$context.Order[Interleaved[Int]]", orderTests[Interleaved[Int]].order) checkAll(s"$context.Order[Recursive]", orderTests[Recursive].order) checkAll(s"$context.Order[GenericAdt[Int]]", orderTests[GenericAdt[Int]].order) + checkAll(s"$context.Order[EnumK0]", orderTests[EnumK0].order) checkAll(s"$context.Order is Serializable", SerializableTests.serializable(summonInline[Order[Interleaved[Int]]])) } @@ -57,5 +58,6 @@ object OrderSuite { given Order[Interleaved[Int]] = semiauto.order given Order[Recursive] = semiauto.order given Order[GenericAdt[Int]] = semiauto.order + given Order[EnumK0] = semiauto.order } } diff --git a/core/src/test/scala-3/cats/derived/PartialOrderSuite.scala b/core/src/test/scala-3/cats/derived/PartialOrderSuite.scala index 4b05dc28..af35587b 100644 --- a/core/src/test/scala-3/cats/derived/PartialOrderSuite.scala +++ b/core/src/test/scala-3/cats/derived/PartialOrderSuite.scala @@ -36,6 +36,7 @@ class PartialOrderSuite extends KittensSuite: checkAll(s"$context.PartialOrder[Tree[Int]]", partialOrderTests[Tree[Int]].partialOrder) checkAll(s"$context.PartialOrder[Recursive]", partialOrderTests[Recursive].partialOrder) checkAll(s"$context.PartialOrder[Box[KeyValue]]", partialOrderTests[Box[KeyValue]].partialOrder) + checkAll(s"$context.PartialOrder[EnumK0]", partialOrderTests[EnumK0].partialOrder) checkAll( s"$context.PartialOrder is Serialiable", SerializableTests.serializable(summonInline[PartialOrder[Tree[Int]]]) @@ -73,6 +74,7 @@ object PartialOrderSuite: given PartialOrder[Tree[Int]] = semiauto.partialOrder given PartialOrder[Recursive] = semiauto.partialOrder given PartialOrder[Box[KeyValue]] = semiauto.partialOrder + given PartialOrder[EnumK0] = semiauto.partialOrder final case class KeyValue(key: String, value: Int) object KeyValue extends ((String, Int) => KeyValue): diff --git a/core/src/test/scala-3/cats/derived/ReducibleSuite.scala b/core/src/test/scala-3/cats/derived/ReducibleSuite.scala index c61cc50c..b3b6f8cf 100644 --- a/core/src/test/scala-3/cats/derived/ReducibleSuite.scala +++ b/core/src/test/scala-3/cats/derived/ReducibleSuite.scala @@ -39,6 +39,7 @@ class ReducibleSuite extends KittensSuite: checkAll(s"$context.Reducible[VecAndNel]", reducibleTests[VecAndNel].reducible[Option, Int, Long]) checkAll(s"$context.Reducible[Interleaved]", reducibleTests[Interleaved].reducible[Option, Int, Long]) checkAll(s"$context.Reducible[BoxZipper]", reducibleTests[BoxZipper].reducible[Option, Int, Long]) + checkAll(s"$context.Reducible[EnumK1]", reducibleTests[EnumK1].reducible[Option, Int, Long]) checkAll(s"$context.Reducible is Serializable", SerializableTests.serializable(summonInline[Reducible[Tree]])) locally { @@ -69,6 +70,7 @@ object ReducibleSuite: given Reducible[VecAndNel] = semiauto.reducible given Reducible[Interleaved] = semiauto.reducible given Reducible[BoxZipper] = semiauto.reducible + given Reducible[EnumK1] = semiauto.reducible final case class Zipper[+A](left: List[A], focus: A, right: List[A]) object Zipper: diff --git a/core/src/test/scala-3/cats/derived/ShowSuite.scala b/core/src/test/scala-3/cats/derived/ShowSuite.scala index 8a624d71..10ba0d53 100644 --- a/core/src/test/scala-3/cats/derived/ShowSuite.scala +++ b/core/src/test/scala-3/cats/derived/ShowSuite.scala @@ -66,6 +66,13 @@ class ShowSuite extends KittensSuite: assertEquals(show(value), shown) } + test(s"$context.Show[EnumK0]") { + val value: EnumK0 = EnumK0.LeafI(3) + val shown = + "LeafI(value = 3)" + assertEquals(show(value), shown) + } + test(s"$context.Show respects existing instances") { val value = Box(Bogus(42)) val shown = "Box(content = Blah)" @@ -108,5 +115,6 @@ object ShowSuite: given Show[Interleaved[Int]] = semiauto.show given Show[Tree[Int]] = semiauto.show given Show[Box[Bogus]] = semiauto.show + given Show[EnumK0] = semiauto.show end ShowSuite diff --git a/core/src/test/scala-3/cats/derived/TraverseSuite.scala b/core/src/test/scala-3/cats/derived/TraverseSuite.scala index 3f0e4171..27e66c96 100644 --- a/core/src/test/scala-3/cats/derived/TraverseSuite.scala +++ b/core/src/test/scala-3/cats/derived/TraverseSuite.scala @@ -30,6 +30,10 @@ class TraverseSuite extends KittensSuite: s"$context.Traverse[Interleaved]", traverseTests[Interleaved].traverse[Int, Double, String, Long, Option, Option] ) + checkAll( + s"$context.Traverse[EnumK1]", + traverseTests[EnumK1].traverse[Int, Double, String, Long, Option, Option] + ) checkAll(s"$context.Traverse is Serializable", SerializableTests.serializable(summonInline[Traverse[Tree]])) locally { @@ -59,5 +63,6 @@ object TraverseSuite: given Traverse[ListSnoc] = semiauto.traverse given Traverse[AndChar] = semiauto.traverse given Traverse[Interleaved] = semiauto.traverse + given Traverse[EnumK1] = semiauto.traverse end TraverseSuite diff --git a/core/src/test/scala-3/cats/derived/adtdefns.scala b/core/src/test/scala-3/cats/derived/adtdefns.scala index 215e6146..5de94a4d 100644 --- a/core/src/test/scala-3/cats/derived/adtdefns.scala +++ b/core/src/test/scala-3/cats/derived/adtdefns.scala @@ -25,6 +25,102 @@ import scala.annotation.tailrec object TestDefns: + enum EnumK0: + case LeafS(value: String) + case LeafI(value: Int) + + object EnumK0: + given Arbitrary[EnumK0] = Arbitrary( + Gen.oneOf( + Arbitrary.arbitrary[String].map(LeafS.apply), + Arbitrary.arbitrary[Int].map(LeafI.apply) + ) + ) + + given Cogen[EnumK0] = Cogen[Either[String, Int]].contramap { + case LeafS(s) => Left(s) + case LeafI(i) => Right(i) + } + + enum EnumK1[A]: + case Leaf(value: A) + case Rec(l: EnumK1[A], r: EnumK1[A]) + + object EnumK1: + given [A](using Arbitrary[A]): Arbitrary[EnumK1[A]] = Arbitrary( + Gen.recursive(rec => + Gen.sized(size => + val leaf = Arbitrary.arbitrary[A].map(Leaf.apply) + if size == 0 then leaf + else + Gen.resize( + size / 2, + Gen.oneOf( + leaf, + for + l <- rec + r <- rec + yield Rec(l, r) + ) + ) + ) + ) + ) + + enum EnumK1Contra[-A]: + case Leaf(value: A => Unit) + case Rec(l: EnumK1Contra[A], r: EnumK1Contra[A]) + + object EnumK1Contra: + given [A](using Arbitrary[A => Unit]): Arbitrary[EnumK1Contra[A]] = Arbitrary( + Gen.recursive(rec => + Gen.sized(size => + val leaf = Arbitrary.arbitrary[A => Unit].map(Leaf.apply) + if size == 0 then leaf + else + Gen.resize( + size / 2, + Gen.oneOf( + leaf, + for + l <- rec + r <- rec + yield Rec(l, r) + ) + ) + ) + ) + ) + + enum EnumK1Inv[A]: + case Leaf(cov: A, contra: A => Unit) + case Rec(l: EnumK1Inv[A], r: EnumK1Inv[A]) + + object EnumK1Inv: + given [A](using Arbitrary[A], Arbitrary[A => Unit]): Arbitrary[EnumK1Inv[A]] = Arbitrary( + Gen.recursive(rec => + Gen.sized(size => + val leaf = + for + cov <- Arbitrary.arbitrary[A] + contra <- Arbitrary.arbitrary[A => Unit] + yield Leaf(cov, contra) + if size == 0 then leaf + else + Gen.resize( + size / 2, + Gen.oneOf( + leaf, + for + l <- rec + r <- rec + yield Rec(l, r) + ) + ) + ) + ) + ) + sealed trait Rgb object Rgb: case object Red extends Rgb @@ -430,4 +526,36 @@ trait TestEqInstances: given Eq[Outer] = Eq.fromUniversalEquals + given Eq[EnumK0] = + import EnumK0.* + Eq.instance { + case (LeafS(s1), LeafS(s2)) => s1 === s2 + case (LeafI(i1), LeafI(i2)) => i1 === i2 + case _ => false + } + + given [A](using Eq[A]): Eq[EnumK1[A]] = + import EnumK1.* + Eq.instance { + case (Leaf(v1), Leaf(v2)) => v1 === v2 + case (Rec(l1, r1), Rec(l2, r2)) => l1 === l2 && r1 === r2 + case _ => false + } + + given [A](using Eq[A => Unit]): Eq[EnumK1Contra[A]] = + import EnumK1Contra.* + Eq.instance { + case (Leaf(v1), Leaf(v2)) => v1 === v2 + case (Rec(l1, r1), Rec(l2, r2)) => l1 === l2 && r1 === r2 + case _ => false + } + + given [A](using Eq[A], Eq[A => Unit]): Eq[EnumK1Inv[A]] = + import EnumK1Inv.* + Eq.instance { + case (Leaf(cov1, contra1), Leaf(cov2, contra2)) => cov1 === cov2 && contra1 === contra2 + case (Rec(l1, r1), Rec(l2, r2)) => l1 === l2 && r1 === r2 + case _ => false + } + end TestEqInstances