Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClassCastException shrinking value class #91

Open
steinybot opened this issue Oct 16, 2018 · 1 comment
Open

ClassCastException shrinking value class #91

steinybot opened this issue Oct 16, 2018 · 1 comment

Comments

@steinybot
Copy link

I'm using https://github.com/fthomas/refined and I was pretty sure it had been working fine but today I got a ClassCastException when shrinking a case class that contained a field which was a Refined type. My guess is it has something to do with it being a value class.

Here is the exception:

Caused by: java.lang.ClassCastException: java.lang.Integer cannot be cast to eu.timepit.refined.api.Refined
	at com.geneious.nucleus.service.job.api.generators.JobStatusGenerators$anon$macro$381$1.from(JobStatusGenerators.scala:20)
	at com.geneious.nucleus.service.job.api.generators.JobStatusGenerators$anon$macro$381$1.from(JobStatusGenerators.scala:20)
	at org.scalacheck.derive.MkShrink$.$anonfun$genericProduct$2(MkShrink.scala:41)
	at scala.collection.immutable.Stream.map(Stream.scala:415)
	at org.scalacheck.derive.MkShrink$.$anonfun$lazyxmap$1(MkShrink.scala:32)
	at org.scalacheck.Shrink$$anon$1.shrink(Shrink.scala:40)
	at org.scalacheck.derive.MkHListShrink$.$anonfun$hcons$2(MkShrink.scala:88)
	at org.scalacheck.Shrink$$anon$1.shrink(Shrink.scala:40)
	at org.scalacheck.derive.MkHListShrink$.$anonfun$hcons$4(MkShrink.scala:89)
	at scala.collection.immutable.Stream.append(Stream.scala:252)
	at scala.collection.immutable.Stream$ConsWrapper.$hash$colon$colon$colon(Stream.scala:1126)
	at org.scalacheck.derive.MkHListShrink$.$anonfun$hcons$2(MkShrink.scala:88)
	at org.scalacheck.Shrink$$anon$1.shrink(Shrink.scala:40)
	at org.scalacheck.derive.MkHListShrink$.$anonfun$hcons$4(MkShrink.scala:89)
	at scala.collection.immutable.Stream.append(Stream.scala:252)
	at scala.collection.immutable.Stream$ConsWrapper.$hash$colon$colon$colon(Stream.scala:1126)
	at org.scalacheck.derive.MkHListShrink$.$anonfun$hcons$2(MkShrink.scala:88)
	at org.scalacheck.Shrink$$anon$1.shrink(Shrink.scala:40)
	at org.scalacheck.derive.MkHListShrink$.$anonfun$hcons$4(MkShrink.scala:89)
	at scala.collection.immutable.Stream.append(Stream.scala:252)
	at scala.collection.immutable.Stream$ConsWrapper.$hash$colon$colon$colon(Stream.scala:1126)
	at org.scalacheck.derive.MkHListShrink$.$anonfun$hcons$2(MkShrink.scala:88)
	at org.scalacheck.Shrink$$anon$1.shrink(Shrink.scala:40)
	at org.scalacheck.derive.MkShrink$.$anonfun$lazyxmap$1(MkShrink.scala:32)
	at org.scalacheck.Shrink$$anon$1.shrink(Shrink.scala:40)
	at org.scalacheck.Shrink$.shrink(Shrink.scala:44)
	at org.scalacheck.Prop$.$anonfun$forAll$16(Prop.scala:913)
	at org.scalacheck.Prop$.shrinker$1(Prop.scala:778)
	at org.scalacheck.Prop$.$anonfun$forAllShrink$1(Prop.scala:802)
	at org.scalacheck.Prop$.$anonfun$apply$1(Prop.scala:307)
	at org.scalacheck.PropFromFun.apply(Prop.scala:22)
	at org.scalacheck.Prop$.result$1(Prop.scala:762)
	at org.scalacheck.Prop$.$anonfun$forAllShrink$1(Prop.scala:800)
	at org.scalacheck.Prop$.$anonfun$apply$1(Prop.scala:307)
	at org.scalacheck.PropFromFun.apply(Prop.scala:22)
	at org.scalacheck.Test$.workerFun$1(Test.scala:326)
	at org.scalacheck.Test$.$anonfun$check$1(Test.scala:355)
	at org.scalacheck.Test$.$anonfun$check$1$adapted(Test.scala:355)
	at org.scalacheck.Platform$.runWorkers(Platform.scala:40)
	at org.scalacheck.Test$.check(Test.scala:355)
	at org.scalatest.enablers.UnitCheckerAsserting$CheckerAssertingImpl.check(CheckerAsserting.scala:89)
	... 53 more

Here is the relevant code:

sealed trait JobStatus {
  def kind: String
  def dateTime: OffsetDateTime
  def messages: immutable.Seq[String]
  def progress: Percentage
}

final case class Running(dateTime: OffsetDateTime,
                         messages: immutable.Seq[String],
                         progress: Percentage) extends JobStatus {
   @transient
  override val kind: String = Running.Kind
}
object CommonRefinedTypes {
  type Percentage = Int Refined Interval.Closed[W.`0`.T, W.`100`.T]
  object Percentage extends RefinedTypeOps.Numeric[Percentage, Int]
}
object CommonRefinedTypeGenerators {
  implicit val arbPercentage: Arbitrary[Percentage] = numeric.intervalClosedArbitrary
  implicit val shrinkPercentage: Shrink[Percentage] = shrinkFrom(Percentage)

  private def shrinkFrom[A <: Refined[B, _], B: Shrink](ops: RefinedTypeOps[A, B]): Shrink[A] = Shrink { a =>
    shrink(a.value).flatMap { shrunk =>
      ops.from(shrunk).fold(_ => Stream.empty, Stream(_))
    }
  }
}
import com.geneious.nucleus.service.util.generators.CommonRefinedTypeGenerators._

trait JobStatusGenerators {
  implicit val arbRunningJobStatus: Arbitrary[Running] = MkArbitrary[Running].arbitrary
  implicit val shrinkRunningJobStatus: Shrink[Running] = MkShrink[Running].shrink
}
@steinybot
Copy link
Author

If I inline shrinkFrom then it works. Not too sure what is going on there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant