Module: Radagen

Extended by:
Radagen
Included in:
Radagen
Defined in:
lib/radagen.rb,
lib/radagen/version.rb,
lib/radagen/generator.rb

Defined Under Namespace

Classes: Generator

Constant Summary collapse

VERSION =
"0.3.6"

Instance Method Summary collapse

Instance Method Details

#array(gen, opts = {}) ⇒ Radagen::Generator

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.

Note:

If you provide a :count value then :min and :max values if passed in are ignored.

Creates a generator that when called returns a fixed or varying length Array with values realized from the passed in generator. Excepts options Hash that can contain the keys :min, :max, :count. These will define the minimum, maximum or fixed amount of values in the realized Array.

Examples:

array(fixnum).sample(4) #=> [[], [-1], [0, -2], [-2, -1]]
array(fixnum, max: 5).sample(4) #=> [[0], [0, 0, -1, 1], [0, 0, -2, 1], [3, 2, -2, -1, 0]]
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]]
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]]

Parameters:

  • gen (Radagen::Generator)

    generator that produces values in the Array

  • opts (Hash) (defaults to: {})

    the options hash to provide extra context to the generator

Options Hash (opts):

  • :min (Fixnum) — default: 0

    minimum number of values in a generated Array

  • :max (Fixnum) — default: *size*

    maximum number of values in a generated Array

  • :count (Fixnum) — default: nil

    fixed number of values in a generated Array

Returns:

Raises:

  • (ArgumentError)


198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/radagen.rb', line 198

def array(gen, opts = {})
  count = { count: nil }.merge(opts)[:count]
  raise ArgumentError, "count must be an Integer or Nil" unless count.is_a?(Integer) or count.is_a?(NilClass)

  if count
    gens = (0...count).map { gen }
    tuple(*gens)
  else
    size_gen = sized do |size|
      min, max = { min: 0, max: size }.merge(opts).values_at(:min, :max)
      raise RangeError.new, "max value (#{max}) needs to be larger than or equal to min value (#{min})" unless max >= min
      choose(min, max)
    end

    bind(size_gen) do |_size|
      gens = (0..._size).map { gen }
      tuple(*gens)
    end
  end
end

#bind(gen, &block) ⇒ Radagen::Generator

Note:

The Proc has to return a generator.

Takes a generator and a Proc. The Proc is passed a value taken from calling the generator. You then can use that value as an input to the generator returned.

Examples:

bind_gen = bind(fixnum) do |i|
  array(string_numeric, {max: i})
end

bind_gen.sample(5) #=> [[], ["1"], ["86"], [], ["64", "25", ""]]

Parameters:

  • gen (Radagen::Generator)

    generator that produces value passed to Proc

  • block (Proc)

    takes a value from generator and returns a new generator using that value

Returns:



144
145
146
147
148
149
# File 'lib/radagen.rb', line 144

def bind(gen, &block)
  RG.new do |prng, size|
    inner_gen = block.call(gen.call(prng, size))
    inner_gen.call(prng, size)
  end
end

#booleanRadagen::Generator

Returns a generator that will return either true or false.

Examples:

boolean.sample(5) #=> [false, true, false, false, true]

Returns:



595
596
597
# File 'lib/radagen.rb', line 595

def boolean
  elements([false, true])
end

#byte_stringRadagen::Generator

Returns a generator that will return bytes represented as a string of hex characters. Similar to Random.new.bytes

Examples:

byte_string.sample(5) #=> [ "8&\xB6\xD3\x10", "#\xE3RS\x92 ", "\xC2c\xD2\x19,*", "2", "\xD2s\x80" ]

Returns:



691
692
693
# File 'lib/radagen.rb', line 691

def byte_string
  fmap(not_empty(string)) { |s| [s].pack('H*') }
end

#bytesRadagen::Generator

Returns a generator that will return Byte array representations.

Examples:

bytes.sample(5) #=> [[194, 187], [58], [194, 139], [75], [195, 186, 195, 181, 56]]

Returns:



679
680
681
# File 'lib/radagen.rb', line 679

