-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
99 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package io.github.martinhh.derived.extras | ||
|
||
import io.github.martinhh.derived.genOneOf | ||
|
||
import org.scalacheck.Arbitrary | ||
import org.scalacheck.Gen | ||
|
||
import scala.compiletime.summonInline | ||
|
||
// Serves more or less the same purpose as io.github.martinhh.derived.Gens (just in the context of unions). | ||
// Using a separate type here (instead of reusing Gens) is intended to reduce the compile-time for implicit resolution. | ||
private case class UnionGens[+A](gens: List[Gen[A]]) | ||
|
||
private object UnionGens: | ||
inline given derived[A]: UnionGens[A] = | ||
UnionGens(List(summonInline[Arbitrary[A]].arbitrary)) | ||
|
||
private trait UnionArbitraries: | ||
|
||
transparent inline given unionGensMacro[X]: UnionGens[X] = | ||
io.github.martinhh.derived.extras.unionGensMacro | ||
|
||
transparent inline given arbUnion[X](using inline bg: UnionGens[X]): Arbitrary[X] = | ||
Arbitrary(genOneOf(bg.gens)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package io.github.martinhh.derived.extras | ||
|
||
object union extends UnionArbitraries |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package io.github.martinhh.derived.extras | ||
|
||
import scala.quoted.* | ||
|
||
// macro based on this StackOverflow answer by Dmytro Mitin: https://stackoverflow.com/a/78567397/6152669 | ||
private def unionGens[X: Type](using Quotes): Expr[UnionGens[X]] = | ||
import quotes.reflect.* | ||
TypeRepr.of[X] match | ||
case OrType(l, r) => | ||
(l.asType, r.asType) match | ||
case ('[a], '[b]) => | ||
(Expr.summon[UnionGens[a]], Expr.summon[UnionGens[b]]) match | ||
case (Some(aInst), Some(bInst)) => | ||
'{ | ||
val x = $aInst | ||
val y = $bInst | ||
UnionGens(x.gens ++ y.gens) | ||
}.asExprOf[UnionGens[X]] | ||
case (_, _) => | ||
report.errorAndAbort(s"Could not summon UnionGens") | ||
|
||
private transparent inline given unionGensMacro[X]: UnionGens[X] = | ||
${ unionGens[X] } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package io.github.martinhh | ||
|
||
import org.scalacheck.Arbitrary | ||
import org.scalacheck.Gen | ||
import org.scalacheck.Gen.Parameters | ||
import org.scalacheck.rng.Seed | ||
|
||
class ArbitrarySuite extends munit.FunSuite: | ||
|
||
protected def equalValues[T]( | ||
expectedGen: Gen[T], | ||
nTests: Int = 100 | ||
)(using arbUnderTest: Arbitrary[T]): Unit = | ||
(0 until nTests).foldLeft(Seed.random()) { case (seed, _) => | ||
val expected = expectedGen(Parameters.default, seed) | ||
val derived = arbUnderTest.arbitrary(Parameters.default, seed) | ||
assertEquals(derived, expected, s"Differing values for seed $seed") | ||
seed.next | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package io.github.martinhh | ||
|
||
import org.scalacheck.Arbitrary.arbitrary | ||
import org.scalacheck.Gen | ||
|
||
class UnionExtrasSuite extends ArbitrarySuite: | ||
|
||
test("Arbitrary for union of two types") { | ||
import io.github.martinhh.derived.extras.union.given | ||
type TheUnion = String | Int | ||
val expectedGen = Gen.oneOf[TheUnion](arbitrary[String], arbitrary[Int]) | ||
equalValues(expectedGen) | ||
} | ||
|
||
test("Arbitrary for union of three types") { | ||
import io.github.martinhh.derived.extras.union.given | ||
type TheUnion = Boolean | String | Int | ||
val expectedGen = Gen.oneOf[TheUnion](arbitrary[Boolean], arbitrary[String], arbitrary[Int]) | ||
equalValues(expectedGen) | ||
} |