Code from Rational spec use something which belong to different testing style:
package funobject
it("should have a total order") {
import RationalOrderingCheck._
check(propertyReflexive) should be ('passed)
check(propertySymmetry) should be ('passed)
check(propertyTransitive) should be ('passed)
}
It is QuickCheck fixture.
"
ScalaCheck is a powerful tool for automatic unit testing",
normal unit testing considered `manual and unreliable.
package funobject
import org.scalatest.FunSuite
import org.scalatest.matchers.ShouldMatchers
import org.scalatest.tools._
import org.scalacheck._
import org.scalacheck.Prop._
import org.scalacheck.Arbitrary.arbitrary
object ArbitraryRational {
import funobject._
implicit def arbRational: Arbitrary[Rational] = Arbitrary {
val genRational = for {
n <- Gen.choose(-5, 5)
d <- Gen.choose(-6, 6) suchThat (_ != 0)
} yield Rational(n, d)
genRational
}
}
object RationalOrderingCheck {
import ArbitraryRational._
/** reflexive: compare(x, x) == 0, for any x of type T.
*/
val propertyReflexive = forAll {
r: Rational => (r.compare(r) == 0)
}
/** symmetry: compare(x, y) == z and compare(y, x) == w
* then math.signum(z) == -math.signum(w),
* for any x and y of type T and z and w of type Int.
*/
val propertySymmetry = forAll {
(x: Rational, y:Rational) => {
val z = x.compare(y)
val w = y.compare(x)
math.signum(z) == -math.signum(w)
}
}
/** transitive: if compare(x, y) == z and compare(y, w) == v
* and math.signum(z) >= 0 and math.signum(v) >= 0
* then compare(x, w) == u and math.signum(z + v) == math.signum(u),
* for any x, y, and w of type T and z, v, and u of type Int.
*/
val propertyTransitive = forAll {
(x: Rational, y:Rational, w: Rational) => {
val z = x.compare(y)
val v = y.compare(x)
val u = x.compare(w)
if (math.signum(z) > 0 &&
math.signum(v) > 0)
math.signum(u) > 0
else if (math.signum(z) < 0 &&
math.signum(v) < 0)
math.signum(u) < 0
else true
}
}
}