def bytes
  fmap(not_empty(string)) { |s| s.bytes }
end

#charRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create characters from codepoints 0-255.

Examples:

char.sample(5) #=> ["\u008F", "c", "0", "#", "x"]

Returns:



447
448
449
450
451
# File 'lib/radagen.rb', line 447

def char
  fmap(choose(0, 255)) do |v|
    v.chr(CHAR_ENCODING)
  end
end

#char_alphaRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create alpha characters from codepoint ranges: 65-90, 97-122.

Examples:

char_alpha.sample(5) #=> ["w", "p", "J", "W", "b"]

Returns:



491
492
493
494
495
# File 'lib/radagen.rb', line 491

def char_alpha
  fmap(one_of(choose(65, 90), choose(97, 122))) do |v|
    v.chr(CHAR_ENCODING)
  end
end

#char_alphanumericRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create alphanumeric characters from codepoint ranges: 48-57, 65-90, 97-122.

Examples:

char_alphanumeric.sample(5) #=> ["2", "A", "L", "I", "S"]

Returns:



476
477
478
479
480
# File 'lib/radagen.rb', line 476

def char_alphanumeric
  fmap(one_of(choose(48, 57), choose(65, 90), choose(97, 122))) do |v|
    v.chr(CHAR_ENCODING)
  end
end

#char_asciiRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create ascii characters from codepoints 32-126.

Examples:

char_ascii.sample(5) #=> [".", "P", "=", ":", "l"]

Returns:



461
462
463
464
465
# File 'lib/radagen.rb', line 461

def char_ascii
  fmap(choose(32, 126)) do |v|
    v.chr(CHAR_ENCODING)
  end
end

#char_numericRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create numeric characters from codepoints 48-57

Examples:

char_numeric.sample(5) #=> ["8", "5", "7", "0", "8"]

Returns:



506
507
508
509
510
# File 'lib/radagen.rb', line 506

def char_numeric
  fmap(choose(48, 57)) do |v|
    v.chr(CHAR_ENCODING)
  end
end

#choose(Fixnum, Fixnum) ⇒ Radagen::Generator #choose(Float, Float) ⇒ Radagen::Generator

Note:

This is a low level generator and is used to build up most of the generator abstractions

Creates a generator that will choose (inclusive) at random a number between lower and upper bounds. The sampling is with replacement.

Examples:

choose(1, 5).sample(5) #=> [5, 1, 3, 4, 5]
choose(0.0, 1.0).sample(5) #=> [0.7892616716655776, 0.9918259286064951, 0.8583139574435731, 0.9567596959947294, 0.3024080166537295]

Overloads:

  • #choose(Fixnum, Fixnum) ⇒ Radagen::Generator

    Parameters:

    • lower (Fixnum)

      set the lower bound (inclusive)

    • upper (Fixnum)

      set the upper bound (inclusive)

    Returns:

  • #choose(Float, Float) ⇒ Radagen::Generator

    Parameters:

    • lower (Float)

      set the lower bound (inclusive)

    • upper (Float)

      set the upper bound (inclusive)

    Returns:

Raises:

  • (RangeError.new)


37
38
39
40
# File 'lib/radagen.rb', line 37

def choose(lower, upper)
  raise RangeError.new, 'upper needs to be greater than or equal to lower value' unless upper >= lower
  RG.new { |prng, _| prng.rand(lower..upper) }
end

#elements(coll) ⇒ Radagen::Generator

Note:

Sampling is with replacement.

Returns a generator that takes a single element from the passed in collection. Works with object that implement .to_a.

Examples:

elements([1,2,3,4,5]).sample(4) #=> [4, 2, 5, 5]

showing that #.to_a will be called on coll

elements({:this => :this, :that => :that}).sample(2) #=> [[:that, :that], [:that, :that]]

Parameters:

  • coll (Object)

    collection object that an element will be selected from

Returns:



386
387
388
389
390
391
392
# File 'lib/radagen.rb', line 386

def elements(coll)
  _coll = coll.to_a

  bind(choose(0, _coll.count - 1)) do |i|
    identity(_coll.fetch(i))
  end
