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”))

Search Document