defmodule Chaperon.Action.CallFunction do @moduledoc """ Performs & measures a function call (with args) within a session's `Chaperon.Scenario` module. """ defstruct func: nil, args: [] @type callback :: atom | {module, atom} | (Chaperon.Session.t() -> Chaperon.Session.t()) @type t :: %Chaperon.Action.CallFunction{ func: callback, args: [any] } end defimpl Chaperon.Actionable, for: Chaperon.Action.CallFunction do alias Chaperon.Session def run(%{func: f, args: args}, session) when is_atom(f) do metric = {:call, {session.scenario.module, f}} session |> Session.time(metric, fn session -> apply(session.scenario.module, f, [session | args]) end) |> Session.ok() end def run(%{func: {mod, f}, args: args}, session) do metric = {:call, {mod, f}} session |> Session.time(metric, fn session -> apply(mod, f, [session | args]) end) |> Session.ok() end def run(%{func: f, args: args}, session) do metric = {:call, inspect(f)} session |> Session.time(metric, fn session -> f |> apply([session | args]) end) |> Session.ok() end def abort(action, session) do {:ok, action, session} end end defimpl String.Chars, for: Chaperon.Action.CallFunction do def to_string(%{func: func}) when is_atom(func) do "#{func}" end def to_string(%{func: func}) when is_function(func) do "Function[#{inspect(func)}]" end end