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 `any integers` but `arrays(of: integers)` reads better than `arrays(of: integer)`.

Constant Summary

Constants included from Hypothesis

DEFAULT_DATABASE_PATH

Instance Method Summary collapse

Methods included from Hypothesis

#any, #assume, #hypothesis, included, setup_called

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 the size may vary and the same values are possible at any position. For example, arrays(of: 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:



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

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:



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

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:



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

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 an 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]
end

“‘

Returns:

  • (Possible)

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



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

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:



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

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:



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

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:



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

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:



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

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:



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

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:



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

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 largest valid length for a provided string

Returns:



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

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