Hegel.Generators (hegel_elixir v0.1.0)

View Source

Generators for Hegel property tests.

Functions use familiar StreamData names such as integer/1, list_of/2, map/2, and bind/2. A %Hegel.Generator{} draws through the active test case. libhegel chooses primitives; compound generators add spans and collections that guide shrinking.

Use composite/1 for dependent draws:

pair =
  composite(fn draw ->
    lower = draw.(integer(0..10))
    {lower, draw.(integer(lower..20))}
  end)

Summary

Functions

Generates arbitrary byte-aligned binaries.

Draws from generator, then uses its value to build a dependent generator.

Generates booleans, with probability as the chance of true.

Alias for boolean/0.

Generates an integer byte (0..255).

Generates one Unicode character as its integer codepoint.

Alias for character/1, matching StreamData's terminology.

Creates a generator from imperative draw code.

Returns value without drawing from libhegel.

Generates naive NaiveDateTime values between inclusive bounds.

Generates domain names.

Generates RFC 5321/5322 email address strings.

Alias for email/0.

Keeps values satisfying predicate, discarding rejected choice spans.

Generates a fixed-length list, drawing from each supplied generator.

Generates maps with fixed keys and one generator per value.

Generates finite BEAM floats using libhegel's IEEE-754 draw.

Chooses from {positive_weight, generator} pairs.

Generates strings matching a Python re pattern.

Generates an arbitrary-precision integer.

Generates an integer in the inclusive interval min..max.

Alias for integer/0.

Generates an Erlang/Elixir IP-address tuple.

Generates IPv4 address tuples.

Generates IPv6 address tuples.

Alias for constant/1, matching Hegel's other frontends.

Defers generator construction until draw time.

Generates variable-length lists from element_generator.

Transforms each value produced by generator.

Generates variable-size maps from key and value generators.

Picks a value from a non-empty, finite enumerable.

Generates integers greater than or equal to zero.

Generates either nil or a value from generator.

Chooses and draws from one of a non-empty enumerable of generators.

Convenience two-generator form of one_of/1.

Generates integers greater than zero.

Alias for member_of/1, matching Hegel's other frontends.

StreamData-style string entry point.

Generates UTF-8 text.

Generates Time values between inclusive :min and :max bounds.

Generates tuples matching the fixed shape of generator_tuple.

Alias for text/1, emphasizing the returned Elixir UTF-8 binary.

Generates lists whose elements are unique.

Generates RFC 3986 HTTP or HTTPS URL strings.

Alias for url/0.

Generates canonical lower-case UUID strings.

Types

options()

@type options() :: keyword() | map()

Functions

binaries(options \\ [])

@spec binaries(options()) :: Hegel.Generator.t(binary())

Alias for binary/1.

binary(options \\ [])

@spec binary(options()) :: Hegel.Generator.t(binary())

Generates arbitrary byte-aligned binaries.

bind(generator, binder)

@spec bind(Hegel.Generator.t(input), (input -> Hegel.Generator.t(output))) ::
  Hegel.Generator.t(output)
when input: term(), output: term()

Draws from generator, then uses its value to build a dependent generator.

This is also known as flat_map in Hegel's other frontends.

boolean(probability \\ 0.5)

@spec boolean(number()) :: Hegel.Generator.t(boolean())

Generates booleans, with probability as the chance of true.

booleans()

@spec booleans() :: Hegel.Generator.t(boolean())

Alias for boolean/0.

byte()

@spec byte() :: Hegel.Generator.t(byte())

Generates an integer byte (0..255).

character(options \\ [])

@spec character(options()) :: Hegel.Generator.t(non_neg_integer())

Generates one Unicode character as its integer codepoint.

Elixir represents characters as integers; use text(length: 1) when a one-codepoint binary is preferred.

characters(options \\ [])

@spec characters(options()) :: Hegel.Generator.t(non_neg_integer())

Alias for character/1.

codepoint(kind_or_options \\ [])

@spec codepoint(:utf8 | :unicode | :ascii | options()) ::
  Hegel.Generator.t(non_neg_integer())

Alias for character/1, matching StreamData's terminology.

composite(fun, options \\ [])

@spec composite(function(), options()) :: Hegel.Generator.t(term())

Creates a generator from imperative draw code.

The callback receives draw, an arity-one function accepting another generator. An arity-two callback also receives the active test case as its first argument. Hegel groups nested draws in one frontend-owned span; pass label: non_negative_integer to distinguish custom structures.

constant(value)

@spec constant(value) :: Hegel.Generator.t(value) when value: term()

Returns value without drawing from libhegel.

date(options_or_range \\ [])

@spec date(Date.Range.t() | options()) :: Hegel.Generator.t(Date.t())

