View Source Myrmidex.Generators (myrmidex v0.3.0)
Custom and composed generators for use in generator schema modules. These generators cover many common cases you might encounter in your codebase. E.g., handling primary key generation:
...
@impl Myrmidex.GeneratorSchema
def cast_field({_field, {:autogenerate, type}, _term}, _opts) when is_binary_id_field(type) do
Myrmidex.Generators.uuid()
end
By default, most generators are configured to allow for narrowing, i.e. use
in property-based testing. You can, for example, wrap functions in
StreamData.unshrinkable/1
to avoid narrowing in other use cases. Or define
your own generators more suited to your domain in a custom generator schema.
Summary
Functions
Generate data approximate to a given term. Accepts integers, floats, dates, times, and datetimes.
Globally unique streamable counters.
Generate a random date, optionally constrained by date fields.
Generate random datetimes, optionally constrained by calendar fields.
Choose one from a (predetermined, limited) list of values.
Builds a StreamData.fixed_map/1
generator from an enumerable, optionally
transforming the keys to strings or atoms.
Generate data that is quantitavely or chronologically greater than or equal to the given term.
Generate data that is quantitavely or chronologically less than or equal to the given term.
Generate monotonically increasing integer data.
Maps binary or bitstring input into matching generators.
Generate a random time, optionally constrained by hour
, minute
, second
,
or microsecond
.
Defaults to current time in utc.
Generate uuids, e.g. for schema primary keys.
Functions
Generate data approximate to a given term. Accepts integers, floats, dates, times, and datetimes.
Generated data is random within the given scale and limits, i.e. not characterized by any trend.
Examples
iex> stream = Myrmidex.Generators.approximate(10, scale: 100)
...> int = Myrmidex.one(stream)
...> int >= -90 and int <= 110
true
iex> stream = Myrmidex.Generators.approximate(Date.utc_today(), limits: [:upper])
...> date = Myrmidex.one(stream)
...> Date.compare(date, Date.utc_today()) in [:gt, :eq]
true
Options
:scale
(pos_integer
,float
, or{atom, :pos_integer}
) - The minimum proximity to (maximum distance from) the term. The default value is1
.:limits
(non_neg_integer
orRange
) - Controls the range of generation in relation to the term. The default value is[:lower, :upper]
.
Globally unique streamable counters.
Useful for ids or other cases where more control over streaming monotonic data is needed, e.g., a mock unix timestamp that can be advanced or reversed as needed.
Examples
iex> stream = Myrmidex.Generators.counter(0, 2)
...> Myrmidex.many(stream, 4)
[2, 4, 6, 8]
iex> stream_1 = Myrmidex.Generators.counter()
...> stream_2 = Myrmidex.Generators.counter()
...> {Myrmidex.one(stream_1), Myrmidex.one(stream_2)}
{1, 1}
iex> start = DateTime.new!(~D[1984-01-01], ~T[00:00:00])
...> start_unix = DateTime.to_unix(start)
...> stream = Myrmidex.Generators.counter(start_unix, -60)
...> Myrmidex.many(stream, 4)
[441763140, 441763080, 441763020, 441762960]
Generate a random date, optionally constrained by date fields.
See datetime/1
for available options.
Examples
iex> stream = Myrmidex.Generators.date(year: 1984)
...> Myrmidex.one(stream).year
1984
Generate random datetimes, optionally constrained by calendar fields.
Examples
iex> stream = Myrmidex.Generators.datetime(year: 1984)
...> Myrmidex.one(stream).year
1984
iex> stream = Myrmidex.Generators.datetime(precision: :second)
...> Myrmidex.one(stream).microsecond
{0, 0}
Options
This and other calendar generators accept either integers or ranges as option values, allowing specific fields to be fixed as constants, or limited to lower and upper bounds.
:year
(non_neg_integer
orRange
) - The default value is1984..2044
.:month
(non_neg_integer
orRange
) - The default value is1..12
.:day
(non_neg_integer
orRange
) - The default value is1..31
.:hour
(non_neg_integer
orRange
) - The default value is0..23
.:minute
(non_neg_integer
orRange
) - The default value is0..59
.:second
(non_neg_integer
orRange
) - The default value is0..59
.:microsecond
(non_neg_integer
orRange
) - The default value is0..999999
.:precision
(:second
,:millisecond
, or:microsecond
) - The default value is:microsecond
.
Choose one from a (predetermined, limited) list of values.
Note that this generator is passed via StreamData.unshrinkable/1
to ensure
random output.
Examples
iex> values = ["🐜", "🪰", "🪳"]
...> stream = Myrmidex.Generators.enum(values)
...> Myrmidex.one(stream) in values
true
Builds a StreamData.fixed_map/1
generator from an enumerable, optionally
transforming the keys to strings or atoms.
Examples
iex> %{id: Myrmidex.Generators.counter()}
...> |> Myrmidex.affix(species: "🐜")
...> |> Myrmidex.Generators.fixed_map(:string)
...> |> Myrmidex.many(3)
[
%{"id" => 1, "species" => "🐜"},
%{"id" => 2, "species" => "🐜"},
%{"id" => 3, "species" => "🐜"}
]
Generate data that is quantitavely or chronologically greater than or equal to the given term.
See approximate/2
for details.
Examples
iex> stream = Myrmidex.Generators.gte(10)
...> Myrmidex.one(stream) >= 10
true
Generate data that is quantitavely or chronologically less than or equal to the given term.
See approximate/2
for details.
Examples
iex> stream = Myrmidex.Generators.lte(10)
...> Myrmidex.one(stream) <= 10
true
Generate monotonically increasing integer data.
Useful for ids, although by default ids are only unique per runtime instance:
i.e. all schemas will share the same sequence of ids. See counter/2
for
integer counters unique to a stream.
Per StreamData docs.
Examples
iex> stream = Myrmidex.Generators.monotonic_integer()
...> Myrmidex.one(stream) < Myrmidex.one(stream)
true
Maps binary or bitstring input into matching generators.
Examples
iex> stream = Myrmidex.Generators.string(<<128>>)
...> is_bitstring(Myrmidex.one(stream))
true
iex> stream = Myrmidex.Generators.string("catch_all")
...> is_binary(Myrmidex.one(stream))
true
Generate a random time, optionally constrained by hour
, minute
, second
,
or microsecond
.
See datetime/1
for available options.
Examples
iex> stream = Myrmidex.Generators.time(hour: 1..9)
...> Myrmidex.one(stream).hour < 10
true
iex> [hour: 1, minute: 1, second: 1, microsecond: 999999, precision: :millisecond]
...> |> Myrmidex.Generators.time()
...> |> Myrmidex.one
...> |> Time.to_string()
"01:01:01.999"
Defaults to current time in utc.
The default generator for timestamp fields. Can be limited to second precision
by passing :utc_datetime
in the type
argument.
Examples
iex> stream = Myrmidex.Generators.timestamp()
...> DateTime.compare(Myrmidex.one(stream), Myrmidex.one(stream))
:lt
iex> stream = Myrmidex.Generators.timestamp(:utc_datetime)
...> Myrmidex.one(stream).microsecond
{0, 0}
Generate uuids, e.g. for schema primary keys.
Per StreamData docs.
Examples
iex> stream = Myrmidex.Generators.uuid()
...> Ecto.UUID.equal?(Myrmidex.one(stream), Myrmidex.one(stream))
false