-
Notifications
You must be signed in to change notification settings - Fork 91
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better handling of Array[T] in assertions #339
Comments
Thank you for reporting! Can you elaborate on the expected behavior? Should assertEquals have a special case for arrays or should there be a separate assertions? |
I think the expected behavior would be to have Of course, it'd be great to have a solution that would also and transparently "to the right thing" (™) for nested arrays located e.g. somewhere in the depths of my case class hierarchy but that would of course raise a number of much more difficult to answer questions. |
For better or worse, arrays use reference equality so I would be surprised if MUnit had a special case for arrays like that. It’s especially unsatisfying that such a workaround doesn’t handle nested arrays. There’s an open PR that implements support to configure the equality of assertEquals via a typeclass. It’s a binary breaking change so it’s been kept open for a while now. Is this something you think could address this issue? |
FWIW, MUnit has special assertions for comparing equality of float/double primitives. I think it would be fine to add something similar for arrays. The benefit of a separate assertion is that it makes (IMO) the code easier to understand when you assert two arrays have structural equality. We shouldn’t hide the fact that arrays have reference equality on the JVM, it’s highly relevant if your application uses arrays. |
Typeclass-based equality would (and will) be the proper, long-term solution, yes. Quite a few codebases that I've been working in use arrays as simple and fast helper structures in tests and I always trip over the ref-equality special casing.
Adding a separate assertion without changing the existing ones wouldn't really add much value IMHO. I won't even remember to use a special, potential Maybe the solution would be to special case arrays in
Then accidental errors would become impossible and the tests remains very clear to all readers. I myself currently use this wrapper around MUnit to get the job done. It doesn't support nested arrays but they don't appear in our case class hierarchies anyway, so that's a non-issue for us: class MySuite extends FunSuite {
implicit class ArrowAssert[A](lhs: A) {
@nowarn("cat=unused-params")
def ==>[B](rhs: B)(implicit ev: MySuite.CanEqual[A, B], loc: munit.Location): Unit = {
def arrayToSeq(x: Any) =
x match {
case a: Array[_] => a.toSeq
case _ => x
}
assertEquals(arrayToSeq(lhs), arrayToSeq(rhs))
}
}
}
object MySuite {
@implicitNotFound("Types ${A} and ${B} cannot be compared]")
sealed trait CanEqual[A, B]
object CanEqual extends LowerPrioCanEqual {
implicit def canEqual1[A, B <: A]: CanEqual[A, B] = null // phantom type
}
abstract class LowerPrioCanEqual {
implicit def canEqual2[A, B <: A]: CanEqual[B, A] = null // phantom type
}
} |
As another data point: |
I totally agree with @sirthias that MUnit should either have assertion for |
When there is something unfortunate in Scala like
I hope MUnit will choose to simply leave well enough alone here. Giving existing methods special behavior isn't an improvement IMO, and adding more methods I have to learn isn't an improvement either. Keep MUnit simple and minimal! And if it is decided that this must be addressed, then please address it by adding new methods, rather than by silently giving an existing method special semantics that differ from Scala's usual semantics. (I'm agreeing with Olaf's previous remarks.) |
I can completely subscribe to this take.
Yes, having thought more about this issue I now think that the best way for MUnit would be to improve upon
|
Perhaps this could be accomplished via a Scalafix linting rule rather than through API expansion? |
Yes, MUnit could simply push this to Scalafix. Additionally, Scalafix wouldn't be able to fix the problem on the code reading side. |
I opened #395 to customise the error message when comparing arrays with equal values. Thank you @SethTisue for sharing your thoughts. I agree that MUnit should not hide the fact that arrays use reference equality (which isn't even an unfortunate design decision IMO, it's a reasonable choice for mutable collections). Users can implement their own custom assertions (or even override |
Currently (version 0.7.23) munit doesn't provide special handling for comparing arrays, which has certainly tripped up users many times already.
uTest provides a simple hack, which isn't pretty, but gets the job done.
The suggestion is to provide something similar (or even better) for special-casing arrays.
The text was updated successfully, but these errors were encountered: