The generator for any?
will occasionally give back Double/NaN value(s). Since NaNs & equality (via =
) don't get along, :ret spec'ing a fn which transforms/processes a collection according to a predicate, becomes rather problematic. That's because the most obvious thing to check under :ret (the case where the predicate didn't return true for any value, and so the output coll should be equal to the input coll because nothing was transformed/processed), cannot be expressed trivially.
The workaround I've come up with in my own specs is to spec the elements of the collection with (s/and any? (complement double-NaN?))
instead of just any?
, and it works. However, even though I can live without NaNs in the tests, I must admit it still feels sort of hacky.
Ideas:
1) The generator for any?
could be hardcoded to never return Double/NaN. Sounds rather invasive.
2) The generator for any?
could be reworked to somehow be configurable wrt allowing/prohibiting Double/NaNs. Then perhaps a dynamic-var and/or a macro (e.g. without-NaNs
) could expose this (just brainstorming here).
3) The generator for any? could stay as is, but a new equality operator could be added (e.g.
clojure.spec/===`), which somehow ignores NaNs (a naive implementation for instance might walk the data-structures and replace all NaNs with keywords, and only then perform a regular comparison).