2024 Clojure状态调查中分享您的观点!

欢迎!请查看关于页面以了解更多此网站的信息。

0
test.check

有许多生成器会返回一系列(列表、向量、元组、映射、字符串等)。有时在生成的序列上设置大小限制,无论是最小还是最大,都是有用的。有一个接收序列生成器并确保生成的序列具有固定长度的生成器将会很棒。以下是一些例子:
(of-length min max gen)
(of-max-length max gen) => (of-length 0 max gen)
(of-min-length min gen) => (of-length min nil gen)

of-length检查生成的序列长度。如果它太小,使用 (take min (cycle s)) 来扩展序列的长度。
如果它太长,使用 (take max s) 来返回最长长度
需要小心地返回接收到的相同类型。
如果不接收一系列,则将其视为一个元素序列。
如果min不是0,则使用such-that not nil确保生成适当序列。

22 答案

0

由:gfredericks发表的评论

大多数收集生成器已经接受用于控制其大小的选项;有没有你在构想的场景中那些控制不够充足的使用案例?

0

由:m0smith发表的评论

我完全忽略了那些接受:min和:max选项的生成器。

特别是,我正在查看基于字符串的生成器,因为我需要填充数据库表,所以字符串必须符合列定义,例如非空和varchar(15)。当我思考这个问题时,似乎编写一个可以组合以强制长度限制的生成器比尝试为所有生成序列结构的生成器进行重构更有意义。

简要检查generators.cljc后显示,列表、哈希映射和一些以数组为基础的生成器可以采用最小和最大选项。

0

由:m0smith发表的评论

如果我尝试从def将字符串更新为defn,以允许大小等参数的多个参数,比如

(defn string ([] (fmap clojure.string/join (vector char))) ([size] (fmap clojure.string/join (vector char size))) ([min max] (fmap clojure.string/join (vector char min max))))

然后(sample string)就不再工作了,但(sample (string)) (sample (string 5)) (sample (string 3 7))都工作了

是否有什么技巧可以使“string”正常工作?或者有更好的方法来修改string以接受多个参数?

0
_评论者:gfredericks_

我认为没有干净的方法来解决你提到的问题,这也是我认为这里没有明显解决方案的原因之一。

我在创建{{large-integer}}和{{double}}生成器时遇到了这个问题,我决定创建两个生成器:{{large-integer}}是一个具有默认行为的生成器,而{{large-integer*}}是一个接受选项并返回生成器的函数。

回顾过去,我不知道这是否是最好的选择,因为它很容易混淆。我向大卫·麦克伊弗询问了他在hypothesis(一个类似的Python库)中是如何处理这个问题的,他告诉我他没有任何原始生成器,只有返回生成器的函数(有时没有参数)。我喜欢这种一致性的方法,但显然这将需要对test.check进行重大增加变更(尽管有一些拙劣的技巧可以保留向后兼容性)。

这个问题比这个项目更大。关于你显示的代码,我认为我更喜欢类似于{{gen/set}}的API,使用选项映射而不是位置参数。

现在你让我想到了这个问题,我开始迷上了一个重大变更API的想法,它使用技巧在其他几个版本中保留向后兼容性,这样就可以清理大量的不一致之处。但正如我说的,这比这个项目更大。

如果我们不能提出一个干净的中期方法,我对接受事物的标准在[test.chuck|https://github.com/gfredericks/test.chuck] ☺要宽松得多。

0

由:m0smith发表的评论

你更喜欢哪个?添加类似 of-length 这样限制现有序列生成器的功能,还是创建 (def string ...) 和 (defn string* ...)?我刚刚完成了 TCHECK-97 的 Unicode 实现工作,所以我会按照我们决定的任何模式跟随。

0

由:gfredericks发表的评论

难道我们至少不具有三个字符串生成器吗?你是想为每一个提供一个替代方案吗?

0
_评论者:m0smith_

我提出这个请求的真正想法。我们真的想将字符串生成器的数量翻倍吗?更不用说数组等其他事物。

另一个想法是添加一个单独的新生成器,比如 to-string,它可以接受不同的字符生成器,并使用它制作基于元素生成器的字符串。


 (defn to-string
   ([element-gen] (to-string element-gen {})))
   ([element-gen [{:keys [num-elements min-elements max-elements max-tries ] :or {num-elements nil min-elements 0 max-elements nil max-retries 10}}]
                   (fmap clojure.string/join (vector char-gen ==apply-options==))))


我没有给出正确处理选项的代码,但希望你能理解这个想法。

它可以这样调用: (to-string char {:min-elements 5 :max-elements 10})  或 (to-string char-ascii {:num-elements 5})

这样就可以添加新的字符生成器,这些生成器可以很容易地转换为字符串。
0
_评论者:m0smith_

看着它,coll-distinct-by 几乎完全符合我的需求,除了 allow-dups? 标志没有按照我预期的行事。

(sample (coll-distinct-by [] identity true  false (elements [\a \b \c \d \e ]) {:num-elements 4})) 无论 allow-dups? 是否为真,始终返回不同的元素
0

由:gfredericks发表的评论

{{coll-distinct-by}} 是一个相当专用的功能,可能与此处不相关。

我认为可以将 (link: num-elements min-elements max-elements) 轻松地转换为与 gen/vector 相同的参数。 max-retries不应该适用。

像 {{to-string}} 这样的东西可能很好,特别是如果它与您为 TCHECK-97 考虑的内容相符(例如,TCHECK-97 提供与 {{to-string}} 一起使用的参数)。

0

由:m0smith发表的评论

使用git --no-pager diff master feature/TCHECK-99在https://github.com/m0smith/test.check.git生成的补丁

0

由:m0smith发表的评论

忽略该补丁。我与master版本相差甚远。新补丁正在路上

0

由:m0smith发表的评论

TCHECK-99-2.patch是在将test.check与我的分支同步后生成的。应该是最新的。

0
_评论者:m0smith_

我还考虑了一种方法来允许将一个函数视为生成器。  在函数中添加类似:

(defn to-string
  "生成元素生成器的字符串,默认为字符"
   {:generator-factory to-string}
   ([] (to-string char {})))
   ([element-gen] (to-string element-gen {})))
   ([element-gen [{:keys [num-elements min-elements max-elements]}]
                   (fmap clojure.string/join (vector char-gen ==apply-options==))))


生成器可以更新为接受任何具有:generator-factory元数据的对象
call-gen可以更新为查找新元数据,如果存在,则调用相关的函数并使用结果作为生成器

0

由:gfredericks发表的评论

是的,这基本上是我为了保持向后兼容的想法 -- 元数据生成器将以某种方式附带弃用警告。

0
_评论者:m0smith_

此外,对于to-string,clojure.string/join支持分隔符,可以轻松添加为附加选项,例如:

(to-string int {:sep ","})

如果您同意,我将更新补丁。
...