test.check:'properties / for-all'中的let-style行为

时间:2015-12-28 17:39:57

标签: clojure monads test.check

关注此question以及此处引用的博客post,是否有理由prop/for-all不直接推出此类功能?例如。类似的东西:

(require '[clojure.test.check.generators :as gen])
(require '[clojure.test.check.properties :as prop])
(require '[clojure.test.check.clojure-test :refer :all])

(defspec some-props-test
  (prop/for-all [n (gen/choose 1 10)
                 v (gen/vector gen/int n) ;; treat n like its produced value
                 e (gen/element v)]
    ... do stuff with n, v & e ...
  ))

基本上,我想重新使用另一个生成器中的一个生成器生成的,然后引用实际测试代码中生成的两个值。这实际上会扩展for-all的糖/魔法,允许引用宏提供的let-like块中生成的值,因为它在下面的表达式块中工作。

如果我遗漏了其他可能使其成为可能的内容,或者由于某种原因无法实施,请告诉我。

2 个答案:

答案 0 :(得分:5)

我同意此功能可能比for-all目前的功能更有用。它没有被改变的主要原因是为了向后兼容(尽管使用旧式的代码不会破坏,它不会像以前那样收缩)。

但是你有更多选择,而不仅仅是monad:

  • gen/let,它使用let - 样式绑定(它不是for-all的替代品,但您可以一起使用它们)
  • {li> com.gfredericks.test.chuck.generators/fortest.chuck帮助程序库中定义 - 它就像gen/let 的发烧友版本
  • com.gfredericks.test.chuck.properties/for-all,位于同一个库中, for-all
  • 的替代品

答案 1 :(得分:0)

我在该系列中找到了后来的博客post,它完全刷新了updateResult的使用情况(需要首先阅读<script type="text/babel"> var Calculator = React.createClass({ createString: function(event){ var previousState = this.state.string; var target = event.target; var number = target.innerHTML; var newState = previousState+number; this.setState({string: newState}); }, clearingState: function(event){ var newState = ""; this.setState({string: newState}); }, getResult: function(){ var stringResult = this.state.string; var updateResult = eval(stringResult); return document.getElementById("display").innerHTML = updateResult; }, getInitialState: function(){ return ({ string: "" }) }, render: function(){ return ( <div> <div id ="display">{this.state.string}</div> <div id="main"> <div className="key zero" onClick={this.createString}>0</div> <div className="key one" onClick={this.createString}>1</div> <div className="key two" onClick={this.createString}>2</div> <div className="key three" onClick={this.createString}>3</div> <div className="key four" onClick={this.createString}>4</div> <div className="key five" onClick={this.createString}>5</div> <div className="key six" onClick={this.createString}>6</div> <div className="key seven" onClick={this.createString}>7</div> <div className="key eight" onClick={this.createString}>8</div> <div className="key nine" onClick={this.createString}>9</div> <div className="key d" onClick={this.createString}>.</div> <div className="key C" onClick={this.clearingState}>C</div> </div> <div id="operators"> <div className="key mp" onClick={this.createString}>*</div> <div className="key dv" onClick={this.createString}>/</div> <div className="key ad" onClick={this.createString}>+</div> <div className="key sb" onClick={this.createString}>-</div> <div className="key eq" onClick={this.getResult}>=</div> </div> </div> ); } }); ReactDOM.render( <Calculator/>, document.getElementById('calculator') ) 稍微了解一下)。所以首先可以声明monad:

test.check

monads monad允许引用为先前声明的生成器生成的值。

然后,它可以直接用于(require '[clojure.algo.monads :as m]) (m/defmonad gen-m [m-bind gen/bind m-result gen/return]) (def vector-and-elem (m/domonad gen-m [n (gen/choose 1 10) v (gen/vector gen/int n) e (gen/element v)] [n v e])) 调用:

gen-m

您可以通过向量(或地图,如果您喜欢)传递for-all monad调用生成的表达式中与约束检查代码相关的所有值,并对其进行解构以获得你需要。

不过,如果这是在(defspec some-props-test (prop/for-all [[n v e] vector-and-elem] ... do stuff with n, v & e ... )) 中自动完成的话,那会很好,但是效果还不错。