2024 State of 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
参考:https://clojure.atlassian.net/browse/CLJ-2095 (由alex+import报告)
...