Skip to content

Commit

Permalink
Merge pull request #529 from commercetools/cut-adhoc-flaky-discount-test
Browse files Browse the repository at this point in the history
Fix for reading Some(Map.empty)
  • Loading branch information
martinw-ct authored Sep 11, 2023
2 parents 51637a9 + 965f752 commit e667059
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 0 deletions.
11 changes: 11 additions & 0 deletions json/json-core/src/main/scala/io/sphere/json/FromJSON.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,17 @@ object FromJSON extends FromJSONInstances {
private def validEmptyVector[A]: Valid[Vector[A]] =
validEmptyAnyVector.asInstanceOf[Valid[Vector[A]]]

implicit def optionMapReader[@specialized A](implicit
c: FromJSON[A]): FromJSON[Option[Map[String, A]]] =
new FromJSON[Option[Map[String, A]]] {
private val internalMapReader = mapReader[A]

def read(jval: JValue): JValidation[Option[Map[String, A]]] = jval match {
case JNothing | JNull => validNone
case x => internalMapReader.read(x).map(Some.apply)
}
}

implicit def optionReader[@specialized A](implicit c: FromJSON[A]): FromJSON[Option[A]] =
new FromJSON[Option[A]] {
def read(jval: JValue): JValidation[Option[A]] = jval match {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.sphere.json

import io.sphere.json.generic._
import org.json4s.{JArray, JLong, JNothing, JObject, JString}
import org.scalatest.OptionValues
import org.scalatest.matchers.must.Matchers
import org.scalatest.wordspec.AnyWordSpec
Expand All @@ -19,6 +20,15 @@ object OptionReaderSpec {
implicit val json: JSON[ComplexClass] = jsonProduct(apply _)
}

case class MapClass(id: Long, map: Option[Map[String, String]])
object MapClass {
implicit val json: JSON[MapClass] = jsonProduct(apply _)
}

case class ListClass(id: Long, list: Option[List[String]])
object ListClass {
implicit val json: JSON[ListClass] = jsonProduct(apply _)
}
}

class OptionReaderSpec extends AnyWordSpec with Matchers with OptionValues {
Expand Down Expand Up @@ -61,6 +71,42 @@ class OptionReaderSpec extends AnyWordSpec with Matchers with OptionValues {
result mustEqual None
}

"handle optional map" in {
getFromJValue[MapClass](JObject("id" -> JLong(1L))) mustEqual MapClass(1L, None)

getFromJValue[MapClass](JObject("id" -> JLong(1L), "map" -> JObject())) mustEqual
MapClass(1L, Some(Map.empty))

getFromJValue[MapClass](
JObject("id" -> JLong(1L), "map" -> JObject("a" -> JString("b")))) mustEqual
MapClass(1L, Some(Map("a" -> "b")))

toJValue[MapClass](MapClass(1L, None)) mustEqual
JObject("id" -> JLong(1L), "map" -> JNothing)
toJValue[MapClass](MapClass(1L, Some(Map()))) mustEqual
JObject("id" -> JLong(1L), "map" -> JObject())
toJValue[MapClass](MapClass(1L, Some(Map("a" -> "b")))) mustEqual
JObject("id" -> JLong(1L), "map" -> JObject("a" -> JString("b")))
}

"handle optional list" in {
getFromJValue[ListClass](
JObject("id" -> JLong(1L), "list" -> JArray(List(JString("hi"))))) mustEqual
ListClass(1L, Some(List("hi")))
getFromJValue[ListClass](JObject("id" -> JLong(1L), "list" -> JArray(List.empty))) mustEqual
ListClass(1L, Some(List()))
getFromJValue[ListClass](JObject("id" -> JLong(1L))) mustEqual
ListClass(1L, None)

toJValue(ListClass(1L, Some(List("hi")))) mustEqual JObject(
"id" -> JLong(1L),
"list" -> JArray(List(JString("hi"))))
toJValue(ListClass(1L, Some(List.empty))) mustEqual JObject(
"id" -> JLong(1L),
"list" -> JArray(List.empty))
toJValue(ListClass(1L, None)) mustEqual JObject("id" -> JLong(1L), "list" -> JNothing)
}

"handle absence of all fields mixed with ignored fields" in {
val json = """{ "value3": "a" }"""
val result = getFromJSON[Option[SimpleClass]](json)
Expand Down

0 comments on commit e667059

Please sign in to comment.