Skip to content

Commit

Permalink
fix #240, ser of option with trait value type
Browse files Browse the repository at this point in the history
Not sure if this is the best fix or not, but it at least
provides a simple inline test case to reproduce the issue
and passes all of the existing tests.
  • Loading branch information
brharrington committed Jul 7, 2016
1 parent db8b67d commit 0add81c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
Expand Up @@ -3,6 +3,7 @@ package module.scala
package ser

import java.lang.reflect.Type

import com.fasterxml.jackson.annotation.JsonInclude
import com.fasterxml.jackson.core.JsonGenerator
import com.fasterxml.jackson.databind._
Expand Down Expand Up @@ -96,7 +97,10 @@ private class OptionSerializer(referredType: JavaType,
ser = ser.orElse(valueSerializer).map(prov.handlePrimaryContextualization(_, prop)).asInstanceOf[Option[JsonSerializer[AnyRef]]]
ser = Option(findConvertingContentSerializer(prov, prop, ser.orNull).asInstanceOf[JsonSerializer[AnyRef]])
ser = ser match {
case None => if (hasContentTypeAnnotation(prov, prop)) {
case None => if (hasContentTypeAnnotation(prov, prop) && referredType.isContainerType) {
// In some cases `findValueSerializer` will return a BeanSerializer instance
// if the value type is a trait. This results in empty objects if the concrete
// value is a case class.
Option(prov.findValueSerializer(referredType, prop)).filterNot(_.isInstanceOf[UnknownSerializer])
} else None
case Some(s) => Option(prov.handlePrimaryContextualization(s, prop).asInstanceOf[JsonSerializer[AnyRef]])
Expand Down
Expand Up @@ -46,8 +46,20 @@ object OptionSerializerTest {
_base = base
}
}

// For issue #240, for some reason it works fine when these classes are part
// of the object.
trait M1
case class F1(label: String) extends M1
case class C1(m: Option[M1])
}

// For issue #240, these need to be outside of the object to reproduce
// the problem.
trait M2
case class F2(label: String) extends M2
case class C2(m: Option[M2])

@RunWith(classOf[JUnitRunner])
class OptionSerializerTest extends SerializerTest {
import OptionSerializerTest._
Expand Down Expand Up @@ -75,6 +87,19 @@ class OptionSerializerTest extends SerializerTest {
serialize(noneOption) should be ("null")
}

it should "serialize concrete type when using Option[Trait] (in object)" in {
// Additional test case for #240, for some reason this test case works fine.
// However, if the classes are moved outside of the object then it starts
// breaking.
serialize(C1(Some(F1("foo")))) should be ("""{"m":{"label":"foo"}}""")
}

it should "serialize concrete type when using Option[Trait]" in {
// See https://github.com/FasterXML/jackson-module-scala/issues/240 for more information.
// This test case reproduces the problem in the ticket.
serialize(C2(Some(F2("foo")))) should be ("""{"m":{"label":"foo"}}""")
}

it should "serialize an Option[java.lang.Integer] when accessed on a class" in {
case class Review(score: java.lang.Integer)
val r1: Review = null
Expand Down

0 comments on commit 0add81c

Please sign in to comment.