Packages
estructura
1.2.11
1.13.0
1.12.0
1.11.0
1.10.2
1.10.1
1.10.0
1.9.0
1.8.3
1.8.2
1.8.1
1.8.0
1.7.2
1.7.1
1.7.0
1.6.1
1.6.0
1.5.0
1.4.2
1.4.1
1.4.0
1.3.3
1.3.2
1.3.1
1.3.0
1.2.12
1.2.11
1.2.10
1.2.9
1.2.8
1.2.7
1.2.6
1.2.5
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.0
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.2
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
Extensions for Elixir structures.
Current section
Files
Jump to
Current section
Files
lib/estructura/stream_data.ex
defmodule Estructura.StreamData do
@moduledoc """
Additional generators to be used with `__generator__/1` generated by `Use Estructura`
"""
@typep seed() :: :rand.state()
@typep size() :: non_neg_integer()
@typep generator_fun(a) :: (seed(), size() -> StreamData.LazyTree.t(a))
@typedoc """
An opaque type that represents an `Estructura.StreamData` generator that generates values
of type `a`.
"""
@opaque t(a) :: %StreamData{generator: generator_fun(a)} | Enumerable.t()
@doc "Identity function as a stream data generator"
@spec id(keyword()) :: StreamData.t((term() -> term()))
def id(_options \\ []) do
StreamData.constant(&Function.identity/1)
end
@doc "Helper to generate _unshrinkable_ streams as per `Stream.iterate/2`."
@spec iterate(value, (value -> value)) :: StreamData.t(value) when value: term()
def iterate(initial_value, next_fun) when is_function(next_fun, 1) do
initial_value
|> StreamData.constant()
|> StreamData.bind(&StreamData.constant(next_fun.(&1)))
|> StreamData.unshrinkable()
end
@spec date(keyword()) :: StreamData.t(Date.t())
@doc """
Generates an instance of `Date.t()`. This generator is unshrinkable.
"""
def date(options \\ []) do
from = Keyword.get(options, :from, ~D|2000-01-01|)
to = Keyword.get(options, :to, Date.utc_today())
step = Keyword.get(options, :step, :random)
from
|> iterate(fn d ->
next =
case step do
days when is_integer(days) -> Date.add(d, days)
:random -> Date.add(d, Enum.random(-30..30//1))
{:random, num} -> Date.add(d, Enum.random(-num..num//1))
end
case Date.diff(to, next) do
diff when diff <= 0 -> to
diff when diff > 0 -> Date.add(from, diff)
end
end)
end
@spec datetime(keyword()) :: StreamData.t(DateTime.t())
@doc """
Generates an instance of `DateTime.t()`. This generator is unshrinkable.
"""
def datetime(options \\ []) do
from = Keyword.get(options, :from, ~U|2000-01-01T00:00:00Z|)
to = Keyword.get(options, :to, DateTime.utc_now())
step = Keyword.get(options, :step, :random)
from
|> iterate(fn dt ->
next =
case step do
secs when is_integer(secs) -> DateTime.add(dt, secs, :second)
{num, unit} when is_integer(num) -> DateTime.add(dt, num, unit)
:random -> DateTime.add(dt, Enum.random(-86_400..86_400//1), :second)
{:random, num} -> DateTime.add(dt, Enum.random(-num..num//1), :second)
end
case DateTime.diff(to, next) do
diff when diff <= 0 -> to
diff when diff > 0 -> DateTime.add(from, diff)
end
end)
end
end