Skip to content

Commit

Permalink
Merge pull request #41 from sh0hei/hello-scalafmt
Browse files Browse the repository at this point in the history
Hello, scalafmt
  • Loading branch information
yanns authored Feb 16, 2021
2 parents 60e8b1f + a2ee73e commit 80d2fee
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 60 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ jobs:
- name: Check binary compatibility
run: sbt ++${{ matrix.scala }} mimaReportBinaryIssues

- name: Check formatting
run: sbt ++${{ matrix.scala }} scalafmtCheckAll

- name: Check that workflows are up to date
run: sbt ++${{ matrix.scala }} githubWorkflowCheck

Expand Down
18 changes: 18 additions & 0 deletions .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version = 2.7.5

style = default

maxColumn = 100

// Vertical alignment is pretty, but leads to bigger diffs
align.preset = none

danglingParentheses.preset = false

rewrite.rules = [
AvoidInfix
RedundantBraces
RedundantParens
AsciiSortImports
PreferCurlyFors
]
27 changes: 17 additions & 10 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@ mimaPreviousArtifacts := Set("org.sangria-graphql" %% "sangria-play-json" % "2.0

description := "Sangria play-json marshalling"
homepage := Some(url("http://sangria-graphql.org"))
licenses := Seq("Apache License, ASL Version 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0"))
licenses := Seq(
"Apache License, ASL Version 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0"))

ThisBuild / crossScalaVersions := Seq("2.12.13", "2.13.4")
ThisBuild / scalaVersion := crossScalaVersions.value.last
ThisBuild / githubWorkflowPublishTargetBranches := List()
ThisBuild / githubWorkflowBuildPreamble ++= List(
WorkflowStep.Sbt(List("mimaReportBinaryIssues"), name = Some("Check binary compatibility"))
WorkflowStep.Sbt(List("mimaReportBinaryIssues"), name = Some("Check binary compatibility")),
WorkflowStep.Sbt(List("scalafmtCheckAll"), name = Some("Check formatting"))
)

scalacOptions += "-target:jvm-1.8"
Expand All @@ -21,9 +23,9 @@ scalacOptions ++= Seq("-deprecation", "-feature")
libraryDependencies ++= Seq(
"org.sangria-graphql" %% "sangria-marshalling-api" % "1.0.5",
"com.typesafe.play" %% "play-json" % "2.9.2",

"org.sangria-graphql" %% "sangria-marshalling-testkit" % "1.0.3" % Test,
"org.scalatest" %% "scalatest" % "3.2.3" % Test)
"org.scalatest" %% "scalatest" % "3.2.3" % Test
)

// Publishing

Expand All @@ -34,15 +36,20 @@ publishArtifact in Test := false
pomIncludeRepository := (_ => false)
publishTo := Some(
if (version.value.trim.endsWith("SNAPSHOT"))
"snapshots" at "https://oss.sonatype.org/content/repositories/snapshots"
"snapshots".at("https://oss.sonatype.org/content/repositories/snapshots")
else
"releases" at "https://oss.sonatype.org/service/local/staging/deploy/maven2")
"releases".at("https://oss.sonatype.org/service/local/staging/deploy/maven2"))
startYear := Some(2016)
organizationHomepage := Some(url("https://github.com/sangria-graphql"))
developers := Developer("OlegIlyenko", "Oleg Ilyenko", "", url("https://github.com/OlegIlyenko")) :: Nil
scmInfo := Some(ScmInfo(
browseUrl = url("https://github.com/sangria-graphql/sangria-play-json.git"),
connection = "scm:git:[email protected]:sangria-graphql/sangria-play-json.git"))
developers := Developer(
"OlegIlyenko",
"Oleg Ilyenko",
"",
url("https://github.com/OlegIlyenko")) :: Nil
scmInfo := Some(
ScmInfo(
browseUrl = url("https://github.com/sangria-graphql/sangria-play-json.git"),
connection = "scm:git:[email protected]:sangria-graphql/sangria-play-json.git"))

// nice *magenta* prompt!

