X3m.System.Aggregate.TestSupport (X3m System v0.9.1)

Copy Markdown View Source

Helpers for testing aggregates as pure functions, in a given/when/then style.

An aggregate command is a plain function cmd(X3m.System.Message.t(), X3m.System.Aggregate.State.t()) returning {:block | :noblock, message, state}. To test one:

  • given - state_from_events/3 rebuilds the state from prior events;
  • when - command_message/3 builds the message; you call the command;
  • then - apply_events/4 folds the events the command emitted onto the given state so you can assert the resulting client_state.

No aggregate process or event store is involved.

Summary

Functions

Folds events onto an existing state via aggregate_mod's generated apply_events/3.

Builds a X3m.System.Message for service_name, with raw_request and each entry of assigns applied via X3m.System.Message.assign/3.

Builds the state you'd have after events were applied to aggregate_mod's initial state - apply_events/4 starting from X3m.System.Aggregate.initial_state/1.

Functions

apply_events(aggregate_mod, state, events, opts \\ [])

@spec apply_events(
  aggregate_mod :: module(),
  state :: X3m.System.Aggregate.State.t(),
  events :: [any()],
  opts :: Keyword.t()
) :: X3m.System.Aggregate.State.t()

Folds events onto an existing state via aggregate_mod's generated apply_events/3.

Options:

  • :version - version to stamp on the result. Defaults to state.version + length(events).

command_message(service_name, raw_request \\ %{}, assigns \\ %{})

@spec command_message(service_name :: atom(), raw_request :: map(), assigns :: map()) ::
  X3m.System.Message.t()

Builds a X3m.System.Message for service_name, with raw_request and each entry of assigns applied via X3m.System.Message.assign/3.

Examples

iex> msg = X3m.System.Aggregate.TestSupport.command_message(:open_account, %{"id" => "a1"}, %{invoked_by: %{admin?: true}})
iex> {msg.service_name, msg.raw_request, msg.assigns}
{:open_account, %{"id" => "a1"}, %{invoked_by: %{admin?: true}}}

state_from_events(aggregate_mod, events, opts \\ [])

@spec state_from_events(
  aggregate_mod :: module(),
  events :: [any()],
  opts :: Keyword.t()
) ::
  X3m.System.Aggregate.State.t()

Builds the state you'd have after events were applied to aggregate_mod's initial state - apply_events/4 starting from X3m.System.Aggregate.initial_state/1.

Options:

  • :version - version to stamp on the result. Defaults to length(events) - 1 (initial version -1 plus one per event), matching a fresh stream.