以下示例显示,您可以使用 mult-specs 从 s/merge 中获取生成的值,这些 mult-specs 在预期的 spec 中不一定有意义。
查看 s/merge 生成器的实现时,s/merge 的每个参数都会单独生成,但如果没有从右到左流动,则像多 specs 这样的选择将不会从它们的分配中随机选择。
(s/def :ent/id string?)
(defmulti ent-multi-id :ent/id)
(defmethod ent-multi-id :default [_] (s/keys))
(defn maybe-retag-fn [retag-k]
(fn [gen-v dispatch-tag]
(if (= dispatch-tag :default)
gen-v
(assoc gen-v retag-k dispatch-tag))))
(s/def ::ent (s/merge (s/multi-spec ent-multi-id (maybe-retag-fn :ent/id))
(s/keys :req [:ent/id])))
(gen/sample (s/gen ::ent) 5)
;; => ({:ent/id ""} {:ent/id "w"} {:ent/id ""} {:ent/id "66"} {:ent/id "63v"})
(s/def :foo/id string?)
(defmethod ent-multi-id "foo" [_]
(s/keys :req [:foo/id]))
(gen/sample (s/gen ::ent) 5)
;; => ({:foo/id "", :ent/id ""} {:foo/id "6", :ent/id "f"} {:foo/id "A", :ent/id "W"} {:foo/id "L", :ent/id "nd"} {:ent/id "H"})