Open olivercoad opened 5 years ago
Wouldn't it be more correct and easier to reason about types of measurements? You could provide equality comparers for euclidian distance, similarity, groupedness, or whatever you consider is almost equal. Then we can build a library of these comparers. In your case, for values with overridden operators, you'd select the abs(a - b)
comparer, for example.
If we were to do this in full i.e. recursive then it should form the basis of showing where exactly types differ generally. Applying different measures would be part of it too.
@haf Equality comparers would make a lot of sense, since it moves control over what is considered almost equal to the tests (where it probably should be) rather than the types.
However because comparers are not covariant, it is difficult to provide them in a type-safe way (thinking Map<Type, IEqualityComparer<object>>
). How do you suggest it would work?
@AnthonyLloyd That is a good idea. Perhaps, depending on the implementation, it could even feed back into #280 to recursively find the point of difference with Expect.equal
also. And #276 on unions/tuples.
What do you mean by "Applying different measures"?
I think I have come up with what I think is a relatively elegant way of supporting almost-equality comparers and showing where objects differ, which is also composable. It will have to wait till the morning though.
I use
Expect.floatClose
in my tests, but often need to compare records such aswhere each float is compared using
floatClose
, as well as the floats in the Vector.I propose adding a new test such as
almostEqual : accuracy:Accuracy -> actual'a -> expected:'a -> message:string -> unit
which would recursively check for equality of each member, with the accuracy being used on floats*, otherwise F#'s normal structural equality for other primitives or complex types.This would use reflection similar to in #280. If possible it would also be great to support unions and tuples.
*Would there be any good way for types to control how they are compared with accuracy (preferably without a dependency on anything)? For example a Vector that has a minus operator and abs member could be compared based on Euclidean distance.