Skip to content
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@

package cats.effect.internals

import cats.effect.{BaseTestsSuite, IO}
import cats.effect.{BaseTestsSuite, ContextShift, IO}
import scala.util.Success

class IOContextShiftTests extends BaseTestsSuite {
testAsync("ContextShift[IO] instance based on implicit ExecutionContext") { implicit ec =>
val contextShift = ec.contextShift[IO]
val contextShift: ContextShift[IO] = ec.ioContextShift

val f = contextShift.shift.map(_ => 1).unsafeToFuture()
f.value shouldBe None
Expand Down
4 changes: 2 additions & 2 deletions laws/jvm/src/test/scala/cats/effect/DeferredJVMTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ class DeferredJVMParallelism4Tests extends BaseDeferredJVMTests(4)
abstract class BaseDeferredJVMTests(parallelism: Int) extends AnyFunSuite with Matchers with BeforeAndAfter {
var service: ExecutorService = _

implicit val context = new ExecutionContext {
implicit val context: ExecutionContext = new ExecutionContext {
def execute(runnable: Runnable): Unit =
service.execute(runnable)
def reportFailure(cause: Throwable): Unit =
cause.printStackTrace()
}

implicit val cs = IO.contextShift(context)
implicit val cs: ContextShift[IO] = IO.contextShift(context)
implicit val timer: Timer[IO] = IO.timer(context)

before {
Expand Down
6 changes: 3 additions & 3 deletions laws/jvm/src/test/scala/cats/effect/IOJVMTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class IOJVMTests extends AnyFunSuite with Matchers {

test("parMap2 concurrently") {
import scala.concurrent.ExecutionContext.Implicits.global
implicit val cs = IO.contextShift(global)
implicit val cs: ContextShift[IO] = IO.contextShift(global)

val io1 = IO.shift *> IO(1)
val io2 = IO.shift *> IO(2)
Expand All @@ -107,7 +107,7 @@ class IOJVMTests extends AnyFunSuite with Matchers {

test("long synchronous loops that are forked are cancelable") {
val thread = new AtomicReference[Thread](null)
implicit val ec = new ExecutionContext {
implicit val ec: ExecutionContext = new ExecutionContext {
def execute(runnable: Runnable): Unit = {
val th = new Thread(runnable)
if (!thread.compareAndSet(null, th))
Expand All @@ -122,7 +122,7 @@ class IOJVMTests extends AnyFunSuite with Matchers {
val latch = new java.util.concurrent.CountDownLatch(1)
def loop(): IO[Int] = IO.suspend(loop())

implicit val ctx = IO.contextShift(ec)
implicit val ctx: ContextShift[IO] = IO.contextShift(ec)
val task = IO.shift *> IO(latch.countDown()) *> loop()
val c = task.unsafeRunCancelable {
case Left(e) => e.printStackTrace()
Expand Down
4 changes: 2 additions & 2 deletions laws/jvm/src/test/scala/cats/effect/MVarJVMTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ class MVarFullJVMParallelism4Tests extends BaseMVarJVMTests(4) {
abstract class BaseMVarJVMTests(parallelism: Int) extends AnyFunSuite with Matchers with BeforeAndAfter {
var service: ExecutorService = _

implicit val context = new ExecutionContext {
implicit val context: ExecutionContext = new ExecutionContext {
def execute(runnable: Runnable): Unit =
service.execute(runnable)
def reportFailure(cause: Throwable): Unit =
cause.printStackTrace()
}

implicit val cs = IO.contextShift(context)
implicit val cs: ContextShift[IO] = IO.contextShift(context)
implicit val timer: Timer[IO] = IO.timer(context)

before {
Expand Down
4 changes: 2 additions & 2 deletions laws/jvm/src/test/scala/cats/effect/SemaphoreJVMTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ class SemaphoreJVMParallelism4Tests extends BaseSemaphoreJVMTests(4)
abstract class BaseSemaphoreJVMTests(parallelism: Int) extends AnyFunSuite with Matchers with BeforeAndAfter {
var service: ExecutorService = _

implicit val context = new ExecutionContext {
implicit val context: ExecutionContext = new ExecutionContext {
def execute(runnable: Runnable): Unit =
service.execute(runnable)
def reportFailure(cause: Throwable): Unit =
cause.printStackTrace()
}

implicit val cs = IO.contextShift(context)
implicit val cs: ContextShift[IO] = IO.contextShift(context)
implicit val timer: Timer[IO] = IO.timer(context)

before {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ final class TestContext private () extends ExecutionContext { self =>
lastReportedFailure = None
)

/**
* Derives a `cats.effect.Timer` from this `TestContext` for `IO`.
*/
def ioTimer: Timer[IO] = timer[IO](IO.ioEffect)

/**
* Derives a `cats.effect.Timer` from this `TestContext`, for any data
* type that has a `LiftIO` instance.
Expand Down Expand Up @@ -165,9 +170,14 @@ final class TestContext private () extends ExecutionContext { self =>
}
}

/**
* Derives a `cats.effect.ContextShift` from this `TestContext` for `IO`.
*/
def ioContextShift: ContextShift[IO] = contextShift[IO](IO.ioEffect)

/**
* Derives a `cats.effect.ContextShift` from this `TestContext`, for any data
* type that has a `LiftIO` and `MonadError` instance.
* type that has an `Async` instance.
*
* Example:
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import scala.util.Success

class ConcurrentCancelableFTests extends BaseTestsSuite {
testAsync("Concurrent.cancelableF works for immediate values") { implicit ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift

check { (value: Either[Throwable, Int]) =>
val received = Concurrent.cancelableF[IO, Int](cb => IO { cb(value); IO.unit })
Expand All @@ -36,7 +36,7 @@ class ConcurrentCancelableFTests extends BaseTestsSuite {
}

testAsync("Concurrent.cancelableF works for async values") { implicit ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift

check { (value: Either[Throwable, Int]) =>
val received = Concurrent.cancelableF[IO, Int] { cb =>
Expand All @@ -48,7 +48,7 @@ class ConcurrentCancelableFTests extends BaseTestsSuite {

testAsync("Concurrent.cancelableF can delay callback") { implicit ec =>
import scala.concurrent.duration._
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val timer = ec.timer[IO]

val task = Concurrent.cancelableF[IO, Int] { cb =>
Expand All @@ -70,7 +70,7 @@ class ConcurrentCancelableFTests extends BaseTestsSuite {

testAsync("Concurrent.cancelableF can delay task execution") { implicit ec =>
import scala.concurrent.duration._
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val timer = ec.timer[IO]

val complete = Promise[Unit]()
Expand All @@ -89,7 +89,7 @@ class ConcurrentCancelableFTests extends BaseTestsSuite {
}

testAsync("Concurrent.cancelableF can yield cancelable tasks") { implicit ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift

val task = for {
d <- MVar.empty[IO, Unit]
Expand All @@ -114,8 +114,8 @@ class ConcurrentCancelableFTests extends BaseTestsSuite {
testAsync("Concurrent.cancelableF executes generated task uninterruptedly") { implicit ec =>
import scala.concurrent.duration._

implicit val cs = ec.contextShift[IO]
implicit val timer = ec.timer[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
implicit val timer: Timer[IO] = ec.timer[IO]

var effect = 0
val task = Concurrent.cancelableF[IO, Unit] { cb =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ import scala.util.Success
class ConcurrentContinualTests extends BaseTestsSuite {
testAsync("Concurrent.continual allows interruption of its input") { implicit ec =>
import scala.concurrent.duration._
implicit val cs = ec.contextShift[IO]
implicit val timer = ec.timer[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
implicit val timer: Timer[IO] = ec.timer[IO]

val task = Ref[IO].of(false).flatMap { canceled =>
(IO.never: IO[Unit])
Expand All @@ -42,8 +42,8 @@ class ConcurrentContinualTests extends BaseTestsSuite {

testAsync("Concurrent.continual backpressures on finalizers") { implicit ec =>
import scala.concurrent.duration._
implicit val cs = ec.contextShift[IO]
implicit val timer = ec.timer[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
implicit val timer: Timer[IO] = ec.timer[IO]

val task = Ref[IO].of(false).flatMap { canceled =>
(IO.never: IO[Unit])
Expand All @@ -63,7 +63,7 @@ class ConcurrentContinualTests extends BaseTestsSuite {
}

testAsync("Concurrent.continual behaves like flatMap on the happy path") { implicit ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val task = IO(1).continual(n => IO(n.toOption.get + 1)).map(_ + 1)

val f = task.unsafeToFuture()
Expand All @@ -72,7 +72,7 @@ class ConcurrentContinualTests extends BaseTestsSuite {
}

testAsync("Concurrent.continual behaves like handleErrorWith on errors") { implicit ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift

val ex = new Exception("boom")
val task = IO.raiseError[Unit](ex).continual(n => IO(n.swap.toOption.get))
Expand All @@ -83,7 +83,7 @@ class ConcurrentContinualTests extends BaseTestsSuite {
}

testAsync("Concurrent.continual propagates errors in the continuation") { implicit ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift

val ex = new Exception("boom")
val task = IO(1).continual(_ => IO.raiseError(ex)).handleError(identity)
Expand All @@ -95,8 +95,8 @@ class ConcurrentContinualTests extends BaseTestsSuite {

testAsync("Concurrent.continual respects the continual guarantee") { implicit ec =>
import scala.concurrent.duration._
implicit val cs = ec.contextShift[IO]
implicit val timer = ec.timer[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
implicit val timer: Timer[IO] = ec.timer[IO]

val task = Ref[IO].of(false).flatMap { completed =>
IO.unit
Expand Down
30 changes: 15 additions & 15 deletions laws/shared/src/test/scala/cats/effect/ContextShiftTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class ContextShiftTests extends BaseTestsSuite {
type IorTIO[A] = IorT[IO, Int, A]

testAsync("ContextShift[IO].shift") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift

val f = cs.shift.unsafeToFuture()
f.value shouldBe None
Expand All @@ -40,7 +40,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("ContextShift[IO].evalOn") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val ec2 = TestContext()

val f = cs.evalOn(ec2)(IO(1)).unsafeToFuture()
Expand All @@ -56,7 +56,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("ContextShift.evalOnK[IO]") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val ec2 = TestContext()

val funK = ContextShift.evalOnK[IO](ec2)
Expand All @@ -75,7 +75,7 @@ class ContextShiftTests extends BaseTestsSuite {
// -- EitherT

testAsync("Timer[EitherT].shift") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val f = implicitly[ContextShift[EitherTIO]].shift.value.unsafeToFuture()

f.value shouldBe None
Expand All @@ -85,7 +85,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("Timer[EitherT].evalOn") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val cs2 = implicitly[ContextShift[EitherTIO]]
val ec2 = TestContext()

Expand All @@ -104,7 +104,7 @@ class ContextShiftTests extends BaseTestsSuite {
// -- OptionT

testAsync("Timer[OptionT].shift") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val f = implicitly[ContextShift[OptionTIO]].shift.value.unsafeToFuture()

f.value shouldBe None
Expand All @@ -114,7 +114,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("Timer[OptionT].evalOn") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val cs2 = implicitly[ContextShift[OptionTIO]]
val ec2 = TestContext()

Expand All @@ -133,7 +133,7 @@ class ContextShiftTests extends BaseTestsSuite {
// -- WriterT

testAsync("Timer[WriterT].shift") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val f = implicitly[ContextShift[WriterTIO]].shift.value.unsafeToFuture()

f.value shouldBe None
Expand All @@ -143,7 +143,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("Timer[WriterT].evalOn") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val cs2 = implicitly[ContextShift[WriterTIO]]
val ec2 = TestContext()

Expand All @@ -162,7 +162,7 @@ class ContextShiftTests extends BaseTestsSuite {
// -- StateT

testAsync("Timer[StateT].shift") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val f = implicitly[ContextShift[StateTIO]].shift.run(0).unsafeToFuture()

f.value shouldBe None
Expand All @@ -172,7 +172,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("Timer[StateT].evalOn") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val cs2 = implicitly[ContextShift[StateTIO]]
val ec2 = TestContext()

Expand All @@ -191,7 +191,7 @@ class ContextShiftTests extends BaseTestsSuite {
// -- Kleisli

testAsync("Timer[Kleisli].shift") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val f = implicitly[ContextShift[KleisliIO]].shift.run(0).unsafeToFuture()

f.value shouldBe None
Expand All @@ -201,7 +201,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("Timer[Kleisli].evalOn") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val cs2 = implicitly[ContextShift[KleisliIO]]
val ec2 = TestContext()

Expand All @@ -220,7 +220,7 @@ class ContextShiftTests extends BaseTestsSuite {
// -- IorT

testAsync("Timer[IorT].shift") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val f = implicitly[ContextShift[IorTIO]].shift.value.unsafeToFuture()

f.value shouldBe None
Expand All @@ -230,7 +230,7 @@ class ContextShiftTests extends BaseTestsSuite {
}

testAsync("Timer[IorT].evalOn") { ec =>
implicit val cs = ec.contextShift[IO]
implicit val cs: ContextShift[IO] = ec.ioContextShift
val cs2 = implicitly[ContextShift[IorTIO]]
val ec2 = TestContext()

Expand Down
Loading