amnaredo / test

0 stars 0 forks source link

Problem with default values #145

Open amnaredo opened 2 years ago

amnaredo commented 2 years ago

When using case class as parameter of another case class, default parameter does not work. This probably would not be base of problem. When case class have only one parameter and it has default value, it works. But (presented example), when case class has two parameters, booth with default value, it does not work.

Sample:

import upickle.default._
case class NestedDefault(asdf: Double = null.asInstanceOf[Double], qwer: Int = null.asInstanceOf[Int])
read[NestedDefault]("""{}""")
/*
upickle.Invalid$Data
    at upickle.GeneratedUtil$class.mapToArray(ScalaSandbox.sc0.tmp:40)
    at upickle.default$.mapToArray(ScalaSandbox.sc0.tmp:21)
    at upickle.Implicits$$anonfun$CaseR$1.applyOrElse(ScalaSandbox.sc0.tmp:78)
    at upickle.Implicits$$anonfun$CaseR$1.applyOrElse(ScalaSandbox.sc0.tmp:77)
    at scala.runtime.AbstractPartialFunction.apply(ScalaSandbox.sc0.tmp:32)
    at upickle.Types$Reader$$anonfun$read$1.applyOrElse(ScalaSandbox.sc0.tmp:89)
    at upickle.Types$Reader$$anonfun$read$1.applyOrElse(ScalaSandbox.sc0.tmp:89)
    at scala.PartialFunction$OrElse.apply(ScalaSandbox.sc0.tmp:163)
    at upickle.Types$class.readJs(ScalaSandbox.sc0.tmp:133)
    at upickle.default$.readJs(ScalaSandbox.sc0.tmp:21)
    at upickle.Types$class.read(ScalaSandbox.sc0.tmp:129)
    at upickle.default$.read(ScalaSandbox.sc0.tmp:21)
    at #worksheet#.#worksheet#(ScalaSandbox.sc0.tmp:44)
*/

ID: 111 Original Author: LubomirVarga

amnaredo commented 2 years ago

Workaround is to not use default values (obviously). You can than partly make it nice by using alternative apply methods for default things (like copy method).

Original Author: LubomirVarga

amnaredo commented 2 years ago

There is no such a bug in uPickle. The default values feature does work correctly. The reported problem was caused by "IntelliJ Scala Worksheet" (the usage is visible in the provided error stack). The problem is, that the case class in defined in the worksheet directly and in such a case the Scala macros are not applied to it. The default values does work in a normal case (in tests, in application code). It will work in IntelliJ Scala Worksheet only, when the case class is defined outside of it.

Original Author: gforro

amnaredo commented 2 years ago

Well I got a similar bug in regular code here's a test to hopefully reproduce (JVM, scala 2.11, pickle 0.3.6):

testdata.scala:

package upickle.testdata

case class Content(
  foo: Int = 999,
  bar: Option[String] = None
)

object Protocol {
  case class Container(content: Content)
  def read(str: String) = upickle.default.read[Container](str)
}

UpickleSpec.scala:

package upickle.test

import org.scalatest._
import upickle.testdata.Protocol
import upickle.testdata.Content

class UpickleSpec extends Matchers with FlatSpecLike {
  behavior of "upickle"

  // fails
  it should "read/write our case class with Protocol.read" in {
    val in: Protocol.Container = Protocol.Container(Content())
    val ser = upickle.default.write(in)
    val out = Protocol.read(ser)
    out should be (in)
  }

  // works
  it should "read/write our case class with inline read" in {
    val in: Protocol.Container = Protocol.Container(Content())
    val ser = upickle.default.write(in)
    val out = upickle.default.read[Protocol.Container](ser)
    out should be (in)
  }
}

What's stunning is that in a previous version of upickle I had the exact opposite behaviour, impossible to read something from another module with pickle.default.read but worked perfectly with the def defined in the file containing the data to serialise/deserialize.

Original Author: labe-me