harnais_runner v0.1.0 Harnais.Runner.Cridar View Source
The cridar manages a test call.
Each test call specification is used to create a cridar.
See Harnais.Runner for the overview.
Cridar State
A cridar has the following fields:
| Key | Aliases |
|---|---|
:module | :m, :d, :mod, :test_mod, :test_module |
:fun | :f, :function, :test_fun, :test_function |
:args | :a, :test_args |
:rest_args | :ra, :test_rest_args |
The default for all fields is the unset value (Plymio.Fontais.Guard.the_unset_value/0).
Cridar Field: :module
The :module holds the name of the module to be used in an MFA apply (Kernel.apply/3).
Cridar Field: :fun
The :fun can hold either an atom to be use in a MFA appply, or a function.
Cridar Field: :args
If set, the :args holds all of the argumemenst for a call.
Cridar Field: rest_args
If set, the :rest_args is intended to be used together with other arguments.
Link to this section Summary
Link to this section Types
Link to this section Functions
call/2 take a cridar and and optional test value and actions the test call
returning {:ok, {answer, cridar} or {error, error}.
Examples
An MFA apply. Note the :args are “listified” (List.wrap/1):
iex> {:ok, {answer, %CRIDAR{}}} = [
...> mod: Map, fun: :get, args: [%{a: 42}, :a]
...> ] |> CRIDAR.new! |> CRIDAR.call
...> answer
42
Another MFA but the :rest_args is set. The “listified” :rest_args are prepended
with the 2nd argument:
iex> {:ok, {answer, %CRIDAR{}}} = [
...> m: Map, f: :get, rest_args: [:a]
...> ] |> CRIDAR.new! |> CRIDAR.call(%{a: 42})
...> answer
42
The :fun is an arity 0 function so the :args,
:rest_args and test value are ignored:
iex> {:ok, {value, %CRIDAR{}}} = [
...> f: fn -> 123 end, ra: [:a]
...> ] |> CRIDAR.new! |> CRIDAR.call(%{a: 42})
...> value
123
An arity 1 function is called just with the test value:
iex> {:ok, {value, %CRIDAR{}}} = [
...> fun: fn value -> value |> Map.fetch(:b) end,
...> args: :will_be_ignored, rest_args: :will_be_ignored
...> ] |> CRIDAR.new! |> CRIDAR.call(%{b: 222})
...> value
{:ok, 222}
When :fun is any other arity, and the :args is set, it is
called with the “vanilla” :args:
iex> {:ok, {answer, %CRIDAR{}}} = [
...> fun: fn _x,y,_z -> y end,
...> a: [1,2,3], ra: :this_is_rest_args
...> ] |> CRIDAR.new! |> CRIDAR.call(%{b: 2})
...> answer
2
When :fun is any other arity, :args is not set but :rest_args is, it is
called (Kernel.apply/2) with the test value and “listified” :rest_args:
iex> {:ok, {answer, %CRIDAR{}}} = [
...> fun: fn _p,_q,_r,s -> s end,
...> rest_args: [:a,:b,:c]
...> ] |> CRIDAR.new! |> CRIDAR.call(:any_answer)
...> answer
:c
When :fun is any other arity, and neither :args not :rest_args
is set, an error will be returned:
iex> {:error, error} = [
...> f: fn _p,_q,_r,s -> s end,
...> ] |> CRIDAR.new! |> CRIDAR.call(:any_value)
...> error |> Exception.message |> String.starts_with?("cridar invalid")
true
new/1 creates a new instance of the module’s struct and, if the optional
opts were given, calls update/2 with the instance and the opts,
returning {:ok, instance}, else {:error, error}.
update/2 takes an instance of the module’s struct and an optional opts.
The opts are normalised by calling the module’s update_canonical_opts/1
and then reduced with update_field/2:
opts |> Enum.reduce(instance, fn {k,v}, s -> s |> update_field({k,v}) end)
{:ok, instance} is returned.