Expand Down
1 change: 1 addition & 0 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ addSbtPlugin("com.typesafe" % "sbt-mima-plugin" % "0.8.1")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.6.1")
addSbtPlugin("org.scoverage" % "sbt-coveralls" % "1.2.7")
addSbtPlugin("com.codecommit" % "sbt-github-actions" % "0.10.1")
addSbtPlugin("org.scalameta" % "sbt-scalafmt" % "2.4.2")
50 changes: 29 additions & 21 deletions src/main/scala/sangria/marshalling/playJson.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ object playJson extends PlayJsonSupportLowPrioImplicits {
type MapBuilder = ArrayMapBuilder[Node]

override def emptyMapNode(keys: Seq[String]): MapBuilder = new ArrayMapBuilder[Node](keys)
override def addMapNodeElem(builder: MapBuilder, key: String, value: Node, optional: Boolean): MapBuilder = builder.add(key, value)
override def addMapNodeElem(
builder: MapBuilder,
key: String,
value: Node,
optional: Boolean): MapBuilder = builder.add(key, value)

override def mapNode(builder: MapBuilder): Node = JsObject(builder.toSeq)
override def mapNode(keyValues: Seq[(String, JsValue)]): Node = JsObject(keyValues)
Expand All @@ -22,18 +26,19 @@ object playJson extends PlayJsonSupportLowPrioImplicits {
case None => nullNode
}

override def scalarNode(value: Any, typeName: String, info: Set[ScalarValueInfo]): Node = value match {
case v: String => JsString(v)
case true => JsTrue
case false => JsFalse
case v: Int => JsNumber(BigDecimal(v))
case v: Long => JsNumber(BigDecimal(v))
case v: Float => JsNumber(BigDecimal(v.toDouble))
case v: Double => JsNumber(BigDecimal(v))
case v: BigInt => JsNumber(BigDecimal(v))
case v: BigDecimal => JsNumber(v)
case v => throw new IllegalArgumentException("Unsupported scalar value: " + v)
}
override def scalarNode(value: Any, typeName: String, info: Set[ScalarValueInfo]): Node =
value match {
case v: String => JsString(v)
case true => JsTrue
case false => JsFalse
case v: Int => JsNumber(BigDecimal(v))
case v: Long => JsNumber(BigDecimal(v))
case v: Float => JsNumber(BigDecimal(v.toDouble))
case v: Double => JsNumber(BigDecimal(v))
case v: BigInt => JsNumber(BigDecimal(v))
case v: BigDecimal => JsNumber(v)
case v => throw new IllegalArgumentException("Unsupported scalar value: " + v)
}

override def enumNode(value: String, typeName: String): Node = JsString(value)

Expand All @@ -48,19 +53,21 @@ object playJson extends PlayJsonSupportLowPrioImplicits {
}

implicit object PlayJsonInputUnmarshaller extends InputUnmarshaller[JsValue] {
override def getRootMapValue(node: JsValue, key: String): Option[JsValue] = node.asInstanceOf[JsObject].value get key
override def getRootMapValue(node: JsValue, key: String): Option[JsValue] =
node.asInstanceOf[JsObject].value.get(key)

override def isListNode(node: JsValue) = node.isInstanceOf[JsArray]
override def getListValue(node: JsValue): Seq[JsValue] = node.asInstanceOf[JsArray].value.toSeq

override def isMapNode(node: JsValue): Boolean = node.isInstanceOf[JsObject]
override def getMapValue(node: JsValue, key: String): Option[JsValue] = node.asInstanceOf[JsObject].value get key
override def getMapValue(node: JsValue, key: String): Option[JsValue] =
node.asInstanceOf[JsObject].value.get(key)
override def getMapKeys(node: JsValue): Iterable[String] = node.asInstanceOf[JsObject].keys

override def isDefined(node: JsValue): Boolean = node != JsNull
override def getScalarValue(node: JsValue): Any = node match {
case JsBoolean(b) => b
case JsNumber(d) => d.toBigIntExact getOrElse d
case JsNumber(d) => d.toBigIntExact.getOrElse(d)
case JsString(s) => s
case _ => throw new IllegalStateException(s"$node is not a scalar value")
}
Expand All @@ -75,7 +82,8 @@ object playJson extends PlayJsonSupportLowPrioImplicits {
}

override def isVariableNode(node: JsValue): Boolean = false
override def getVariableName(node: JsValue): String = throw new IllegalArgumentException("variables are not supported")
override def getVariableName(node: JsValue): String = throw new IllegalArgumentException(
"variables are not supported")

override def render(node: JsValue): String = Json.stringify(node)
}
Expand All @@ -87,7 +95,7 @@ object playJson extends PlayJsonSupportLowPrioImplicits {
implicit def playJsonToInput[T <: JsValue]: ToInput[T, JsValue] =
PlayJsonToInput.asInstanceOf[ToInput[T, JsValue]]

implicit def playJsonWriterToInput[T : Writes]: ToInput[T, JsValue] =
implicit def playJsonWriterToInput[T: Writes]: ToInput[T, JsValue] =
new ToInput[T, JsValue] {
def toInput(value: T) = implicitly[Writes[T]].writes(value) -> PlayJsonInputUnmarshaller
}
Expand All @@ -100,14 +108,14 @@ object playJson extends PlayJsonSupportLowPrioImplicits {
implicit def playJsonFromInput[T <: JsValue]: FromInput[T] =
PlayJsonFromInput.asInstanceOf[FromInput[T]]

implicit def playJsonReaderFromInput[T : Reads]: FromInput[T] =
implicit def playJsonReaderFromInput[T: Reads]: FromInput[T] =
new FromInput[T] {
val marshaller = PlayJsonResultMarshaller
def fromResult(node: marshaller.Node) = implicitly[Reads[T]].reads(node) match {
case JsSuccess(v, _) => v
case JsError(errors) =>
val formattedErrors = errors.toVector.flatMap {
case (JsPath(nodes), es) => es.map(e => s"At path '${nodes mkString "."}': ${e.message}")
val formattedErrors = errors.toVector.flatMap { case (JsPath(nodes), es) =>
es.map(e => s"At path '${nodes.mkString(".")}': ${e.message}")
}

throw InputParsingError(formattedErrors)
Expand Down
60 changes: 31 additions & 29 deletions src/test/scala/sangria/marshalling/PlayJsonSupportSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,60 +7,62 @@ import sangria.marshalling.playJson._
import org.scalatest.matchers.should.Matchers
import org.scalatest.wordspec.AnyWordSpec


class PlayJsonSupportSpec extends AnyWordSpec with Matchers with MarshallingBehaviour with InputHandlingBehaviour with ParsingBehaviour {
class PlayJsonSupportSpec
extends AnyWordSpec
with Matchers
with MarshallingBehaviour
with InputHandlingBehaviour
with ParsingBehaviour {
implicit val commentFormat = Json.format[Comment]
implicit val articleFormat = Json.format[Article]

"PlayJson integration" should {
behave like `value (un)marshaller` (PlayJsonResultMarshaller)

behave like `AST-based input unmarshaller` (playJsonFromInput[JsValue])
behave like `AST-based input marshaller` (PlayJsonResultMarshaller)

behave like `case class input unmarshaller`
behave like `case class input marshaller` (PlayJsonResultMarshaller)

behave like `input parser` (ParseTestSubjects(
complex = """{"a": [null, 123, [{"foo": "bar"}]], "b": {"c": true, "d": null}}""",
simpleString = "\"bar\"",
simpleInt = "12345",
simpleNull = "null",
list = "[\"bar\", 1, null, true, [1, 2, 3]]",
syntaxError = List("[123, \"FOO\" \"BAR\"")
))
behave.like(`value (un)marshaller`(PlayJsonResultMarshaller))

behave.like(`AST-based input unmarshaller`(playJsonFromInput[JsValue]))
behave.like(`AST-based input marshaller`(PlayJsonResultMarshaller))

behave.like(`case class input unmarshaller`)
behave.like(`case class input marshaller`(PlayJsonResultMarshaller))

behave.like(
`input parser`(ParseTestSubjects(
complex = """{"a": [null, 123, [{"foo": "bar"}]], "b": {"c": true, "d": null}}""",
simpleString = "\"bar\"",
simpleInt = "12345",
simpleNull = "null",
list = "[\"bar\", 1, null, true, [1, 2, 3]]",
syntaxError = List("[123, \"FOO\" \"BAR\"")
)))
}

val toRender = Json.obj(
"a" -> Json.arr(JsNull, JsNumber(123), Json.arr(Json.obj("foo" -> JsString("bar")))),
"b" -> Json.obj(
"c" -> JsBoolean(true),
"d" -> JsNull))
"b" -> Json.obj("c" -> JsBoolean(true), "d" -> JsNull))

"InputUnmarshaller" should {
"throw an exception on invalid scalar values" in {
an [IllegalStateException] should be thrownBy
PlayJsonInputUnmarshaller.getScalarValue(Json.obj())
an[IllegalStateException] should be thrownBy
PlayJsonInputUnmarshaller.getScalarValue(Json.obj())
}

"throw an exception on variable names" in {
an [IllegalArgumentException] should be thrownBy
PlayJsonInputUnmarshaller.getVariableName(JsString("$foo"))
an[IllegalArgumentException] should be thrownBy
PlayJsonInputUnmarshaller.getVariableName(JsString("$foo"))
}

"render JSON values" in {
val rendered = PlayJsonInputUnmarshaller.render(toRender)

rendered should be ("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""")
rendered should be("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""")
}
}

"ResultMarshaller" should {
"render pretty JSON values" in {
val rendered = PlayJsonResultMarshaller.renderPretty(toRender)

rendered.replaceAll("\r", "") should be (
"""{
rendered.replaceAll("\r", "") should be("""{
| "a" : [ null, 123, [ {
| "foo" : "bar"
| } ] ],
Expand All @@ -74,7 +76,7 @@ class PlayJsonSupportSpec extends AnyWordSpec with Matchers with MarshallingBeha
"render compact JSON values" in {
val rendered = PlayJsonResultMarshaller.renderCompact(toRender)

rendered should be ("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""")
rendered should be("""{"a":[null,123,[{"foo":"bar"}]],"b":{"c":true,"d":null}}""")
}
}
}

0 comments on commit 80d2fee

Please sign in to comment.