In-process mock provider for tests and demos.
Scripts are stored in a shared ETS table keyed by the owner process. When
complete/2 runs in a spawned Task (e.g. inside Task.async_stream), it
walks the $callers ancestor chain to find the originating test process
and reads scripts registered by that process.
This makes Mock safe to use under async: true across the Runner's
parallel member execution: each test owns its own script set, and child
tasks discover the right set via the caller chain.
Usage
Mock.script(:my_member, content: "fake answer")
Mock.script(:other_member, fn req -> {:ok, Response.new(content: req.model, model: "mock")} end)
Mock.script(:flaky_member, error: :timeout)
Mock.script(:flaky_member, error: [kind: :transient, reason: :rate_limit])Notes
- If both
:errorand:contentare passed in the keyword form,:errortakes precedence. Request.member_idmust not benil. Mock returns{:error, %CouncilEx.Error{kind: :permanent, reason: :missing_member_id}}in that case.- All errors are returned as
%CouncilEx.Error{}structs. Legacy atom errors (e.g.error: :boom) are auto-classified as:permanent.
Summary
Functions
Clear all scripts for the current owner process.
Register a scripted response for a member id.
Functions
@spec reset() :: :ok
Clear all scripts for the current owner process.
@spec script( atom(), (CouncilEx.Request.t() -> {:ok, CouncilEx.Response.t()} | {:error, term()}) | keyword() ) :: :ok
Register a scripted response for a member id.