Reputation: 1681
Not sure how to write a Spec to check the destructured arguments to a function.
If I have this simple function:
(defn make-name [[first last]]
(str first " " last))
And I write this Spec for the argument:
(s/def ::vstring2 (s/coll-of string? :kind vector? :count 2 :distinct false))
It works correctly:
(s/conform ::vstring2 ["Rich" "Hickey"])
=> ["Rich" "Hickey"]
But when I try to apply it to the function like so:
(s/fdef make-name
:args ::vstring2
:ret string?)
It blows up:
(stest/check `make-name)
=>
({:spec #object[clojure.spec.alpha$fspec_impl$reify__2451
0x7dd4c5ac
"clojure.spec.alpha$fspec_impl$reify__2451@7dd4c5ac"],
:clojure.spec.test.check/ret {:result #error{:cause "Wrong number of args (2) passed to: roster/make-name",
(...)
How do I write the function Spec using ::vstring2
? Or do I?
Thank you.
Upvotes: 4
Views: 508
Reputation: 16194
You just need to specify another spec for your function's arguments e.g. using s/cat
:
(s/fdef make-name
:args (s/cat :arg1 ::vstring2)
:ret string?)
In your example, the :args
spec is expecting two arguments because your ::vstring2
spec is a collection expecting two strings. With this change, the function :args
spec knows that it only takes one argument which should conform to ::vstring2
.
There are more function spec examples here and here.
Upvotes: 4