radagen 0.3.3 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -1
- data/README.md +16 -13
- data/lib/radagen/generator.rb +9 -3
- data/lib/radagen/version.rb +1 -1
- data/lib/radagen.rb +28 -16
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 896666612f1a2920da3ae25a99e8923ac952a10e
|
4
|
+
data.tar.gz: cd19cde8c568b367a79278fc419696780cba5896
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ca65d99d4dd0cd6795c58043e2b625014fc60ba70cdbc4009f7ee29cbfc36fd63c84a271b6e2050438322ba7d425cae71be3dd9716a34390df58dae5f5204075
|
7
|
+
data.tar.gz: f09efadae15a5b844e0ceb478e2f37ddf9db80a8301f789a18cfbe4bb97e0c6c69335be5bac5bd163ffc747c14e2069527f6bacb4c678a471628153c38f7fe17
|
data/.travis.yml
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
# Radagen
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/smidas/radagen.svg?branch=master)](https://travis-ci.org/smidas/radagen)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/radagen.svg)](https://badge.fury.io/rb/radagen)
|
4
5
|
|
5
6
|
Radagen is a psuedo random data generator library for the Ruby language built with two primary design goals: *composition* and *sizing*. These two properties allow this library to be used in a range of different applications from simple test data generation, model checking, fuzz testing, database seeding to the foundation of a generative/property based testing framework.
|
6
7
|
|
@@ -23,11 +24,13 @@ Or install it yourself as:
|
|
23
24
|
|
24
25
|
$ gem install radagen
|
25
26
|
|
26
|
-
##
|
27
|
+
## Documentation
|
28
|
+
|
29
|
+
[Lastest Release API](http://www.rubydoc.info/gems/radagen)
|
27
30
|
|
28
31
|
## Usage
|
29
32
|
|
30
|
-
The main use case for Radagen is to create data generators that produce arbitrarily complex values. These generators can then be used in many different contexts.
|
33
|
+
The main use case for Radagen is to create data generators that produce arbitrarily complex values. These generators can then be used in many different contexts. Let's start with a few of the `scalar` generators provided by Radagen.
|
31
34
|
|
32
35
|
```ruby
|
33
36
|
require 'radagen'
|
@@ -37,14 +40,14 @@ my_fixnum = gen.fixnum
|
|
37
40
|
my_string = gen.string_alphanumeric
|
38
41
|
```
|
39
42
|
|
40
|
-
So far we required the Radagen gem and "namespaced" the Radagen module to `gen`. Throughout the rest of this documentation it will be
|
43
|
+
So far we required the Radagen gem and "namespaced" the Radagen module to `gen`. Throughout the rest of this documentation it will be assumed `Radagen` is namespaced to `gen`. Let's take look at what values these generators produce.
|
41
44
|
|
42
45
|
```ruby
|
43
46
|
my_fixnum.sample => [0, 0, -1, 1, -3, -4, -5, -1, -2, -7]
|
44
47
|
my_string.sample => ["", "", "jV", "", "7zS", "2", "U9O84Q", "4S", "6Ccw66", "0Sip741V"]
|
45
48
|
```
|
46
49
|
|
47
|
-
`sample` above is a utility method on the `Radagen::Generator` object that allows you to interact with your generator seeing what type of values it will produce. As shown above `sample` returns a sampling of 10 values by default. You can
|
50
|
+
`sample` above is a utility method on the `Radagen::Generator` object that allows you to interact with your generator seeing what type of values it will produce. As shown above `sample` returns a sampling of 10 values by default. You can also provide a count.
|
48
51
|
|
49
52
|
```ruby
|
50
53
|
my_string.sample(30) => ["",
|
@@ -79,14 +82,14 @@ my_string.sample(30) => ["",
|
|
79
82
|
"9QbchgbZtY7C57Eq"]
|
80
83
|
```
|
81
84
|
|
82
|
-
|
85
|
+
Notice the values produced by `my_string` generator. They grow in *size* and *complexity* because as `sample` calls the generator, it passes a larger and larger *size* value. This is a very important aspect of all Radagen generators and will be detailed further in `sizing`.
|
83
86
|
|
84
87
|
### Composition
|
85
88
|
|
86
89
|
`scalar` generators are interesting but can only take you so far. We now will explore the ideas around composition. Lets build on the previous generators.
|
87
90
|
|
88
91
|
```ruby
|
89
|
-
my_hash = gen.hash(:fixnum => my_fixnum, :string =>
|
92
|
+
my_hash = gen.hash(:fixnum => my_fixnum, :string => my_string)
|
90
93
|
my_hash.sample => [{:fixnum=>0, :string=>""},
|
91
94
|
{:fixnum=>1, :string=>"9"},
|
92
95
|
{:fixnum=>-1, :string=>"1"},
|
@@ -151,7 +154,7 @@ end
|
|
151
154
|
email_account.sample => ["@gmail.com", "r@gmail.com", "U@gmail.com", "mj@gmail.com", "z^@mailinator.com", "B_@mailinator.com", "(t-f;@gmail.com", "@gmail.com", ")3-@mailinator.com", "n@mailinator.com"]
|
152
155
|
```
|
153
156
|
|
154
|
-
|
157
|
+
`elements` will randomly select an element from the array you pass it (ex. 'gmail.com' or 'mailinator.com'). `string_ascii` will produce strings containing the *ascii* band of characters. `fmap` will take values from a generator, which in this case was a two `tuple` with the first value taken from the *name* generator and the second taken from the *domain* generator, and passes those values to a `block`. Within the block we do some destructuring to the tuple and with string interpolation we return an email account string. Note the block passed to `fmap` requires you return a *value* NOT another generator.
|
155
158
|
|
156
159
|
The first example you noticed has an *empty* name which isn't a valid email address. We see our first example of how a 'stocastic' like tool can challenge our assumptions, or at least forces you to consider the domain you are working a little deeper.
|
157
160
|
|
@@ -217,13 +220,13 @@ You can also leverage the `to_enum` method which will return an enumerable repre
|
|
217
220
|
Sizing provides the ability for a generator to produce values of varying degrees of well, *size*. Size has different meaning depending on the context of the generator being used. In some cases generators don't honor the size parameter at all. Examples being `uuid` and `identity`. When a generator is called to produce a value the *size* that is passed in represents the *upper bound* of all possible sizes starting from zero that could be generated. Why? This is so that methods like `to_enum`, `sample` and `gen` don't return a predictable linear growth of values as they are passed ever increasing size values. It is also why this library and libraries like it seem to have the ability to walk thru progressively more complex values "randomly", perhaps challenging boundary assumptions of a model.
|
218
221
|
|
219
222
|
```ruby
|
220
|
-
5.times { p gen.fixnum.gen(
|
223
|
+
5.times { p gen.fixnum.gen(2) } => 2 0 -1 1 -2
|
221
224
|
|
222
|
-
5.times { p gen.string.gen(
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
225
|
+
5.times { p gen.string.gen(300) } => "oysO930W8B4QU02J05qEWPn6R6H7xTZKFGbG6Hpo28b"
|
226
|
+
"R021N1tw0927BXZP7GbzgRE4rA5t46785g27jsztMRlaz571XzHoi6yBv22ec97194yByN3KIYM3EX1XiRrA08Y32S5i2AvkevMRLClA8Xsb0N7R"
|
227
|
+
"3zFiC25U5495KY52FcB1B12txoA6xlFc83TJ97j9ytKSfi0rs1EwSILytRyMy2S5F70TrT6H457teJkVk5fr"
|
228
|
+
"VaLYheY512yh2qsj2MV31dl7oV56kWmmLlPSDIJwd74mOcyYfQft8N9756VfM5ExtBHql9TnRWl15j3beLww4p176G48s5q8bEWS0Nwcx7RX0WBz2nO412k7fWGi3nmxn8i156C45AHS27ttTB34sT0MiY63HWG0rbXLXnt41d3m5HiWmbnyh9yL36KH3TL4NMwK4vV0A9gZ6DpLrvPUWYaNYgEqQ0MGll1d2009l388upimkl71xaglmK97r7EDA491"
|
229
|
+
"82Q78FWpl1992nXtPUP2cF0rnM7jUPo0M6F8VgvbrQjHY4Var31H0aY94OF0Np6mlxM648S38LBvTrjZObsGn2eB9RPqzqWOlzMD0j71UKRZU90L7B95B5MdZMviaj5vml3JkkIODi6QZQWUobQt4Gr6b0mqR69UQ77897BuK2VjmFdNPLx4z8we7Bk0vU5o6DcJQgxOu7ZP"
|
227
230
|
|
228
231
|
```
|
229
232
|
|
data/lib/radagen/generator.rb
CHANGED
@@ -45,8 +45,8 @@ module Radagen
|
|
45
45
|
# string_alpha.gen(200, 45362642634632684368) => "IaxBvRLxDIvLBhKezMdMmVZBCGzSJZvVjHkcLHsEchCpZWOmLAUQ"
|
46
46
|
#
|
47
47
|
def gen(size=30, seed=Random.new_seed)
|
48
|
-
prng =
|
49
|
-
|
48
|
+
prng = prng(seed)
|
49
|
+
self.call(prng, size)
|
50
50
|
end
|
51
51
|
|
52
52
|
# Create a lazy enumerable of generator values. Size cycles from *size_min* to *size_max*
|
@@ -64,13 +64,19 @@ module Radagen
|
|
64
64
|
def to_enum(opts={})
|
65
65
|
default_opts = {size_min: 0, size_max: 300, seed: Random.new_seed}
|
66
66
|
size_min, size_max, seed = default_opts.merge(opts).values_at(:size_min, :size_max, :seed)
|
67
|
-
prng =
|
67
|
+
prng = prng(seed)
|
68
68
|
|
69
69
|
(size_min...size_max).cycle.lazy.map do |size|
|
70
70
|
@gen_proc.call(prng, size)
|
71
71
|
end
|
72
72
|
end
|
73
73
|
|
74
|
+
private
|
75
|
+
|
76
|
+
def prng(seed)
|
77
|
+
Random.new(seed)
|
78
|
+
end
|
79
|
+
|
74
80
|
end
|
75
81
|
|
76
82
|
end
|
data/lib/radagen/version.rb
CHANGED
data/lib/radagen.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'radagen/version'
|
2
1
|
require 'radagen/generator'
|
3
2
|
|
4
3
|
module Radagen
|
@@ -10,7 +9,7 @@ module Radagen
|
|
10
9
|
# @return [Boolean]
|
11
10
|
#
|
12
11
|
def gen?(obj)
|
13
|
-
obj.
|
12
|
+
obj.is_a?(Radagen::Generator)
|
14
13
|
end
|
15
14
|
|
16
15
|
# Creates a generator that will choose (inclusive)
|
@@ -168,17 +167,19 @@ module Radagen
|
|
168
167
|
end
|
169
168
|
end
|
170
169
|
|
171
|
-
# Creates a generator that when called returns a
|
172
|
-
# length Array with values realized from the passed in
|
173
|
-
# generator. Excepts
|
174
|
-
# keys :min
|
175
|
-
# maximum amount of values in the realized Array.
|
170
|
+
# Creates a generator that when called returns a fixed or
|
171
|
+
# varying length Array with values realized from the passed in
|
172
|
+
# generator. Excepts options Hash that can contain the
|
173
|
+
# keys :min, :max, :count. These will define the minimum,
|
174
|
+
# maximum or fixed amount of values in the realized Array.
|
176
175
|
#
|
177
176
|
# @note If you provide a *:min* value then it is good practice to also provide a *:max* value as you can't be sure that the *size* passed to the generator will be greater or equal to :min.
|
177
|
+
# @note If you provide a *:count* value then *:min* and *:max* values if passed in are ignored.
|
178
178
|
# @param gen [Radagen::Generator] generator that produces values in the Array
|
179
179
|
# @param opts [Hash] the options hash to provide extra context to the generator
|
180
180
|
# @option opts [Fixnum] :min (0) minimum number of values in a generated Array
|
181
181
|
# @option opts [Fixnum] :max (*size*) maximum number of values in a generated Array
|
182
|
+
# @option opts [Fixnum] :count (nil) fixed number of values in a generated Array
|
182
183
|
# @return [Radagen::Generator]
|
183
184
|
#
|
184
185
|
# @example
|
@@ -190,16 +191,27 @@ module Radagen
|
|
190
191
|
# @example
|
191
192
|
# array(fixnum, min: 4, max: 7).sample(4) #=> [[0, 0, 0, 0, 0], [-1, 0, -1, 1, -1], [-2, -2, -1, 2, 0], [0, 2, 3, -1, -2, -2, 3]]
|
192
193
|
#
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
194
|
+
# @example
|
195
|
+
# array(fixnum, count: 10).sample(3) #=> [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [1, -1, 1, 1, 0, 1, 1, 1, 0, 0], [2, 1, 0, 2, 0, -1, -2, 2, 2, 2]]
|
196
|
+
#
|
197
|
+
def array(gen, opts = {})
|
198
|
+
count = { count: nil }.merge(opts)[:count]
|
199
|
+
raise ArgumentError, "count must be an Integer or Nil" unless count.is_a?(Integer) or count.is_a?(NilClass)
|
199
200
|
|
200
|
-
|
201
|
-
gens = (0...
|
201
|
+
if count
|
202
|
+
gens = (0...count).map { gen }
|
202
203
|
tuple(*gens)
|
204
|
+
else
|
205
|
+
size_gen = sized do |size|
|
206
|
+
min, max = { min: 0, max: size }.merge(opts).values_at(:min, :max)
|
207
|
+
raise RangeError.new, "max value (#{max}) needs to be larger than or equal to min value (#{min})" unless max >= min
|
208
|
+
choose(min, max)
|
209
|
+
end
|
210
|
+
|
211
|
+
bind(size_gen) do |_size|
|
212
|
+
gens = (0..._size).map { gen }
|
213
|
+
tuple(*gens)
|
214
|
+
end
|
203
215
|
end
|
204
216
|
end
|
205
217
|
|
@@ -564,7 +576,7 @@ module Radagen
|
|
564
576
|
# @return [Radagen::Generator]
|
565
577
|
#
|
566
578
|
# @example
|
567
|
-
#
|
579
|
+
# string_numeric.sample #=> ["", "0", "16", "5", "277"]
|
568
580
|
#
|
569
581
|
def string_numeric
|
570
582
|
fmap(array(char_numeric)) do |char_array|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: radagen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nathan Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -110,5 +110,5 @@ rubyforge_project:
|
|
110
110
|
rubygems_version: 2.5.1
|
111
111
|
signing_key:
|
112
112
|
specification_version: 4
|
113
|
-
summary: radagen - 0.3.
|
113
|
+
summary: radagen - 0.3.5
|
114
114
|
test_files: []
|