Module: Hypothesis::Possibilities

Extended by:
Possibilities
Includes:
Hypothesis
Included in:
Possibilities
Defined in:
lib/hypothesis/possible.rb

Overview

A module of many common Possible implementations. Rather than subclassing Possible yourself you should use methods from this module to construct Possible values.‘

You can use methods from this module by including Hypothesis::Possibilities in your tests, or by calling them on the module object directly.

Most methods in this module that return a Possible have two names: A singular and a plural name. These are simply aliases and are identical in every way, but are provided to improve readability. For example ‘any integer` reads better than `given integers` but `arrays(of: integers)` reads better than `arrays(of: integer)`.

Instance Method Summary collapse

Methods included from Hypothesis

#any, #assume, #hypothesis

Instance Method Details

#arrays(of:, min_size: 0, max_size: 10) ⇒ Possible Also known as: array

A Possible Array of variable shape. This is used for arrays where all of the elements come from the size may vary and the same values are possible at any position. For example, arrays(booleans) might provide [false, true, false].

Parameters:

  • of (Possible)

    The possible elements of the array.

  • min_size (Integer) (defaults to: 0)

    The smallest valid size of a provided array

  • max_size (Integer) (defaults to: 10)

    The largest valid size of a provided array

Returns:



273
274
275
276
277
278
279
280
281
282
283
# File 'lib/hypothesis/possible.rb', line 273

def arrays(of:, min_size: 0, max_size: 10)
  built_as do
    result = []
    rep = HypothesisCoreRepeatValues.new(
      min_size, max_size, (min_size + max_size) * 0.5
    )
    source = World.current_engine.current_source
    result.push any(of) while rep.should_continue(source)
    result
  end
end

#arrays_of_shape(*elements) ⇒ Possible Also known as: array_of_shape

A Possible Arrays of a fixed shape. This is used for arrays where you know exactly how many elements there are, and different values may be possible at different positions. For example, arrays_of_shape(strings, integers) will give you values like [“a”, 1]

Parameters:

  • elements (Array<Possible>)

    A variable number of Possible. values. The provided array will have this many values, with each value possible for the corresponding argument. If elements contains an array it will be flattened first, so e.g. arrays_of_shape(a, b) is equivalent to arrays_of_shape([a, b])

Returns:



256
257
258
259
260
261
# File 'lib/hypothesis/possible.rb', line 256

def arrays_of_shape(*elements)
  elements = elements.flatten
  built_as do
    elements.map { |e| any e }.to_a
  end
end

#booleansPossible Also known as: boolean

A Possible boolean value

Returns:



150
151
152
# File 'lib/hypothesis/possible.rb', line 150

def booleans
  integers(min: 0, max: 1).map { |i| i == 1 }
end

#built_as(&block) ⇒ Possible Also known as: values_built_as

built_as lets you chain multiple Possible values together, by providing whatever value results from its block.

For example the following provides a array plus some element from that array:

“‘ruby

built_as do
  ls = any array(of: integers)
  # Or min_size: 1 above, but this shows use of
  # assume
  assume ls.size > 0
  i = any element_of(ls)
  [ls, i]

“‘

Returns:

  • (Possible)

    A Possible whose possible values are any result from the passed block.



142
143
144
# File 'lib/hypothesis/possible.rb', line 142

def built_as(&block)
  Hypothesis::Possible::Implementations::CompositePossible.new(block)
end

#codepoints(min: 1, max: 1_114_111) ⇒ Possible Also known as: codepoint

A Possible unicode codepoint.

Parameters:

  • min (Integer) (defaults to: 1)

    The smallest codepoint to provide

  • max (Integer) (defaults to: 1_114_111)

    The largest codepoint to provide

Returns:



160
161
162
163
164
165
166
167
# File 'lib/hypothesis/possible.rb', line 160

def codepoints(min: 1, max: 1_114_111)
  base = integers(min: min, max: max)
  if min <= 126
    from(integers(min: min, max: [126, max].min), base)
  else
    base
  end
end

#element_of(values) ⇒ Possible Also known as: elements_of

Note:

these values are provided as is, so if the provided values are mutated in the test you should be careful to make sure each test run gets a fresh value (if you use this Possible in line in the test you don’t need to worry about this, this is only a problem if you define the Possible outside of your hypothesis block).

A Possible where any one of a fixed array of values is possible.

Parameters:

  • values (Enumerable)

    A collection of possible values.

Returns:



323
324
325
326
327
328
329
330
331
# File 'lib/hypothesis/possible.rb', line 323

def element_of(values)
  values = values.to_a
  indexes = from_hypothesis_core(
    HypothesisCoreBoundedIntegers.new(values.size - 1)
  )
  built_as do
    values.fetch(any(indexes))
  end
end

#from(*components) ⇒ Possible Also known as: mix_of

Note:

This has a slightly non-standard aliasing. It reads more nicely if you write ‘any from(a, b, c)` but e.g. `arrays(of: mix_of(a, b, c))`.

