Clojure: expectations and Double/NaN
Join the DZone community and get the full member experience.
Join For FreeI'm not really a fan of Double/NaN in general, but sometimes it
seems like the least evil choice. When I find myself in one of those
cases I always hate having to write tests in a way that differs from all
the other tests in the codebase. A goal I've always had with
expectations is to keep the syntax consistent, and as a result I've
chosen to treat Double/NaN as equal to Double/NaN when in the various
Clojure data structures.
The following examples demonstrate Double/NaN being treated as equal
;; allow Double/NaN equality in a map (expect {:a Double/NaN :b {:c Double/NaN}} {:a Double/NaN :b {:c Double/NaN}}) ;; allow Double/NaN equality in a set (expect #{1 Double/NaN} #{1 Double/NaN}) ;; allow Double/NaN equality in a list (expect [1 Double/NaN] [1 Double/NaN]) jfields$ lein expectations Ran 3 tests containing 3 assertions in 32 msecs 0 failures, 0 errors.As you would expect, you can also count on Double/NaN being considered equal even if you are using the 'in' function.
;; allow Double/NaN equality when verifying values are in a map (expect {:a Double/NaN :b {:c Double/NaN}} (in {:a Double/NaN :b {:c Double/NaN} :d "other stuff"})) ;; allow Double/NaN equality when verifying it is in a set (expect Double/NaN (in #{1 Double/NaN})) ;; allow Double/NaN equality when verifying it's existence in a list (expect Double/NaN (in [1 Double/NaN])) jfields$ lein expectations Ran 3 tests containing 3 assertions in 32 msecs 0 failures, 0 errors.For completeness I'll also show the examples of each of these examples failing.
;; allow Double/NaN equality in a map (expect {:a Double/NaN :b {:c Double/NaN}} {:a nil :b {:c Double/NaN}}) ;; allow Double/NaN equality with in fn and map (expect {:a Double/NaN :b {:c nil}} (in {:a Double/NaN :b {:c Double/NaN} :d "other stuff"})) ;; allow Double/NaN equality in a set (expect #{1 Double/NaN} #{1 nil}) ;; allow Double/NaN equality with in fn and set (expect Double/NaN (in #{1 nil})) ;; allow Double/NaN equality in a list (expect [1 Double/NaN] [1 nil]) ;; allow Double/NaN equality with in fn and list (expect Double/NaN (in [1 nil])) jfields$ lein expectations failure in (core.clj:5) : sample.test.core (expect {:a Double/NaN, :b {:c Double/NaN}} {:a nil, :b {:c Double/NaN}}) expected: {:a NaN, :b {:c NaN}} was: {:a nil, :b {:c NaN}} :a expected: NaN was: nil failure in (core.clj:8) : sample.test.core (expect {:a Double/NaN, :b {:c nil}} (in {:a Double/NaN, :b {:c Double/NaN}, :d "other stuff"})) expected: {:a NaN, :b {:c nil}} in: {:a NaN, :b {:c NaN}, :d "other stuff"} :b {:c expected: nil was: NaN failure in (core.clj:11) : sample.test.core (expect #{1 Double/NaN} #{nil 1}) expected: #{NaN 1} was: #{nil 1} nil are in actual, but not in expected NaN are in expected, but not in actual failure in (core.clj:14) : sample.test.core (expect Double/NaN (in #{nil 1})) key NaN not found in #{nil 1} failure in (core.clj:17) : sample.test.core (expect [1 Double/NaN] [1 nil]) expected: [1 NaN] was: [1 nil] nil are in actual, but not in expected NaN are in expected, but not in actual failure in (core.clj:20) : sample.test.core (expect Double/NaN (in [1 nil])) value NaN not found in [1 nil] Ran 6 tests containing 6 assertions in 66 msecs 6 failures, 0 errors.There always seems to be downsides to using NaN, so I tend to look for the least painful path. Hopefully expectations provides the most pain-free path when your tests end up needing to include NaN.
From http://blog.jayfields.com/2011/11/clojure-expectations-and-doublenan.html
Opinions expressed by DZone contributors are their own.
Comments