Skip to content

Commit

Permalink
Port Boopickle to cats effect 3 and add basic munit infrastructure
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Quiroz <carlos.m.quiroz@gmail.com>
  • Loading branch information
cquiroz committed Nov 19, 2020
1 parent bcc29da commit 5540926
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 26 deletions.
Expand Up @@ -9,7 +9,7 @@ package booPickle

import boopickle.Default._
import boopickle.Pickler
import cats.effect.Sync
import cats.effect.Concurrent
import fs2.Chunk
import java.nio.ByteBuffer
import org.http4s._
Expand All @@ -21,7 +21,7 @@ import scala.util.{Failure, Success}
* Note that the media type is set for application/octet-stream
*/
trait BooPickleInstances {
private def booDecoderByteBuffer[F[_]: Sync, A](m: Media[F])(implicit
private def booDecoderByteBuffer[F[_]: Concurrent, A](m: Media[F])(implicit
pickler: Pickler[A]): DecodeResult[F, A] =
EntityDecoder.collectBinary(m).subflatMap { chunk =>
val bb = ByteBuffer.wrap(chunk.toArray)
Expand All @@ -36,7 +36,7 @@ trait BooPickleInstances {

/** Create an `EntityDecoder` for `A` given a `Pickler[A]`
*/
def booOf[F[_]: Sync, A: Pickler]: EntityDecoder[F, A] =
def booOf[F[_]: Concurrent, A: Pickler]: EntityDecoder[F, A] =
EntityDecoder.decodeBy(MediaType.application.`octet-stream`)(booDecoderByteBuffer[F, A])

/** Create an `EntityEncoder` for `A` given a `Pickler[A]`
Expand Down
Expand Up @@ -9,17 +9,15 @@ package booPickle

import boopickle.Default._
import cats.effect.IO
import cats.implicits._
import cats.Eq
import cats.effect.laws.util.TestContext
import cats.effect.laws.util.TestInstances._
import cats.effect.testkit.TestContext
import org.http4s.headers.`Content-Type`
import org.http4s.laws.discipline.EntityCodecTests
// import org.http4s.laws.discipline.EntityCodecTests
import org.http4s.MediaType
import org.scalacheck.Arbitrary
import org.scalacheck.Gen

class BoopickleSpec extends Http4sSpec with BooPickleInstances {
class BoopickleSuite extends Http4sSuite with BooPickleInstances {
implicit val testContext = TestContext()

trait Fruit {
Expand Down Expand Up @@ -54,27 +52,23 @@ class BoopickleSpec extends Http4sSpec with BooPickleInstances {

implicit val fruitEq: Eq[Fruit] = Eq.fromUniversalEquals

"boopickle encoder" should {
"have octet-stream content type" in {
encoder.headers.get(`Content-Type`) must_== Some(
`Content-Type`(MediaType.application.`octet-stream`))
}
test("have octet-stream content type") {
assertEquals(
encoder.headers.get(`Content-Type`),
Some(`Content-Type`(MediaType.application.`octet-stream`)))
}

"booEncoderOf" should {
"have octect-stream content type" in {
booEncoderOf[IO, Fruit].headers.get(`Content-Type`) must_== Some(
`Content-Type`(MediaType.application.`octet-stream`))
}
test("have octect-stream content type") {
assertEquals(
booEncoderOf[IO, Fruit].headers.get(`Content-Type`),
Some(`Content-Type`(MediaType.application.`octet-stream`)))
}

"booOf" should {
"decode a class from a boopickle decoder" in {
val result = booOf[IO, Fruit]
.decode(Request[IO]().withEntity(Banana(10.0): Fruit), strict = true)
result.value.unsafeRunSync() must_== Right(Banana(10.0))
}
test("decode a class from a boopickle decoder") {
val result = booOf[IO, Fruit]
.decode(Request[IO]().withEntity(Banana(10.0): Fruit), strict = true)
result.value.map(assertEquals(_, Right(Banana(10.0))))
}

checkAll("EntityCodec[IO, Fruit]", EntityCodecTests[IO, Fruit].entityCodec)
// checkAll("EntityCodec[IO, Fruit]", EntityCodecTests[IO, Fruit].entityCodec)
}
7 changes: 6 additions & 1 deletion build.sbt
Expand Up @@ -30,7 +30,7 @@ lazy val modules: List[ProjectReference] = List(
// theDsl,
jawn,
// argonaut,
// boopickle,
boopickle,
// circe,
// json4s,
// json4sNative,
Expand Down Expand Up @@ -105,7 +105,11 @@ lazy val testing = libraryProject("testing")
description := "Instances and laws for testing http4s code",
libraryDependencies ++= Seq(
specs2Matcher,
munitCatsEffect,
munitDiscipline
),
unusedCompileDependenciesFilter -= moduleFilter(organization = "org.typelevel", name = "discipline-munit"),
unusedCompileDependenciesFilter -= moduleFilter(organization = "org.typelevel", name = "munit-cats-effect-3"),
)
.dependsOn(laws)

Expand Down Expand Up @@ -661,6 +665,7 @@ def http4sProject(name: String) =
.settings(
moduleName := s"http4s-$name",
Test / testOptions += Tests.Argument(TestFrameworks.Specs2, "showtimes", "failtrace"),
testFrameworks += new TestFramework("munit.Framework"),
initCommands()
)
.enablePlugins(AutomateHeaderPlugin)
Expand Down
6 changes: 6 additions & 0 deletions project/Http4sPlugin.scala
Expand Up @@ -329,6 +329,9 @@ object Http4sPlugin extends AutoPlugin {
val logback = "1.2.3"
val log4s = "1.9.0"
val mockito = "3.5.15"
val munit = "0.7.18"
val munitCatsEffect = "0.9.0"
val munitDiscipline = "1.0.2"
val okhttp = "4.9.0"
val parboiledHttp4s = "2.0.1"
val playJson = "2.9.1"
Expand Down Expand Up @@ -390,6 +393,9 @@ object Http4sPlugin extends AutoPlugin {
lazy val log4s = "org.log4s" %% "log4s" % V.log4s
lazy val logbackClassic = "ch.qos.logback" % "logback-classic" % V.logback
lazy val okhttp = "com.squareup.okhttp3" % "okhttp" % V.okhttp
lazy val munit = "org.scalameta" %% "munit" % V.munit
lazy val munitCatsEffect = "org.typelevel" %% "munit-cats-effect-3" % V.munitCatsEffect
lazy val munitDiscipline = "org.typelevel" %% "discipline-munit" % V.munitDiscipline
lazy val playJson = "com.typesafe.play" %% "play-json" % V.playJson
lazy val prometheusClient = "io.prometheus" % "simpleclient" % V.prometheusClient
lazy val prometheusCommon = "io.prometheus" % "simpleclient_common" % V.prometheusClient
Expand Down
15 changes: 15 additions & 0 deletions testing/src/test/scala/org/http4s/Http4sSuite.scala
@@ -0,0 +1,15 @@
/*
* Copyright 2013-2020 http4s.org
*
* SPDX-License-Identifier: Apache-2.0
*/

package org.http4s

import munit._

/** Common stack for http4s' munit based tests
*/
trait Http4sSuite extends CatsEffectSuite with DisciplineSuite {}

object Http4sSuite {}

0 comments on commit 5540926

Please sign in to comment.