From f12726306d5778c5b7d3293c8f683845f2748459 Mon Sep 17 00:00:00 2001 From: Travis Brown Date: Wed, 29 Jan 2020 12:25:03 +0000 Subject: [PATCH 1/5] Add ioTimer and ioContextShift test helpers --- .../internals/IOContextShiftTests.scala | 2 +- .../cats/effect/laws/util/TestContext.scala | 12 ++- .../effect/ConcurrentCancelableFTests.scala | 12 +-- .../effect/ConcurrentContinualTests.scala | 12 +-- .../scala/cats/effect/ContextShiftTests.scala | 30 +++---- .../test/scala/cats/effect/FiberTests.scala | 22 ++--- .../scala/cats/effect/IOCancelableTests.scala | 8 +- .../src/test/scala/cats/effect/IOTests.scala | 82 +++++++++---------- .../scala/cats/effect/InstancesTests.scala | 19 +++-- .../test/scala/cats/effect/MemoizeTests.scala | 18 ++-- .../scala/cats/effect/ResourceTests.scala | 10 +-- .../scala/cats/effect/TestContextTests.scala | 4 +- 12 files changed, 122 insertions(+), 109 deletions(-) diff --git a/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala b/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala index a9e7986a3b..e5078ad43e 100644 --- a/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala +++ b/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala @@ -21,7 +21,7 @@ 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 diff --git a/laws/shared/src/main/scala/cats/effect/laws/util/TestContext.scala b/laws/shared/src/main/scala/cats/effect/laws/util/TestContext.scala index a1ad6a827c..a8705a42e0 100644 --- a/laws/shared/src/main/scala/cats/effect/laws/util/TestContext.scala +++ b/laws/shared/src/main/scala/cats/effect/laws/util/TestContext.scala @@ -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. @@ -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: * diff --git a/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala b/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala index a041c93a12..0dfbdfaeee 100644 --- a/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala +++ b/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala @@ -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 }) @@ -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 => @@ -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 => @@ -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]() @@ -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] @@ -114,7 +114,7 @@ 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 cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] var effect = 0 diff --git a/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala b/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala index 3872e8b8ca..829149e519 100644 --- a/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala +++ b/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala @@ -24,7 +24,7 @@ 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 cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val task = Ref[IO].of(false).flatMap { canceled => @@ -42,7 +42,7 @@ class ConcurrentContinualTests extends BaseTestsSuite { testAsync("Concurrent.continual backpressures on finalizers") { implicit ec => import scala.concurrent.duration._ - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val task = Ref[IO].of(false).flatMap { canceled => @@ -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() @@ -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)) @@ -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) @@ -95,7 +95,7 @@ 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 cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val task = Ref[IO].of(false).flatMap { completed => diff --git a/laws/shared/src/test/scala/cats/effect/ContextShiftTests.scala b/laws/shared/src/test/scala/cats/effect/ContextShiftTests.scala index ae75913b6b..1526ecc24a 100644 --- a/laws/shared/src/test/scala/cats/effect/ContextShiftTests.scala +++ b/laws/shared/src/test/scala/cats/effect/ContextShiftTests.scala @@ -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 @@ -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() @@ -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) @@ -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 @@ -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() @@ -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 @@ -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() @@ -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 @@ -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() @@ -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 @@ -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() @@ -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 @@ -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() @@ -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 @@ -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() diff --git a/laws/shared/src/test/scala/cats/effect/FiberTests.scala b/laws/shared/src/test/scala/cats/effect/FiberTests.scala index 19c5a0dc0b..18158488e4 100644 --- a/laws/shared/src/test/scala/cats/effect/FiberTests.scala +++ b/laws/shared/src/test/scala/cats/effect/FiberTests.scala @@ -34,22 +34,22 @@ class FiberTests extends BaseTestsSuite { Eq.by[Fiber[F, A], F[A]](_.join) checkAllAsync("Fiber[IO, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift ApplicativeTests[Fiber[IO, *]].applicative[Int, Int, Int] }) checkAllAsync("Fiber[IO, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift SemigroupTests[Fiber[IO, Int]](Fiber.fiberSemigroup[IO, Int]).semigroup }) checkAllAsync("Fiber[IO, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift MonoidTests[Fiber[IO, Int]].monoid }) testAsync("Canceling join does not cancel the source fiber") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift var fiberCanceled = false var joinCanceled = false @@ -84,7 +84,7 @@ class FiberTests extends BaseTestsSuite { } testAsync("Applicative[Fiber[IO, *].map2 preserves both cancelation tokens") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift var canceled = 0 // Needs latches due to IO being auto-cancelable at async boundaries @@ -112,7 +112,7 @@ class FiberTests extends BaseTestsSuite { } testAsync("Applicative[Fiber[IO, *].map2 cancels first, when second terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false @@ -139,7 +139,7 @@ class FiberTests extends BaseTestsSuite { } testAsync("Applicative[Fiber[IO, *].map2 cancels second, when first terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false @@ -165,7 +165,7 @@ class FiberTests extends BaseTestsSuite { } testAsync("Monoid[Fiber[IO, *].combine cancels first, when second terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false @@ -191,7 +191,7 @@ class FiberTests extends BaseTestsSuite { } testAsync("Monoid[Fiber[IO, *].combine cancels second, when first terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false @@ -217,7 +217,7 @@ class FiberTests extends BaseTestsSuite { } testAsync("Semigroup[Fiber[IO, *].combine cancels first, when second terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false @@ -243,7 +243,7 @@ class FiberTests extends BaseTestsSuite { } testAsync("Semigroup[Fiber[IO, *].combine cancels second, when first terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false diff --git a/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala b/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala index 84392261c3..59a2fe795e 100644 --- a/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala @@ -36,7 +36,7 @@ class IOCancelableTests extends BaseTestsSuite { } testAsync("IO.cancelBoundary can be canceled") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val f = (IO.shift *> IO.cancelBoundary).unsafeToFuture() f.value shouldBe None @@ -51,7 +51,7 @@ class IOCancelableTests extends BaseTestsSuite { } testAsync("(fa <* IO.cancelBoundary).cancel <-> IO.never") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift check { (fa: IO[Int]) => val received = @@ -66,7 +66,7 @@ class IOCancelableTests extends BaseTestsSuite { } testAsync("task.start.flatMap(id) <-> task") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift check { (task: IO[Int]) => task.start.flatMap(_.join) <-> task @@ -74,7 +74,7 @@ class IOCancelableTests extends BaseTestsSuite { } testAsync("task.start is cancelable") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val task = (IO.shift *> IO.cancelBoundary *> IO(1)).start.flatMap(_.join) diff --git a/laws/shared/src/test/scala/cats/effect/IOTests.scala b/laws/shared/src/test/scala/cats/effect/IOTests.scala index 09f545c568..a81dc29a9f 100644 --- a/laws/shared/src/test/scala/cats/effect/IOTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOTests.scala @@ -36,7 +36,7 @@ import scala.concurrent.duration._ class IOTests extends BaseTestsSuite { checkAllAsync("IO", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift ConcurrentEffectTests[IO].concurrentEffect[Int, Int, Int] }) @@ -45,19 +45,19 @@ class IOTests extends BaseTestsSuite { checkAllAsync("IO", implicit ec => AlignTests[IO].align[Int, Int, Int, Int]) checkAllAsync("IO.Par", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift CommutativeApplicativeTests[IO.Par].commutativeApplicative[Int, Int, Int] }) checkAllAsync("IO.Par", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift AlignTests[IO.Par].align[Int, Int, Int, Int] }) checkAllAsync( "IO", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift // do NOT inline this val; it causes the 2.13.0 compiler to crash for... reasons (see: scala/bug#11732) val module = ParallelTests[IO] @@ -73,14 +73,14 @@ class IOTests extends BaseTestsSuite { checkAllAsync( "IO(ConcurrentEffect defaults)", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val ioConcurrent = IOTests.ioConcurrentEffectDefaults(ec) ConcurrentEffectTests[IO].concurrentEffect[Int, Int, Int] } ) testAsync("IO.Par's applicative instance is different") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicitly[Applicative[IO]] shouldNot be(implicitly[Applicative[IO.Par]]) } @@ -175,7 +175,7 @@ class IOTests extends BaseTestsSuite { } testAsync("shift works for success (via Timer)") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val expected = IO.shift.flatMap(_ => IO(1)).unsafeToFuture() expected.value shouldEqual None @@ -193,7 +193,7 @@ class IOTests extends BaseTestsSuite { } testAsync("shift works for failure (via Timer)") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") val expected = IO.shift.flatMap(_ => IO.raiseError(dummy)).unsafeToFuture() @@ -536,7 +536,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 for successful values") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val io1 = IO.shift *> IO.pure(1) val io2 = IO.shift *> IO.pure(2) @@ -548,7 +548,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 can fail for one") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") val io1 = IO.shift *> IO.pure(1) @@ -568,7 +568,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 can fail for both, with non-deterministic failure") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift catchSystemErr { val dummy1 = new RuntimeException("dummy1") @@ -586,7 +586,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 is stack safe") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 100000 else 5000 val io = (0 until count).foldLeft(IO(0))((acc, e) => (acc, IO(e)).parMapN(_ + _)) @@ -597,7 +597,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 cancels first, when second terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false @@ -616,7 +616,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 cancels second, when first terminates in error") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val dummy = new RuntimeException("dummy") var wasCanceled = false @@ -635,7 +635,7 @@ class IOTests extends BaseTestsSuite { } testAsync("IO.cancelable IOs can be canceled") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift var wasCanceled = false val p = Promise[Int]() @@ -680,7 +680,7 @@ class IOTests extends BaseTestsSuite { } testAsync("IO.timeout can mirror the source") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] check { (ioa: IO[Int]) => @@ -689,7 +689,7 @@ class IOTests extends BaseTestsSuite { } testAsync("IO.timeout can end in timeout") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val task = for { @@ -759,7 +759,7 @@ class IOTests extends BaseTestsSuite { } testAsync("bracket does not evaluate use on cancel") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] var use = false @@ -784,7 +784,7 @@ class IOTests extends BaseTestsSuite { } testAsync("racePair should be stack safe, take 1") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 100000 else 1000 val tasks = (0 until count).map(_ => IO.shift *> IO(1)) @@ -804,7 +804,7 @@ class IOTests extends BaseTestsSuite { } testAsync("racePair should be stack safe, take 2") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 100000 else 1000 val tasks = (0 until count).map(_ => IO(1)) @@ -824,7 +824,7 @@ class IOTests extends BaseTestsSuite { } testAsync("racePair has a stack safe cancelable") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 10000 else 1000 val p = Promise[Int]() @@ -854,7 +854,7 @@ class IOTests extends BaseTestsSuite { } testAsync("racePair avoids extraneous async boundaries") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = IO .racePair(IO.shift *> IO(1), IO.shift *> IO(1)) @@ -872,7 +872,7 @@ class IOTests extends BaseTestsSuite { } testAsync("race should be stack safe, take 1") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 100000 else 1000 val tasks = (0 until count).map(_ => IO.shift *> IO(1)) @@ -892,7 +892,7 @@ class IOTests extends BaseTestsSuite { } testAsync("race should be stack safe, take 2") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 100000 else 1000 val tasks = (0 until count).map(_ => IO(1)) @@ -912,7 +912,7 @@ class IOTests extends BaseTestsSuite { } testAsync("race has a stack safe cancelable") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 10000 else 1000 val p = Promise[Int]() @@ -939,7 +939,7 @@ class IOTests extends BaseTestsSuite { } testAsync("race forks execution") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = IO .race(IO(1), IO(1)) @@ -956,7 +956,7 @@ class IOTests extends BaseTestsSuite { } testAsync("race avoids extraneous async boundaries") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = IO .race(IO.shift *> IO(1), IO.shift *> IO(1)) @@ -973,7 +973,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 should be stack safe") { ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 100000 else 1000 val tasks = (0 until count).map(_ => IO(1)) @@ -985,7 +985,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 has a stack safe cancelable") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val count = if (IOPlatform.isJVM) 10000 else 1000 val tasks = (0 until count).map(_ => IO.never: IO[Int]) @@ -1004,7 +1004,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 forks execution") { ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = (IO(1), IO(1)).parMapN(_ + _).unsafeToFuture() f.value shouldBe None @@ -1017,7 +1017,7 @@ class IOTests extends BaseTestsSuite { } testAsync("parMap2 avoids extraneous async boundaries") { ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = (IO.shift *> IO(1), IO.shift *> IO(1)) .parMapN(_ + _) @@ -1033,7 +1033,7 @@ class IOTests extends BaseTestsSuite { } testAsync("start forks automatically") { ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = IO(1).start.flatMap(_.join).unsafeToFuture() f.value shouldBe None @@ -1042,7 +1042,7 @@ class IOTests extends BaseTestsSuite { } testAsync("start avoids async boundaries") { ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = (IO.shift *> IO(1)).start.flatMap(_.join).unsafeToFuture() f.value shouldBe None @@ -1051,7 +1051,7 @@ class IOTests extends BaseTestsSuite { } testAsync("background cancels the action in cleanup") { ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = Deferred[IO, Unit] .flatMap { started => //wait for this before closing resource @@ -1069,7 +1069,7 @@ class IOTests extends BaseTestsSuite { } testAsync("background allows awaiting the action") { ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift val f = Deferred[IO, Unit] .flatMap { latch => @@ -1085,7 +1085,7 @@ class IOTests extends BaseTestsSuite { } testAsync("cancel should wait for already started finalizers on success") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val fa = for { @@ -1105,7 +1105,7 @@ class IOTests extends BaseTestsSuite { } testAsync("cancel should wait for already started finalizers on failure") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val dummy = new RuntimeException("dummy") @@ -1127,7 +1127,7 @@ class IOTests extends BaseTestsSuite { } testAsync("cancel should wait for already started use finalizers") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val fa = for { @@ -1151,7 +1151,7 @@ class IOTests extends BaseTestsSuite { } testAsync("second cancel should wait for use finalizers") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val fa = for { @@ -1175,7 +1175,7 @@ class IOTests extends BaseTestsSuite { } testAsync("second cancel during acquire should wait for it and finalizers to complete") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val fa = for { @@ -1201,7 +1201,7 @@ class IOTests extends BaseTestsSuite { testAsync("second cancel during acquire should wait for it and finalizers to complete (non-terminating)") { implicit ec => - implicit val contextShift = ec.contextShift[IO] + implicit val contextShift: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val fa = for { diff --git a/laws/shared/src/test/scala/cats/effect/InstancesTests.scala b/laws/shared/src/test/scala/cats/effect/InstancesTests.scala index d9c03a80f8..78435e1f0f 100644 --- a/laws/shared/src/test/scala/cats/effect/InstancesTests.scala +++ b/laws/shared/src/test/scala/cats/effect/InstancesTests.scala @@ -36,7 +36,7 @@ class InstancesTests extends BaseTestsSuite { ) checkAllAsync("OptionT[IO, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift ConcurrentTests[OptionT[IO, *]].concurrent[Int, Int, Int] }) @@ -49,7 +49,7 @@ class InstancesTests extends BaseTestsSuite { ) checkAllAsync("Kleisli[IO, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift ConcurrentTests[Kleisli[IO, Int, *]].concurrent[Int, Int, Int] }) @@ -58,7 +58,7 @@ class InstancesTests extends BaseTestsSuite { checkAllAsync( "EitherT[IO, Throwable, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift ConcurrentEffectTests[EitherT[IO, Throwable, *]].concurrentEffect[Int, Int, Int] } ) @@ -71,10 +71,13 @@ class InstancesTests extends BaseTestsSuite { } ) - checkAllAsync("WriterT[IO, Int, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] - ConcurrentEffectTests[WriterT[IO, Int, *]].concurrentEffect[Int, Int, Int] - }) + checkAllAsync( + "WriterT[IO, Int, *]", + implicit ec => { + implicit val cs: ContextShift[IO] = ec.ioContextShift + ConcurrentEffectTests[WriterT[IO, Int, *]].concurrentEffect[Int, Int, Int] + } + ) checkAllAsync( "WriterT[IO, Int, *]", @@ -85,7 +88,7 @@ class InstancesTests extends BaseTestsSuite { ) checkAllAsync("IorT[IO, Int, *]", implicit ec => { - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift ConcurrentTests[IorT[IO, Int, *]].concurrent[Int, Int, Int] }) diff --git a/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala b/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala index ed7ecd0c28..db05a3b023 100644 --- a/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala +++ b/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala @@ -28,7 +28,7 @@ import cats.laws.discipline._ class MemoizeTests extends BaseTestsSuite { testAsync("Concurrent.memoize does not evaluates the effect if the inner `F[A]`isn't bound") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val timer = ec.timer[IO] val prog = for { @@ -45,7 +45,7 @@ class MemoizeTests extends BaseTestsSuite { } testAsync("Concurrent.memoize evalutes effect once if inner `F[A]` is bound twice") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val prog = for { ref <- Ref.of[IO, Int](0) @@ -66,7 +66,7 @@ class MemoizeTests extends BaseTestsSuite { testAsync("Concurrent.memoize effect evaluates effect once if the inner `F[A]` is bound twice (race)") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val timer = ec.timer[IO] val prog = for { @@ -88,14 +88,14 @@ class MemoizeTests extends BaseTestsSuite { } testAsync("Concurrent.memoize and then flatten is identity") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift check { fa: IO[Int] => Concurrent.memoize(fa).flatten <-> fa } } testAsync("Memoized effects can be canceled when there are no other active subscribers (1)") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val prog = for { @@ -115,7 +115,7 @@ class MemoizeTests extends BaseTestsSuite { } testAsync("Memoized effects can be canceled when there are no other active subscribers (2)") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val prog = for { @@ -138,7 +138,7 @@ class MemoizeTests extends BaseTestsSuite { } testAsync("Memoized effects can be canceled when there are no other active subscribers (3)") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val prog = for { @@ -161,7 +161,7 @@ class MemoizeTests extends BaseTestsSuite { } testAsync("Running a memoized effect after it was previously canceled reruns it") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val prog = for { @@ -183,7 +183,7 @@ class MemoizeTests extends BaseTestsSuite { } testAsync("Attempting to cancel a memoized effect with active subscribers is a no-op") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift implicit val timer = ec.timer[IO] val prog = for { diff --git a/laws/shared/src/test/scala/cats/effect/ResourceTests.scala b/laws/shared/src/test/scala/cats/effect/ResourceTests.scala index 35c521cbb4..cb56bb5c87 100644 --- a/laws/shared/src/test/scala/cats/effect/ResourceTests.scala +++ b/laws/shared/src/test/scala/cats/effect/ResourceTests.scala @@ -97,8 +97,8 @@ class ResourceTests extends BaseTestsSuite { } testAsync("liftF - interruption") { implicit ec => - implicit val timer = ec.timer[IO] - implicit val ctx = ec.contextShift[IO] + implicit val timer: Timer[IO] = ec.ioTimer + implicit val ctx: ContextShift[IO] = ec.ioContextShift def p = Deferred[IO, ExitCase[Throwable]] @@ -135,7 +135,7 @@ class ResourceTests extends BaseTestsSuite { testAsync("(evalMap with error <-> IO.raiseError") { implicit ec => case object Foo extends Exception - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift check { (g: Int => IO[Int]) => val effect: Int => IO[Int] = a => (g(a) <* IO(throw Foo)) @@ -150,7 +150,7 @@ class ResourceTests extends BaseTestsSuite { } testAsync("evalTap with cancellation <-> IO.never") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift check { (g: Int => IO[Int]) => val effect: Int => IO[Int] = a => @@ -166,7 +166,7 @@ class ResourceTests extends BaseTestsSuite { testAsync("(evalTap with error <-> IO.raiseError") { implicit ec => case object Foo extends Exception - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift check { (g: Int => IO[Int]) => val effect: Int => IO[Int] = a => (g(a) <* IO(throw Foo)) diff --git a/laws/shared/src/test/scala/cats/effect/TestContextTests.scala b/laws/shared/src/test/scala/cats/effect/TestContextTests.scala index ee9b165675..6514268997 100644 --- a/laws/shared/src/test/scala/cats/effect/TestContextTests.scala +++ b/laws/shared/src/test/scala/cats/effect/TestContextTests.scala @@ -90,7 +90,7 @@ class TestContextTests extends BaseTestsSuite { } testAsync("IO.shift via implicit ExecutionContext") { implicit ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val f = IO.shift.flatMap(_ => IO(1 + 1)).unsafeToFuture() assert(f.value === None) @@ -100,7 +100,7 @@ class TestContextTests extends BaseTestsSuite { } testAsync("IO.shift via Timer") { ec => - implicit val cs = ec.contextShift[IO] + implicit val cs: ContextShift[IO] = ec.ioContextShift val f = IO.shift.flatMap(_ => IO(1 + 1)).unsafeToFuture() assert(f.value === None) From c11d299fd883890d82a89d365f0430bac554cc97 Mon Sep 17 00:00:00 2001 From: Travis Brown Date: Wed, 29 Jan 2020 12:43:32 +0000 Subject: [PATCH 2/5] Add type annotations --- .../scala/cats/effect/DeferredJVMTests.scala | 4 +-- .../test/scala/cats/effect/IOJVMTests.scala | 6 ++--- .../test/scala/cats/effect/MVarJVMTests.scala | 4 +-- .../scala/cats/effect/SemaphoreJVMTests.scala | 4 +-- .../effect/ConcurrentCancelableFTests.scala | 2 +- .../effect/ConcurrentContinualTests.scala | 6 ++--- .../scala/cats/effect/IOCancelableTests.scala | 8 +++--- .../src/test/scala/cats/effect/IOTests.scala | 26 +++++++++---------- .../test/scala/cats/effect/MemoizeTests.scala | 10 +++---- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/laws/jvm/src/test/scala/cats/effect/DeferredJVMTests.scala b/laws/jvm/src/test/scala/cats/effect/DeferredJVMTests.scala index bd153365a4..05513c1bf7 100644 --- a/laws/jvm/src/test/scala/cats/effect/DeferredJVMTests.scala +++ b/laws/jvm/src/test/scala/cats/effect/DeferredJVMTests.scala @@ -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 { diff --git a/laws/jvm/src/test/scala/cats/effect/IOJVMTests.scala b/laws/jvm/src/test/scala/cats/effect/IOJVMTests.scala index fede4c1d45..2ded4120aa 100644 --- a/laws/jvm/src/test/scala/cats/effect/IOJVMTests.scala +++ b/laws/jvm/src/test/scala/cats/effect/IOJVMTests.scala @@ -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) @@ -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)) @@ -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() diff --git a/laws/jvm/src/test/scala/cats/effect/MVarJVMTests.scala b/laws/jvm/src/test/scala/cats/effect/MVarJVMTests.scala index fba124c406..1a2c80afd5 100644 --- a/laws/jvm/src/test/scala/cats/effect/MVarJVMTests.scala +++ b/laws/jvm/src/test/scala/cats/effect/MVarJVMTests.scala @@ -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 { diff --git a/laws/jvm/src/test/scala/cats/effect/SemaphoreJVMTests.scala b/laws/jvm/src/test/scala/cats/effect/SemaphoreJVMTests.scala index 2197241df8..c8b8054f53 100644 --- a/laws/jvm/src/test/scala/cats/effect/SemaphoreJVMTests.scala +++ b/laws/jvm/src/test/scala/cats/effect/SemaphoreJVMTests.scala @@ -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 { diff --git a/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala b/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala index 0dfbdfaeee..e45931a850 100644 --- a/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala +++ b/laws/shared/src/test/scala/cats/effect/ConcurrentCancelableFTests.scala @@ -115,7 +115,7 @@ class ConcurrentCancelableFTests extends BaseTestsSuite { import scala.concurrent.duration._ implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] var effect = 0 val task = Concurrent.cancelableF[IO, Unit] { cb => diff --git a/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala b/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala index 829149e519..14c22a8999 100644 --- a/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala +++ b/laws/shared/src/test/scala/cats/effect/ConcurrentContinualTests.scala @@ -25,7 +25,7 @@ class ConcurrentContinualTests extends BaseTestsSuite { testAsync("Concurrent.continual allows interruption of its input") { implicit ec => import scala.concurrent.duration._ implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val task = Ref[IO].of(false).flatMap { canceled => (IO.never: IO[Unit]) @@ -43,7 +43,7 @@ class ConcurrentContinualTests extends BaseTestsSuite { testAsync("Concurrent.continual backpressures on finalizers") { implicit ec => import scala.concurrent.duration._ implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val task = Ref[IO].of(false).flatMap { canceled => (IO.never: IO[Unit]) @@ -96,7 +96,7 @@ class ConcurrentContinualTests extends BaseTestsSuite { testAsync("Concurrent.continual respects the continual guarantee") { implicit ec => import scala.concurrent.duration._ implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val task = Ref[IO].of(false).flatMap { completed => IO.unit diff --git a/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala b/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala index 59a2fe795e..92aaba947a 100644 --- a/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala @@ -89,7 +89,7 @@ class IOCancelableTests extends BaseTestsSuite { } testAsync("bracket back-pressures on the finalizer") { ec => - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val p1 = Promise[Unit]() val io = IO.unit.bracket(_ => IO.never: IO[Unit]) { _ => @@ -116,7 +116,7 @@ class IOCancelableTests extends BaseTestsSuite { } testAsync("CancelUtils.cancelAll") { ec => - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val token1 = IO.sleep(1.seconds) val token2 = IO.sleep(2.seconds) @@ -142,7 +142,7 @@ class IOCancelableTests extends BaseTestsSuite { } testAsync("nested brackets are sequenced") { ec => - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val atom = new AtomicInteger(0) val io = @@ -226,7 +226,7 @@ class IOCancelableTests extends BaseTestsSuite { // regression test for https://github.com/typelevel/cats-effect/issues/487 testAsync("bracket can be canceled while failing to acquire") { ec => - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val io = (IO.sleep(2.second) *> IO.raiseError[Unit](new Exception())) .bracket(_ => IO.unit)(_ => IO.unit) diff --git a/laws/shared/src/test/scala/cats/effect/IOTests.scala b/laws/shared/src/test/scala/cats/effect/IOTests.scala index a81dc29a9f..2f5b8bcb73 100644 --- a/laws/shared/src/test/scala/cats/effect/IOTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOTests.scala @@ -66,7 +66,7 @@ class IOTests extends BaseTestsSuite { ) checkAllAsync("IO(Effect defaults)", implicit ec => { - implicit val ioEffect = IOTests.ioEffectDefaults + implicit val ioEffect: Effect[IO] = IOTests.ioEffectDefaults EffectTests[IO].effect[Int, Int, Int] }) @@ -74,7 +74,7 @@ class IOTests extends BaseTestsSuite { "IO(ConcurrentEffect defaults)", implicit ec => { implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val ioConcurrent = IOTests.ioConcurrentEffectDefaults(ec) + implicit val ioConcurrent: ConcurrentEffect[IO] = IOTests.ioConcurrentEffectDefaults(ec) ConcurrentEffectTests[IO].concurrentEffect[Int, Int, Int] } ) @@ -221,7 +221,7 @@ class IOTests extends BaseTestsSuite { } testAsync("IO.sleep") { ec => - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val io = IO.sleep(10.seconds) *> IO(1 + 1) val f = io.unsafeToFuture() @@ -453,7 +453,7 @@ class IOTests extends BaseTestsSuite { testAsync("sync.to[IO] is stack-safe") { implicit ec => // Override default generator to only generate // synchronous instances that are stack-safe - implicit val arbIO = Arbitrary(genSyncIO[Int].map(_.toIO)) + implicit val arbIO: Arbitrary[IO[Int]] = Arbitrary(genSyncIO[Int].map(_.toIO)) check { (io: IO[Int]) => repeatedTransformLoop(10000, io) <-> io @@ -681,7 +681,7 @@ class IOTests extends BaseTestsSuite { testAsync("IO.timeout can mirror the source") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] check { (ioa: IO[Int]) => ioa.timeout(1.day) <-> ioa @@ -690,7 +690,7 @@ class IOTests extends BaseTestsSuite { testAsync("IO.timeout can end in timeout") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val task = for { p <- Deferred[IO, Unit] @@ -760,7 +760,7 @@ class IOTests extends BaseTestsSuite { testAsync("bracket does not evaluate use on cancel") { implicit ec => implicit val contextShift: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] var use = false var release = false @@ -1086,7 +1086,7 @@ class IOTests extends BaseTestsSuite { testAsync("cancel should wait for already started finalizers on success") { implicit ec => implicit val contextShift: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val fa = for { pa <- Deferred[IO, Unit] @@ -1106,7 +1106,7 @@ class IOTests extends BaseTestsSuite { testAsync("cancel should wait for already started finalizers on failure") { implicit ec => implicit val contextShift: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val dummy = new RuntimeException("dummy") @@ -1128,7 +1128,7 @@ class IOTests extends BaseTestsSuite { testAsync("cancel should wait for already started use finalizers") { implicit ec => implicit val contextShift: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val fa = for { pa <- Deferred[IO, Unit] @@ -1152,7 +1152,7 @@ class IOTests extends BaseTestsSuite { testAsync("second cancel should wait for use finalizers") { implicit ec => implicit val contextShift: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val fa = for { pa <- Deferred[IO, Unit] @@ -1176,7 +1176,7 @@ class IOTests extends BaseTestsSuite { testAsync("second cancel during acquire should wait for it and finalizers to complete") { implicit ec => implicit val contextShift: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val fa = for { pa <- Deferred[IO, Unit] @@ -1202,7 +1202,7 @@ class IOTests extends BaseTestsSuite { testAsync("second cancel during acquire should wait for it and finalizers to complete (non-terminating)") { implicit ec => implicit val contextShift: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val fa = for { pa <- Deferred[IO, Unit] diff --git a/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala b/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala index db05a3b023..4b81ed718f 100644 --- a/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala +++ b/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala @@ -96,7 +96,7 @@ class MemoizeTests extends BaseTestsSuite { testAsync("Memoized effects can be canceled when there are no other active subscribers (1)") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val prog = for { completed <- Ref[IO].of(false) @@ -116,7 +116,7 @@ class MemoizeTests extends BaseTestsSuite { testAsync("Memoized effects can be canceled when there are no other active subscribers (2)") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val prog = for { completed <- Ref[IO].of(false) @@ -139,7 +139,7 @@ class MemoizeTests extends BaseTestsSuite { testAsync("Memoized effects can be canceled when there are no other active subscribers (3)") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val prog = for { completed <- Ref[IO].of(false) @@ -162,7 +162,7 @@ class MemoizeTests extends BaseTestsSuite { testAsync("Running a memoized effect after it was previously canceled reruns it") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val prog = for { started <- Ref[IO].of(0) @@ -184,7 +184,7 @@ class MemoizeTests extends BaseTestsSuite { testAsync("Attempting to cancel a memoized effect with active subscribers is a no-op") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - implicit val timer = ec.timer[IO] + implicit val timer: Timer[IO] = ec.timer[IO] val prog = for { condition <- Deferred[IO, Unit] From 461fe53fef861b8e7612868e91135c1cb7b42416 Mon Sep 17 00:00:00 2001 From: Travis Brown Date: Wed, 29 Jan 2020 14:54:37 +0000 Subject: [PATCH 3/5] Add parentheses for Dotty --- .../src/test/scala/cats/effect/IOTests.scala | 2 +- .../src/test/scala/cats/effect/MemoizeTests.scala | 2 +- .../src/test/scala/cats/effect/ResourceTests.scala | 14 +++++++------- .../src/test/scala/cats/effect/SyncIOTests.scala | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/laws/shared/src/test/scala/cats/effect/IOTests.scala b/laws/shared/src/test/scala/cats/effect/IOTests.scala index 2f5b8bcb73..ce343a539d 100644 --- a/laws/shared/src/test/scala/cats/effect/IOTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOTests.scala @@ -93,7 +93,7 @@ class IOTests extends BaseTestsSuite { } testAsync("throw in register is fail") { implicit ec => - check { e: Throwable => + check { (e: Throwable) => IO.async[Unit](_ => throw e) <-> IO.raiseError(e) } } diff --git a/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala b/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala index 4b81ed718f..5a39b70ffb 100644 --- a/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala +++ b/laws/shared/src/test/scala/cats/effect/MemoizeTests.scala @@ -89,7 +89,7 @@ class MemoizeTests extends BaseTestsSuite { testAsync("Concurrent.memoize and then flatten is identity") { implicit ec => implicit val cs: ContextShift[IO] = ec.ioContextShift - check { fa: IO[Int] => + check { (fa: IO[Int]) => Concurrent.memoize(fa).flatten <-> fa } } diff --git a/laws/shared/src/test/scala/cats/effect/ResourceTests.scala b/laws/shared/src/test/scala/cats/effect/ResourceTests.scala index cb56bb5c87..db70237f1f 100644 --- a/laws/shared/src/test/scala/cats/effect/ResourceTests.scala +++ b/laws/shared/src/test/scala/cats/effect/ResourceTests.scala @@ -41,7 +41,7 @@ class ResourceTests extends BaseTestsSuite { } test("releases resources in reverse order of acquisition") { - check { as: List[(Int, Either[Throwable, Unit])] => + check { (as: List[(Int, Either[Throwable, Unit])]) => var released: List[Int] = Nil val r = as.traverse { case (a, e) => @@ -91,7 +91,7 @@ class ResourceTests extends BaseTestsSuite { } testAsync("liftF") { implicit ec => - check { fa: IO[String] => + check { (fa: IO[String]) => Resource.liftF(fa).use(IO.pure) <-> fa } } @@ -175,7 +175,7 @@ class ResourceTests extends BaseTestsSuite { } testAsync("mapK") { implicit ec => - check { fa: Kleisli[IO, Int, Int] => + check { (fa: Kleisli[IO, Int, Int]) => val runWithTwo = new ~>[Kleisli[IO, Int, *], IO] { override def apply[A](fa: Kleisli[IO, Int, A]): IO[A] = fa(2) } @@ -219,7 +219,7 @@ class ResourceTests extends BaseTestsSuite { } testAsync("allocated produces the same value as the resource") { implicit ec => - check { resource: Resource[IO, Int] => + check { (resource: Resource[IO, Int]) => val a0 = Resource(resource.allocated).use(IO.pure).attempt val a1 = resource.use(IO.pure).attempt @@ -240,7 +240,7 @@ class ResourceTests extends BaseTestsSuite { _ <- IO(released.get() shouldBe true) } yield () - prog.unsafeRunSync + prog.unsafeRunSync() } test("allocate does not release until close is invoked on mapK'd Resources") { @@ -252,7 +252,7 @@ class ResourceTests extends BaseTestsSuite { val takeAnInteger = new ~>[IO, Kleisli[IO, Int, *]] { override def apply[A](fa: IO[A]): Kleisli[IO, Int, A] = Kleisli.liftF(fa) } - val plusOne = Kleisli { i: Int => + val plusOne = Kleisli { (i: Int) => IO { i + 1 } } val plusOneResource = Resource.liftF(plusOne) @@ -268,7 +268,7 @@ class ResourceTests extends BaseTestsSuite { _ <- IO(released.get() shouldBe true) } yield () - prog.unsafeRunSync + prog.unsafeRunSync() } test("safe attempt suspended resource") { diff --git a/laws/shared/src/test/scala/cats/effect/SyncIOTests.scala b/laws/shared/src/test/scala/cats/effect/SyncIOTests.scala index 8b4d48be37..984687ac2d 100644 --- a/laws/shared/src/test/scala/cats/effect/SyncIOTests.scala +++ b/laws/shared/src/test/scala/cats/effect/SyncIOTests.scala @@ -91,7 +91,7 @@ class SyncIOTests extends BaseTestsSuite { } } - val value = loop.unsafeRunSync + val value = loop.unsafeRunSync() value shouldEqual count } From a16399efa4ffe858892ebfcb06a614247755651c Mon Sep 17 00:00:00 2001 From: Travis Brown Date: Wed, 29 Jan 2020 14:56:53 +0000 Subject: [PATCH 4/5] Explicitly discard values --- laws/shared/src/test/scala/cats/effect/FiberTests.scala | 2 +- laws/shared/src/test/scala/cats/effect/IOAsyncTests.scala | 4 ++-- .../src/test/scala/cats/effect/IOCancelableTests.scala | 5 ++++- laws/shared/src/test/scala/cats/effect/IOTests.scala | 2 +- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/laws/shared/src/test/scala/cats/effect/FiberTests.scala b/laws/shared/src/test/scala/cats/effect/FiberTests.scala index 18158488e4..118c6fad3d 100644 --- a/laws/shared/src/test/scala/cats/effect/FiberTests.scala +++ b/laws/shared/src/test/scala/cats/effect/FiberTests.scala @@ -104,7 +104,7 @@ class FiberTests extends BaseTestsSuite { _ <- IO.fromFuture(IO.pure(latch1.future)) _ <- IO.fromFuture(IO.pure(latch2.future)) _ <- fiber1.map2(fiber2)(_ + _).cancel - } yield fiber2.join + } yield { fiber2.join; () } f.unsafeToFuture() ec.tick() diff --git a/laws/shared/src/test/scala/cats/effect/IOAsyncTests.scala b/laws/shared/src/test/scala/cats/effect/IOAsyncTests.scala index d71a6c2985..d394c9a10e 100644 --- a/laws/shared/src/test/scala/cats/effect/IOAsyncTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOAsyncTests.scala @@ -42,8 +42,8 @@ class IOAsyncTests extends AsyncFunSuite with Matchers { effect.future.onComplete(attempt.success) val io = source.runAsync { - case Right(a) => IO(effect.success(a)) - case Left(e) => IO(effect.failure(e)) + case Right(a) => IO { effect.success(a); () } + case Left(e) => IO { effect.failure(e); () } } for (_ <- io.toIO.unsafeToFuture(); v <- attempt.future) yield { diff --git a/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala b/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala index 92aaba947a..93d8828e40 100644 --- a/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOCancelableTests.scala @@ -93,7 +93,7 @@ class IOCancelableTests extends BaseTestsSuite { val p1 = Promise[Unit]() val io = IO.unit.bracket(_ => IO.never: IO[Unit]) { _ => - IO.sleep(3.seconds) *> IO(p1.success(())) + IO.sleep(3.seconds) *> IO(p1.success(())).void } val p2 = Promise[Unit]() @@ -151,16 +151,19 @@ class IOCancelableTests extends BaseTestsSuite { IO(3).bracket(_ => IO.never: IO[Unit]) { x3 => IO.sleep(3.seconds) *> IO { atom.compareAndSet(0, x3) shouldBe true + () } } } { x2 => IO.sleep(2.seconds) *> IO { atom.compareAndSet(3, x2) shouldBe true + () } } } { x1 => IO.sleep(1.second) *> IO { atom.compareAndSet(2, x1) shouldBe true + () } } diff --git a/laws/shared/src/test/scala/cats/effect/IOTests.scala b/laws/shared/src/test/scala/cats/effect/IOTests.scala index ce343a539d..798e03c534 100644 --- a/laws/shared/src/test/scala/cats/effect/IOTests.scala +++ b/laws/shared/src/test/scala/cats/effect/IOTests.scala @@ -316,7 +316,7 @@ class IOTests extends BaseTestsSuite { val io1 = IO.fromFuture(IO(Future { effect = f(effect, a) })) val io2 = IO.fromFuture(IO(Future { effect = g(effect, a) })) - io2.flatMap(_ => io1).flatMap(_ => io2) <-> IO(g(f(g(a, a), a), a)) + io2.flatMap(_ => io1).flatMap(_ => io2) <-> IO(g(f(g(a, a), a), a)).void } } From 2c7ee8e2a30a13e802da2c8bfa07f141780e1c26 Mon Sep 17 00:00:00 2001 From: Travis Brown Date: Wed, 29 Jan 2020 15:42:45 +0000 Subject: [PATCH 5/5] Fix import in Scala.js test --- .../test/scala/cats/effect/internals/IOContextShiftTests.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala b/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala index e5078ad43e..41947681b5 100644 --- a/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala +++ b/laws/js/src/test/scala/cats/effect/internals/IOContextShiftTests.scala @@ -16,7 +16,7 @@ package cats.effect.internals -import cats.effect.{BaseTestsSuite, IO} +import cats.effect.{BaseTestsSuite, ContextShift, IO} import scala.util.Success class IOContextShiftTests extends BaseTestsSuite {