Reputation: 39018
I have the following expression in a spec, with the intention of ensuring that each element has a value distanceToEnd
that is very close to the sum of the distanceFromPrevious
values of the elements following it.
foo.tails.foreach {
case h +: t => h.distanceToEnd.miles must
beCloseTo(t.map(_.distanceFromPrevious.miles).sum, 10e-10)
case _ => ok
}
Ideally, this should be in the form foo.tails must contain { ... }.forall
, but I have trouble understanding how to create the necessary ValueCheck
parameter for contains
. How would I convert this particular example?
Upvotes: 1
Views: 133
Reputation: 15557
Unfortunately type inference doesn't work with partial functions so you need to match explicitly:
foo.tails must contain { ts: List[Foo] =>
ts match {
case h +: t => h.distanceToEnd.miles must
beCloseTo(t.map(_.distanceFromPrevious.miles).sum, 10e-10)
case _ => ok
}
}.forall
Upvotes: 1
Reputation: 20135
You can use forall
if you calculate the partial sums of distanceFromPrevious
and subtract distanceToEnd
before using any specs2 matchers. Then you can just use one of the beCloseTo
matchers to compare with 0, as follows:
foo.tail.scanRight(0.0)(_.distanceFromPrevious.miles + _).init // calculate partial sums of previous distances
.zip(foo.init.map(_.distanceToEnd.miles)) // combine with end distances
.map(t => t._1 - t._2) // take difference of summed and end distances
.must(contain(be ~(0.0 +/- 10e-10)).forall) // all differences should be effectively 0
Upvotes: 0