-
-
Notifications
You must be signed in to change notification settings - Fork 148
/
Copy pathgenerator-examples.html
118 lines (118 loc) · 9.69 KB
/
generator-examples.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<!DOCTYPE html PUBLIC ""
"">
<html><head><meta charset="UTF-8" /><title>Generator Examples</title><link rel="stylesheet" type="text/css" href="css/default.css" /><link rel="stylesheet" type="text/css" href="css/highlight.css" /><script type="text/javascript" src="js/highlight.min.js"></script><script type="text/javascript" src="js/jquery.min.js"></script><script type="text/javascript" src="js/page_effects.js"></script><script>hljs.initHighlightingOnLoad();</script></head><body><link rel="stylesheet" type="text/css" href="https://storage.googleapis.com/app.klipse.tech/css/codemirror.css" /><div style="visibility: hidden;"><div class="klipse" data-external-libs="https://raw.githubusercontent.com/clojure/test.check/master/src/main/clojure">(ns my.test
(:require [clojure.test.check :as tc :refer [quick-check]]
[clojure.test.check.generators :as gen]
[clojure.test.check.properties :as prop :include-macros true]))</div></div><div id="header"><h2>Generated by <a href="https://github.com/weavejester/codox">Codox</a></h2><h1><a href="index.html"><span class="project-title"><span class="project-name">Test.check</span> <span class="project-version">0.9.1-SNAPSHOT</span></span></a></h1></div><div class="sidebar primary"><h3 class="no-link"><span class="inner">Project</span></h3><ul class="index-link"><li class="depth-1 "><a href="index.html"><div class="inner">Index</div></a></li></ul><h3 class="no-link"><span class="inner">Topics</span></h3><ul><li class="depth-1 "><a href="cheatsheet.html"><div class="inner"><span>test.check cheatsheet</span></div></a></li><li class="depth-1 current"><a href="generator-examples.html"><div class="inner"><span>Generator Examples</span></div></a></li><li class="depth-1 "><a href="intro.html"><div class="inner"><span>Introduction to test.check</span></div></a></li><li class="depth-1 "><a href="migrating-from-simple-check.html"><div class="inner"><span>Migrating from simple-check</span></div></a></li></ul><h3 class="no-link"><span class="inner">Namespaces</span></h3><ul><li class="depth-1"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clojure</span></div></div></li><li class="depth-2"><div class="no-link"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>test</span></div></div></li><li class="depth-3"><a href="clojure.test.check.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>check</span></div></a></li><li class="depth-4 branch"><a href="clojure.test.check.clojure-test.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>clojure-test</span></div></a></li><li class="depth-4 branch"><a href="clojure.test.check.generators.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>generators</span></div></a></li><li class="depth-4"><a href="clojure.test.check.properties.html"><div class="inner"><span class="tree"><span class="top"></span><span class="bottom"></span></span><span>properties</span></div></a></li></ul></div><div class="document" id="content"><p id="klipse-loader-wrapper">Click <a id="klipse-loader" href="javascript:void(0)">here</a> to make these examples interactive with ClojureScript.</p><div class="doc"><div class="markdown"><h1><a href="#generator-examples" name="generator-examples"></a>Generator Examples</h1>
<p>The following examples assume you have the following namespace alias:</p>
<pre><code class="clojure">(require '[clojure.test.check.generators :as gen])
</code></pre>
<p>For the most part, these are in order of simplest to most complex. They also skip over some of the built-in, basic generators.</p>
<h2><a href="#integers-5-through-9-inclusive" name="integers-5-through-9-inclusive"></a>Integers 5 through 9, inclusive</h2>
<pre><code class="clojure">(def five-through-nine (gen/choose 5 9))
(gen/sample five-through-nine)
;; => (6 5 9 5 7 7 6 9 7 9)
</code></pre>
<h2><a href="#a-random-element-from-a-vector" name="a-random-element-from-a-vector"></a>A random element from a vector</h2>
<pre><code class="clojure">(def languages (gen/elements ["clojure" "haskell" "erlang" "scala" "python"]))
(gen/sample languages)
;; => ("clojure" "scala" "clojure" "haskell" "clojure" "erlang" "erlang"
;; => "erlang" "haskell" "python")
</code></pre>
<h2><a href="#an-integer-or-nil" name="an-integer-or-nil"></a>An integer or nil</h2>
<pre><code class="clojure">(def int-or-nil (gen/one-of [gen/int (gen/return nil)]))
(gen/sample int-or-nil)
;; => (nil 0 -2 nil nil 3 nil nil 4 2)
</code></pre>
<h2><a href="#an-integer-90-of-the-time-nil-10-" name="an-integer-90-of-the-time-nil-10-"></a>An integer 90% of the time, nil 10%</h2>
<pre><code class="clojure">(def mostly-ints (gen/frequency [[9 gen/int] [1 (gen/return nil)]]))
(gen/sample mostly-ints)
;; => (0 -1 nil 0 -2 0 6 -6 8 7)
</code></pre>
<h2><a href="#even-positive-integers" name="even-positive-integers"></a>Even, positive integers</h2>
<pre><code class="clojure">(def even-and-positive (gen/fmap #(* 2 %) gen/pos-int))
(gen/sample even-and-positive 20)
;; => (0 0 2 0 8 6 4 12 4 18 10 0 8 2 16 16 6 4 10 4)
</code></pre>
<h2><a href="#powers-of-two" name="powers-of-two"></a>Powers of two</h2>
<pre><code class="clojure">;; generate exponents with gen/s-pos-int (strictly positive integers),
;; and then apply the lambda to them
(def powers-of-two (gen/fmap #(int (Math/pow 2 %)) gen/s-pos-int))
(gen/sample powers-of-two)
;; => (2 2 8 16 16 64 16 2 4 4)
</code></pre>
<h2><a href="#sorted-seq-of-integers" name="sorted-seq-of-integers"></a>Sorted seq of integers</h2>
<pre><code class="clojure">;; apply the sort function to each generated vector
(def sorted-vec (gen/fmap sort (gen/vector gen/int)))
(gen/sample sorted-vec)
;; => (() (-1) (-2 -2) (-1 2 3) (-1 2 4) (-3 2 3 3 4) (1)
;; => (-4 0 1 3 4 6) (-5 -4 -1 0 2 8) (1))
</code></pre>
<h2><a href="#an-integer-and-a-boolean" name="an-integer-and-a-boolean"></a>An integer and a boolean</h2>
<pre><code class="clojure">(def int-and-boolean (gen/tuple gen/int gen/boolean))
(gen/sample int-and-boolean)
;; => ([0 false] [0 true] [0 true] [3 true] [-3 false]
;; => [0 true] [4 true] [0 true] [-2 true] [-9 false])
</code></pre>
<h2><a href="#any-number-but-5" name="any-number-but-5"></a>Any number but 5</h2>
<pre><code class="clojure">(def anything-but-five (gen/such-that #(not= % 5) gen/int))
(gen/sample anything-but-five)
;; => (0 0 -2 1 -3 1 -4 7 -1 6)
</code></pre>
<p>It’s important to note that <code>such-that</code> should only be used for predicates that are <em>very</em> likely to match. For example, you should <em>not</em> use <code>such-that</code> to filter out random vectors that are not sorted, as is this is exceedingly unlikely to happen randomly. If you want sorted vectors, just sort them using <code>gen/fmap</code> and <code>sort</code>.</p>
<h2><a href="#a-vector-and-a-random-element-from-it" name="a-vector-and-a-random-element-from-it"></a>A vector and a random element from it</h2>
<pre><code class="clojure">(def vector-and-elem (gen/bind (gen/not-empty (gen/vector gen/int))
#(gen/tuple (gen/return %) (gen/elements %))))
(gen/sample vector-and-elem)
;; =>([[-1] -1]
;; => [[0] 0]
;; => [[-1 -1] -1]
;; => [[2 0 -2] 2]
;; => [[0 1 1] 0]
;; => [[-2 -3 -1 1] -1]
;; => [[-1 2 -5] -5]
;; => [[5 -7 -3 7] 5]
;; => [[-1 2 2] 2]
;; => [[-8 7 -3 -2 -6] -3])
</code></pre>
<p><code>gen/bind</code> and <code>gen/fmap</code> are similar: they’re both binary functions that take a generator and a function as arguments (though their argument order is reversed). They differ in what the provided function’s return value should be. The function provided to <code>gen/fmap</code> should return a <em>value</em>. We saw that earlier when we used <code>gen/fmap</code> to sort a vector. <code>sort</code> returns a normal value. The function provided to <code>gen/bind</code> should return a <em>generator</em>. Notice how above we’re providing a function that returns a <code>gen/tuple</code> generator? The decision of which to use depends on whether you want to simply transform the <em>value</em> of a generator (sort it, multiply it by two, etc.), or create an entirely new generator out of it.</p>
<hr />
<p>Go <a href="intro.html">back</a> to the intro.</p></div></div></div><script>window.klipse_settings = {
selector: '.klipse,.clojure',
codemirror_options_in: {
lineWrapping: true,
autoCloseBrackets: true
},
codemirror_options_out: {
lineWrapping: true
}
};</script><script>
function klipseLocalStorageEnabled() {
var mod = 'modernizr';
try {
localStorage.setItem(mod, mod);
localStorage.removeItem(mod);
return true;
} catch (e) {
return false;
}
}
function klipseLoad() {
if (klipseLocalStorageEnabled()) { sessionStorage.setItem('klipse', true);}
$('#klipse-loader-wrapper').remove();
var s = document.createElement('script');
s.setAttribute('src','https://storage.googleapis.com/app.klipse.tech/plugin/js/klipse_plugin.js');
document.head.appendChild(s);
}
if(!true) {
klipseLoad();
} else {
if((klipseLocalStorageEnabled() && sessionStorage.getItem('klipse')) || window.location.search.match(/klipse=1/)) {
klipseLoad();
} else {
$('#klipse-loader').click(function(){
klipseLoad();
});
}
}
</script></body></html>