From 2a372d47b4000f487080b3eeeacd58ba2dfbceea Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Tue, 11 Sep 2018 17:47:44 -0700 Subject: Upgrade magnolia --- CHANGELOG.md | 4 ++++ build.sbt | 2 +- shared/src/main/scala/DerivedFormats.scala | 22 +++++++++----------- shared/src/test/scala/FieldNameTests.scala | 1 + shared/src/test/scala/OptionFieldTests.scala | 24 +++++++++++++++++++++- shared/src/test/scala/ProductTypeFormatTests.scala | 20 +++++++++--------- 6 files changed, 49 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4c52155..54ffb7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +# UNRELEASED + +- Upgrade magnolia to official upstream, 0.10.0. + # Version 0.6.0 - Value classes are handled transparently. I.e. their values are diff --git a/build.sbt b/build.sbt index f4a72e0..349f96e 100644 --- a/build.sbt +++ b/build.sbt @@ -21,7 +21,7 @@ lazy val sprayJsonDerivation = ), libraryDependencies ++= Seq( "io.crashbox" %%% "spray-json" % "1.3.4-1", - "io.crashbox" %%% "magnolia" % "0.8.0-1" + "com.propensive" %%% "magnolia" % "0.10.0" ) ) .platformsSettings(JVMPlatform, JSPlatform)( diff --git a/shared/src/main/scala/DerivedFormats.scala b/shared/src/main/scala/DerivedFormats.scala index 7c13314..c4781fa 100644 --- a/shared/src/main/scala/DerivedFormats.scala +++ b/shared/src/main/scala/DerivedFormats.scala @@ -29,14 +29,16 @@ trait DerivedFormats { self: BasicFormats => val param = ctx.parameters.head param.typeclass.write(param.dereference(value)) } else { - val fields: Seq[(String, JsValue)] = ctx.parameters.collect { - case param - if !param.option || param.dereference(value) != None || printNull => - extractFieldName(param.label) -> param.typeclass.write( - param.dereference(value) - ) + val fields: Seq[(String, JsValue)] = ctx.parameters.map { param => + extractFieldName(param.label) -> param.typeclass.write( + param.dereference(value) + ) + } + val nullFiltered = fields.filter { + case (_, JsNull) => printNull + case (_, _) => true } - JsObject(fields: _*) + JsObject(nullFiltered: _*) } override def read(value: JsValue): T = value match { @@ -48,11 +50,7 @@ trait DerivedFormats { self: BasicFormats => } else { ctx.construct { param => val fieldName = extractFieldName(param.label) - val fieldValue = if (param.option) { - obj.fields.getOrElse(fieldName, JsNull) - } else { - obj.fields(fieldName) - } + val fieldValue = obj.fields.getOrElse(fieldName, JsNull) param.typeclass.read(fieldValue) } } diff --git a/shared/src/test/scala/FieldNameTests.scala b/shared/src/test/scala/FieldNameTests.scala index ef4064d..cda5837 100644 --- a/shared/src/test/scala/FieldNameTests.scala +++ b/shared/src/test/scala/FieldNameTests.scala @@ -9,6 +9,7 @@ class FieldNameTests extends FlatSpec with FormatTests { case class C(abA: String) trait All extends DefaultJsonProtocol with DerivedFormats { + implicit val aFormat = jsonFormat[A] implicit val bFormat = jsonFormat[B] implicit val cFormat = jsonFormat[C] } diff --git a/shared/src/test/scala/OptionFieldTests.scala b/shared/src/test/scala/OptionFieldTests.scala index 8cabf25..ac925d7 100644 --- a/shared/src/test/scala/OptionFieldTests.scala +++ b/shared/src/test/scala/OptionFieldTests.scala @@ -6,7 +6,8 @@ class OptionFieldTests extends FlatSpec with FormatTests { - case class Opt(x: Option[Int]) + sealed trait Super + case class Opt(x: Option[Int]) extends Super object HideNull extends DerivedJsonProtocol { override def printNull = false @@ -49,5 +50,26 @@ class OptionFieldTests assert("{}".parseJson.convertTo[Opt] == Opt(None)) } + { + import ShowNull._ + implicit val superFmt = jsonFormat[Super] + "Option fields of ADTs" should behave like checkRoundtrip( + Opt(Some(2)): Super, + """{ "@type": "Opt", "x":2}""" + ) + } + + sealed trait Enum + case class Value(x: Int) extends Enum + case class Wrapper(enum: Option[Enum]) + + import ShowNull._ + implicit val enumFormat: RootJsonFormat[Enum] = jsonFormat[Enum] + implicit val superFmt: RootJsonFormat[Wrapper] = jsonFormat[Wrapper] + "Option fields of inner ADTs" should behave like checkRoundtrip( + Wrapper(Some(Value(1))), + """{"enum":{"@type":"Value", "x": 1}}""" + ) + } diff --git a/shared/src/test/scala/ProductTypeFormatTests.scala b/shared/src/test/scala/ProductTypeFormatTests.scala index d7721ba..7964743 100644 --- a/shared/src/test/scala/ProductTypeFormatTests.scala +++ b/shared/src/test/scala/ProductTypeFormatTests.scala @@ -12,8 +12,8 @@ class ProductTypeFormatTests case class C(b: B) case object D case class E(d: D.type) - case class F(x: Int) - case class G(f: F) + case class FF(x: Int) + case class G(f: FF) implicit val aFormat: RootJsonFormat[A] = jsonFormat[A] implicit val bFormat: RootJsonFormat[B] = jsonFormat[B] @@ -44,28 +44,28 @@ class ProductTypeFormatTests ) // custom format for F, that inverts the value of parameter x - implicit val fFormat: RootJsonFormat[F] = new RootJsonFormat[F] { - override def write(f: F): JsValue = JsObject("y" -> f.x.toJson) - override def read(js: JsValue): F = - F(js.asJsObject.fields("y").convertTo[Int]) + implicit val fFormat: RootJsonFormat[FF] = new RootJsonFormat[FF] { + override def write(f: FF): JsValue = JsObject("y" -> f.x.toJson) + override def read(js: JsValue): FF = + FF(js.asJsObject.fields("y").convertTo[Int]) } "Overriding with a custom format" should behave like checkRoundtrip( - F(2), + FF(2), """{"y":2}""" ) implicit val gFormat: RootJsonFormat[G] = jsonFormat[G] "Derving a format with a custom child format" should behave like checkRoundtrip( - G(F(2)), + G(FF(2)), """{"f": {"y":2}}""" ) case class H(x: Boolean) case class I(h: H) - // there is no format defined for H, Magnolia will generate one automatically + implicit val hFormat = jsonFormat[H] implicit val iFormat: RootJsonFormat[I] = jsonFormat[I] "Deriving a format that has no implicit child formats available" should behave like checkRoundtrip( @@ -105,7 +105,7 @@ class ProductTypeFormatTests implicit def vcg[T: JsonFormat] = jsonFormat[ProductTypeFormatTests.WrapperGeneric[T]] "Value classes with generic parameters" should behave like checkRoundtrip( - ProductTypeFormatTests.WrapperGeneric[F](F(42)), + ProductTypeFormatTests.WrapperGeneric[FF](FF(42)), """{"y": 42}""" ) -- cgit v1.2.3