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:

KeyAliases
: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

Functions

call/2 take a cridar and and optional test value and actions the test call returning {:ok, {answer, cridar} or {error, error}

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}

new!/1 calls new/1 and, if the result is {:ok, instance} returns the instance

update/2 takes an instance of the module’s struct and an optional opts

update!/2 calls update/2 and, if the result is {:ok, instance} returns the instance

Link to this section Types

Link to this type t() View Source
t() :: %Harnais.Runner.Cridar{
  args: term(),
  fun: term(),
  module: term(),
  rest_args: term()
}

Link to this section Functions

Link to this function call(cridar, test_value \\ nil) View Source
call(t(), any()) :: {:ok, {any(), t()}} | {:error, error()}

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
Link to this function new(opts \\ []) View Source
new(any()) :: {:ok, t()} | {:error, error()}

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}.

Link to this function new!(opts \\ []) View Source
new!(any()) :: t() | no_return()

new!/1 calls new/1 and, if the result is {:ok, instance} returns the instance.

Link to this function update(t, opts \\ []) View Source
update(t(), opts()) :: {:ok, t()} | {: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.

Link to this function update!(t, opts \\ []) View Source
update!(t(), any()) :: t() | no_return()

update!/2 calls update/2 and, if the result is {:ok, instance} returns the instance.