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).