Let's say we have the following function:
(defn nat-num-count [nums] (count (remove neg? nums)))
We can write a spec for this function by defining a function spec of the same name:
(clojure.spec/fdef nat-num-count
:args (s/cat :nums (s/coll-of number?))
:ret integer?
:fn #(<= (:ret %) (-> % :args :nums count)))
:args
takes a regex spec which describes the sequence of arguments by a keyword label corresponding to the argument name and a corresponding spec. The reason the spec required by :args
is a regex spec is to support multiple arities for a function. :ret
specifies a spec for the return value of the function.
:fn
is a spec which constrains the relationship between the :args
and the :ret
. It is used as a property when run through test.check.
It is called with a single argument: a map with two keys: :args
(the conformed arguments to the function) and :ret
(the function's conformed return value).