2024年Clojure状态调查!中分享您的想法。

欢迎!有关如何操作的更多信息,请查看关于页面。

+1
Spec
自定义生成器可以在规范生成器上构建(通过fmap/bind)。顶层生成器覆盖在自定义生成器内无效


(require '[clojure.spec :as s])
(require '[clojure.test.check.generators :as gen])

;; 存储单个整数值的映射
(s/def ::val integer?)
(s/def ::body (s/keys :req [::val]))

;; 此规范匹配'body'的字符串化版本。
;; (read-string)仅为演示目的
(s/def ::stringy-body
  (s/with-gen
    (s/and string? #(s/valid? ::body (read-string %)))
    #(gen/fmap pr-str (s/gen ::body))))

(s/valid? ::stringy-body "{:user/val 37}") ;; => true

;; 如预期,生成各种字符串化映射
(take 3 (gen/sample (s/gen ::stringy-body)))
;; => ("#:user{:val -1}" "#:user{:val 0}" "#:user{:val -1}")

;; *** 但覆盖不起作用 ***
(take 3 (gen/sample (s/gen ::stringy-body {::val #(s/gen #{42})})))
;; ("#:user{:val -1}" "#:user{:val 0}" "#:user{:val 0}")


应考虑在s/gen,s/with-gen等中记录这一点

5 答案

0

评论由:alexmiller

使用with-gen时,您基本上覆盖了内置的gen机制(该机制支持覆盖)并提供了自己的(对于规范不可见)生成器。您不应期望在自定义生成器内生效的覆盖。

0

评论由:mullr

这很合理,但我原本期望(并且寻找了)一些方法来从传递给s/with-gen的函数中获取覆盖映射,但没有找到。

0

评论由:mullr

... 第一次解析您的评论时我没有全部理解。从实现中可以看出,自定义生成器(gfn内部)从未传递任何内置规范拥有的上下文信息。听起来这似乎是故意的,所以有必要在s/gen或s/with-gen的文档字符串中注明此限制。

0

评论由:alexmiller

这不是一个疯狂的想法,但在当前的实现中,没有进行一些相当重大的更改似乎无法实现这一点。

0
参考:[CLJ-2095](https://clojure.atlassian.net/browse/CLJ-2095)(由 alex+import 报告)
...