I'm struggling with Clojure(script) spec. I slightly found out what part causes problem but I can't solve it.
(defn filter-ids
[[items fields] _]
(let [ids
(for [item items
field-tags (vals fields)
:let [item-tags (-> item second :tags)
item-id (first item)]
:when (and
(seq field-tags)
(empty? (set/difference field-tags item-tags)))]
item-id)]
(into #{} ids)))
Above code is what I tried to define spec. (fdef)
And I defined spec.
(spec/def :common/id (spec/and
keyword?
#(-> %1 name js/parseInt nat-int?)))
(spec/def :common/label string?)
(spec/def :common/tags (spec/coll-of string? :kind set?))
(spec/def :common/item (spec/keys :req-un [:common/label :common/tags]))
(spec/fdef filter-ids
:args (spec/cat
:useful (spec/cat
:items (spec/map-of :common/id :common/item)
:fields (spec/map-of :common/id :common/tags))
:useless any?)
:ret (spec/coll-of :common/id :kind set?))
And when I run it with instrument, error occurs.
(stest/instrument `filter-ids)
(filter-ids [{:0 {:label "task0" :tags #{"one" "two"}}}
{:0 #{"three"}, :1 #{"one"}}]
nil)
; Execution error - invalid arguments to taggy.states.subs/filter-ids at (<cljs repl>:1).
[{:0 {:label "task0", :tags #{"two" "one"}}} {:0 #{"three"}, :1 #{"one"}}] - failed: map? at: [:useful :items]
It seems like spec think first argument needs to be map, which is what I'm not intended to.
When I do like below, it doesn't complaining about map?. (although still a error because it's not valid at all)
(filter-ids {{:0 {:label "task0" :tags #{"one" "two"}}} 1
{:0 #{"three"}, :1 #{"one"}} 2}
nil)
I'm a newbie and really need some help to move on.
Thanks.