end

#fixnumRadagen::Generator

Returns a generator that will return fixnums.

Examples:

fixnum.sample(5) #=> [0, 0, -1, 0, -2]

Returns:



606
607
608
# File 'lib/radagen.rb', line 606

def fixnum
  sized { |size| choose(-size, size) }
end

#fixnum_negRadagen::Generator

Note:

0 is excluded

Returns a generator that will return negative fixnums.

Examples:

fixnum_neg.sample(5) #=> [-1, -1, -1, -2, -2]

Returns:



630
631
632
# File 'lib/radagen.rb', line 630

def fixnum_neg
  fmap(fixnum_pos) { |f| f * -1 }
end

#fixnum_posRadagen::Generator

Note:

0 is excluded

Returns a generator that will return positive fixnums.

Examples:

fixnum_pos.sample(5) #=> [1, 1, 3, 2, 4]

Returns:



618
619
620
# File 'lib/radagen.rb', line 618

def fixnum_pos
  such_that(natural) { |f| f > 0 }
end

#floatRadagen::Generator

Returns a generator that will return Floats.

Examples:

float.sample(5) #=> [0.0, -0.2676817207773654, 1.0318897544602246, 0.025701283892250792, -3.694547741510407]

Returns:



653
654
655
# File 'lib/radagen.rb', line 653

def float
  sized { |size| choose(-size.to_f, size.to_f) }
end

#fmap(gen, &block) ⇒ Radagen::Generator

Note:

A value (not a generator) needs to be returned from the Proc.

Takes a generator and a Proc. The Proc is passed a value taken from calling the generator. You then are free to transform the value before it is returned.

Examples:

fmap(fixnum) { |i| [i, i ** i] }.sample(4) #=> [[0, 1], [-1, -1], [2, 4], [-1, -1]]

Parameters:

  • gen (Radagen::Generator)

    generator that produces values passed to Proc

  • block (Proc)

    proc that is intended to manipulate value and return it

Returns:



122
123
124
125
126
# File 'lib/radagen.rb', line 122

def fmap(gen, &block)
  RG.new do |prng, size|
    block.call(gen.call(prng, size))
  end
end

#frequency(weighted_hash) ⇒ Radagen::Generator

Returns a generator that will select a generator from the weighted hash basing the sampling probability on the weights. The weighted_hash is a hash where the keys are generators and values are the sampling weight relative to all other weights, allowing you to control the probability of value sampling.

Examples:

sample a uuid with three times the probability as string

frequency({uuid => 3, string_ascii => 1}).sample(5) #=> ["", "Y", "3a1d740e-0587-40ca-a9e5-0e550e9afa0d", "2af98855-5bd8-43b4-8b80-1f0ef67712b3", "4fba95b5-9751-492f-889c-a850e7d9b313"]

Parameters:

Returns:



429
430
431
432
433
434
435
436
437
# File 'lib/radagen.rb', line 429

def frequency(weighted_hash)
  _weights = weighted_hash.values
  _gens = weighted_hash.keys
  raise ArgumentError.new 'all keys in kvs hash need to be Gen::Generator' unless _gens.all? { |g| gen? g }

  bind(choose(0, _weights.reduce(&:+) - 1)) do |r|
    frequency_helper(_gens, _weights, r, idx=0, sum=0)
  end
end

#gen?(obj) ⇒ Boolean

Predicate to check if obj is an instance of Gen::Generator

Parameters:

  • obj (Object)

    object to be checked

Returns:

  • (Boolean)


12
13
14
# File 'lib/radagen.rb', line 12

def gen?(obj)
  obj.is_a?(Radagen::Generator)
end

#hash(model_hash) ⇒ Radagen::Generator

Creates a generator that produces Hashes based on the model_hash passed in. This model_hash is a Hash of scalar keys and generator values. The hashes returned will have values realized from the generators provided.

Examples:

