Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft: Laws testing for Queue instances #3676

Draft
wants to merge 6 commits into
base: series/3.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions tests/shared/src/test/scala/cats/effect/std/DequeueLawsSpec.scala
Original file line number Diff line number Diff line change
@@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to refactor this code.


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])
}
}
71 changes: 71 additions & 0 deletions tests/shared/src/test/scala/cats/effect/std/PQueueLawsSpec.scala
Original file line number Diff line number Diff line change
@@ -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])
}
}
83 changes: 83 additions & 0 deletions tests/shared/src/test/scala/cats/effect/std/QueueLawsSpec.scala
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was not able to transform Sink implementation into a List since it only has offer methods.


// 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])

// }
}