A Possible where the possible values are any one of a number of other possible values. For example, from(strings, integers) could provide either of “a” or 1.

Parameters:

  • components (Array<Possible>)

    A number of Possible values, where the result will include any value possible from any of them. If components contains an array it will be flattened first, so e.g. from(a, b) is equivalent to from([a, b])

Returns:



301
302
303
304
305
306
307
308
309
310
# File 'lib/hypothesis/possible.rb', line 301

def from(*components)
  components = components.flatten
  indexes = from_hypothesis_core(
    HypothesisCoreBoundedIntegers.new(components.size - 1)
  )
  built_as do
    i = any indexes
    any components[i]
  end
end

#hashes_of_shape(hash) ⇒ Possible Also known as: hash_of_shape

A Possible Hash, where all possible values have a fixed shape. This is used for hashes where you know exactly what the keys are, and different keys may have different possible values. For example, hashes_of_shape(a: integers, b: booleans) will give you values like ‘11, b: false`.

Parameters:

  • hash (Hash)

    A hash describing the values to provide. The keys will be present unmodified in the provided hashes, mapping to their Possible value in the result.

Returns:



209
210
211
212
213
214
215
# File 'lib/hypothesis/possible.rb', line 209

def hashes_of_shape(hash)
  built_as do
    result = {}
    hash.each { |k, v| result[k] = any(v) }
    result
  end
end

#hashes_with(keys:, values:, min_size: 0, max_size: 10) ⇒ Possible Also known as: hash_with

A Possible Hash of variable shape.

Parameters:

  • keys (Possible)

    the possible keys

  • values (Possible)

    the possible values

Returns:



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/hypothesis/possible.rb', line 223

def hashes_with(keys:, values:, min_size: 0, max_size: 10)
  built_as do
    result = {}
    rep = HypothesisCoreRepeatValues.new(
      min_size, max_size, (min_size + max_size) * 0.5
    )
    source = World.current_engine.current_source
    while rep.should_continue(source)
      key = any keys
      if result.include?(key)
        rep.reject
      else
        result[key] = any values
      end
    end
    result
  end
end

#integers(min: nil, max: nil) ⇒ Possible Also known as: integer

A Possible integer

Parameters:

  • min (Integer) (defaults to: nil)

    The smallest value integer to provide.

  • max (Integer) (defaults to: nil)

    The largest value integer to provide.

Returns:



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
# File 'lib/hypothesis/possible.rb', line 339

def integers(min: nil, max: nil)
  base = from_hypothesis_core HypothesisCoreIntegers.new
  if min.nil? && max.nil?
    base
  elsif min.nil?
    built_as { max - any(base).abs }
  elsif max.nil?
    built_as { min + any(base).abs }
  else
    bounded = from_hypothesis_core(
      HypothesisCoreBoundedIntegers.new(max - min)
    )
    if min.zero?
      bounded
    else
      built_as { min + any(bounded) }
    end
  end
end

#strings(codepoints: nil, min_size: 0, max_size: 10) ⇒ Possible Also known as: string

A Possible String

Parameters:

  • codepoints (Possible, nil) (defaults to: nil)

    The Possible codepoints that can be found in the string. If nil, will default to self.codepoints. These will be further filtered to ensure the generated string is valid.

  • min_size (Integer) (defaults to: 0)

    The smallest valid length for a provided string

  • max_size (Integer) (defaults to: 10)

    The smallest valid length for a provided string

Returns:



182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/hypothesis/possible.rb', line 182

def strings(codepoints: nil, min_size: 0, max_size: 10)
  codepoints = self.codepoints if codepoints.nil?
  codepoints = codepoints.select do |i|
    begin
      [i].pack('U*').codepoints
      true
    rescue ArgumentError
      false
    end
  end
  arrays(of: codepoints, min_size: min_size, max_size: max_size).map do |ls|
    ls.pack('U*')
  end
end