Skip to content

Instantly share code, notes, and snippets.

@LMnet
Created October 16, 2019 08:24
Show Gist options
  • Save LMnet/58e440b4801d17ae46b487ce77c6c927 to your computer and use it in GitHub Desktop.
Save LMnet/58e440b4801d17ae46b487ce77c6c927 to your computer and use it in GitHub Desktop.
Stable scalacheck seed
import java.util.concurrent.atomic.AtomicReference
import org.scalacheck.rng.Seed
import scala.annotation.tailrec
import scala.util.Try
class GlobalSeed(initial: Seed) extends Seed {
private val current = new AtomicReference[Seed](initial)
override def toBase64: String = current.get().toBase64
override def toString: String = s"""GlobalSeed.fromBase64("$toBase64")"""
override def next: Seed = { current.updateAndGet(_.next); this }
override def reseed(n: Long): Seed = { current.updateAndGet(_.reseed(n)); this }
override def slide: Seed = { current.updateAndGet(_.slide); this }
override def long: (Long, Seed) = {
@tailrec def go: (Long, Seed) = {
val oldV = current.get()
val (longV, newV) = oldV.long
if (current.compareAndSet(oldV, newV)) (longV, this)
else go
}
go
}
override def double: (Double, Seed) = {
@tailrec def go: (Double, Seed) = {
val oldV = current.get()
val (doubleV, newV) = oldV.double
if (current.compareAndSet(oldV, newV)) (doubleV, this)
else go
}
go
}
}
object GlobalSeed {
def fromBase64(s: String): Try[GlobalSeed] = Seed.fromBase64(s).map(new GlobalSeed(_))
def random(): GlobalSeed = new GlobalSeed(Seed.random())
}
import org.scalacheck.Gen
import org.scalatest.Suite
import org.slf4j.LoggerFactory
trait StableSeedSupport { self: Suite =>
import StableSeedSupport._
private val logger = LoggerFactory.getLogger(getClass)
protected implicit final val seed: GlobalSeed = GlobalSeed.random()
logger.info(s"Initial seed for test ${self.suiteName}: $seed.get")
implicit def toGenOps[A](self: Gen[A]): GenOps[A] = new GenOps[A](self)
}
object StableSeedSupport {
class GenOps[A](val self: Gen[A]) extends AnyVal {
def gen(implicit seed: GlobalSeed): A = {
self.apply(Gen.Parameters.default, seed.next).get
}
}
}
@LMnet
Copy link
Author

LMnet commented Oct 16, 2019

Works with this: LMnet/scalacheck@5df44f4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment