Reputation: 1404
I have this (not (some #(= (:length %1) 0) %))
as a postcondition. Written like this it's pretty clear, but when this condition isn't met I get this:
Assert failed: (not (some (fn* [p1__17852#] (= (:length p1__17852#) 0)) %))
Which isn't very readable. Is there a way to define the message for a postcondition, or for a precondition?
Edit 1:
Following noahlz and noisesmiths suggestion, (but using an external named function):
(defn not-zero-length
[evseq]
(not (some (fn [item] (= (:length item) 0)) evseq)))
(defn my-func
[evseq]
{:post [(not-zero-length %)]}
evseq)
(my-func '({:length 3}{:length 0}))
gives:
AssertionError Assert failed: (not-zero-length %)
Which is alot clearer.
Upvotes: 8
Views: 1354
Reputation: 668
This post in the same thread suggests the use of the clojure.test/is macro, which returns a meaningful error message.
(require '[clojure.test :refer [is]])
(defn get-key [m k]
{:pre [(is (map? m) "m is not a map!")]}
(m k))
(get-key [] 0)
returns
FAIL in clojure.lang.PersistentList$EmptyList@1 (form-init8401797809408331100.clj:2)
m is not a map!
expected: (map? m)
actual: (not (map? []))
AssertionError Assert failed: (is (map? m) "m is not a map!")
Upvotes: 6
Reputation: 172
This is discussed in the following clojure mailing list thread.
Looking at the clojure.core source you can see the fn macro only passes in a boolean to the assert function, and does not include an optional parameter for passing an additional message argument in.
So it looks like there is no way to do this cleanly yet.
Upvotes: 7
Reputation: 20194
expanding on a suggestion above:
(not (some (fn zero-length [item] (= (:length item) 0)) %))
when you name an anonymous function, any errors involving that fn will be more readable
also, how is it that you have two % substitutions above? #() does not nest.
Upvotes: 2