I have Double
values that are going to be similar in value, but not exact. Normally I would do:
val a: Double = ???
val b: Double = ???
a shouldEqual b +- 0.25
And if I was just comparing a single case class I would do:
case class Data(label: String, value: Double)
val a: Data = ???
val b: Data = ???
a.value shouldEqual b.value +- 0.25
In my case, I have a list of case class instances, and would like to compare them with a tolerance for their value
attributes:
val output = Seq(Data("a", 1.1), Data("b", 1.2))
val expected = Seq(Data("a", 0.9), Data("b", 1.1))
output should contain theSameElementsInOrderAs expected
Of course, that would file because the value
attributes do not match exactly. What I need is something like this:
output should contain theSameElementsInOrderAs expected +- 0.25
I ended up defining a custom Matcher
for my Seq[Data]
type:
trait CustomMatcher {
class SeqDataContainsTheSameElementsInOrderAs(expected: Seq[Data]) {
override def apply(left: Seq[Data]): MatchResult = {
// ... do other checks like comparing the length and such
val bad = left.zip(expected).filter(t => {
val difference = Math.abs(t._1.value - t._2.value)
difference > TOLERANCE // Declare this somewhere
})
// Return the MatchResult, you will probably want to give better error messages than this
MatchResult(
bad.isEmpty,
s"""Some of the values were not equal""",
s"""Everything was equal"""
)
}
def customContainTheSameElementsInOrderAs(expected: Seq[Data]) = new SeqDataContainsTheSameElementsInOrderAs(expected)
}
}
Then I use it like:
output should customContainTheSameElementsInOrderAs(expected)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With