Last active
April 20, 2022 08:45
-
-
Save fanf/8e77ffcb6af1be02670338254356135d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* These codec used to work with zio-json 2.0.0-M3 but are not working anymore with | |
* zio-json 3.0.0-R7. | |
* Even more strange, if I remove the encoder part (ie from codec to simple decoder), | |
* then the decoding works in 3.0.0-R7. | |
* It looks like a bug | |
*/ | |
package test | |
import org.junit.runner.RunWith | |
import org.specs2.mutable.Specification | |
import org.specs2.runner.JUnitRunner | |
import zio.json._ | |
import zio.json.internal.Write | |
@RunWith(classOf[JUnitRunner]) | |
class ReproduceErrorTest extends Specification { | |
final case class JsonExpectedValueId7_1(id: String, v: String) | |
final case class JsonValueExpectedReport7_1( | |
vid: String | |
, vs: List[Either[List[String],JsonExpectedValueId7_1]] | |
) | |
implicit lazy val codecJsonExpectedValueId7_1: JsonCodec[JsonExpectedValueId7_1] = DeriveJsonCodec.gen | |
implicit lazy val codecJsonEitherValue: JsonCodec[Either[List[String],JsonExpectedValueId7_1]] = { | |
// invariance is complicated | |
def toRight(x: JsonExpectedValueId7_1): Either[List[String],JsonExpectedValueId7_1] = Right(x) | |
def toLeft(x: List[String]): Either[List[String],JsonExpectedValueId7_1] = Left(x) | |
val decoder = JsonDecoder[List[String]].map(toLeft).orElse(codecJsonExpectedValueId7_1.decoder.map(toRight)) | |
val encoder = new JsonEncoder[Either[List[String],JsonExpectedValueId7_1]] { | |
override def unsafeEncode(a: Either[List[String], JsonExpectedValueId7_1], indent: Option[Int], out: Write): Unit = { | |
a match { | |
case Left(x) => JsonEncoder[List[String]].unsafeEncode(x, indent, out) | |
case Right(x) => codecJsonExpectedValueId7_1.encoder.unsafeEncode(x, indent, out) | |
} | |
} | |
} | |
JsonCodec(encoder, decoder) | |
} | |
implicit lazy val codecJsonValueExpectedReport7_1: JsonCodec[JsonValueExpectedReport7_1] = DeriveJsonCodec.gen | |
sequential | |
"the left case" >> { | |
import zio.json._ | |
val jsonMin = | |
""" | |
{ | |
"vid": "Command execution", | |
"vs": [ | |
[ "/bin/echo \"restore\"" ] | |
] | |
} | |
""".stripMargin | |
val expected = JsonValueExpectedReport7_1( | |
"Command execution" | |
, List(Left(List("/bin/echo \"restore\""))) | |
) | |
(jsonMin.fromJson[JsonValueExpectedReport7_1]) must beEqualTo(Right(expected)) | |
} | |
/* | |
Left(.vs[0](expected '{' got '[')) != Right(JsonValueExpectedReport7_1(Command execution,List(Left(List(/bin/echo "restore"))))) expected:<[Right(JsonValueExpectedReport7_1(Command execution,List(Left(List(/bin/echo "restore")))]))> but was:<[Left(.vs[0](expected '{' got '[']))> | |
Comparison Failure: | |
Expected :Right(JsonValueExpectedReport7_1(Command execution,List(Left(List(/bin/echo "restore"))))) | |
Actual :Left(.vs[0](expected '{' got '[')) | |
*/ | |
"the right case" >> { | |
import zio.json._ | |
val jsonMin = | |
""" | |
{ | |
"vid": "Command execution", | |
"vs": [ | |
{"id": "id", "v":"value"} | |
] | |
} | |
""".stripMargin | |
val expected = JsonValueExpectedReport7_1( | |
"Command execution" | |
, List(Right(JsonExpectedValueId7_1("id", "value"))) | |
) | |
(jsonMin.fromJson[JsonValueExpectedReport7_1]) must beEqualTo(Right(expected)) | |
} | |
/* | |
Left(.vs[0](missing fields)) != Right(JsonValueExpectedReport7_1(Command execution,List(Right(JsonExpectedValueId7_1(id,value))))) expected:<[Right(JsonValueExpectedReport7_1(Command execution,List(Right(JsonExpectedValueId7_1(id,value)))]))> but was:<[Left(.vs[0](missing fields]))> | |
Comparison Failure: | |
Expected :Right(JsonValueExpectedReport7_1(Command execution,List(Right(JsonExpectedValueId7_1(id,value))))) | |
Actual :Left(.vs[0](missing fields)) | |
*/ | |
} | |
// | |
// REMOVING encoder makes the decoder works?!? | |
// | |
@RunWith(classOf[JUnitRunner]) | |
class ReproduceErrorTest extends Specification { | |
final case class JsonExpectedValueId7_1(id: String, v: String) | |
final case class JsonValueExpectedReport7_1( | |
vid: String | |
, vs: List[Either[List[String],JsonExpectedValueId7_1]] | |
) | |
implicit lazy val codecJsonExpectedValueId7_1: JsonDecoder[JsonExpectedValueId7_1] = DeriveJsonDecoder.gen | |
implicit lazy val codecJsonEitherValue: JsonDecoder[Either[List[String],JsonExpectedValueId7_1]] = { | |
// invariance is complicated | |
def toRight(x: JsonExpectedValueId7_1): Either[List[String],JsonExpectedValueId7_1] = Right(x) | |
def toLeft(x: List[String]): Either[List[String],JsonExpectedValueId7_1] = Left(x) | |
JsonDecoder[List[String]].map(toLeft).orElse(codecJsonExpectedValueId7_1.map(toRight)) | |
} | |
implicit lazy val codecJsonValueExpectedReport7_1: JsonDecoder[JsonValueExpectedReport7_1] = DeriveJsonDecoder.gen | |
sequential | |
"the left case" >> { | |
import zio.json._ | |
val jsonMin = | |
""" | |
{ | |
"vid": "Command execution", | |
"vs": [ | |
[ "/bin/echo \"restore\"" ] | |
] | |
} | |
""".stripMargin | |
val expected = JsonValueExpectedReport7_1( | |
"Command execution" | |
, List(Left(List("/bin/echo \"restore\""))) | |
) | |
(jsonMin.fromJson[JsonValueExpectedReport7_1]) must beEqualTo(Right(expected)) | |
} | |
// SUCCESS | |
"the right case" >> { | |
import zio.json._ | |
val jsonMin = | |
""" | |
{ | |
"vid": "Command execution", | |
"vs": [ | |
{"id": "id", "v":"value"} | |
] | |
} | |
""".stripMargin | |
val expected = JsonValueExpectedReport7_1( | |
"Command execution" | |
, List(Right(JsonExpectedValueId7_1("id", "value"))) | |
) | |
(jsonMin.fromJson[JsonValueExpectedReport7_1]) must beEqualTo(Right(expected)) | |
} | |
// SUCCESS | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment