lode/sandbox
A test sandbox: run a test body inside a transaction that is always rolled back, so the database is left exactly as it was — per-test isolation without truncation, and without ordering coupling between tests.
It is built on repo.transaction, so a repo.transaction the body itself
opens (on the tx repo) becomes a savepoint nested inside the sandbox’s
outer transaction — sandboxed tests of transactional code roll back cleanly.
Unlike Ecto’s Ecto.Adapters.SQL.Sandbox, there is no process-ownership
registry (lode has no process-dictionary repo — see DESIGN.md). A
serial test shares the connection via the tx repo it is handed; concurrent
tests each use their own Repo (their own connection), so they never see one
another’s uncommitted rows.
Values
pub fn run(
repo repo: repo.Repo,
body body: fn(repo.Repo) -> a,
) -> Nil
Run body against a transaction-scoped repo, then roll the transaction back
regardless of how body finishes — the database is untouched afterward. The
body’s return value is discarded (tests assert via side effects).
use tx <- sandbox.run(r)
let assert Ok(_) = repo.insert(tx, user_schema(), new_user(“Alice”, 30))
// assertions run against tx; ROLLBACK happens on the way out
Or with an explicit callback, when you also want to assert after the sandbox that the writes did not persist:
sandbox.run(r, fn(tx) { …; Nil }) let assert Ok([]) = repo.all(r, schema, query.from(“t”, “t”))