Packages
commanded
1.4.8
1.4.10
1.4.9
1.4.8
1.4.7
1.4.6
1.4.3
1.4.2
1.4.1
1.4.0
1.4.0-rc.0
1.3.1
1.3.0
1.2.0
1.1.1
1.1.0
1.0.1
1.0.0
1.0.0-rc.1
1.0.0-rc.0
0.19.1
0.19.0
0.18.1
0.18.0
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.0
0.16.0-rc.1
0.16.0-rc.0
0.15.1
0.15.0
0.14.0
0.14.0-rc.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.5
0.8.4
0.8.3
0.8.1
0.8.0
0.7.1
0.6.2
0.6.1
0.6.0
0.4.0
0.3.1
0.3.0
0.2.1
0.2.0
0.1.0
Use Commanded to build your own Elixir applications following the CQRS/ES pattern.
Current section
Files
Jump to
Current section
Files
test/support/aggregate_case.ex
defmodule Commanded.AggregateCase do
@moduledoc """
This module defines the test case to be used by aggregate tests.
"""
use ExUnit.CaseTemplate
alias Commanded.Aggregate.Multi
using opts do
quote do
@aggregate Keyword.fetch!(unquote(opts), :aggregate)
# Assert that the expected events are returned when the given commands have been executed
defp assert_events(commands, expected_events) do
assert_events([], commands, expected_events)
end
defp assert_events(initial_events, commands, expected_events) do
assert {:ok, _state, events} = aggregate_run(initial_events, commands)
actual_events = List.wrap(events)
expected_events = List.wrap(expected_events)
assert actual_events == expected_events
end
# Assert that the aggregate will have the expected_state after the given commands have been executed
defp assert_state(commands, expected_state) do
assert_state([], commands, expected_state)
end
defp assert_state(initial_events, commands, expected_state) do
assert {:ok, state, events} = aggregate_run(initial_events, commands)
assert state == expected_state
end
defp assert_error(commands, expected_error) do
assert_error([], commands, expected_error)
end
defp assert_error(initial_events, commands, expected_error) do
assert ^expected_error = aggregate_run(initial_events, commands)
end
# Apply the given commands to the aggregate hydrated with the given initial_events
defp aggregate_run(initial_events, commands) do
@aggregate
|> struct()
|> evolve(initial_events)
|> execute(commands)
end
# Execute one or more commands against an aggregate.
defp execute(state, commands) do
try do
{state, events} =
commands
|> List.wrap()
|> Enum.reduce({state, []}, fn command, {state, events} ->
case @aggregate.execute(state, command) do
{:error, _error} = error ->
throw(error)
%Multi{} = multi ->
case Multi.run(multi) do
{:error, _reason} = error ->
throw(error)
{state, new_events} ->
{state, events ++ new_events}
end
none when none in [:ok, nil, []] ->
{state, events}
{:ok, new_events} ->
{evolve(state, new_events), events ++ List.wrap(new_events)}
new_events when is_list(new_events) ->
{evolve(state, new_events), events ++ new_events}
new_event when is_map(new_event) ->
{evolve(state, new_event), events ++ [new_event]}
invalid ->
flunk("unexpected: " <> inspect(invalid))
end
end)
{:ok, state, events}
catch
{:error, _error} = reply -> reply
end
end
# Apply the given events to the aggregate state
defp evolve(state, events) do
events
|> List.wrap()
|> Enum.reduce(state, &@aggregate.apply(&2, &1))
end
end
end
end