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

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

0
规范
给一个使用这样的that的生成器失败找不到一个值时,错误没有足够的信息来确定哪个规范或谓词有问题


(require '[clojure.spec :as s])
(s/exercise (s/and string? #{"hi"}))
ExceptionInfo 在100次尝试后无法满足这样的that谓词。  clojure.core/ex-info (core.clj:4725)


这是这种情况的特殊情况之一是当你提供一个自定义生成器,它产生一个有效的但不能满足规范(Clojure在内部添加此过滤器)


(require '[clojure.spec :as s])
(s/exercise (s/with-gen int? #(s/gen #{:a})))


*(提案):在错误中指出哪个规范失败生成(如果可行)以及在整体规范中的路径。

(注意:原描述已移动到注释)

6 答案

0
由:alexmiller评论

[原描述从票务:]

我创建了一个不符合规范的生成器(doh!)。生成器包含such-that谓词。当我试图从生成器创建一个样本时,我得到了这个错误

ExceptionInfo 在100次尝试后无法满足这样的that谓词。  clojure.core/ex-info (core.clj:4725)

我假设它指的是我的自定义生成器,但这是一个误导,因为实际上是规范必须使用such-that来确保生成的值符合规范,而这个such-that触发了失败,不是我在自定义生成器中的那个。

代码(问题已纠正,但显示了我在生成器中的such-that)


(defn mod11-checkdigit
  "计算校验位,见http://freagra.com/imthealth/mitNNC.html
  [n]
  (let [x (->> (map #(Integer/parseInt (str %)) (take 9 n))
               (map * (range 10 1 -1))
               (reduce +))
        y (mod x 11)
        c (- 11 y)]
    (cond (== 10 c) nil
          (== 11 c) 0
          :else c)))

(定义 nhs-number-gen
  “生成有效的NHS号码”
  (gen/fmap #(str (+ (* 10 %) (mod11-checkdigit (str %)))
            (gen/such-that #(mod11-checkdigit (str %))
                             (gen/choose 100000000 999999999))))

(定义nhs-number?
  “如果传入的NHS号码有效则返回true,否则返回false”
  [n]
  (and (string? n) (= 10 (count n)) (= (str (mod11-checkdigit n)) (str (last n)))))

(s/def ::nhs-number (s/with-gen nhs-number?
                                (fn [] nhs-number-gen)))




生成值不符合规范声明所抛出的错误会更友好。
0

评论者:alexmiller

我不确定我们现在基于提供给test.check和从test.check获取的内容是否可行。

0

评论者:glittershark

看起来test.check正在更新以支持错误定制: https://github.com/clojure/test.check/commit/5aea0e275257680b672309b1e940be6dae92c17d 。我已经有一个补丁,它更新了clojure.spec以使用它,尽管很明显它还没有在test.check的发布版本中使用。

0

评论者:glittershark

另请参阅 http://dev.clojure.org/jira/browse/TCHECK-107 我猜

0

评论者:glittershark

附加了补丁以便将来参考(better-such-that-info.patch)。

0
参考: https://clojure.atlassian.net/browse/CLJ-2025 (由alexiport报告)
...