Does Scalatest provide a matcher for NaN
and infinities?
I would like to make these assertions a bit more descriptive if there's a way:
Double.NaN.isNaN shouldBe true
Double.NegativeInfinity.isInfinite shouldBe true
The most flexible way to handle this is probably using ScalaTest's support for symbols to handle boolean matches on properties. So, the following tests all work and give a pretty useful error message on failure:
class DoubleSpec extends FreeSpec with Matchers {
"NaN should be NaN" in {
Double.box(Double.NaN) shouldBe 'NaN
}
"1 should not be NaN" in {
Double.box(1d) should not be 'NaN
}
"Infinity should be infinite" in {
Double.box(Double.PositiveInfinity) shouldBe 'Infinite
}
"1 should not be infinite" in {
Double.box(1d) should not be 'Infinite
}
}
Unfortunately, symbol support only exists for reference types - there's an implicit parameter T <:< AnyRef
required. I welcome suggestions for handling this without needing to call Double.box
every single time.
You can also write your own matchers for this:
val NaN : BeMatcher[Double] = (left: Double) => MatchResult(
left.isNaN,
s"$left is not NaN",
s"$left is NaN"
)
"NaN should be NaN" in {
Double.NaN shouldBe NaN
}
"1 should not be NaN" in {
1d should not be NaN
}
Avoids the boxing problem and is more type-safe, but does require a few extra lines of code.
By definition, NaN is not equal to anything (https://en.wikipedia.org/w/index.php?title=NaN#Comparison_with_NaN).
For this reason I don't think any scalatest matcher would and should exist for NaN and you would better use .isNaN as you already done.
As for infinite values, you may equally use :
val value = -1.0/0.0
value.isNegInfinity shouldBe true
value.isInfinite shouldBe true
value should equal (Double.NegativeInfinity)