elm-explorations / test

Write unit and fuzz tests for Elm code.
https://package.elm-lang.org/packages/elm-explorations/test/latest
BSD 3-Clause "New" or "Revised" License
237 stars 39 forks source link

Better expect API #216

Open gampleman opened 1 year ago

gampleman commented 1 year ago

Currently the Expect api has a number of equality assertions specialised for different datastructures.

The problem with these is that they don't compose. This is most notable with the float equality operator (Expect.within). You even get an error message when you try to Expect.equal two Float values, but Expect.equal { foo = 3.14 } { foo = pi } is fine...

This is also the case with listsEqual setsEqual and dictsEqual, albeit it's a bit less of a problem for those.

Finally, I should mention (and perhaps this is worth highlighting in a separate issue) that the floating equality doesn't deal with NaN values...

API Proposal

So I would propose the following:

equal : a -> a -> Expectation

type NaNBehavior = NaNsAlwaysEqual | NaNsNeverEqual

equalWithNumbers : NaNBehavior -> FloatingPointTolerance -> a -> a -> Expectation 

not : (a -> b -> Expectation) -> a -> b -> Expectation

and remove:

Implementation concerns

Of course to implement the new APIs I think we would need to reach into native code. Essentially we would be copying https://github.com/elm/core/blob/65cea00afa0de03d7dda0487d964a305fc3d58e3/src/Elm/Kernel/Utils.js#L15, but rather than returning booleans, we would use runtime type information to specialise behavior.

Numbers are relatively easy to detect, and we can use the arguments to provide correct matching behavior. I'm less sure about the feasability of correctly detecting lists, sets and dicts to provide nice diff formatting...