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

Introduce munit-cats-effect #4522

Merged
merged 3 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ val logbackVersion = "1.4.11"
val magnoliaVersion = "1.1.6"
val mockitoVersion = "1.17.29"
val munitVersion = "1.0.0-M10"
val munitCatsEffectVersion = "2.0.0-M4"
val nimbusJoseJwtVersion = "9.37.1"
val postgresJdbcVersion = "42.6.0"
val pureconfigVersion = "0.17.4"
Expand Down Expand Up @@ -111,6 +112,7 @@ lazy val logback = "ch.qos.logback" % "logback-classic
lazy val magnolia = "com.softwaremill.magnolia1_2" %% "magnolia" % magnoliaVersion
lazy val mockito = "org.mockito" %% "mockito-scala" % mockitoVersion
lazy val munit = "org.scalameta" %% "munit" % munitVersion
lazy val munitCatsEffect = "org.typelevel" %% "munit-cats-effect" % munitCatsEffectVersion
lazy val nimbusJoseJwt = "com.nimbusds" % "nimbus-jose-jwt" % nimbusJoseJwtVersion
lazy val pureconfig = "com.github.pureconfig" %% "pureconfig" % pureconfigVersion
lazy val pureconfigCats = "com.github.pureconfig" %% "pureconfig-cats" % pureconfigVersion
Expand Down Expand Up @@ -217,6 +219,7 @@ lazy val kernel = project
pureconfig,
pureconfigCats,
munit % Test,
munitCatsEffect % Test,
scalaTest % Test
),
addCompilerPlugin(kindProjector),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,66 +1,65 @@
package ch.epfl.bluebrain.nexus.delta.kernel.utils

import cats.effect.IO
import cats.effect.unsafe.implicits._
import ch.epfl.bluebrain.nexus.delta.kernel.utils.ClasspathResourceError.{InvalidJson, InvalidJsonObject}
import io.circe.syntax._
import io.circe.{Json, JsonObject}
import org.scalatest.concurrent.ScalaFutures
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpecLike
import munit.CatsEffectSuite

class ClasspathResourceLoaderSpec extends AnyWordSpecLike with Matchers with ScalaFutures {
class ClasspathResourceLoaderSpec extends CatsEffectSuite {
private val loader: ClasspathResourceLoader = ClasspathResourceLoader()

private def accept[A](io: IO[A]): A =
io.attempt.unsafeRunSync() match {
case Left(value) => fail(s"Expected Right, found Left with value '$value'")
case Right(value) => value
}

private def reject[A](io: IO[A]): Throwable =
io.attempt.unsafeRunSync() match {
case Left(value) => value
case Right(value) => fail(s"Expected Left, found Right with value '$value'")
}

"A ClasspathResourceUtils" should {
val resourceIO = loader.contentOf("resource.txt", "value" -> "v")
test("return the path") {
loader.absolutePath("resource.txt").assert(_.endsWith("resource.txt"))
}

"return the path" in {
accept(loader.absolutePath("resource.txt")) should endWith("resource.txt")
}
test("return the contents of a handlebar template") {
loader
.contentOf("resource.txt", "value" -> "v")
.assertEquals("A text resource with replacement 'v'")
}

"return a text" in {
accept(resourceIO) shouldEqual "A text resource with replacement 'v'"
}
test("return the contents of a handlebar template, multiple times") {
val io = loader.contentOf("resource.txt", "value" -> "v")

"read a second time" in {
accept(resourceIO) shouldEqual "A text resource with replacement 'v'"
for {
_ <- io.assertEquals("A text resource with replacement 'v'")
_ <- io.assertEquals("A text resource with replacement 'v'")
} yield {
()
}
}

"return a json" in {
accept(loader.jsonContentOf("resource.json", "value" -> "v")) shouldEqual Json.obj("k" -> "v".asJson)
}
test("return the contents of a handlebar template as json") {
loader
.jsonContentOf("resource.json", "value" -> "v")
.assertEquals(Json.obj("k" -> "v".asJson))
}

"return a json object" in {
accept(loader.jsonObjectContentOf("resource.json", "value" -> "v")) shouldEqual JsonObject("k" -> "v".asJson)
}
test("fail when a file cannot be parsed as json") {
loader
.jsonContentOf("resource.txt", "value" -> "v")
.intercept[InvalidJson]
}

"fail when resource is not a json" in {
reject(loader.jsonContentOf("resource.txt")) shouldBe a[InvalidJson]
}
test("return the contaents of a handlebar template as a json object") {
loader
.jsonObjectContentOf("resource.json", "value" -> "v")
.assertEquals(JsonObject("k" -> "v".asJson))
}

"fail when resource is not a json object" in {
reject(loader.jsonObjectContentOf("resource-json-array.json")) shouldEqual InvalidJsonObject(
"resource-json-array.json"
test("fail when a file contains JSON but is not a json object") {
loader
.jsonObjectContentOf("resource-json-array.json")
.intercept[InvalidJsonObject]
.assertEquals(
InvalidJsonObject("resource-json-array.json")
)
}
}

"fail when resource does not exists" in {
reject(loader.contentOf("resource2.txt", "value" -> "v")).getMessage should (include("not found") and include(
"resource2.txt"
))
}
test("fail when a resource does not exist") {
loader
.contentOf("resource2.txt", "value" -> "v")
.intercept[Throwable]
.assert(e => e.getMessage.contains("not found") && e.getMessage.contains("resource2.txt"))
Copy link
Contributor

Choose a reason for hiding this comment

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

Not a new change and I'm not sure about asserting on library errors anyway, but if we are gonna do that could do something like

Suggested change
.intercept[Throwable]
.assert(e => e.getMessage.contains("not found") && e.getMessage.contains("resource2.txt"))
.interceptMessage[IOException]("Resource resource2.txt not found")

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 wrote it this way because the message changed slightly when I switched libraries and I wanted the assertion to be a bit looser (say that it wasn't found, say the name of the thing)

}
}
Loading