Skip to content

Instantly share code, notes, and snippets.

@slashdotdash
Created December 6, 2018 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slashdotdash/3a15ad0ef5dde3c9a42f256b89b71824 to your computer and use it in GitHub Desktop.
Save slashdotdash/3a15ad0ef5dde3c9a42f256b89b71824 to your computer and use it in GitHub Desktop.
Commanded event store assertion tp refute receive event
defmodule Commanded.EventStore.Assertions do
import ExUnit.Assertions
alias Commanded.EventStore.RecordedEvent
@doc """
Refute that an event of the given type has been received.
An optional predicate may be provided to filter events matching the refuted
type.
## Examples
require Commanded.EventStore.Assertions
# Refute that `ExampleEvent` is created by `example/1` function
refute_receive_event(ExampleEvent), do: example()
# Refute that `ExampleEvent` matching given predicate is created by `example/1` function
refute_receive_event(ExampleEvent, predicate: fn event -> event.foo == :foo end) do
example()
end
"""
defmacro refute_receive_event(refute_event_struct, opts \\ [], do: block) do
predicate = Keyword.get(opts, :predicate)
timeout =
Keyword.get(opts, :timeout, Application.fetch_env!(:ex_unit, :refute_receive_timeout))
quote do
task =
Task.async(fn ->
subscribe_to_all_events()
do_refute_receive_event(unquote(refute_event_struct), unquote(predicate))
end)
unquote(block)
reply =
case Task.yield(task, unquote(timeout)) || Task.shutdown(task) do
{:ok, :ok} -> :ok
{:ok, {:error, event}} -> flunk("Unexpectedly received event: " <> inspect(event))
{:error, error} -> throw({:error, error})
{:exit, error} -> throw({:error, error})
nil -> :ok
end
end
end
def do_refute_receive_event(refute_event_struct, predicate) do
receive do
{:events, events} ->
try do
for %RecordedEvent{data: %{__struct__: ^refute_event_struct} = data} <- events do
case predicate do
nil ->
throw({:error, data})
fun when is_function(fun, 1) ->
if predicate.(data), do: throw({:error, data})
end
end
do_refute_receive_event(refute_event_struct, predicate)
catch
{:error, _event} = reply -> reply
end
end
end
def subscribe_to_all_events, do: Commanded.EventStore.subscribe("$all")
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment