如果我有像
这样的规范$ cat tca.cql | cypher-shell -u *** -p ***
COUNT(*)
21
$ cat glycolysis.cql | cypher-shell -u *** -p ***
COUNT(*)
22
node
(:Metabolism:TCA:Glycolysis {name: "pyruvate"})
$
当我做的时候
:Metabolism
有没有办法告诉生成器在为它生成数据时始终考虑可选键?
我知道这可以通过自定义生成器完成,但我想知道是否有可用的功能,或者更简单的方法,不涉及我定义自定义生成器。
答案 0 :(得分:3)
我认为对你的问题的简短回答是" no"但你可以s/merge
使用需要可选键的规范{/ 1}}:
(s/def ::name string?)
(s/def ::age pos-int?)
(s/def ::person (s/keys :req [::name] :opt [::age]))
(gen/sample (s/gen ::person)) ;; ::age not always gen'd
(gen/sample ;; ::age always gen'd
(s/gen (s/merge ::person (s/keys :req [::age]))))
你可以编写一个生成s/keys
规范w /生成器的宏来执行此操作。
答案 1 :(得分:0)
我的方法是遍历该规范的表单(使用clojure.spec.alpha/form
),如果使用clojure.spec.alpha/keys
创建规范,则将可选键合并到必需的键中,最后重新生成规范。
(defn merge-opt-keys
"Merges optional keys into requried keys (for specs which are created using `clojure.spec.alpha/keys`) using a spec's form/description"
[fspec]
(let [keymap (into {} (map (fn [pair] (vec pair)) (partition 2 (rest fspec))))]
(->> (cond-> {}
(contains? keymap :opt)
(assoc :req (vec (concat (keymap :req) (keymap :opt))))
(contains? keymap :opt-un)
(assoc :req-un (vec (concat (keymap :req-un) (keymap :opt-un)))))
(mapcat identity)
(cons 'clojure.spec.alpha/keys))))
(clojure.spec.alpha/def ::name string?)
(clojure.spec.alpha/def ::desc string?)
(clojure.spec.alpha/def ::book (clojure.spec.alpha/keys :req [::name] :opt [:desc]))
(clojure.spec.gen.alpha/generate (clojure.spec.alpha/gen (eval (merge-opt-keys (clojure.spec.alpha/form ::book)))))