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.

Parameters:

  • pattern (Hash)

    a hash that will be used as a template for samples

Returns:



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

Parameters:

  • args (Array)

    a template structure

Returns:



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.

Parameters:

  • sampler (Quick::Sampler)

    a sampler to sample array elements from

  • non_empty (Boolean) (defaults to: false)

    pass true to never produce empty arrays

Returns:

  • (Quick::Sampler)

    a sampler that produces arrays of values sampled from its argument



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

#object_like(the_class, *args) ⇒ Object

Arbitrary object sampler.

Parameters:

  • the_class (Class, Quick::Sampler<Class>)

    a class of the object to create (or a sampler producing classes)

  • *args (*Anything)

    arguments to pass to the constructor (may contain samplers)



133
134
135
# File 'lib/quick/sampler/dsl/simple_combinators.rb', line 133

def object_like the_class, *args
  send_to(the_class, :new, *args)
end

#one_of(*args) ⇒ Quick::Sampler

Returns a sampler that recursively samples on of the arguments at random.

Returns:

  • (Quick::Sampler)

    a sampler that recursively samples on of the arguments at random



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

Returns a sampler that recursively samples on of the expressions at random, with likelyhood of picking one of the expressions depends on its weight.

Returns:

  • (Quick::Sampler)

    a sampler that recursively samples on of the expressions at random, with likelyhood of picking one of the expressions depends on its weight.



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

Returns a sampler producing values from the range or array.

Returns:

  • (Quick::Sampler)

    a sampler producing values from the range or array



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) }
  else
    feed { source.to_a.sample }
  end
end

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

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

Overloads:

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

    Parameters:

    • recipient (Object, Quick::Sampler<Object>)

      message recipient or a sampler producing recipients

    • message (Symbol, Quick::Sampler<Symbol>)

      message to send or a sampler producing messages

    • args (Array)

      argument list that may contain samplers producing arguments

  • #send_to(sampler) ⇒ Quick::Sampler

    Parameters:

    • sampler (Quick::Sampler<[Object, Symbol, *Anything]>)

      a sampler producing the message send details

Returns:

  • (Quick::Sampler)

    a sampler of dynamically generated message send 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.

Parameters:

  • length (Integer)

    sample array length

  • sampler (Quick::Sampler)

    a sampler to sample array elements from

Returns:

  • (Quick::Sampler)

    a sampler that produces arrays of length of values sampled from sampler



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

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