hash({name: not_empty(string_alpha), age: fixnum_neg, occupation: elements([:engineer, :scientist, :chief])}).sample(4) #=> [{:name=>"r", :age=>-1, :occupation=>:engineer}, {:name=>"n", :age=>-1, :occupation=>:chief}, {:name=>"f", :age=>-2, :occupation=>:engineer}, {:name=>"O", :age=>-2, :occupation=>:chief}]

Parameters:

Returns:



252
253
254
255
256
257
258
259
260
# File 'lib/radagen.rb', line 252

def hash(model_hash)
  ks = model_hash.keys
  vs = model_hash.values
  raise ArgumentError.new 'all values in hash need to be a Gen::Generator' unless vs.all? { |g| gen? g }

  fmap(tuple(*vs)) do |vs|
    Hash[ks.zip(vs)]
  end
end

#hash_map(key_gen, value_gen) ⇒ Radagen::Generator

Note:

This will create hashes of various sizes and will grow along with the keys and values.

Creates a generator that when called will return hashes containing keys taken from key_gen and values taken from value_gen.

Examples:

hash_map(symbol, fixnum_pos).sample(5) #=> [{}, {:t=>1}, {:DE=>2}, {:nvq=>1, :EN=>2, :L=>2}, {:QTCB=>4, :V=>3, :g=>3, :ue=>2}]

Parameters:

Returns:



273
274
275
276
277
# File 'lib/radagen.rb', line 273

def hash_map(key_gen, value_gen)
  fmap(array(tuple(key_gen, value_gen))) do |tuple_array|
    Hash[tuple_array]
  end
end

#identity(value) ⇒ Radagen::Generator Also known as: return

Returns a generator that when called always returns the value passed in. The identity generator.

Examples:

identity(["something"]).sample(4) #=> [["something"], ["something"], ["something"], ["something"]]

Parameters:

  • value (Object)

    object that will always be returned by generator

Returns:



366
367
368
# File 'lib/radagen.rb', line 366

def identity(value)
  RG.new { |_, _| value }
end

#naturalRadagen::Generator

Note:

0 is included

Returns a generator that will return natural fixnums.

Examples:

natural.sample(5) #=> [0, 1, 2, 3, 0]

Returns:



642
643
644
# File 'lib/radagen.rb', line 642

def natural
  fmap(fixnum) { |f| f.abs }
end

#not_empty(gen) ⇒ Radagen::Generator

Note:

Of course this will throw if you pass it a generator who's values don't produce types that respond to #empty?

Creates a generator that empty values from the provided generator are disregarded. Literally calls #empty? on object. This is a convenience generator for dealing with strings and collection types.

Examples:

not_empty(string_ascii).sample(5) #=> ["r", "!R", ";", "}", "HKh"]
not_empty(array(string_ascii)).sample(5) #=> [["`"], ["", ""], ["", ""], ["MH(", "gM", "{mz"], ["!", "9;", "c"]]

Parameters:

  • gen (Radagen::Generator)

    generator that produces values that #empty? will be called on

Returns:



315
316
317
# File 'lib/radagen.rb', line 315

def not_empty(gen)
  such_that(gen) { |x| not x.empty? }
end

#one_of(generator, generator, ...) ⇒ Radagen::Generator

Creates a generator that when called will select one of the passed in generators returning it's realized value.

Examples:

one_of(fixnum, char_ascii, boolean).sample(5) #=> [0, "d", false, 1, -1]

Parameters:

Returns:



329
330
331
332
333
# File 'lib/radagen.rb', line 329

def one_of(*gens)
  bind(choose(0, gens.count - 1)) do |i|
    gens.fetch(i)
  end
end

#rationalRadagen::Generator

Returns a generator that will return Rationals.

Examples:

rational.sample(5) #=> [(0/1), (-1/1), (1/1), (-1/2), (0/1)]

Returns:



664
665
666
667
668
669
670
# File 'lib/radagen.rb', line 664

def rational
  denom_gen = such_that(fixnum) { |f| not f == 0 }

  fmap(tuple(fixnum, denom_gen)) do |(n, d)|
    Rational(n, d)
  end
end

#resize(gen, size) ⇒ Radagen::Generator

