0

我试图让 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

任何帮助深表感谢!

4

1 回答 1

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
于 2018-03-31T21:04:30.683 回答