Skip to content

Commit

Permalink
add .oneOf as syntax extension on the Arbitrary companion object
Browse files Browse the repository at this point in the history
  • Loading branch information
vreuter committed Oct 4, 2024
1 parent ed1c320 commit 1ff0351
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
1 change: 1 addition & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ lazy val testing = defineModule("testing", false)(project)
ironScalacheck,
scalacheck,
scalatest % Test,
scalatestScalacheck % Test,
))

lazy val zarr = defineModule("zarr")(project)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,21 @@ package at.ac.oeaw.imba.gerlich.gerlib.testing
package syntax

import org.scalacheck.{Arbitrary, Gen}
import org.scalacheck.Arbitrary.arbitrary

/** Syntax enrichment on ScalaCheck data types */
trait SyntaxForScalacheck:
/** Add nicer syntax to arbitrary instances. */

/** Add nicer syntax to [[org.scalacheck.Arbitrary]] instances. */
extension [A](arb: Arbitrary[A])
infix def suchThat(p: A => Boolean): Arbitrary[A] =
(arb.arbitrary `suchThat` p).toArbitrary

/** Add nicer syntax to the [[org.scalacheck.Arbitrary]] companion object. */
extension (Arb: Arbitrary.type)
def oneOf[A: Arbitrary, B: Arbitrary]: Arbitrary[A | B] =
Arbitrary { Gen.oneOf(arbitrary[A], arbitrary[B]) }

/** Add nicer syntax to generators. */
extension [A](g: Gen[A])
def toArbitrary: Arbitrary[A] = Arbitrary(g)
Expand Down
48 changes: 48 additions & 0 deletions modules/testing/src/test/scala/TestSyntaxExtensions.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package at.ac.oeaw.imba.gerlich.gerlib
package testing

import cats.Alternative
import cats.syntax.all.*

import org.scalacheck.{Arbitrary, Gen}
import org.scalacheck.Arbitrary.arbitrary
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should
import org.scalatestplus.scalacheck.ScalaCheckPropertyChecks
import at.ac.oeaw.imba.gerlich.gerlib.testing.syntax.SyntaxForScalacheck

/** Tests for for the syntax extensions we provide to Scalacheck instances and
* companion objects
*/
class TestSyntaxExtensions
extends AnyFunSuite,
ScalaCheckPropertyChecks,
should.Matchers,
SyntaxForScalacheck // the trait under test
:
test(
"Arbitrary.oneOf produces values of each type, in plausible relative proportions."
) {
given Arbitrary[Boolean | Int] = Arbitrary.oneOf[Boolean, Int]
val n = 10000
val (lowerBound, upperBound) =
val zStar = 3.719016
val p = 0.5
val sd = scala.math.sqrt(n * p * p)
val exp = n * p
(-zStar * sd + exp, zStar * sd + exp)
forAll(Gen.listOfN(n, arbitrary[Boolean | Int])) { values =>
val (bools, ints): (List[Boolean], List[Int]) =
Alternative[List].separate(
values map {
case p: Boolean => p.asLeft
case z: Int => z.asRight
}
)
bools.length > lowerBound shouldBe true
bools.length < upperBound shouldBe true
ints.length > lowerBound shouldBe true
ints.length < upperBound shouldBe true
}
}
end TestSyntaxExtensions

0 comments on commit 1ff0351

Please sign in to comment.