1
|
|
package algebra
|
2
|
|
|
3
|
|
import org.scalacheck._
|
4
|
|
import org.scalacheck.util.Pretty
|
5
|
|
import Prop.{False, Proof, Result}
|
6
|
|
|
7
|
|
package object laws {
|
8
|
|
|
9
|
1
|
lazy val proved = Prop(Result(status = Proof))
|
10
|
|
|
11
|
1
|
lazy val falsified = Prop(Result(status = False))
|
12
|
|
|
13
|
|
object Ops {
|
14
|
|
def run[A](sym: String)(lhs: A, rhs: A)(f: (A, A) => Boolean): Prop =
|
15
|
3
|
if (f(lhs, rhs)) proved else falsified :| {
|
16
|
3
|
val exp = Pretty.pretty(lhs, Pretty.Params(0))
|
17
|
3
|
val got = Pretty.pretty(rhs, Pretty.Params(0))
|
18
|
2
|
s"($exp $sym $got) failed"
|
19
|
|
}
|
20
|
|
}
|
21
|
|
|
22
|
|
implicit class CheckEqOps[A](lhs: A)(implicit ev: Eq[A], pp: A => Pretty) {
|
23
|
3
|
def ?==(rhs: A): Prop = Ops.run("?==")(lhs, rhs)(ev.eqv)
|
24
|
3
|
def ?!=(rhs: A): Prop = Ops.run("?!=")(lhs, rhs)(ev.neqv)
|
25
|
|
}
|
26
|
|
|
27
|
|
implicit class CheckOrderOps[A](lhs: A)(implicit ev: PartialOrder[A], pp: A => Pretty) {
|
28
|
0
|
def ?<(rhs: A): Prop = Ops.run("?<")(lhs, rhs)(ev.lt)
|
29
|
3
|
def ?<=(rhs: A): Prop = Ops.run("?<=")(lhs, rhs)(ev.lteqv)
|
30
|
0
|
def ?>(rhs: A): Prop = Ops.run("?>")(lhs, rhs)(ev.gt)
|
31
|
0
|
def ?>=(rhs: A): Prop = Ops.run("?>=")(lhs, rhs)(ev.gteqv)
|
32
|
|
}
|
33
|
|
|
34
|
|
implicit class BooleanOps[A](lhs: Boolean)(implicit pp: Boolean => Pretty) {
|
35
|
0
|
def ?&&(rhs: Boolean): Prop = Ops.run("?&&")(lhs, rhs)(_ && _)
|
36
|
3
|
def ?||(rhs: Boolean): Prop = Ops.run("?||")(lhs, rhs)(_ || _)
|
37
|
|
}
|
38
|
|
}
|
39
|
|
|