diff --git a/tests/shared/src/test/scala/cats/effect/std/DequeueLawsSpec.scala b/tests/shared/src/test/scala/cats/effect/std/DequeueLawsSpec.scala new file mode 100644 index 0000000000..f0769dfb63 --- /dev/null +++ b/tests/shared/src/test/scala/cats/effect/std/DequeueLawsSpec.scala @@ -0,0 +1,68 @@ +package cats.effect +package std + +import cats.Eq +import cats.effect._ +import cats.effect.kernel.Outcome +import cats.laws.discipline.{FunctorTests, InvariantTests} +import cats.syntax.all._ + +import org.scalacheck.{Arbitrary, Gen} +import org.typelevel.discipline.specs2.mutable.Discipline + +class DequeueLawsSpec extends BaseSpec with Discipline { + + sequential + + def toList[A](q: Dequeue[IO, A]): IO[List[A]] = + for { + size <- q.size + list <- q.tryTakeN(size.some) + } yield list + + def fromList[A: Arbitrary](as: List[A]): IO[Dequeue[IO, A]] = { + for { + queue <- Dequeue.bounded[IO, A](Int.MaxValue) + _ <- as.traverse(a => queue.offer(a)) + } yield queue + } + + def genDequeue[A: Arbitrary](implicit ticker: Ticker): Gen[Dequeue[IO, A]] = + for { + list <- Arbitrary.arbitrary[List[A]] + queue = fromList(list) + outcome = unsafeRun(queue) match { + case Outcome.Succeeded(a) => a + case _ => None + } + } yield outcome.get + + def toListSource[A](q: DequeueSource[IO, A]): IO[List[A]] = + for { + size <- q.size + list <- q.tryTakeN(size.some) + } yield list + + implicit def eqForDequeueSource[A: Eq](implicit ticker: Ticker): Eq[DequeueSource[IO, A]] = + Eq.by(toListSource) + + implicit def arbDequeueSource[A: Arbitrary]( + implicit ticker: Ticker): Arbitrary[DequeueSource[IO, A]] = + Arbitrary(genDequeue) + + { + implicit val ticker = Ticker() + checkAll("DequeueFunctorLaws", FunctorTests[DequeueSource[IO, *]].functor[Int, Int, String]) + } + + implicit def eqForDequeue[A: Eq](implicit ticker: Ticker): Eq[Dequeue[IO, A]] = + Eq.by(toList) + + implicit def arbDequeue[A: Arbitrary](implicit ticker: Ticker): Arbitrary[Dequeue[IO, A]] = + Arbitrary(genDequeue) + + { + implicit val ticker = Ticker() + checkAll("DequeueInvariantLaws", InvariantTests[Dequeue[IO, *]].invariant[Int, Int, String]) + } +} diff --git a/tests/shared/src/test/scala/cats/effect/std/PQueueLawsSpec.scala b/tests/shared/src/test/scala/cats/effect/std/PQueueLawsSpec.scala new file mode 100644 index 0000000000..925e062353 --- /dev/null +++ b/tests/shared/src/test/scala/cats/effect/std/PQueueLawsSpec.scala @@ -0,0 +1,71 @@ +package cats.effect +package std + +import cats.{Eq, Order} +import cats.effect._ +import cats.effect.kernel.Outcome +import cats.laws.discipline.{FunctorTests, InvariantTests} +import cats.syntax.all._ + +import org.scalacheck.{Arbitrary, Gen} +import org.typelevel.discipline.specs2.mutable.Discipline + +class PQueueLawsSpec extends BaseSpec with Discipline { + + sequential + + def toList[A](q: PQueue[IO, A]): IO[List[A]] = + for { + size <- q.size + list <- q.tryTakeN(size.some) + } yield list + + def fromList[A: Arbitrary](as: List[A])(implicit ord: Order[A]): IO[PQueue[IO, A]] = { + for { + queue <- PQueue.bounded[IO, A](Int.MaxValue) + _ <- as.traverse(a => queue.offer(a)) + } yield queue + } + + def genPQueue[A: Arbitrary](implicit ticker: Ticker, ord: Order[A]): Gen[PQueue[IO, A]] = + for { + list <- Arbitrary.arbitrary[List[A]] + queue = fromList(list) + outcome = unsafeRun(queue) match { + case Outcome.Succeeded(a) => a + case _ => None + } + } yield outcome.get + + def toListSource[A](q: PQueueSource[IO, A]): IO[List[A]] = + for { + size <- q.size + list <- q.tryTakeN(size.some) + } yield list + + implicit def eqForPQueueSource[A: Eq](implicit ticker: Ticker): Eq[PQueueSource[IO, A]] = + Eq.by(toListSource) + + implicit def arbPQueueSource[A: Arbitrary]( + implicit ticker: Ticker, + ord: Order[A]): Arbitrary[PQueueSource[IO, A]] = + Arbitrary(genPQueue) + + { + implicit val ticker = Ticker() + checkAll("PQueueFunctorLaws", FunctorTests[PQueueSource[IO, *]].functor[Int, Int, String]) + } + + implicit def eqForPQueue[A: Eq](implicit ticker: Ticker): Eq[PQueue[IO, A]] = + Eq.by(toList) + + implicit def arbPQueue[A: Arbitrary]( + implicit ticker: Ticker, + ord: Order[A]): Arbitrary[PQueue[IO, A]] = + Arbitrary(genPQueue) + + { + implicit val ticker = Ticker() + checkAll("PQueueInvariantLaws", InvariantTests[PQueue[IO, *]].invariant[Int, Int, String]) + } +} diff --git a/tests/shared/src/test/scala/cats/effect/std/QueueLawsSpec.scala b/tests/shared/src/test/scala/cats/effect/std/QueueLawsSpec.scala new file mode 100644 index 0000000000..f55337fc9e --- /dev/null +++ b/tests/shared/src/test/scala/cats/effect/std/QueueLawsSpec.scala @@ -0,0 +1,83 @@ +package cats.effect +package std + +import cats.Eq +import cats.effect._ +import cats.effect.kernel.Outcome +import cats.laws.discipline.{FunctorTests, InvariantTests} +import cats.syntax.all._ + +import org.scalacheck.{Arbitrary, Gen} +import org.typelevel.discipline.specs2.mutable.Discipline + +class QueueLawsSpec extends BaseSpec with Discipline { + + sequential + + def toList[A](q: Queue[IO, A]): IO[List[A]] = + for { + size <- q.size + list <- q.tryTakeN(size.some) + } yield list + + def fromList[A: Arbitrary](as: List[A]): IO[Queue[IO, A]] = { + for { + queue <- Queue.bounded[IO, A](Int.MaxValue) + _ <- as.traverse(a => queue.offer(a)) + } yield queue + } + + def genQueue[A: Arbitrary](implicit ticker: Ticker): Gen[Queue[IO, A]] = + for { + list <- Arbitrary.arbitrary[List[A]] + queue = fromList(list) + outcome = unsafeRun(queue) match { + case Outcome.Succeeded(a) => a + case _ => None + } + } yield outcome.get + + def toListSource[A](q: QueueSource[IO, A]): IO[List[A]] = + for { + size <- q.size + list <- q.tryTakeN(size.some) + } yield list + + implicit def eqForQueueSource[A: Eq](implicit ticker: Ticker): Eq[QueueSource[IO, A]] = + Eq.by(toListSource) + + implicit def arbQueueSource[A: Arbitrary]( + implicit ticker: Ticker): Arbitrary[QueueSource[IO, A]] = + Arbitrary(genQueue) + + { + implicit val ticker = Ticker() + checkAll("QueueFunctorLaws", FunctorTests[QueueSource[IO, *]].functor[Int, Int, String]) + } + + implicit def eqForQueue[A: Eq](implicit ticker: Ticker): Eq[Queue[IO, A]] = + Eq.by(toList) + + implicit def arbQueue[A: Arbitrary](implicit ticker: Ticker): Arbitrary[Queue[IO, A]] = + Arbitrary(genQueue) + + { + implicit val ticker = Ticker() + checkAll("QueueInvariantLaws", InvariantTests[Queue[IO, *]].invariant[Int, Int, String]) + } + + // implicit def eqForQueueSink[A: Eq](implicit ticker: Ticker): Eq[QueueSink[IO, A]] = + // Eq.by(toListSink) + + // implicit def arbQueueSink[A: Arbitrary]( + // implicit ticker: Ticker): Arbitrary[QueueSink[IO, A]] = + // Arbitrary(genQueue) + + // { + // implicit val ticker = Ticker() + // checkAll( + // "QueueContravariantLaws", + // ContravariantTests[QueueSink[IO, *]].contravariant[Int, Int, String]) + + // } +}