你如何在参数中使用“fdef”和地图?

时间:2018-03-30 15:26:00

标签: clojure clojure.spec

我正在尝试让fdef成功验证一组地图作为参数。我得到以下内容:

(defn func
  [foo bar])
(def t [{:a "hi ":b "jimbob"} {:a "hi" :b "johnboy"}])
(spec/def ::a string?)
(spec/def ::b string?)
(spec/def ::c string?)
(spec/def ::d string?)
(spec/fdef func :args
           (spec/cat :foo string?
                     :bar (spec/+ (spec/keys
                                    :req-un [::a ::b]
                                    :opt-un [::c ::d]))))
(stest/instrument)
(func "hello" t)
=> #'user/func
=> #'user/t
=> :user/a
=> :user/b
=> :user/c
=> :user/d
=> user/func
=> [user/func]
ExceptionInfo Call to #'user/func did not conform to spec:
In: [1] val: [{:a "hi ", :b "jimbob"} {:a "hi", :b "johnboy"}] fails at: [:args :bar] predicate: map?
  clojure.core/ex-info (core.clj:4739)

显然我很想念如何将args与他们的规格相结合;这有效:

(spec/explain string? "hello")
Success!
=> nil

就像这样

(spec/explain (spec/+ (spec/keys
                        :req-un [::a ::b]
                        :opt-un [::c ::d]))
                      [{:a "hi ":b "jimbob"} {:a "hi" :b "johnboy"}])
Success!
=> nil

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

将'spec / +'更改为'spec / coll-of'解决了问题:

(defn func
  [foo bar])
(def t [{:a "hi ":b "jimbob"} {:a "hi" :b "johnboy"}])
(spec/def ::a string?)
(spec/def ::b string?)
(spec/def ::c string?)
(spec/def ::d string?)
(spec/fdef func :args
           (spec/cat :foo string?
                     :bar (spec/coll-of (spec/keys
                                    :req-un [::a ::b]
                                    :opt-un [::c ::d]))))
(stest/instrument)
(func "hello" t)
=> #'user/func
=> #'user/t
=> :user/a
=> :user/b
=> :user/c
=> :user/d
=> user/func
=> [user/func]
=> nil