Skip to content

Commit

Permalink
Merge pull request #2276 from djspiewak/feature/time-mocking
Browse files Browse the repository at this point in the history
Added `TestControl`, with first-class support for time mocking
  • Loading branch information
djspiewak authored Sep 20, 2021
2 parents f6063b6 + 2022ef9 commit a2f2fb7
Show file tree
Hide file tree
Showing 13 changed files with 786 additions and 206 deletions.
60 changes: 52 additions & 8 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,8 @@ val ScalaCheckVersion = "1.15.4"
val DisciplineVersion = "1.2.2"
val CoopVersion = "1.1.1"

val MacrotaskExecutorVersion = "0.2.0"

replaceCommandAlias("ci", CI.AllCIs.map(_.toString).mkString)

addCommandAlias(CI.JVM.command, CI.JVM.toString)
Expand Down Expand Up @@ -264,9 +266,23 @@ lazy val kernel = crossProject(JSPlatform, JVMPlatform)
.in(file("kernel"))
.settings(
name := "cats-effect-kernel",
libraryDependencies ++= Seq(
("org.specs2" %%% "specs2-core" % Specs2Version % Test).cross(CrossVersion.for3Use2_13),
"org.typelevel" %%% "cats-core" % CatsVersion)
libraryDependencies += "org.typelevel" %%% "cats-core" % CatsVersion)
.jvmSettings(libraryDependencies += {
if (isDotty.value)
("org.specs2" %%% "specs2-core" % Specs2Version % Test).cross(CrossVersion.for3Use2_13)
else
"org.specs2" %%% "specs2-core" % Specs2Version % Test
})
.jsSettings(
libraryDependencies += {
if (isDotty.value)
("org.specs2" %%% "specs2-core" % Specs2Version % Test)
.cross(CrossVersion.for3Use2_13)
.exclude("org.scala-js", "scala-js-macrotask-executor_sjs1_2.13")
else
"org.specs2" %%% "specs2-core" % Specs2Version % Test
},
libraryDependencies += "org.scala-js" %%% "scala-js-macrotask-executor" % MacrotaskExecutorVersion % Test
)

/**
Expand All @@ -281,7 +297,10 @@ lazy val kernelTestkit = crossProject(JSPlatform, JVMPlatform)
libraryDependencies ++= Seq(
"org.typelevel" %%% "cats-free" % CatsVersion,
"org.scalacheck" %%% "scalacheck" % ScalaCheckVersion,
"org.typelevel" %%% "coop" % CoopVersion)
"org.typelevel" %%% "coop" % CoopVersion),
mimaBinaryIssueFilters ++= Seq(
ProblemFilters.exclude[DirectMissingMethodProblem](
"cats.effect.kernel.testkit.TestContext.this"))
)

/**
Expand Down Expand Up @@ -387,8 +406,7 @@ lazy val core = crossProject(JSPlatform, JVMPlatform)
javacOptions ++= Seq("-source", "1.8", "-target", "1.8")
)
.jsSettings(
libraryDependencies += "org.scala-js" %%% "scala-js-macrotask-executor" % "0.2.0"
)
libraryDependencies += "org.scala-js" %%% "scala-js-macrotask-executor" % MacrotaskExecutorVersion)

/**
* Test support for the core project, providing various helpful instances like ScalaCheck
Expand All @@ -399,7 +417,21 @@ lazy val testkit = crossProject(JSPlatform, JVMPlatform)
.dependsOn(core, kernelTestkit)
.settings(
name := "cats-effect-testkit",
libraryDependencies ++= Seq("org.scalacheck" %%% "scalacheck" % ScalaCheckVersion))
libraryDependencies += "org.scalacheck" %%% "scalacheck" % ScalaCheckVersion)
.jvmSettings(libraryDependencies += {
if (isDotty.value)
("org.specs2" %%% "specs2-core" % Specs2Version % Test).cross(CrossVersion.for3Use2_13)
else
"org.specs2" %%% "specs2-core" % Specs2Version % Test
})
.jsSettings(libraryDependencies += {
if (isDotty.value)
("org.specs2" %%% "specs2-core" % Specs2Version % Test)
.cross(CrossVersion.for3Use2_13)
.exclude("org.scala-js", "scala-js-macrotask-executor_sjs1_2.13")
else
"org.specs2" %%% "specs2-core" % Specs2Version % Test
})

/**
* Unit tests for the core project, utilizing the support provided by testkit.
Expand Down Expand Up @@ -429,16 +461,28 @@ lazy val std = crossProject(JSPlatform, JVMPlatform)
.dependsOn(kernel)
.settings(
name := "cats-effect-std",
libraryDependencies += "org.scalacheck" %%% "scalacheck" % ScalaCheckVersion % Test)
.jvmSettings(libraryDependencies += {
if (isDotty.value)
("org.specs2" %%% "specs2-scalacheck" % Specs2Version % Test)
.cross(CrossVersion.for3Use2_13)
.exclude("org.scalacheck", "scalacheck_2.13")
.exclude("org.scalacheck", "scalacheck_sjs1_2.13")
else
"org.specs2" %%% "specs2-scalacheck" % Specs2Version % Test
})
.jsSettings(
libraryDependencies += {
if (isDotty.value)
("org.specs2" %%% "specs2-scalacheck" % Specs2Version % Test)
.cross(CrossVersion.for3Use2_13)
.exclude("org.scala-js", "scala-js-macrotask-executor_sjs1_2.13")
.exclude("org.scalacheck", "scalacheck_2.13")
.exclude("org.scalacheck", "scalacheck_sjs1_2.13")
else
"org.specs2" %%% "specs2-scalacheck" % Specs2Version % Test
},
libraryDependencies += "org.scalacheck" %%% "scalacheck" % ScalaCheckVersion % Test
libraryDependencies += "org.scala-js" %%% "scala-js-macrotask-executor" % MacrotaskExecutorVersion % Test
)

/**
Expand Down
16 changes: 16 additions & 0 deletions core/shared/src/main/scala/cats/effect/IO.scala
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,19 @@ sealed abstract class IO[+A] private () extends IOPlatform[A] {
def redeemWith[B](recover: Throwable => IO[B], bind: A => IO[B]): IO[B] =
attempt.flatMap(_.fold(recover, bind))

def replicateA(n: Int): IO[List[A]] =
if (n <= 0)
IO.pure(Nil)
else
flatMap(a => replicateA(n - 1).map(a :: _))

// TODO PR to cats
def replicateA_(n: Int): IO[Unit] =
if (n <= 0)
IO.unit
else
flatMap(_ => replicateA_(n - 1))

/**
* Returns an IO that will delay the execution of the source by the given duration.
*/
Expand Down Expand Up @@ -1450,6 +1463,9 @@ object IO extends IOCompanionPlatform with IOLowPriorityImplicits {
override def productR[A, B](left: IO[A])(right: IO[B]): IO[B] =
left.productR(right)

override def replicateA[A](n: Int, fa: IO[A]): IO[List[A]] =
fa.replicateA(n)

def start[A](fa: IO[A]): IO[FiberIO[A]] =
fa.start

Expand Down
2 changes: 0 additions & 2 deletions example/js/src/main/scala/cats/effect/example/Example.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@
package cats.effect
package example

import cats.syntax.all._

object Example extends IOApp {

def run(args: List[String]): IO[ExitCode] =
Expand Down
Loading

0 comments on commit a2f2fb7

Please sign in to comment.