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

Added test for render validation of PostService #2389

Open
wants to merge 3 commits into
base: series/2.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
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
46 changes: 36 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import com.typesafe.tools.mima.core.*
import org.scalajs.linker.interface.ModuleSplitStyle
import sbtcrossproject.CrossPlugin.autoImport.{ crossProject, CrossType }
import sbt.*
import Keys.*

val scala212 = "2.12.20"
val scala213 = "2.13.15"
Expand Down Expand Up @@ -215,7 +217,24 @@ lazy val tools = project
"dev.zio" %% "zio-test" % zioVersion % Test,
"dev.zio" %% "zio-test-sbt" % zioVersion % Test,
"dev.zio" %% "zio-json" % zioJsonVersion % Test
)
),
Test / publishArtifact := true,

// Include test artifact for publishLocal
publishLocalConfiguration := {
val config = publishLocalConfiguration.value
val testArtifacts = (Test / packagedArtifacts).value
config.withArtifacts(config.artifacts ++ testArtifacts).withOverwrite(true)
},
// Exclude test artifact from publish
publishConfiguration := {
val config = publishConfiguration.value
config
.withArtifacts(config.artifacts.filterNot { case (artifact, _) =>
artifact.configurations.exists(_.name == "test")
})
.withOverwrite(true)
}
Comment on lines +221 to +237
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should prevent test compile classes from being included on publish, but allow for it for publishLocal.

)
.dependsOn(core, clientJVM, quickAdapter % Test)

Expand Down Expand Up @@ -266,18 +285,25 @@ lazy val codegenSbt = project
.settings(
scriptedLaunchOpts := {
scriptedLaunchOpts.value ++
Seq("-Xmx1024M", "-Xss4M", "-Dplugin.version=" + version.value)
Seq(
"-Xmx1024M",
"-Xss4M",
"-Dplugin.version=" + version.value,
s"-Dproject.dir=${baseDirectory.value.getAbsolutePath}"
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Since sbt-test run from /tmp we add project.dir property to be able to resolve and update graphql snapshot file.

)
},
scriptedBufferLog := false,
scriptedDependencies := {
(macros / publishLocal).value
(core / publishLocal).value
(clientJVM / publishLocal).value
(tools / publishLocal).value
publishLocal.value
}
scriptedDependencies := scriptedDependencies
.dependsOn(
macros / publishLocal,
core / publishLocal,
clientJVM / publishLocal,
tools / publishLocal,
publishLocal
)
.value
)
.dependsOn(tools)
.dependsOn(tools % "compile->compile;test->test")

lazy val catsInterop = project
.in(file("interop/cats"))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
# Test doc

This test project has been copied from: https://github.com/guizmaii/poc_compile_time_caliban_client_generation
This test project has been copied from:
https://github.com/guizmaii/poc_compile_time_caliban_client_generation

### Running locally
You can run these tests using following sbt commandos:

```sbt
project codegenSbt
++2.12
update
scripted compiletime-codegen/test-compile
```
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,20 @@ ThisBuild / crossScalaVersions := allScala

// ### Dependencies ###