Creates a generator that allows you to pin the size of a generator to specified value. Think of the size as being the upper bound the generator's size can be.

Examples:

Set the size of a integer generator

resize(fixnum, 500).sample(3) #=> [484, -326, -234]

Without resize

fixnum.sample(3) #=> [0, 1, 1]

Parameters:

  • gen (Radagen::Generator)

    generator to set the size on

  • size (Fixnum)

    actual size to be set

Returns:



79
80
81
82
83
# File 'lib/radagen.rb', line 79

def resize(gen, size)
  RG.new do |prng, _|
    gen.call(prng, size)
  end
end

#scale(gen, &block) ⇒ Radagen::Generator

Note:

This is intended to be used for generators that accept a size. This is partly a convenience function, as you can accomplish much the same with sized.

Creates a generator that allows you to modify the size parameter of the passed in generator with the block. The block accepts the size and allows you to change the size at different rates other than linear.

Examples:

Cube size parameter

scaled_nums = scale(string_numeric) do |size|
  size ** 3
end

scaled_nums.sample(3) #=> ["", "5", "69918"]

Parameters:

  • gen (Radagen::Generator)

    generator that will be resized by the scaled size

  • block (Proc)

    proc that will accept transform and return the size parameter

Returns:

See Also:



103
104
105
106
107
108
# File 'lib/radagen.rb', line 103

def scale(gen, &block)
  sized do |size|
    _size = block.call(size)
    resize(gen, _size)
  end
end

#set(gen, opts = {}) ⇒ Radagen::Generator

Note:

If the provided generator generates two of the same values then the set will only contain a single representation of that value.

Creates a generator that when called returns a varying length Set with values realized from the passed in generator. Excepts the same values and provides similar behavior of Array options.

Examples:

set(fixnum).sample(5) #=> [#<Set: {}>, #<Set: {}>, #<Set: {1, -2}>, #<Set: {-3}>, #<Set: {-1, -4, -3}>]

Parameters:

  • gen (Radagen::Generator)

    generator that produces values in the Set

  • opts (Hash) (defaults to: {})

    the options hash to provide extra context to the generator

Options Hash (opts):

  • :min (Fixnum) — default: 0

    minimum number of values in a generated Set

  • :max (Fixnum) — default: *size*

    maximum number of values in a generated Set

Returns:

See Also:



235
236
237
238
239
# File 'lib/radagen.rb', line 235

def set(gen, opts={})
  fmap(array(gen, opts)) do |array|
    Set[*array]
  end
end

#shuffle(coll) ⇒ Radagen::Generator

Returns a generator that will create a collection of same length with the elements reordered.

Examples:

shuffle([:this, :that, :other]).sample(4) #=> [[:other, :that, :this], [:this, :that, :other], [:that, :other, :this], [:other, :this, :that]]

Parameters:

  • coll (Object)

    collection object that elements will be reordered

Returns:



403
404
405
406
407
408
409
410
411
412
413
414
415
# File 'lib/radagen.rb', line 403

def shuffle(coll)
  _coll = coll.to_a
  _idx_gen = choose(0, _coll.length - 1)

  fmap(array(tuple(_idx_gen, _idx_gen), {max: _coll.length * 3})) do |swap_indexes|
    swap_indexes.reduce(_coll.clone) do |coll, (i, j)|
      temp = coll[i]
      coll[i] = coll[j]
      coll[j] = temp
      coll
    end
  end
end

#simple_printableRadagen::Generator

Note:

size does not effect derived UUID

Returns a random selection of a screen printable simple type.

Examples:

simple_printable.sample(5) #=> [0, "w", "tr", "aO", -3.072343865486716]

Returns:



751
752
753
# File 'lib/radagen.rb', line 751

def simple_printable
  one_of(fixnum, rational, float, boolean, symbol, char_ascii, string_ascii, char_alphanumeric, string_alphanumeric, uuid)
end

#simple_typeRadagen::Generator

Note:

size does not effect derived UUID

Returns a random selection of a simple type.

Examples:

