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

欢迎!请参阅关于页面以了解有关此内容的更多信息。

0
test.check

Haskell QuickCheck 允许在 for-all 表达式中进行嵌套。当生成值之间存在依赖关系时,这非常有用。test.check 也应该允许这样做。

目前,嵌套的 for-all 总是成功,这有些有害。

我已经添加了一个实现此功能的补丁。

9 个答案

0

评论由: reiddraper 提出

谢谢 Michael。我 appreciate 这个补丁,但在我们进入代码细节之前,有一些设计细节可以讨论。作为一个独立的,但也相关的问题,我一直想实现 something like your {{CheckResult}} 类型,但作为具有更多字段的记录。这些字段将包含有关发现错误的纯文本描述、统计信息(类似于 QuickCheck 的 {{collect}}、{{classify}} 等)。我还想编写一个协议,允许基本类型,如布尔值,被转换为此记录。这将类似于 Haskell QuickCheck 的 {{Testable}} 类型类。虽然这是一个技术问题,但我认为我们应该在处理嵌套 for-alls 时与之结合起来,特别是由于嵌套的 for-alls 可以通过仅使用生成器级别的 bind 来模拟。这有道理吗?

0

评论由: sperber 提出

当然。

我个人会从补丁开始,然后继续进行,除非您想要做根本性的不同的事情,而不是添加更多东西。

无论如何,我怎么能帮助让它发生呢?

0

评论由: reiddraper 提出

这是一个好问题。我会思考这个问题,并在最短时间内给你答复。我也希望能够尽快完成这个任务。

0
_评论者:reiddraper_

对于延迟造成的麻烦,这里是我的草图,我一直在用的


diff --git a/src/main/clojure/clojure/test/check/properties.clj b/src/main/clojure/clojure/test/check/properties.clj
index 99b5222..139ae9a 100644
--- a/src/main/clojure/clojure/test/check/properties.clj
+++ b/src/main/clojure/clojure/test/check/properties.clj
@@ -8,13 +8,47 @@
 ;   请勿从本软件中删除此声明或任何其他声明。
 
 (ns clojure.test.check.properties
+  (:import clojure.test.check.generators.Generator)
   (:require [clojure.test.check.generators :as gen]))
 
+(defrecord Result [result pass? message stamps])
+
+(defprotocol ToResult
+  (to-result [a]))
+
+(extend java.lang.Object
+  ToResult
+  {:to-result (fn [b]
+               ;;; 在这里不需要检查捕获的异常
+               (->Result b (not (false? b)) nil nil))})
+
+(extend nil
+  ToResult
+  {:to-result (fn [b]
+               (->Result b false nil nil))})
+
+(extend java.lang.Boolean
+  ToResult
+  {:to-result (fn [b]
+               (->Result b b nil nil))})
+
+(extend Generator
+  ToResult
+  {:to-result identity})
+
+(extend Result
+  ToResult
+  {:to-result identity})
+
+(defn message
+  [m property]
+  (assoc property :message m))
+
 (defn- apply-gen
   [function]
   (fn [args]
-    (let [result (try (apply function args) (catch Throwable t t))]
-      {:result result
+    (let [result (to-result (try (apply function args) (catch Throwable t t)))]
+      {:result (:result result)
        :function function
        :args args})))
 
@@ -29,9 +63,18 @@
   (for-all* [gen/int gen/int] (fn [a b] (>= (+ a b) a)))
   "
   [args function]
-  (gen/fmap
-    (apply-gen function)
-    (apply gen/tuple args)))
+  (gen/bind
+    (apply gen/tuple args)
+    (fn [a]
+      (let [result ((apply-gen function) a)]
+        (cond (gen/generator? result) (gen/fmap (fn [r] (println "foo") (update-in r :args #(conj % a))) result)
+              ;; 执行这行代码前留个快速笔记给自己,
+              ”; else”被执行,因为我们将结果
+              :/// INNERDetection    封装在一个{:result ...}的映射中。
+              ;; 我想我们还需要两种结果类型,一种用于从
+              ;; 该属性本身,并将其作为结果重新使用 'args'。
+              :else (do (println "bar") (gen/return result)))
+    ))
 
 (defn binding-vars
   [bindings]
0

评论由: sperber 提出

看起来没问题。然而,很难理解为什么它会让您比我的补丁更快地达到您想要的地点...

0

评论由: reiddraper 提出

bq. 看起来没问题。然而,很难理解为什么它会比我的补丁让您更快地达到您说的目的地...

这很公平。部分原因是我写草稿更容易。当我尝试支持嵌套生成器时,我试图覆盖的主要内容是确保

  1. 我们还支持即将推出的收集和返回关于测试的统计信息的功能,类似于Haskell QuickCheck中的 {{collect}}
  2. 我们有一种合理的方式将失败的测试返回给用户。目前,在返回图的 {{:fail}} 和 {{:smallest}} 键中,我们告诉用户失败的参数。由于您可能使用多个生成器,您可以在 {{prop/for-all}} 中使用它们,所以它们总是被至少一个向量包裹。我们对该嵌套属性怎么办?我们如何区分在同一级别的多个生成器与嵌套属性?或者我们不需要区分?我们所做的决定是否可与向后兼容?

重点是,我想确保我们不是在回答这些问题之前就做出嵌套属性的承诺,对我个人而言,尝试将这些东西放在一起一起玩,看看它们将如何搭配会更容易一些。

0
_评论由:expez_

我真的很不想嵌套 for-all,我更愿意让它像 let 那样工作,我们可以在其中引用以前的值。 也就是说,不管哪种解决方案,这是我对 test.check 在当前的最大的 complaint,所以任何解决方案都 preferable 于另一年的 hammock time。

这是一个解决方案,来自 wildcard。我确信还有许多其他的解决方案,因为人们非常需要它,但这个是从Nathan Marz的 specter 库中取出的


(defmacro for-all+ [bindings & body]
  (let [parts (partition 2 bindings)
        vars (vec (map first parts))
        genned (reduce
                  (fn [curr [v code]]
                  `(gen/bind ~code (fn [~v] ~curr)))
                `(gen/return ~vars)
                (reverse parts))]
    `(prop/for-all [~vars ~genned]
                   ~@body )))
0

评论者:gfredericks

我们一直在考虑类似的问题(链接:http://dev.clojure.org/jira/browse/TCHECK-81 文本:TCHECK-81),同时有一个更花哨的{{for-all}}变体(链接:https://github.com/gfredericks/test.chuck#properties 文本:此处)。

0
参考:https://clojure.atlassian.net/browse/TCHECK-44(由alexis+import报告)
...