Module: Quick::Sampler::DSL::SimpleCombinators

Included in:
Quick::Sampler::DSL
Defined in:
lib/quick/sampler/dsl/simple_combinators.rb

Overview

DSL methods that allow to combine samplers in various ways.

Recursive samplers

Some of the combinators are recursive: given a nested structure of Arrays and Hashes containing samplers and non-sampler values they would produce an analogous structure where samplers are replaced by their #next value.

Instance Method Summary collapse

Instance Method Details

#hash_like(template) ⇒ Quick::Sampler<Hash>

Sampler of hashe's that in turn may contain Arrays, Hashes and Quick::Samplers.



95
96
97
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 95

def hash_like template
  send_to list_like(template), :first
end

#list_like(*args) ⇒ Quick::Sampler

Sampler of arbitrary nested structures made up of Arrays, Hashes, Quick::Samplers and non-sampler values



86
87
88
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 86

def list_like *args
  feed { args.map { |arg| recursive_sample(arg) } }
end

#list_of(sampler, non_empty: false) ⇒ Quick::Sampler

Sampler of uniform arrays

This sampler honors upper_bound config variable and samples Arrays of up to that many elements.

Rosetta stone the single argument version corresponds to QuickCheck's listOf. Passing non_empty: true turns it into QuickCheck's listOf1.



60
61
62
63
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 60

def list_of sampler, non_empty: false
  lower_bound = non_empty ? 1 : 0
  feed { sampler.first(rand(lower_bound..upper_bound)) }
end

#one_of(*args) ⇒ Quick::Sampler



25
26
27
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 25

def one_of *args
  feed { recursive_sample(args.sample) }
end

#one_of_weighted(expression_weights) ⇒ Quick::Sampler



32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 32

def one_of_weighted expression_weights
  total_weight, expressions = expression_weights
    .reduce([0, {}]) { |(total_weight, expressions), (expression, weight)|
      total_weight += weight
      [total_weight, expressions.merge(total_weight => expression)]
    }

  feed {
    dice = rand * total_weight
    weight_class = expressions.keys.find{|w| dice < w}
    recursive_sample(expressions[weight_class])
  }
end

#pick_from(source) ⇒ Quick::Sampler



14
15
16
17
18
19
20
21
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 14

def pick_from source
  case source
  when Range
    feed { rand(source) }
  when Array
    feed { source.sample }
  end
end

#send_to(recipient, message, *args) ⇒ Quick::Sampler #send_to(sampler) ⇒ Quick::Sampler

Sampler of arbitrary message send ("method call") results



115
116
117
118
119
120
121
122
123
124
125
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 115

def send_to *args
  call_sampler = if args.count > 1
                   list_like *args
                 else
                   args.first
                 end
  feed {
    object, message, *args = call_sampler.next
    object.send( message, *args )
  }
end

#vector_of(length, sampler) ⇒ Quick::Sampler

Sampler of uniform fixed length arrays

Rosetta stone this sampler corresponds to QuickCheck's vectorOf.



75
76
77
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 75

def vector_of length, sampler
  feed { sampler.take(length).force }
end