simple_type.sample(5) #=> ["Á", -0.6330060889340847, (-1/1), "Vé", 1]

Returns:



739
740
741
# File 'lib/radagen.rb', line 739

def simple_type
  one_of(fixnum, rational, bytes, float, boolean, symbol, char, string, uuid)
end

#sized(&block) ⇒ Radagen::Generator

Creates a generator that 'exposes' the size value passed to the generator. block is a Proc that takes a fixnum and returns a generator. This can be used to see, manipulate or wrap another generator with the passed in size.

Examples:

Cube the size passed to a generator

sized do |size|
  cube_size = size ** 3
  choose(1, cube_size)
end

Parameters:

  • block (Proc)

    takes a size returning a generator

Returns:



57
58
59
60
61
62
# File 'lib/radagen.rb', line 57

def sized(&block)
  RG.new do |prng, size|
    sized_gen = block.call(size)
    sized_gen.call(prng, size)
  end
end

#some_of(generator, generator, ...) ⇒ Radagen::Generator

Note:

Order of generator selection will be shuffled

Creates a generator that when called will select 1..n generators provided and return and Array of realized values from those chosen generators.

Examples:

some_of(uuid, symbol, float).sample(4) #=> [["be136967-98e9-4b56-a562-1555c2d0dd2e"], [0.3905013788606524, "bf148e98-8454-4482-9b90-b0f3f2813785", :j], [0.40012165933893407, "8e6e4e58-75ed-4295-b53d-c60416c1a975", :bA], [-0.3612584756590138, :m]]

Parameters:

Returns:



347
348
349
350
351
352
353
354
355
# File 'lib/radagen.rb', line 347

def some_of(*gens)
  bind(tuple(*gens)) do |_vals|
    bind(choose(1, _vals.count)) do |_count|
      fmap(shuffle(_vals)) do |__vals|
        __vals.take(_count)
      end
    end
  end
end

#stringRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create strings from characters within codepoints 0-255

Examples:

string.sample #=> ["", "®", "M", "", "", "Ù¡", "¾H", "<*<", "=\u000FW\u0081", "m¦w"]

Returns:



521
522
523
524
525
# File 'lib/radagen.rb', line 521

def string
  fmap(array(char)) do |char_array|
    char_array.join
  end
end

#string_alphaRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create strings from alpha characters within codepoint ranges: 65-90, 97-122

Examples:

string_alpha.sample #=> ["", "", "", "H", "i", "Nxc", "gPfIt", "KpGRCl", "BjuiQE", "FCnfPkr"]

Returns:



567
568
569
570
571
# File 'lib/radagen.rb', line 567

def string_alpha
  fmap(array(char_alpha)) do |char_array|
    char_array.join
  end
end

#string_alphanumericRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create strings from alphanumeric characters within codepoint ranges: 48-57, 65-90, 97-122

Examples:

string_alphanumeric.sample #=> ["", "e", "yh", "8", "", "8z0", "u441", "L3", "257o", "gWGhZ9"]

Returns:



552
553
554
555
556
# File 'lib/radagen.rb', line 552

def string_alphanumeric
  fmap(array(char_alphanumeric)) do |char_array|
    char_array.join
  end
end

#string_asciiRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create strings from ascii characters within codepoints 32-126

Examples:

string_ascii.sample #=> ["", "^", "", "", "M5a", "", "c", "/gL`Q\\W", "D$I0:F", "`hC|w"]

Returns:



536
537
538
539
540
# File 'lib/radagen.rb', line 536

def string_ascii
  fmap(array(char_ascii)) do |char_array|
    char_array.join
  end
end

#string_numericRadagen::Generator

Note:

Defaults to UTF-8 encoding

Returns a generator that will create strings from alpha characters within codepoints 48-57

Examples:

string_numeric.sample #=> ["", "0", "16", "5", "277"]

Returns:



582
583
584
585
586
# File 'lib/radagen.rb', line 582

def string_numeric
  fmap(array(char_numeric)) do |char_array|
    char_array.join
  end
end

#such_that(gen, tries = 10, &pred) ⇒ Radagen::Generator

