Skip to content

Commit

Permalink
Add unit tests to tapiro
Browse files Browse the repository at this point in the history
  • Loading branch information
gabro committed Mar 27, 2020
1 parent e2e37e4 commit b8c8ee6
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 12 deletions.
6 changes: 5 additions & 1 deletion project/Dependencies.scala
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ object Dependencies {
val tapirHttp4s = "com.softwaremill.sttp.tapir" %% "tapir-http4s-server" % V.tapir
val munit = "org.scalameta" %% "munit" % V.munit
val munitScalaCheck = "org.scalameta" %% "munit-scalacheck" % V.munit
val log4j = "org.apache.logging.log4j" % "log4j-api" % "2.13.1"

val enumeroDependencies = List(
munit,
Expand Down Expand Up @@ -186,11 +187,14 @@ object Dependencies {

val tapiroCoreDependencies = List(
sbtLogging,
log4j,
scalameta,
scalafmtCore,
circeCore,
pprint,
)
) ++ List(
munit,
).map(_ % Test)

val docsDependencies = List(
plantuml,
Expand Down
2 changes: 1 addition & 1 deletion tapiro/ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ set -e

apk add --no-cache curl

sbt -batch ';tapiroCore/compile ;sbt-tapiro/scripted' # TODO(claudio): compile to test once we have them
sbt -batch ';tapiroCore/test ;sbt-tapiro/scripted'
9 changes: 4 additions & 5 deletions tapiro/core/src/main/scala/io/buildo/tapiro/Util.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,9 @@ import scala.meta._
import scala.util.control.NonFatal
import java.nio.file.Paths
import java.nio.file.Files

import cats.data.NonEmptyList

import MetarpheusHelper._

import sbt.internal.util.ManagedLogger
import org.apache.logging.log4j.LogManager

import Meta.typeNameString

Expand All @@ -36,9 +33,11 @@ object TapiroRouteError {

case class TapiroRoute(route: Route, error: TapiroRouteError)

class Util(logger: ManagedLogger) {
class Util() {
import Formatter.format

val logger = LogManager.getLogger("io.buildo.tapiro")

def createFiles(
routesPaths: List[String],
modelsPaths: List[String],
Expand Down
6 changes: 6 additions & 0 deletions tapiro/core/src/test/resources/log4j2-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Loggers>
<Logger name="io.buildo.tapiro" level="error" />
</Loggers>
</Configuration>
58 changes: 58 additions & 0 deletions tapiro/core/src/test/scala/io/buildo/tapiro/FileLayout.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.buildo.tapiro

import java.nio.charset.Charset
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.StandardOpenOption
import scala.meta.io.AbsolutePath

//TODO(gabro): add Metals notice
object FileLayout {

def mapFromString(layout: String): Map[String, String] = {
if (!layout.trim.isEmpty) {
val lines = layout.replaceAllLiterally("\r\n", "\n")
lines
.split("(?=\n/[^/])")
.map { row =>
row.stripPrefix("\n").split("\n", 2).toList match {
case path :: contents :: Nil =>
path.stripPrefix("/") -> contents
case els =>
throw new IllegalArgumentException(
s"Unable to split argument info path/contents! \n$els",
)
}
}
.toMap
} else {
Map.empty
}
}

def fromString(
layout: String,
root: AbsolutePath = AbsolutePath(Files.createTempDirectory("tapiro")),
charset: Charset = StandardCharsets.UTF_8,
): AbsolutePath = {
if (!layout.trim.isEmpty) {
mapFromString(layout).foreach {
case (path, contents) =>
val file =
path.split("/").foldLeft(root)(_.resolve(_))
val parent = file.toNIO.getParent
if (!Files.exists(parent)) { // cannot create directories when parent is a symlink
Files.createDirectories(parent)
}
Files.deleteIfExists(file.toNIO)
Files.write(
file.toNIO,
contents.getBytes(charset),
StandardOpenOption.WRITE,
StandardOpenOption.CREATE,
)
}
}
root
}
}
135 changes: 135 additions & 0 deletions tapiro/core/src/test/scala/io/buildo/tapiro/TapiroSuite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
package io.buildo.tapiro

import java.nio.file.Files

class TapiroSuite extends munit.FunSuite {

check(
"http4s",
Server.Http4s,
"src/main/scala/schools/endpoints",
"""
|/src/main/scala/schools/SchoolController.scala
|package schools
|
|case class School(id: Long, name: String)
|
|sealed trait SchoolReadError
|object SchoolReadError {
| case object NotFound extends SchoolReadError
|}
|
|trait SchoolController[F[_], T] {
| @query
| def read(id: Long): F[Either[SchoolReadError, School]]
|}
|""".stripMargin,
"""
|/src/main/scala/schools/endpoints/SchoolControllerTapirEndpoints.scala
|//----------------------------------------------------------
|// This code was generated by tapiro.
|// Changes to this file may cause incorrect behavior
|// and will be lost if the code is regenerated.
|//----------------------------------------------------------
|
|package endpoints
|import schools._
|import sttp.tapir._
|import sttp.tapir.Codec.{JsonCodec, PlainCodec}
|import sttp.model.StatusCode
|
|trait SchoolControllerTapirEndpoints[AuthToken] {
| val read: Endpoint[Long, SchoolReadError, School, Nothing]
|}
|
|object SchoolControllerTapirEndpoints {
|
| def create[AuthToken](statusCodes: String => StatusCode)(
| implicit codec0: JsonCodec[School],
| codec1: JsonCodec[SchoolReadError.NotFound.type],
| codec2: PlainCodec[Long]
| ) = new SchoolControllerTapirEndpoints[AuthToken] {
| override val read: Endpoint[Long, SchoolReadError, School, Nothing] =
| endpoint.get
| .in("read")
| .in(query[Long]("id"))
| .errorOut(
| oneOf[SchoolReadError](
| statusMapping(
| statusCodes("NotFound"),
| jsonBody[SchoolReadError.NotFound.type]
| )
| )
| )
| .out(jsonBody[School])
| }
|}
|
|/src/main/scala/schools/endpoints/SchoolControllerHttpEndpoints.scala
|//----------------------------------------------------------
|// This code was generated by tapiro.
|// Changes to this file may cause incorrect behavior
|// and will be lost if the code is regenerated.
|//----------------------------------------------------------
|
|package endpoints
|import schools._
|import cats.effect._
|import cats.implicits._
|import cats.data.NonEmptyList
|import org.http4s._
|import org.http4s.server.Router
|import sttp.tapir.server.http4s._
|import sttp.tapir.Codec.{JsonCodec, PlainCodec}
|import sttp.model.StatusCode
|
|object SchoolControllerHttpEndpoints {
|
| def routes[F[_]: Sync, AuthToken](
| controller: SchoolController[F, AuthToken],
| statusCodes: String => StatusCode = _ => StatusCode.UnprocessableEntity
| )(
| implicit codec0: JsonCodec[School],
| codec1: JsonCodec[SchoolReadError.NotFound.type],
| codec2: PlainCodec[Long],
| cs: ContextShift[F]
| ): HttpRoutes[F] = {
| val endpoints =
| SchoolControllerTapirEndpoints.create[AuthToken](statusCodes)
| val read = endpoints.read.toRoutes(controller.read)
| Router("/SchoolController" -> NonEmptyList(read, List()).reduceK)
| }
|}
|""".stripMargin,
)

def check(
name: String,
server: Server,
endpointDirectory: String,
layout: String,
expectedLayout: String,
`package`: List[String] = List("endpoints"),
)(
implicit loc: munit.Location,
): Unit =
test(name) {
val projectRoot = FileLayout.fromString(layout)
val tapiro = new Util()
tapiro.createFiles(
List(projectRoot.toString),
List(projectRoot.toString),
projectRoot.resolve(endpointDirectory).toString,
`package`,
server,
)

FileLayout.mapFromString(expectedLayout).map {
case (path, content) =>
val filePath = path.split("/").foldLeft(projectRoot)(_.resolve(_))
assertNoDiff(Files.readString(filePath.toNIO), content)
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ object SbtTapiro extends AutoPlugin {
override val projectSettings = inConfig(Compile)(
Seq(
tapiro := {
(new Util(streams.value.log)).createFiles(
new Util().createFiles(
tapiroRoutesPaths.in(tapiro).value.map(s => (scalaSource.value / s).toString),
tapiroModelsPaths.in(tapiro).value.map(s => (scalaSource.value / s).toString),
(scalaSource.value / tapiroOutputPath.in(tapiro).value).toString,
Expand Down
2 changes: 1 addition & 1 deletion tapiro/sbt-tapiro/src/sbt-test/sbt-tapiro/simple/build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ lazy val root = (project in file("."))
"com.softwaremill.sttp.tapir" %% "tapir-core" % "0.12.15",
"org.http4s" %% "http4s-blaze-server" % http4sVersion,
"org.http4s" %% "http4s-circe" % http4sVersion,
"ch.qos.logback" % "logback-classic" % "1.2.3",
"org.apache.logging.log4j" % "log4j-core" % "2.13.1",
) ++ Seq(
"io.circe" %% "circe-core",
"io.circe" %% "circe-generic",
Expand Down

This file was deleted.

0 comments on commit b8c8ee6

Please sign in to comment.