The executable form of the Managoat.Sandbox contract: a shared suite
every adapter must pass.
It lives under lib/, not test/support, on purpose: it is compiled in
every environment so that an adapter written outside this package (a
host's self-hosted runner, a fourth vendor) can use it from its own test
suite. A test/support module would exist only while this package runs
its own tests. ExUnit is part of Elixir, so shipping the macros costs a
consumer nothing.
Usage:
defmodule Managoat.Sandbox.FakeConformanceTest do
use Managoat.Sandbox.ConformanceCase,
adapter: Managoat.Sandbox.Fake,
fixtures: %{
exec_ok: {"emit", ["out:hello"], "hello"},
exec_fail: {"emit", ["out:oops", "exit:3"], 3},
spawn_ok: {"emit", ["out:hello", "exit:0"]},
spawn_drop: {"emit", ["out:partial", "drop"]},
spawn_stay: {"emit", ["out:ready", "stay"]}
}
setup do
Managoat.Sandbox.Fake.reset()
:ok
end
endfixtures supplies the adapter-appropriate command vocabulary (the Fake
speaks its scripted instructions; a live adapter would use bash -lc), and
an optional name: {Mod, :fun, args} mints sandbox names when the adapter
needs a particular shape:
exec_ok—{cmd, args, expected_stdout}, exits 0exec_fail—{cmd, args, nonzero_exit_code}spawn_ok— emits some stdout then exits 0spawn_drop— the transport closes without an exit frame (optional; pins the closes-without-exit-is-an-error rule)spawn_stay— emits stdout then stays alive until stdin EOF (needed for the write-totality and attach-replay tests)
Semantics pinned here and nowhere else: create idempotency, the not-found/transient distinction, destroy tolerance, full-view listing, exec-never-raises with nonzero-exit-as-data, the owner-message frame contract with exactly one terminal frame and no synthesised exit code, stdin-write totality (#603), attach replay-from-start, and suspend/resume totality.