生成器覆盖在多规范上无法按预期工作。
以下代码演示了这个问题。
{code:none}
(s/def ::obj-type #{:a :b})
(s/def ::base-obj (s/keys :req [::obj-type]))
(defmulti obj-type ::obj-type)
(defmethod obj-type :a [_]
::base-obj)
(defmethod obj-type :b [_]
::base-obj)
(s/def ::obj (s/multi-spec obj-type ::obj-type))
{code:none}
(gen/sample (s/gen ::obj {::obj-type #(gen/return :a)}))
在上面的例子中,多方法的分发函数*::obj-type*被分配了一个生成器覆盖。
它应该只返回*{::obj-type :a}*集合。
但实际上它也会返回*{::obj-type :b}*。
这意味着生成器不能用于限制采样分发键的组合。
h2. 当前方法
在多方法的情况下,为每个可能的分发值构造一个生成器。
然后随机选择一个,而不关心对分发函数(键)的覆盖。
h2. 修补方法
提交可在此处找到[此处|
https://github.com/bonega/spec.alpha/commit/9cb42478b52eac275d496ec29669e2bf4b3e8e1f]
修补版本以与原始版本相同的方式为分发值构建生成器。
之后,会检查是否存在对分发函数的覆盖。
如果存在,则使用覆盖生成器执行gen/bind。
bind函数从覆盖生成器生成一个值。
然后使用该值查找并返回正确的多方法生成器。
[测试用例|
https://pastebin.com/62ZT5Zfc]