【发布时间】:2019-11-29 10:43:20
【问题描述】:
我想为哈希映射编写一个 clojure 规范,其中一个值 键被限制为等于其他两个键的值之和。一世 知道一种手动为此类规范编写测试生成器的方法:
(ns my-domain)
(require '[clojure.test :refer :all ]
'[clojure.spec.alpha :as s ]
'[clojure.spec.gen.alpha :as gen ]
'[clojure.pprint :refer (pprint) ])
(s/def ::station-id string?)
(s/def ::sim-time (s/double-in :infinite? true, :NaN? false))
(s/def ::reserved-counts (s/and int? #(not (neg? %))))
(s/def ::free-counts (s/and int? #(not (neg? %))))
(def counts-preimage (s/gen (s/keys :req [::station-id
::sim-time
::reserved-counts
::free-counts])))
(pprint (gen/generate
(gen/bind
counts-preimage
#(gen/return
(into % {::total-counts
(+ (::reserved-counts %)
(::free-counts %))})))))
#:my-domain{:station-id "sHN8Ce0tKWSdXmRd4e46fB", :sim-time -3.4619293212890625, :reserved-counts 58, :free-counts 194, :total-counts 252}
但是我还没有想出如何为它写一个规范,更不用说一个规范了
产生一个类似的生成器。问题的要点是,在规格空间中,我缺乏一种方法来
掌握规范中的“原像”,也就是说,我缺少 bind 的类似物
从发电机的空间。这是一次失败的尝试:
(s/def ::counts-partial-hash-map
(s/keys :req [::station-id
::sim-time
::reserved-counts
::free-counts]))
(s/def ::counts-attempted-hash-map
(s/and ::counts-partial-hash-map
#(into % {::total-counts (+ (::reserved-counts %)
(::free-counts %))})))
(pprint (gen/generate (s/gen ::counts-attempted-hash-map)))
#:my-domain{:station-id "ls5qBUoF", :sim-time ##Inf, :reserved-counts 56797960, :free-counts 17}
生成的样本符合规范,因为#(into % {...}) 是真实的,
但结果不包含键为 ::total-counts 的新属性。
如果您有任何指导,我将不胜感激。
编辑:今天我了解了s/with-gen,这将允许我附加
我的(工作)测试生成器到我的“原像”或“部分”规范。可能
这是最好的前进方式吗?
【问题讨论】:
标签: clojure clojure.spec