lazy val calibanLib: Seq[ModuleID] =
sys.props.get("plugin.version") match {
case Some(x) => Seq("com.github.ghostdogpr" %% "caliban" % x)
case _ => sys.error("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
}
lazy val calibanLib = Seq(
"com.github.ghostdogpr" %% "caliban" % Version.pluginVersion,
"com.github.ghostdogpr" %% "caliban-tools" % Version.pluginVersion % "compile->compile;test->test"
)

lazy val sttp = Seq(
"com.softwaremill.sttp.client3" %% "core" % "3.9.8",
"com.softwaremill.sttp.client3" %% "zio" % "3.9.8"
)

lazy val zioTest = Seq(
"dev.zio" %% "zio-test" % "2.1.9" % Test,
"dev.zio" %% "zio-test-sbt" % "2.1.9" % Test
)
// ### App Modules ###

/**
Expand Down Expand Up @@ -103,7 +105,7 @@ lazy val posts =
)
)
)
.settings(libraryDependencies ++= calibanLib)
.settings(libraryDependencies ++= calibanLib ++ zioTest)

lazy val potatoes =
project
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
scalar Unit

input AuthorNameInput {
name: String!
}

input PostContentInput {
content: String!
}

input PostTitleInput {
title: String!
}

type AuthorName {
name: String!
}

type Mutation {
createPost(authorName: AuthorNameInput!, title: PostTitleInput!, content: PostContentInput!): Post
deletePost(id: ID!): Unit
}

type Post {
id: PostId!
author: AuthorName!
title: PostTitle!
content: PostContent!
}

type PostContent {
content: String!
}

type PostId {
id: ID!
}

type PostTitle {
title: String!
}

type Query {
postById(id: ID!): Post
}

type Subscription {
allPostsByAuthor(name: String!): Post
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import poc.caliban.posts.GraphQLApi

import scala.io.Source
import zio.test.Assertion._
import zio.test._
import caliban.tools._
import java.nio.file.Path

object ValidateGraphQlSpec extends SnapshotTest {
override val testName: String = "ValidateGraphQlSpec"

val graphqlFile= "src/sbt-test/compiletime-codegen/test-compile/modules/posts/src/test/resources/postservice.graphql"
val projectDir = sys.props.get("project.dir").getOrElse("")

override def spec =
suite("Validate Postservice")(
test("Render postservice as earlier") {
val gqlApi = GraphQLApi.api
val renderContent: String = s"${gqlApi.render}"

writeAndCompare(Path.of(projectDir).resolve(graphqlFile), renderContent, "Render postservice")
}
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
object Version {
def pluginVersion: String =
sys.props.get("plugin.version") match {
case Some(x) => x
case _ => sys.error("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -201,3 +201,5 @@ $ exists modules/potatoes-clients/src/main/scala/poc/caliban/client/generated/po
-$ newer modules/posts/target/ctCalibanServer/touch modules/posts/target/ctCalibanServer/touch_old
# TODO: This should be newer, sadly I don't find how to make it work.
-$ newer modules/posts-clients/target/scala-2.12/src_managed/main/poc/caliban/client/generated/posts/CalibanClient.scala modules/posts-clients/tmp/CalibanClient.scala.old

> reload; test
81 changes: 48 additions & 33 deletions tools/src/test/scala/caliban/tools/SnapshotTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package caliban.tools

import caliban.tools.SnapshotTest.GitLock
import zio.internal.stacktracer.SourceLocation
import zio.test.{ assert, assertTrue, Assertion, Spec, TestResult, ZIOSpecDefault }
import zio.prelude._
import zio.test.Assertion.equalTo
import zio.test.{ assert, assertNever, assertTrue, Assertion, Spec, TestResult, ZIOSpecDefault }
import zio.{ Task, Trace }

import java.nio.file.{ Files, Path }
Expand All @@ -16,51 +18,64 @@ trait SnapshotTest extends ZIOSpecDefault {
)(str: Task[String])(implicit sourceLocation: SourceLocation, trace: Trace): Spec[Any, Throwable] = {
val label = label0.replace('/', '_').replace("'", "")
zio.test.test[Task[TestResult]](label) {
str.map { str =>
val isCi = SnapshotTest.isCi
str.map { content =>
val path = SnapshotTest.projectRoot.resolve(s"tools/src/test/resources/snapshots/$testName/${label + ".scala"}")
writeAndCompare(path, content, label)
}
}
}

def write(): TestResult = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moving helper function out for reuse

Files.createDirectories(path.getParent)
Files.writeString(path, str)
import scala.sys.process._
// at least don't take the git lock multiple times from same process. this can still fail if concurrent processes try to take it.
GitLock.synchronized {
// allow failing external command, but complain to stderr
try s"git add '$path'".!
catch {
case th: Throwable =>
System.err.println(s"Could not add snapshot file '$path' to git: ${th.getMessage}")
}
}
assert(())(Assertion.anything)
}
private def write(path: Path, str: String): TestResult = {
Files.createDirectories(path.getParent)
Files.writeString(path, str)
import scala.sys.process._

Try(Files.readString(path)) match {
case Success(existing) if isCi =>
assertTrue(str == existing).label(
s"generated result for test '$label' did not match snapshot contents in file '$path. Rerun with environment `CI` not set to 'true' to update and then check in the file"
)
case Success(_) =>
write()
case Failure(_) if isCi =>
assertTrue(false).label(
s"Could not read snapshot file '$path'. Rerun with environment `CI` not set to 'true' to create and then check in the file"
)
case Failure(_) =>
write()
var exitCode = 0
// at least don't take the git lock multiple times from same process. this can still fail if concurrent processes try to take it.
GitLock.synchronized {
// allow failing external command, but complain to stderr
exitCode =
Copy link
Contributor Author

Choose a reason for hiding this comment

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

execution can fail with exitCode so we need to check it as it won`t be throwing exception

try
s"git add '$path'".!
catch {
case th: Throwable =>
System.err.println(s"Could not add snapshot file '$path' to git: ${th.getMessage}")
-1
}
}
}

if (exitCode == 0) {
assert(())(Assertion.anything)
} else {
assertNever(s"Failed to add file '$path' to git. Exit code: $exitCode")
}
}

def writeAndCompare(path: Path, content: String, label: String): TestResult =
Try(Files.readString(path)) match {
case Success(existing) if SnapshotTest.isCi =>
assertTrue(content == existing).label(
s"generated result for test '$label' did not match snapshot contents in file '$path. Rerun with environment `CI` not set to 'true' to update and then check in the file"
)
case Success(existing) if existing.equals(content) =>
assert(())(Assertion.anything)
case Success(_) =>
write(path, content)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Only if it changed we attempt to update it and add it to git.
In case of scripted test, it will be updated, but test will fail on adding to git. (running from /tmp ) - as warning,
but snapshot will be updated for second run.

case Failure(_) if SnapshotTest.isCi =>
assertTrue(false).label(
s"Could not read snapshot file '$path'. Rerun with environment `CI` not set to 'true' to create and then check in the file"
)
case Failure(_) =>
write(path, content)
}

}

object SnapshotTest {
val `.git`: Path = Path.of(".git")
val cwd: Path = Path.of(sys.props("user.dir"))

val projectRoot: Path = {
lazy val projectRoot: Path = {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

For scripted test this will fail so better not evaluate it.

def lookUpwards(p: Path): Option[Path] =
if (Files.list(p).anyMatch(p => p.getFileName == `.git`)) Some(p)
else Option(p.getParent).flatMap(lookUpwards)
Expand Down