According to the current sources:
infix fun Double.shouldBe(other: Double): Unit = ToleranceMatcher(other, 0.0).test(this)
where ToleranceMatcher
is
class ToleranceMatcher(val expected: Double, val tolerance: Double) : Matcher<Double> {
override fun test(value: Double) {
if (tolerance == 0.0)
println("[WARN] When comparing doubles consider using tolerance, eg: a shouldBe b plusOrMinus c")
val diff = Math.abs(value - expected)
if (diff > tolerance)
throw AssertionError("$value is not equal to $expected")
}
infix fun plusOrMinus(tolerance: Double): ToleranceMatcher = ToleranceMatcher(expected, tolerance)
}
So, matching d shouldBe e
will compare the doubles exactly without any tolerance (a - b
will never give 0
for different doubles) and print the warning:
[WARN] When comparing doubles consider using tolerance, eg: a shouldBe b plusOrMinus c
Whereas exactly(d)
is defined as
fun exactly(d: Double): Matcher<Double> = object : Matcher<Double> {
override fun test(value: Double) {
if (value != d)
throw AssertionError("$value is not equal to expected value $d")
}
}
So that it will do the same, though without any warning.
I guess, the meaning of this warning is to encourage developers to specify it explicitly that doubles are compared exactly, or else specify the tolerance, because even the same arithmetics done in different order might produce different results with doubles.