Test helpers for DoubleDown contracts.
Start the ownership server in test/test_helper.exs:
DoubleDown.Testing.start()Then in your tests, register handlers per-contract:
setup do
DoubleDown.Testing.set_module_handler(MyApp.Todos, MyApp.Todos.InMemory)
:ok
endHandlers are process-scoped via NimbleOwnership, so async: true
tests are isolated. Use allow/3 to share handlers with child processes.
Summary
Functions
Allow a child process to use the current process's handlers.
Enable dispatch logging for a contract.
Retrieve the dispatch log for a contract.
Reset all handlers and logs for a process.
Register a module as the handler for a contract.
Register a stateful handler for a contract.
Register a function as the handler for a contract.
Start the DoubleDown ownership server.
Functions
Allow a child process to use the current process's handlers.
Use this when spawning Tasks or other processes that need to dispatch through the same test handlers.
@spec enable_log(module()) :: :ok
Enable dispatch logging for a contract.
After enabling, all dispatches through the contract's facade will be
recorded. Retrieve with get_log/1.
Retrieve the dispatch log for a contract.
Returns a list of {contract, operation, args, result} tuples
in the order they were dispatched.
@spec reset(pid()) :: :ok
Reset all handlers and logs for a process.
Clears all NimbleOwnership entries owned by pid. Defaults to
self().
on_exit caveat: reset() (without arguments) uses self(),
which inside an on_exit callback is the callback process — not
the test process. To reset the test process's handlers from
on_exit, capture the pid first:
setup do
pid = self()
on_exit(fn -> DoubleDown.Testing.reset(pid) end)
:ok
endIn most cases you don't need explicit cleanup — NimbleOwnership automatically cleans up when the owning process exits.
Register a module as the handler for a contract.
The module must implement the contract's @behaviour.
@spec set_stateful_handler(module(), DoubleDown.Dispatch.Types.stateful_fun(), term()) :: :ok
Register a stateful handler for a contract.
The function may be 4-arity or 5-arity:
- 4-arity:
fn contract, operation, args, state -> {result, new_state} end - 5-arity:
fn contract, operation, args, state, all_states -> {result, new_state} end
5-arity handlers receive a read-only snapshot of all contract states as
the 5th argument. This enables cross-contract state access (e.g. a Queries
handler reading the Repo InMemory store). The all_states map is keyed by
contract module and includes a DoubleDown.Contract.GlobalState sentinel key.
The handler must return only its own contract's new state — not the global map.
State is stored in NimbleOwnership and updated atomically on each dispatch.
Register a function as the handler for a contract.
The function receives (contract, operation, args) and returns the result.
Start the DoubleDown ownership server.
Call this once in test/test_helper.exs.