Creates a generator taking values from the passed in generator and applies them to the pred block, returning only the values that satisfy the predicate. This acts much the same way as enumerable's #select method. By default it will try 10 times to satisfy the predicate with different sizes passed to the generator. You can provide a count of the number of tries.

Examples:

such_that(string_ascii) { |s| s.length > 4 }.sample(5) #=> ["/%daW", "bQ@t'", "{1%]o", "8j*vzL", "Ga2#Z"]

Parameters:

  • gen (Radagen::Generator)

    generator that produces values applied to predicate block

  • tries (Fixnum) (defaults to: 10)

    (10) maximum number of tries the generator will make to satify the predicate

  • pred (Proc)

    proc/function that takes a value from gen and returns a truthy or falsy value

Returns:



294
295
296
297
298
# File 'lib/radagen.rb', line 294

def such_that(gen, tries=10, &pred)
  RG.new do |prng, size|
    select_helper(gen, tries, prng, size, &pred)
  end
end

#symbolRadagen::Generator

Returns a generator that will return Ruby Symbols.

Examples:

symbol.sample(5) #=> [:"7K", :a, :"82", :lhK, :qI4]

Returns:



702
703
704
705
706
# File 'lib/radagen.rb', line 702

def symbol
  fmap(not_empty(array(char_alphanumeric))) do |char_array|
    char_array.join.intern
  end
end

#tuple(generator, generator, ...) ⇒ Radagen::Generator

Takes n generators returning an n-tuple of realized values from generators in arity order.

Examples:

tuple(string_alphanumeric, uuid, boolean).sample(5) #=> [["", "6e63d2cc-82bf-4b34-b326-e5befeb30309", false], ["A", "2847889f-f93d-4239-86f5-c6411c639554", true], ["", "d04e894f-b35b-4edc-a214-abf76d9c1b60", true], ["05", "7e3ff332-8e35-44ca-905c-8e0538fb14f8", false], ["GR", "3f6c0be8-6b16-4b2b-9510-922961ff0f7a", true]]

Parameters:

Returns:



161
162
163
164
165
166
167
168
169
# File 'lib/radagen.rb', line 161

def tuple(*gens)
  raise ArgumentError.new 'all arguments need to be generators' unless gens.all? { |g| gen? g }

  RG.new do |prng, size|
    gens.map do |gen|
      gen.call(prng, size)
    end
  end
end

#uuidRadagen::Generator

Note:

size does not effect derived UUIDs

Returns a random type 4 uuid.

Examples:

uuid.sample(2) #=> ["1e9a99d0-d412-4362-a36a-6754c055a016", "d28326d7-db57-43ce-85f6-929d73aa3cbf"]

Returns:



716
717
718
719
720
721
722
723
724
725
726
727
728
729
# File 'lib/radagen.rb', line 716

def uuid
  fmap(array(choose(0, 15), {min: 31, max: 31})) do |nibbles|
    rhex = (8 + (nibbles[15] & 3)).to_s(16)

    [nibbles[0].to_s(16), nibbles[1].to_s(16), nibbles[2].to_s(16), nibbles[3].to_s(16),
     nibbles[4].to_s(16), nibbles[5].to_s(16), nibbles[6].to_s(16), nibbles[7].to_s(16), '-',
     nibbles[8].to_s(16), nibbles[9].to_s(16), nibbles[10].to_s(16), nibbles[11].to_s(16), '-',
     4, nibbles[12].to_s(16), nibbles[13].to_s(16), nibbles[14].to_s(16), '-',
     rhex, nibbles[16].to_s(16), nibbles[17].to_s(16), nibbles[18].to_s(16), '-',
     nibbles[19].to_s(16), nibbles[20].to_s(16), nibbles[21].to_s(16), nibbles[22].to_s(16),
     nibbles[23].to_s(16), nibbles[24].to_s(16), nibbles[25].to_s(16), nibbles[26].to_s(16),
     nibbles[27].to_s(16), nibbles[28].to_s(16), nibbles[29].to_s(16), nibbles[30].to_s(16)].join
  end
end