|
2 | 2 | package progscala3.meta |
3 | 3 |
|
4 | 4 | import munit.* |
| 5 | +import org.scalacheck.* |
| 6 | + |
| 7 | +class InvariantSuite extends ScalaCheckSuite: |
| 8 | + import Prop.{forAll, propBoolean} |
5 | 9 |
|
6 | | -class InvariantSuite extends FunSuite: |
7 | 10 | case class Variable(var i: Int, var s: String) |
| 11 | + val genVariables = |
| 12 | + for |
| 13 | + i <- Gen.posNum[Int] |
| 14 | + s <- Arbitrary.arbitrary[String] |
| 15 | + yield Variable(i, s) |
8 | 16 |
|
9 | | - def succeed() = // <1> |
10 | | - val v = Variable(0, "Hello!") |
11 | | - val i1 = invariant(v.s == "Hello!") { // <2> |
12 | | - v.i += 1 |
13 | | - v.i += 1 |
14 | | - v.i |
| 17 | + protected def passingInvariant = |
| 18 | + forAll(genVariables) { variable => |
| 19 | + val s = variable.s |
| 20 | + val i = variable.i |
| 21 | + val i2 = invariant(variable.s == s) { |
| 22 | + variable.i += 2 |
| 23 | + variable.i |
| 24 | + } |
| 25 | + (i2 == i+2 && variable.s == s) :| s"i2=$i2, s=$s, variable = $variable" |
15 | 26 | } |
16 | | - assert(i1 == 2) |
17 | | - |
18 | | - test("invariant.apply should not fail if the invariant holds") { succeed() } |
19 | | - |
20 | | - test("invariant.apply should return the value returned by the expressions") { succeed() } |
21 | 27 |
|
22 | | - test("invariant.apply should fail if the invariant is broken") { |
23 | | - intercept[invariant.InvariantFailure] { // <3> |
24 | | - val v = Variable(0, "Hello!") |
25 | | - invariant(v.s == "Hello!") { |
26 | | - v.i += 1 |
27 | | - v.s = "Goodbye!" |
28 | | - v.i += 1 |
| 28 | + property("invariant.apply should not fail if the invariant holds") { passingInvariant } |
| 29 | + property("invariant.apply should return the value returned by the expressions") { passingInvariant } |
| 30 | + property("invariant.apply should fail if the invariant is broken") { |
| 31 | + forAll(genVariables) { variable => |
| 32 | + val s = variable.s |
| 33 | + intercept[invariant.InvariantFailure] { |
| 34 | + invariant(variable.s == s) { |
| 35 | + variable.i += 2 |
| 36 | + variable.s = "bad" |
| 37 | + } |
29 | 38 | } |
| 39 | + true // hack to make the types check. |
30 | 40 | } |
31 | 41 | } |
0 commit comments