Add custom handling for Disabled companion object

https://github.com/sbt/librarymanagement/pull/316 started returning Disabled companion object for `apply()` instead of creating a new instance.
This leaked into JSON as it uses runtime types for union. This works around that by providing a hand-crafted format.

Ref https://github.com/sbt/sbt/pull/4997
This commit is contained in:
Eugene Yokota 2019-08-28 18:33:46 -04:00
parent 2071b29748
commit b01b61384e
2 changed files with 39 additions and 9 deletions

View File

@ -331,14 +331,30 @@ trait CrossVersionFormats {
with sbt.librarymanagement.ConstantFormats
with sbt.librarymanagement.PatchFormats
with sbt.librarymanagement.FullFormats =>
implicit lazy val CrossVersionFormat: JsonFormat[sbt.librarymanagement.CrossVersion] =
flatUnionFormat6[
sbt.librarymanagement.CrossVersion,
sbt.librarymanagement.Disabled,
sbt.librarymanagement.Disabled.type,
sbt.librarymanagement.Binary,
sbt.librarymanagement.Constant,
sbt.librarymanagement.Patch,
sbt.librarymanagement.Full
implicit lazy val CrossVersionFormat: JsonFormat[CrossVersion] = {
val format = flatUnionFormat6[
CrossVersion,
Disabled,
Disabled.type,
Binary,
Constant,
Patch,
Full
]("type")
// This is a hand-crafted formatter to avoid Disabled$ showing up in JSON
new JsonFormat[CrossVersion] {
override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): CrossVersion =
format.read(jsOpt, unbuilder)
override def write[J](obj: CrossVersion, builder: Builder[J]): Unit = {
if (obj == Disabled) {
builder.beginPreObject()
builder.addFieldName("type")
builder.writeString("Disabled")
builder.endPreObject()
builder.beginObject()
builder.endObject()
} else format.write(obj, builder)
}
}
}
}

View File

@ -1,8 +1,11 @@
package sbt.librarymanagement
import sbt.internal.librarymanagement.UnitSpec
import sjsonnew.support.scalajson.unsafe.{ Converter, CompactPrinter, Parser }
class ModuleIdTest extends UnitSpec {
val expectedJson =
"""{"organization":"com.acme","name":"foo","revision":"1","isChanging":false,"isTransitive":true,"isForce":false,"explicitArtifacts":[],"inclusions":[],"exclusions":[],"extraAttributes":{},"crossVersion":{"type":"Disabled"}}"""
"Module Id" should "return cross-disabled module id as equal to a copy" in {
ModuleID("com.acme", "foo", "1") shouldBe ModuleID("com.acme", "foo", "1")
}
@ -14,4 +17,15 @@ class ModuleIdTest extends UnitSpec {
(ModuleID("com.acme", "foo", "1") cross CrossVersion.binary) shouldBe
(ModuleID("com.acme", "foo", "1") cross CrossVersion.binary)
}
it should "format itself into JSON" in {
import LibraryManagementCodec._
val json = Converter.toJson(ModuleID("com.acme", "foo", "1")).get
assert(CompactPrinter(json) == expectedJson)
}
it should "thaw back from JSON" in {
import LibraryManagementCodec._
val json = Parser.parseUnsafe(expectedJson)
val m = Converter.fromJsonUnsafe[ModuleID](json)
assert(m == ModuleID("com.acme", "foo", "1"))
}
}