Generates Date values.

Accepts either a Date.Range or :min and :max options. The default is the conventional Hypothesis range 0001-01-01 through 9999-12-31.

dates(options_or_range \\ [])

@spec dates(Date.Range.t() | options()) :: Hegel.Generator.t(Date.t())

Alias for date/1.

datetime(options \\ [])

@spec datetime(options()) :: Hegel.Generator.t(NaiveDateTime.t())

Generates naive NaiveDateTime values between inclusive bounds.

libhegel generates datetimes without a timezone. This function returns NaiveDateTime.

datetimes(options \\ [])

@spec datetimes(options()) :: Hegel.Generator.t(NaiveDateTime.t())

Alias for datetime/1.

domain(options \\ [])

@spec domain(options()) :: Hegel.Generator.t(String.t())

Generates domain names.

domains(options \\ [])

@spec domains(options()) :: Hegel.Generator.t(String.t())

Alias for domain/1.

email()

@spec email() :: Hegel.Generator.t(String.t())

Generates RFC 5321/5322 email address strings.

emails()

@spec emails() :: Hegel.Generator.t(String.t())

Alias for email/0.

filter(generator, predicate, attempts_or_options \\ 3)

@spec filter(
  Hegel.Generator.t(value),
  (value -> as_boolean(term())),
  pos_integer() | options()
) ::
  Hegel.Generator.t(value)
when value: term()

Keeps values satisfying predicate, discarding rejected choice spans.

After max_attempts local retries the complete test case is rejected, which lets libhegel's filter health check diagnose a narrow predicate.

fixed_list(generators)

@spec fixed_list([Hegel.Generator.t(term())]) :: Hegel.Generator.t([term()])

Generates a fixed-length list, drawing from each supplied generator.

fixed_map(generator_map)

@spec fixed_map(%{optional(term()) => Hegel.Generator.t(term())}) ::
  Hegel.Generator.t(map())

Generates maps with fixed keys and one generator per value.

flat_map(generator, binder)

@spec flat_map(Hegel.Generator.t(input), (input -> Hegel.Generator.t(output))) ::
  Hegel.Generator.t(output)
when input: term(), output: term()

Alias for bind/2.

float(options \\ [])

@spec float(options()) :: Hegel.Generator.t(float())

Generates finite BEAM floats using libhegel's IEEE-754 draw.

Supported options are :min, :max, :exclude_min, :exclude_max, :width (32 or 64), and :allow_subnormal. The libhegel flags BEAM float terms cannot represent NaN or infinity, so :allow_nan and :allow_infinity must be false.

floats(options \\ [])

@spec floats(options()) :: Hegel.Generator.t(float())

Alias for float/1.

frequency(weighted_generators)

@spec frequency([{pos_integer(), Hegel.Generator.t(term())}]) ::
  Hegel.Generator.t(term())

Chooses from {positive_weight, generator} pairs.

from_regex(pattern, options \\ [])

@spec from_regex(String.t(), options()) :: Hegel.Generator.t(String.t())

Generates strings matching a Python re pattern.

integer()

@spec integer() :: Hegel.Generator.t(integer())

Generates an arbitrary-precision integer.

A range supplies inclusive bounds. For a range with a non-unit step, Hegel draws an index into the range. With no argument, the generator uses signed 128-bit bounds because libhegel's integer primitive requires a finite domain.

integer(range)

@spec integer(Range.t() | options()) :: Hegel.Generator.t(integer())

integer(min, max)

@spec integer(integer(), integer()) :: Hegel.Generator.t(integer())

Generates an integer in the inclusive interval min..max.

integers()

@spec integers() :: Hegel.Generator.t(integer())

Alias for integer/0.

ip_address(options \\ [])

@spec ip_address(options()) :: Hegel.Generator.t(:inet.ip_address())

Generates an Erlang/Elixir IP-address tuple.

Pass version: 4 or version: 6 to restrict the family; by default the engine chooses between both under a ONE_OF span.

ip_addresses(options \\ [])

@spec ip_addresses(options()) :: Hegel.Generator.t(:inet.ip_address())

Alias for ip_address/1.

ipv4()

Generates IPv4 address tuples.

ipv6()

Generates IPv6 address tuples.

just(value)

@spec just(value) :: Hegel.Generator.t(value) when value: term()

Alias for constant/1, matching Hegel's other frontends.

lazy(fun)

@spec lazy((-> Hegel.Generator.t(value))) :: Hegel.Generator.t(value)
when value: term()

Defers generator construction until draw time.

Use this recursion primitive with a zero-arity function that returns a generator on each draw.

list_of(element_generator, options \\ [])

