Created
April 19, 2019 18:15
-
-
Save kailuowang/9c5b32cca060bbc43969db38266c2f59 to your computer and use it in GitHub Desktop.
PoC of scalacheck free definition of laws
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
trait RuleSetDSL[P] { | |
type Check1[A1, A2] = Checkable1[A1, A2, P] | |
type Check2[A1, A2, A3] = Checkable2[A1, A2, A3, P] | |
implicit def law[A1, A2](s : String, f: A1 => IsEq[A2])(implicit toP1: Check1[A1, A2]): (String, P) = | |
(s, toP1(f)) | |
implicit def law[A1, A2, A3](s : String, f: (A1, A2) => IsEq[A3])(implicit toP2: Check2[A1, A2, A3]): (String, P) = | |
(s, toP2(f)) | |
} | |
class MyRuleSet[P] extends RuleSetDSL[P] { | |
private def mylaw[A]= (a:A) => IsEq(a, a) | |
private def mylaw2[A, B]= (a:A, b: B) => IsEq(a, a) | |
def props[A, B](implicit toP : Check1[A, A], | |
toP2: Check2[A, B, A]): Seq[(String, P)] = | |
Seq(law("dbad", mylaw[A]), | |
law("bgdf", mylaw2[A, B])) | |
} | |
trait Checkable1[A1, A2, P] { | |
def apply(f: A1 => IsEq[A2]): P | |
} | |
trait Checkable2[A1, A2, A3, P] { | |
def apply(f: (A1, A2) => IsEq[A3]): P | |
} | |
import org.scalacheck.util.Pretty | |
class RunnerBase { | |
def checkAll(p: Seq[(String, Prop)]): Unit = ??? | |
import cats.kernel.Eq | |
implicit def catsLawsIsEqToProp[A](isEq: IsEq[A])(implicit ev: Eq[A], pp: A => Pretty): Prop = | |
isEq match { | |
case IsEq(x, y) => | |
if (ev.eqv(x, y)) Prop.proved | |
else | |
Prop.falsified :| { | |
val exp = Pretty.pretty[A](y, Pretty.Params(0)) | |
val act = Pretty.pretty[A](x, Pretty.Params(0)) | |
s"Expected: $exp\n" + s"Received: $act" | |
} | |
} | |
implicit def tp1[A1: Arbitrary, A2](implicit ev: Eq[A2], pp: A2 => Pretty): Checkable1[A1, A2, Prop] = { f => | |
forAll((a: A1) => f(a)) | |
} | |
implicit def tp2[A1: Arbitrary, A2: Arbitrary, A3](implicit ev: Eq[A3], pp: A3 => Pretty): Checkable2[A1, A2, A3, Prop] = { f => | |
forAll((a:A1, b: A2) => f(a,b)) | |
} | |
} | |
class MyRunner extends RunnerBase { | |
import cats.kernel.instances.string._ | |
checkAll(new MyRuleSet[Prop].props[String, String]) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment