rantly 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem version](https://badge.fury.io/rb/rantly.svg)](https://badge.fury.io/rb/rantly)
|
2
|
+
[![Build Status](https://travis-ci.org/rantly-rb/rantly.svg?branch=master)](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
|