@spec list_of(Hegel.Generator.t(value), options()) :: Hegel.Generator.t([value])
when value: term()

Generates variable-length lists from element_generator.

lists(element_generator, options \\ [])

@spec lists(Hegel.Generator.t(value), options()) :: Hegel.Generator.t([value])
when value: term()

Alias for list_of/2.

map(generator, mapper)

@spec map(Hegel.Generator.t(input), (input -> output)) :: Hegel.Generator.t(output)
when input: term(), output: term()

Transforms each value produced by generator.

map_of(key_generator, value_generator, options \\ [])

@spec map_of(Hegel.Generator.t(key), Hegel.Generator.t(value), options()) ::
  Hegel.Generator.t(%{optional(key) => value})
when key: term(), value: term()

Generates variable-size maps from key and value generators.

member_of(enumerable)

@spec member_of(Enumerable.t()) :: Hegel.Generator.t(term())

Picks a value from a non-empty, finite enumerable.

naive_datetime(options \\ [])

@spec naive_datetime(options()) :: Hegel.Generator.t(NaiveDateTime.t())

Alias for datetime/1.

non_negative_integer()

@spec non_negative_integer() :: Hegel.Generator.t(non_neg_integer())

Generates integers greater than or equal to zero.

nullable(generator, options \\ [])

@spec nullable(Hegel.Generator.t(value), options()) :: Hegel.Generator.t(value | nil)
when value: term()

Generates either nil or a value from generator.

one_of(generators)

@spec one_of(Enumerable.t()) :: Hegel.Generator.t(term())

Chooses and draws from one of a non-empty enumerable of generators.

one_of(left, right)

Convenience two-generator form of one_of/1.

optional(generator, options \\ [])

@spec optional(Hegel.Generator.t(value), options()) :: Hegel.Generator.t(value | nil)
when value: term()

Alias for nullable/2.

positive_integer()

@spec positive_integer() :: Hegel.Generator.t(pos_integer())

Generates integers greater than zero.

regex(pattern, options \\ [])

@spec regex(String.t(), options()) :: Hegel.Generator.t(String.t())

Alias for from_regex/2.

sampled_from(enumerable)

@spec sampled_from(Enumerable.t()) :: Hegel.Generator.t(term())

Alias for member_of/1, matching Hegel's other frontends.

string(kind_or_alphabet \\ :unicode, options \\ [])

@spec string(:unicode | :utf8 | :ascii | binary(), options()) ::
  Hegel.Generator.t(String.t())

StreamData-style string entry point.

text(options \\ [])

@spec text(options()) :: Hegel.Generator.t(String.t())

Generates UTF-8 text.

Length options are :length, :min_length, and :max_length (the *_size spellings are also accepted). Character options mirror libhegel: :alphabet, :codec, :min_codepoint, :max_codepoint, :categories, :exclude_categories, :include_characters, and :exclude_characters.

texts(options \\ [])

@spec texts(options()) :: Hegel.Generator.t(String.t())

Alias for text/1.

time(options \\ [])

@spec time(options()) :: Hegel.Generator.t(Time.t())

Generates Time values between inclusive :min and :max bounds.

times(options \\ [])

@spec times(options()) :: Hegel.Generator.t(Time.t())

Alias for time/1.

tuple(generator_tuple)

@spec tuple(tuple()) :: Hegel.Generator.t(tuple())

Generates tuples matching the fixed shape of generator_tuple.

unicode_character(options \\ [])

@spec unicode_character(options()) :: Hegel.Generator.t(non_neg_integer())

Alias for character/1.

unicode_string(options \\ [])

@spec unicode_string(options()) :: Hegel.Generator.t(String.t())

Alias for text/1, emphasizing the returned Elixir UTF-8 binary.

uniq_list_of(element_generator, options \\ [])

@spec uniq_list_of(Hegel.Generator.t(value), options()) :: Hegel.Generator.t([value])
when value: term()

Generates lists whose elements are unique.

:uniq_fun has the same meaning as Enum.uniq_by/2. The collection rejection primitive retries duplicate candidates without adding them to the requested size.

url()

@spec url() :: Hegel.Generator.t(String.t())

Generates RFC 3986 HTTP or HTTPS URL strings.

urls()

@spec urls() :: Hegel.Generator.t(String.t())

Alias for url/0.

uuid(options \\ [])

@spec uuid(options()) :: Hegel.Generator.t(String.t())

Generates canonical lower-case UUID strings.

uuids(options \\ [])

@spec uuids(options()) :: Hegel.Generator.t(String.t())

Alias for uuid/1.

weighted_boolean(probability)

@spec weighted_boolean(number()) :: Hegel.Generator.t(boolean())

Alias for boolean/1.