2024 年 Clojure 状况调查! 上分享您的想法。

欢迎!请参阅 关于 页面以了解有关如何工作的更多信息。

+1
Spec
自定义生成器可能通过 (fmap/bind) 在 spec 生成器上构建。顶层生成器的重写不会在自定义生成器内部生效


(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 机制(该机制支持覆盖)并提供一个自己的(对 spec 不可见的)生成器。您不应期待在内置生成器内部生效。

0

由 mullr 发表的评论:

这个意思是对的,但是按照我原本的预期(并在寻找答案),我本想找到从传递给 s/with-gen 的函数中获取覆盖图(overrides map)的方法,但并未找到。

0

由 mullr 发表的评论:

... 我第一次没有完全理解你的评论。从实现中可以看到,自定义生成器(gfn内部)从未接收过内建规范所拥有的任何上下文信息。既然这听起来是有意为之的,那么在s/gen或s/with-gen的文档字符串中注明这一限制将是有用的。

0

由 alexmiller 发表的评论:

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

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