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

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

+1 投票
规格
自定义生成器可能通过(通过 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的docstring中记录这个限制将会很有用。

0 投票

评论由:alexmiller 提供

这不是一个疯狂的想法,但是看起来在没有做一些相当重大的更改的情况下,不可能在当前的实现中完成这个。

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