Skip to content

Instantly share code, notes, and snippets.

@LLCampos
Created May 15, 2021 09:21
Show Gist options
  • Save LLCampos/bedb2aa841a65267b12d23465bd1e8be to your computer and use it in GitHub Desktop.
Save LLCampos/bedb2aa841a65267b12d23465bd1e8be to your computer and use it in GitHub Desktop.
Scala trait that gives you the ability to share a Cats Effect's Resource across a specs2 suite's tests. Acquires the resource in the beginning of the suite and releases them in the end.
import cats.effect.IO
import cats.effect.kernel.Resource
import cats.effect.unsafe.implicits.global
import org.specs2.mutable.Specification
import org.specs2.specification.core.Fragments
import org.specs2.specification.dsl.ActionDsl
import scala.concurrent.duration._
// This taken from https://github.com/http4s/http4s/blob/bd9a64d95a9d280f46fa0ce3ebd80f741ef96bb0/specs2/src/test/scala/org/http4s/Http4sSpec.scala
// I'm just making it more visible/usable. :)
trait SharedResourceSpec extends Specification with ActionDsl {
protected val timeout: FiniteDuration = 10.seconds
def withResource[A](r: Resource[IO, A])(fs: A => Fragments): Fragments =
r.allocated
.map { case (r, release) =>
fs(r).append(step(release.unsafeRunTimed(timeout)))
}
.unsafeRunTimed(timeout)
.getOrElse(throw new Exception(s"no result after $timeout"))
}
// How to use:
class MySpecs2SharedResourcesSuite extends SharedResourceSpec {
sequential
withResource(MyResources.resources) { resources: (String, String) =>
"MySpecs2SharedResourcesSuite" should {
"test1" in {
println(s"resources $resources being used in test 1")
ok
}
"test2" in {
println(s"resources $resources being used in test 2")
ok
}
}
}
}
object MyResources {
val resources = for {
v1 <- resource1
v2 <- resource2
} yield (v1, v2)
def resource1: Resource[IO, String] =
Resource.make(
IO.delay(println("Started resource 1")).as("resource 1")
)(_ => IO.delay(println("Finished resource 1")))
def resource2: Resource[IO, String] =
Resource.make(
IO.delay(println("Started resource 1")).as("resource 2")
)(_ => IO.delay(println("Finished resource 1")))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment