rantly 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.travis.yml +0 -6
- data/CHANGELOG.md +15 -0
- data/{README.textile → README.md} +120 -113
- data/VERSION.yml +1 -1
- data/lib/rantly/generator.rb +27 -17
- data/lib/rantly/property.rb +0 -8
- data/lib/rantly/shrinks.rb +4 -0
- data/rantly.gemspec +7 -6
- data/test/rantly_test.rb +14 -10
- metadata +10 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 79dd7dec8dc33c88121e8f18e937c066730f92d190e34657742245d5d2ad39ce
|
4
|
+
data.tar.gz: 0d0a1435d25e7ad2d1948d45040a6524b79425011289331484b35b0387d7d750
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f652b90718f7d9f32c1e88995d85371cd87af8d247b7def676a171b58f170cb08d0d29f54cb68259a7f4f42c64299d7c1b8f1741095c9dc174e4208904535b0
|
7
|
+
data.tar.gz: 54a9a7f6c94741379d58268fb56a0fb47e8787868e5f8610904a2c551d65041e6042470a3a3514acd0a585a2e75859b26f73605b0a55e5352f0a913a83b4742c
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -3,6 +3,20 @@ All notable changes to rantly will be documented in this file. The curated log b
|
|
3
3
|
|
4
4
|
This project adheres to [Semantic Versioning](http://semver.org/).
|
5
5
|
|
6
|
+
## [1.2.0](https://github.com/abargnesi/rantly/compare/1.1.0...1.2.0) - 2018-08-29
|
7
|
+
### New features
|
8
|
+
- Allow to generate floats using Gaussian distribution
|
9
|
+
- [Issue #29](https://github.com/rantly-rb/rantly/issues/29)
|
10
|
+
- thanks [Ana María Martínez Gómez][Ana María Martínez Gómez] and [Víctor Gallego][Víctor Gallego]
|
11
|
+
### Bug fixes
|
12
|
+
- `NoMethodError` - undefined method `retry?` - when a test using `dict` fails
|
13
|
+
- [Issue #39](https://github.com/rantly-rb/rantly/issues/39)
|
14
|
+
- thanks [Ana María Martínez Gómez][Ana María Martínez Gómez]
|
15
|
+
### Changes
|
16
|
+
- Correct typo in _Too many tries_ message
|
17
|
+
- thanks [Ana María Martínez Gómez][Ana María Martínez Gómez]
|
18
|
+
|
19
|
+
|
6
20
|
## [1.1.0][1.1.0] - 2017-04-18
|
7
21
|
### Improved
|
8
22
|
- Include failed example and number of example run in failure message.
|
@@ -44,3 +58,4 @@ This project adheres to [Semantic Versioning](http://semver.org/).
|
|
44
58
|
[Jamie English]: https://github.com/english
|
45
59
|
[Oleksii Fedorov]: https://github.com/waterlink
|
46
60
|
[Ana María Martínez Gómez]: https://github.com/Ana06
|
61
|
+
[Víctor Gallego]: https://github.com/vicgalle
|
@@ -1,8 +1,7 @@
|
|
1
|
-
!https://badge.fury.io/rb/rantly.svg
|
1
|
+
[](https://badge.fury.io/rb/rantly)
|
2
|
+
[](https://travis-ci.org/rantly-rb/rantly)
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
h1. Imperative Random Data Generator and Quickcheck
|
4
|
+
# Imperative Random Data Generator and Quickcheck
|
6
5
|
|
7
6
|
You can use Rantly to generate random test data, and use its Test::Unit extension for property-based testing.
|
8
7
|
|
@@ -10,13 +9,14 @@ Rantly is basically a recursive descent interpreter, each of its method returns
|
|
10
9
|
|
11
10
|
Its implementation has no alien mathematics inside. Completely side-effect-free-free.
|
12
11
|
|
13
|
-
h1. Install
|
14
12
|
|
15
|
-
|
13
|
+
# Install
|
14
|
+
|
15
|
+
```ruby
|
16
16
|
$ gem install rantly
|
17
|
-
|
17
|
+
```
|
18
18
|
|
19
|
-
|
19
|
+
```ruby
|
20
20
|
$ irb -rrantly
|
21
21
|
> Rantly { [integer,float] } # same as Rantly.value { integer }
|
22
22
|
=> [20991307, 0.025756845811823]
|
@@ -24,32 +24,33 @@ $ irb -rrantly
|
|
24
24
|
=> [-376856492, 0.452245765751706]
|
25
25
|
> Rantly(5) { integer } # same as Rantly.map(5) { integer }
|
26
26
|
=> [-1843396915550491870, -1683855015308353854, -2291347782549033959, -951461511269053584, 483265231542292652]
|
27
|
-
|
27
|
+
```
|
28
|
+
|
28
29
|
|
29
|
-
|
30
|
+
# Data Generation
|
30
31
|
|
31
|
-
|
32
|
+
## Getting Random Data Values
|
32
33
|
|
33
|
-
|
34
|
+
```ruby
|
34
35
|
Rantly#map(n,limit=10,&block)
|
35
36
|
call the generator n times, and collect values
|
36
37
|
Rantly#each(n,limit=10,&block)
|
37
38
|
call a random block n times
|
38
39
|
Rantly#value(limit=10,&block)
|
39
40
|
call a random block once, and get its value.
|
40
|
-
|
41
|
+
```
|
41
42
|
|
42
43
|
To collect an array of random data,
|
43
44
|
|
44
|
-
|
45
|
+
```ruby
|
45
46
|
# we want 5 random integers
|
46
47
|
> Rantly(5) { integer }
|
47
48
|
=> [-380638946, -29645239, 344840868, 308052180, -154360970]
|
48
|
-
|
49
|
+
```
|
49
50
|
|
50
51
|
To iterate over random data,
|
51
52
|
|
52
|
-
|
53
|
+
```ruby
|
53
54
|
> Rantly.each(5) { puts integer }
|
54
55
|
296971291
|
55
56
|
504994512
|
@@ -57,38 +58,38 @@ To iterate over random data,
|
|
57
58
|
113152364
|
58
59
|
502842783
|
59
60
|
=> nil
|
60
|
-
|
61
|
+
```
|
61
62
|
|
62
63
|
To get one value of random data,
|
63
64
|
|
64
|
-
|
65
|
+
```ruby
|
65
66
|
> Rantly { integer }
|
66
67
|
=> 278101042
|
67
|
-
|
68
|
+
```
|
68
69
|
|
69
|
-
The optional argument
|
70
|
+
The optional argument `limit` is used with generator guard. By default, if you want to generate n items, the generator tries at most n * 10 times.
|
70
71
|
|
71
72
|
This almost always succeeds,
|
72
73
|
|
73
|
-
|
74
|
+
```ruby
|
74
75
|
> Rantly(5) { i = integer; guard i > 0; i }
|
75
76
|
=> [511765059, 250554234, 305947804, 127809156, 285960387]
|
76
|
-
|
77
|
+
```
|
77
78
|
|
78
79
|
This always fails,
|
79
80
|
|
80
|
-
|
81
|
+
```ruby
|
81
82
|
> Rantly(10) { guard integer.is_a?(Float) }
|
82
83
|
Rantly::TooManyTries: Exceed gen limit 100: 101 failed guards)
|
83
|
-
|
84
|
+
```
|
84
85
|
|
85
|
-
|
86
|
+
## Random Generating Methods
|
86
87
|
|
87
|
-
The API is similiar to QuickCheck, but not exactly the same. In particular
|
88
|
+
The API is similiar to QuickCheck, but not exactly the same. In particular `choose` picks a random element from an array, and `range` picks a integer from an interval.
|
88
89
|
|
89
|
-
|
90
|
+
## Simple Randomness
|
90
91
|
|
91
|
-
|
92
|
+
```ruby
|
92
93
|
Rantly#integer(n=nil)
|
93
94
|
random positive or negative integer. Fixnum only.
|
94
95
|
Rantly#range(lo,hi)
|
@@ -101,105 +102,104 @@ Rantly#literal(value)
|
|
101
102
|
No-op. returns value.
|
102
103
|
Rantly#choose(*vals)
|
103
104
|
Pick one value from among vals.
|
104
|
-
|
105
|
+
```
|
105
106
|
|
106
|
-
|
107
|
+
## Meta Randomness
|
107
108
|
|
108
109
|
A rant generator is just a mini interpreter. It's often useful to go meta,
|
109
110
|
|
110
|
-
|
111
|
+
```ruby
|
111
112
|
Rantly#call(gen)
|
112
113
|
If gen is a Symbol, just do a method call with send.
|
113
114
|
If gen is an Array, the first element of the array is the method name, the rest are args.
|
114
115
|
If gen is a Proc, instance_eval it with the generator.
|
115
|
-
|
116
|
+
```
|
116
117
|
|
117
|
-
|
118
|
+
```ruby
|
118
119
|
> Rantly { call(:integer) }
|
119
120
|
=> -240998958
|
120
|
-
|
121
|
+
```
|
121
122
|
|
122
|
-
|
123
|
+
```ruby
|
123
124
|
> Rantly { call([:range,0,10]) }
|
124
125
|
=> 2
|
125
|
-
|
126
|
+
```
|
126
127
|
|
127
|
-
|
128
|
+
```ruby
|
128
129
|
> Rantly { call(Proc.new { [integer] })}
|
129
130
|
=> [522807620]
|
130
|
-
|
131
|
+
```
|
131
132
|
|
132
|
-
The
|
133
|
+
The `call` method is useful to implement other abstractions (See next subsection).
|
133
134
|
|
134
|
-
|
135
|
+
```ruby
|
135
136
|
Rantly#branch(*args)
|
136
137
|
Pick a random arg among args, and Rantly#call it.
|
137
|
-
|
138
|
+
```
|
138
139
|
|
139
140
|
50-50 chance getting an integer or float,
|
140
141
|
|
141
|
-
|
142
|
+
```ruby
|
142
143
|
> Rantly { branch :integer, :float }
|
143
144
|
=> 0.0489446702931332
|
144
145
|
> Rantly { branch :integer, :float }
|
145
146
|
=> 494934533
|
146
|
-
|
147
|
+
```
|
147
148
|
|
148
149
|
|
149
|
-
|
150
|
+
## Frequencies
|
150
151
|
|
151
|
-
|
152
|
+
```ruby
|
152
153
|
Rantly#freq(*pairs)
|
153
154
|
Takes a list of 2-tuples, the first of which is the weight, and the second a Rantly#callable value, and returns a random value picked from the pairs. Follows the distribution pattern specified by the weights.
|
154
|
-
|
155
|
+
```
|
155
156
|
|
156
157
|
Twice as likely to get a float than integer. Never gets a ranged integer.
|
157
158
|
|
158
|
-
|
159
|
+
```ruby
|
159
160
|
> Rantly { freq [1,:integer], [2,:float], [0,:range,0,10] }
|
160
|
-
|
161
|
+
```
|
161
162
|
|
162
|
-
If the "pair" is not an array, but just a symbol,
|
163
|
+
If the "pair" is not an array, but just a symbol, `freq` assumes that the weight is 1.
|
163
164
|
|
164
|
-
|
165
|
+
```ruby
|
165
166
|
# 50-50 between integer and float
|
166
167
|
> Rantly { freq :integer, :float }
|
167
|
-
|
168
|
+
```
|
168
169
|
|
169
|
-
If a "pair" is an Array, but the first element is not an Integer,
|
170
|
+
If a "pair" is an Array, but the first element is not an Integer, `freq` assumes that it's a Rantly method-call with arguments, and the weight is one.
|
170
171
|
|
171
|
-
|
172
|
+
```ruby
|
172
173
|
# 50-50 chance generating integer limited by 10, or by 20.
|
173
174
|
> Rantly { freq [:integer,10], [:integer 20] }
|
174
|
-
|
175
|
+
```
|
175
176
|
|
176
177
|
|
178
|
+
## Sized Structure
|
177
179
|
|
178
|
-
|
180
|
+
A Rantly generator keeps track of how large a datastructure it should generate with its `size` attribute.
|
179
181
|
|
180
|
-
|
181
|
-
|
182
|
-
<pre><code>
|
182
|
+
```ruby
|
183
183
|
Rantly#size
|
184
184
|
returns the current size
|
185
185
|
Rantly#sized(n,&block)
|
186
186
|
sets the size for the duration of recursive call of block. Block is instance_eval with the generator.
|
187
|
-
|
187
|
+
```
|
188
188
|
|
189
189
|
Rantly provides two methods that depends on the size
|
190
190
|
|
191
|
-
|
191
|
+
```ruby
|
192
192
|
Rantly#array(size=default_size,&block)
|
193
193
|
returns a sized array consisted of elements by Rantly#calling random branches.
|
194
194
|
Rantly#string(char_class=:print)
|
195
195
|
returns a sized random string, consisted of only chars from a char_class.
|
196
196
|
Rantly#dict(size=default_size,&block)
|
197
197
|
returns a sized random hash. The generator block should generate tuples of keys and values (arrays that have two elements, the first one is used as key, and the second as value).
|
198
|
-
|
198
|
+
```
|
199
199
|
|
200
200
|
The avaiable char classes for strings are:
|
201
201
|
|
202
|
-
|
202
|
+
```ruby
|
203
203
|
:alnum
|
204
204
|
:alpha
|
205
205
|
:blank
|
@@ -213,31 +213,31 @@ The avaiable char classes for strings are:
|
|
213
213
|
:upper
|
214
214
|
:xdigit
|
215
215
|
:ascii
|
216
|
-
|
216
|
+
```
|
217
217
|
|
218
|
-
|
218
|
+
```ruby
|
219
219
|
# sized 10 array of integers
|
220
220
|
> Rantly { array(10) { integer }}
|
221
221
|
=> [417733046, -375385433, 0.967812380000118, 26478621, 0.888588160450082, 250944144, 305584916, -151858342, 0.308123867823313, 0.316824642414253]
|
222
|
-
|
222
|
+
```
|
223
223
|
|
224
224
|
If you set the size once, it applies to all subsequent recursive structures. Here's a sized 10 array of sized 10 strings,
|
225
225
|
|
226
|
-
|
226
|
+
```ruby
|
227
227
|
> Rantly { sized(10) { array {string}} }
|
228
228
|
=> ["1c}C/,9I#}", "hpA/UWPJ\\j", "H'~ERtI`|]", "%OUaW\\%uQZ", "Z2QdY=G~G!", "H<o|<FARGQ", "g>ojnxGDT3", "]a:L[B>bhb", "_Kl=&{tH^<", "ly]Yfb?`6c"]
|
229
|
-
|
229
|
+
```
|
230
230
|
|
231
231
|
Or a sized 10 array of sized 5 strings,
|
232
232
|
|
233
|
-
|
233
|
+
```ruby
|
234
234
|
> Rantly {array(10){sized(5) {string}}}
|
235
235
|
=> ["S\"jf ", "d\\F-$", "-_8pa", "IN0iF", "SxRV$", ".{kQ7", "6>;fo", "}.D8)", "P(tS'", "y0v/v"]
|
236
|
-
|
236
|
+
```
|
237
237
|
|
238
238
|
Generate a hash that has 5 elements,
|
239
239
|
|
240
|
-
|
240
|
+
```ruby
|
241
241
|
> Rantly { dict { [string,integer] }}
|
242
242
|
{"bR\\qHn"=>247003509502595457,
|
243
243
|
"-Mp '."=>653206579583741142,
|
@@ -245,57 +245,58 @@ Generate a hash that has 5 elements,
|
|
245
245
|
"+SMn:r"=>-1159506450084197716,
|
246
246
|
"^3gYfQ"=>-2154064981943219558,
|
247
247
|
"= :/\\,"=>433790301059833691}
|
248
|
-
|
248
|
+
```
|
249
249
|
|
250
|
-
The
|
250
|
+
The `dict` generator retries if a key is duplicated. If it fails to generate a unique key after too many tries, it gives up by raising an error:
|
251
251
|
|
252
|
-
|
252
|
+
```ruby
|
253
253
|
> Rantly { dict { ["a",integer] }}
|
254
254
|
Rantly::TooManyTries: Exceed gen limit 60: 60 failed guards)
|
255
|
-
|
255
|
+
```
|
256
|
+
|
256
257
|
|
257
|
-
|
258
|
+
# Property Testing
|
258
259
|
|
259
260
|
Rantly extends Test::Unit and MiniTest::Test (5.0)/MiniTest::Unit::TestCase (< 5.0) for property testing. The extensions are in their own modules. So you need to require them explicitly:
|
260
261
|
|
261
|
-
|
262
|
+
```ruby
|
262
263
|
require 'rantly/testunit_extensions' # for 'test/unit'
|
263
264
|
require 'rantly/minitest_extensions' # for 'minitest'
|
264
265
|
require 'rantly/rspec_extensions' # for RSpec
|
265
|
-
|
266
|
+
```
|
266
267
|
|
267
268
|
They define:
|
268
269
|
|
269
|
-
|
270
|
+
```ruby
|
270
271
|
Test::Unit::Assertions#property_of(&block)
|
271
272
|
The block is used to generate random data with a generator. The method returns a Rantly::Property instance, that has the method 'check'.
|
272
|
-
|
273
|
+
```
|
273
274
|
|
274
275
|
Property assertions within Test::Unit could be done like this,
|
275
276
|
|
276
|
-
|
277
|
+
```ruby
|
277
278
|
# checks that integer only generates fixnum.
|
278
279
|
property_of {
|
279
280
|
integer
|
280
281
|
}.check { |i|
|
281
282
|
assert(i.is_a?(Integer), "integer property did not return Integer type")
|
282
283
|
}
|
283
|
-
|
284
|
+
```
|
284
285
|
|
285
286
|
Property assertions within Minitest could be done like this,
|
286
287
|
|
287
|
-
|
288
|
+
```ruby
|
288
289
|
# checks that integer only generates fixnum.
|
289
290
|
property_of {
|
290
291
|
integer
|
291
292
|
}.check { |i|
|
292
293
|
assert_kind_of Integer, i, "integer property did not return Integer type"
|
293
294
|
}
|
294
|
-
|
295
|
+
```
|
295
296
|
|
296
297
|
Property assertions within RSpec could be done like this,
|
297
298
|
|
298
|
-
|
299
|
+
```ruby
|
299
300
|
# checks that integer only generates fixnum.
|
300
301
|
it "integer property only returns Integer type" do
|
301
302
|
property_of {
|
@@ -304,61 +305,61 @@ it "integer property only returns Integer type" do
|
|
304
305
|
expect(i).to be_a(Integer)
|
305
306
|
}
|
306
307
|
end
|
307
|
-
|
308
|
+
```
|
308
309
|
|
309
310
|
The check block takes the generated data as its argument. One idiom I find useful is to include a parameter of the random data for the check argument. For example, if I want to check that Rantly#array generates the right sized array, I could say,
|
310
311
|
|
311
|
-
|
312
|
+
```ruby
|
312
313
|
property_of {
|
313
314
|
len = integer
|
314
315
|
[len,array(len){integer}]
|
315
316
|
}.check { |(len,arr)|
|
316
317
|
assert_equal len, arr.length
|
317
318
|
}
|
318
|
-
|
319
|
+
```
|
319
320
|
|
320
321
|
To control the number of property tests to generate, you have three options. In order of precedence:
|
321
322
|
|
322
|
-
|
323
|
+
1. Pass an integer argument to `check`
|
323
324
|
|
324
|
-
|
325
|
+
```ruby
|
325
326
|
property_of {
|
326
327
|
integer
|
327
328
|
}.check(9000) { |i|
|
328
329
|
assert_kind_of Integer, i
|
329
330
|
}
|
330
|
-
|
331
|
+
```
|
331
332
|
|
332
|
-
|
333
|
+
2. Set the `RANTLY_COUNT` environment variable
|
333
334
|
|
334
|
-
|
335
|
+
```ruby
|
335
336
|
RANTLY_COUNT=9000 ruby my_property_test.rb
|
336
|
-
|
337
|
+
```
|
337
338
|
|
338
|
-
|
339
|
+
3. If neither of the above are set, the default will be to run the `check` block 100 times.
|
339
340
|
|
340
341
|
If you wish to have quiet output from Rantly, set environmental variable:
|
341
|
-
|
342
|
+
```ruby
|
342
343
|
RANTLY_VERBOSE=0 # silent
|
343
344
|
RANTLY_VERBOSE=1 # verbose and default if env is not set
|
344
|
-
|
345
|
+
```
|
345
346
|
This will silence the puts, print, and pretty_print statements in property.rb.
|
346
347
|
|
347
|
-
|
348
|
+
# Shrinking
|
348
349
|
|
349
|
-
Shrinking reduces the value of common types to some terminal lower bound. These functions are added to the Ruby types
|
350
|
+
Shrinking reduces the value of common types to some terminal lower bound. These functions are added to the Ruby types `Integer`, `String`, `Array`, and `Hash`.
|
350
351
|
|
351
|
-
For example a
|
352
|
+
For example a `String` is shrinkable until it is empty (e.g. `""`),
|
352
353
|
|
353
|
-
|
354
|
+
```ruby
|
354
355
|
"foo".shrinkable? # => true
|
355
356
|
"foo".shrink # => "fo"
|
356
357
|
"fo".shrink # => "f"
|
357
358
|
"f".shrink # => ""
|
358
359
|
"".shrinkable? # => false
|
359
|
-
|
360
|
+
```
|
360
361
|
|
361
|
-
Shrinking allows
|
362
|
+
Shrinking allows `Property#check` to find a reduced value that still fails the condition. The value is not truely minimal because:
|
362
363
|
|
363
364
|
* we do not perform a complete in-depth traversal of the failure tree
|
364
365
|
* we limit the search to a maximum 1024 shrinking operations
|
@@ -367,35 +368,41 @@ but is usually reduced enough to start debugging.
|
|
367
368
|
|
368
369
|
Enable shrinking with
|
369
370
|
|
370
|
-
|
371
|
+
```ruby
|
371
372
|
require 'rantly/shrinks'
|
372
|
-
|
373
|
+
```
|
373
374
|
|
374
|
-
Use
|
375
|
+
Use `Tuple` class if you want an array whose elements are individually shrinked, but are not removed. Example:
|
375
376
|
|
376
|
-
|
377
|
+
```ruby
|
377
378
|
property_of {
|
378
379
|
len = range(0, 10)
|
379
380
|
Tuple.new( array(len) { integer } )
|
380
381
|
}.check {
|
381
382
|
# .. property check here ..
|
382
383
|
}
|
383
|
-
|
384
|
+
```
|
384
385
|
|
385
|
-
Use
|
386
|
+
Use `Deflating` class if you want an array whose elements are individully shrinked whenever possible, and removed otherwise. Example:
|
386
387
|
|
387
|
-
|
388
|
+
```ruby
|
388
389
|
property_of {
|
389
390
|
len = range(0, 10)
|
390
|
-
|
391
|
+
Deflating.new( array(len) { integer } )
|
391
392
|
}.check {
|
392
393
|
# .. property check here ..
|
393
394
|
}
|
394
|
-
|
395
|
+
```
|
395
396
|
|
396
397
|
Normal arrays or hashes are not shrinked.
|
397
398
|
|
398
399
|
|
399
|
-
|
400
|
+
# Contributors
|
401
|
+
|
402
|
+
Thanks to [all contributors](https://github.com/rantly-rb/rantly/graphs/contributors). :cupid: New contributors are welcome! :wink:
|
403
|
+
|
404
|
+
|
405
|
+
# License
|
406
|
+
|
407
|
+
Code published under MIT License, Copyright (c) 2009 Howard Yeh. See [LICENSE](https://github.com/abargnesi/rantly/LICENSE).
|
400
408
|
|
401
|
-
Code published under MIT License, Copyright (c) 2009 Howard Yeh. See "LICENSE":https://github.com/abargnesi/rantly/LICENSE
|
data/VERSION.yml
CHANGED
data/lib/rantly/generator.rb
CHANGED
@@ -42,7 +42,7 @@ class Rantly
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def to_s
|
45
|
-
"Exceed gen limit #{@limit}: #{@nfailed} failed guards
|
45
|
+
"Exceed gen limit #{@limit}: #{@nfailed} failed guards"
|
46
46
|
end
|
47
47
|
end
|
48
48
|
|
@@ -121,7 +121,7 @@ class Rantly
|
|
121
121
|
end
|
122
122
|
|
123
123
|
# wanna avoid going into Bignum when calling range with these.
|
124
|
-
INTEGER_MAX = (2**(0.size * 8 -2) -1) / 2
|
124
|
+
INTEGER_MAX = (2**(0.size * 8 - 2) - 1) / 2
|
125
125
|
INTEGER_MIN = -(INTEGER_MAX)
|
126
126
|
def integer(limit=nil)
|
127
127
|
case limit
|
@@ -141,8 +141,18 @@ class Rantly
|
|
141
141
|
range(0)
|
142
142
|
end
|
143
143
|
|
144
|
-
def float
|
145
|
-
|
144
|
+
def float(distribution=nil, params={})
|
145
|
+
case distribution
|
146
|
+
when :normal
|
147
|
+
params[:center] ||= 0
|
148
|
+
params[:scale] ||= 1
|
149
|
+
raise "The distribution scale should be greater than zero" unless params[:scale] > 0
|
150
|
+
# Sum of 6 draws from a uniform distribution give as a draw of a normal
|
151
|
+
# distribution centered in 3 (central limit theorem).
|
152
|
+
([rand, rand, rand, rand, rand, rand].reduce(0, :+) - 3) * params[:scale] + params[:center]
|
153
|
+
else
|
154
|
+
rand
|
155
|
+
end
|
146
156
|
end
|
147
157
|
|
148
158
|
def range(lo=nil,hi=nil)
|
@@ -230,19 +240,19 @@ class Rantly
|
|
230
240
|
end
|
231
241
|
end
|
232
242
|
|
233
|
-
ALNUM = Chars.of
|
234
|
-
ALPHA = Chars.of
|
235
|
-
BLANK = Chars.of
|
236
|
-
CNTRL = Chars.of
|
237
|
-
DIGIT = Chars.of
|
238
|
-
GRAPH = Chars.of
|
239
|
-
LOWER = Chars.of
|
240
|
-
PRINT = Chars.of
|
241
|
-
PUNCT = Chars.of
|
242
|
-
SPACE = Chars.of
|
243
|
-
UPPER = Chars.of
|
244
|
-
XDIGIT = Chars.of
|
245
|
-
ASCII = Chars.of
|
243
|
+
ALNUM = Chars.of(/[[:alnum:]]/)
|
244
|
+
ALPHA = Chars.of(/[[:alpha:]]/)
|
245
|
+
BLANK = Chars.of(/[[:blank:]]/)
|
246
|
+
CNTRL = Chars.of(/[[:cntrl:]]/)
|
247
|
+
DIGIT = Chars.of(/[[:digit:]]/)
|
248
|
+
GRAPH = Chars.of(/[[:graph:]]/)
|
249
|
+
LOWER = Chars.of(/[[:lower:]]/)
|
250
|
+
PRINT = Chars.of(/[[:print:]]/)
|
251
|
+
PUNCT = Chars.of(/[[:punct:]]/)
|
252
|
+
SPACE = Chars.of(/[[:space:]]/)
|
253
|
+
UPPER = Chars.of(/[[:upper:]]/)
|
254
|
+
XDIGIT = Chars.of(/[[:xdigit:]]/)
|
255
|
+
ASCII = Chars.of(/./)
|
246
256
|
|
247
257
|
|
248
258
|
CLASSES = {
|
data/lib/rantly/property.rb
CHANGED
@@ -81,12 +81,4 @@ class Rantly::Property
|
|
81
81
|
end
|
82
82
|
return min_data, max_depth, iteration
|
83
83
|
end
|
84
|
-
|
85
|
-
def report
|
86
|
-
distribs = self.classifiers.sort { |a,b| b[1] <=> a[1] }
|
87
|
-
total = distribs.inject(0) { |sum,pair| sum + pair[1]}
|
88
|
-
distribs.each do |(classifier,count)|
|
89
|
-
format "%10.5f%% of => %s", count, classifier
|
90
|
-
end
|
91
|
-
end
|
92
84
|
end
|
data/lib/rantly/shrinks.rb
CHANGED
data/rantly.gemspec
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "rantly"
|
3
3
|
s.summary = "Ruby Imperative Random Data Generator and Quickcheck"
|
4
|
-
s.homepage = "https://github.com/
|
5
|
-
s.version = "1.
|
4
|
+
s.homepage = "https://github.com/rantly-rb/rantly"
|
5
|
+
s.version = "1.2.0"
|
6
|
+
s.license = "MIT"
|
6
7
|
s.require_paths = ["lib"]
|
7
|
-
s.authors = ["Howard Yeh", "Anthony Bargnesi", "Eric Bischoff"]
|
8
|
-
s.email = ["hayeah@gmail.com", "abargnesi@gmail.com", "ebischoff@nerim.net"]
|
8
|
+
s.authors = ["Ana María Martínez Gómez", "Howard Yeh", "Anthony Bargnesi", "Eric Bischoff"]
|
9
|
+
s.email = ["anamma06@gmail.com", "hayeah@gmail.com", "abargnesi@gmail.com", "ebischoff@nerim.net"]
|
9
10
|
s.extra_rdoc_files = [
|
10
11
|
"LICENSE",
|
11
|
-
"README.
|
12
|
+
"README.md",
|
12
13
|
"CHANGELOG.md"
|
13
14
|
]
|
14
15
|
s.files = [
|
@@ -16,7 +17,7 @@ Gem::Specification.new do |s|
|
|
16
17
|
".travis.yml",
|
17
18
|
"Gemfile",
|
18
19
|
"LICENSE",
|
19
|
-
"README.
|
20
|
+
"README.md",
|
20
21
|
"CHANGELOG.md",
|
21
22
|
"Rakefile",
|
22
23
|
"VERSION.yml",
|
data/test/rantly_test.rb
CHANGED
@@ -57,6 +57,17 @@ describe Rantly::Property do
|
|
57
57
|
property_of { float }.check { |f| assert f.is_a?(Float)}
|
58
58
|
end
|
59
59
|
|
60
|
+
it "generate Float with normal distribution" do
|
61
|
+
property_of{
|
62
|
+
center = integer(100)
|
63
|
+
normal_points = Array.new(100){ float(:normal, { center: center }) }
|
64
|
+
[center, normal_points]
|
65
|
+
}.check{ |center, normal_points|
|
66
|
+
average_center = normal_points.reduce(0, :+) / 100
|
67
|
+
assert average_center.between?(center - 0.5, center + 0.5)
|
68
|
+
}
|
69
|
+
end
|
70
|
+
|
60
71
|
it "generate Boolean" do
|
61
72
|
property_of { boolean }.check { |t|
|
62
73
|
assert t == true || t == false
|
@@ -136,14 +147,14 @@ describe Rantly::Property do
|
|
136
147
|
}
|
137
148
|
property_of {
|
138
149
|
i0 = range(0,100)
|
139
|
-
i1
|
150
|
+
i1 = call Proc.new {
|
140
151
|
range(i0+1,i0+100)
|
141
152
|
}
|
142
153
|
[i0,i1]
|
143
154
|
}.check { |(i0,i1)|
|
144
155
|
assert i0.is_a?(Fixnum) && i1.is_a?(Fixnum)
|
145
|
-
assert i0 != i1
|
146
156
|
assert i1 > i0
|
157
|
+
assert i1 <= (i0 + 100)
|
147
158
|
}
|
148
159
|
end
|
149
160
|
|
@@ -255,14 +266,7 @@ describe Rantly::Property do
|
|
255
266
|
property_of {
|
256
267
|
sized(10) { array { freq(:integer,:string,:float)} }
|
257
268
|
}.check { |arr|
|
258
|
-
assert arr.all? { |o|
|
259
|
-
case o
|
260
|
-
when Fixnum, Float, String
|
261
|
-
true
|
262
|
-
else
|
263
|
-
false
|
264
|
-
end
|
265
|
-
}
|
269
|
+
assert arr.all? { |o| [Fixnum, Float, String].include? o.class }
|
266
270
|
}
|
267
271
|
end
|
268
272
|
|
metadata
CHANGED
@@ -1,16 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rantly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
+
- Ana María Martínez Gómez
|
7
8
|
- Howard Yeh
|
8
9
|
- Anthony Bargnesi
|
9
10
|
- Eric Bischoff
|
10
11
|
autorequire:
|
11
12
|
bindir: bin
|
12
13
|
cert_chain: []
|
13
|
-
date:
|
14
|
+
date: 2018-08-29 00:00:00.000000000 Z
|
14
15
|
dependencies:
|
15
16
|
- !ruby/object:Gem::Dependency
|
16
17
|
name: rake
|
@@ -70,6 +71,7 @@ dependencies:
|
|
70
71
|
version: '0'
|
71
72
|
description:
|
72
73
|
email:
|
74
|
+
- anamma06@gmail.com
|
73
75
|
- hayeah@gmail.com
|
74
76
|
- abargnesi@gmail.com
|
75
77
|
- ebischoff@nerim.net
|
@@ -77,7 +79,7 @@ executables: []
|
|
77
79
|
extensions: []
|
78
80
|
extra_rdoc_files:
|
79
81
|
- LICENSE
|
80
|
-
- README.
|
82
|
+
- README.md
|
81
83
|
- CHANGELOG.md
|
82
84
|
files:
|
83
85
|
- ".document"
|
@@ -85,7 +87,7 @@ files:
|
|
85
87
|
- CHANGELOG.md
|
86
88
|
- Gemfile
|
87
89
|
- LICENSE
|
88
|
-
- README.
|
90
|
+
- README.md
|
89
91
|
- Rakefile
|
90
92
|
- VERSION.yml
|
91
93
|
- lib/rantly.rb
|
@@ -104,8 +106,9 @@ files:
|
|
104
106
|
- test/rantly_test.rb
|
105
107
|
- test/shrinks_test.rb
|
106
108
|
- test/test_helper.rb
|
107
|
-
homepage: https://github.com/
|
108
|
-
licenses:
|
109
|
+
homepage: https://github.com/rantly-rb/rantly
|
110
|
+
licenses:
|
111
|
+
- MIT
|
109
112
|
metadata: {}
|
110
113
|
post_install_message:
|
111
114
|
rdoc_options: []
|
@@ -123,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
123
126
|
version: '0'
|
124
127
|
requirements: []
|
125
128
|
rubyforge_project:
|
126
|
-
rubygems_version: 2.
|
129
|
+
rubygems_version: 2.7.3
|
127
130
|
signing_key:
|
128
131
|
specification_version: 4
|
129
132
|
summary: Ruby Imperative Random Data Generator and Quickcheck
|