Expand description
vcs-testkit — throwaway git/jj sandboxes (and a bare remote) for
integration tests.
Hands a #[test] a real repository to drive: a unique self-cleaning
TempDir, a configured GitSandbox / JjSandbox to build scenarios
in, and a seeded BareRemote to clone/fetch/push against. It is
dependency-free (not even the wrapper crates, so it can be a
dev-dependency of any of them without a cycle), synchronous (test setup
needs no runtime — it shells out with std::process::Command, not the async
client under test), and panics on failure (a broken fixture should fail
loudly at the call site, not thread Results through scenario code).
Built for #[test] / #[ignore] integration tests that need a real repo:
the helpers run the actual git / jj on PATH, so gate any test that
touches one behind #[ignore = "requires the git binary"] — a hermetic CI
with no binaries installed then stays green, and cargo test -- --ignored
runs them locally. Every sandbox is isolated from the host’s VCS config (no
system/global config, no init.templateDir hook leakage, a deterministic
identity even on the commit jj git init creates) — see command.
§The surface
TempDir— a unique temporary directory, removed on drop. Uniqueness without a temp-dir crate: pid + a process-wide monotonic counter, so parallel tests in a run never collide. Every fixture owns one.GitSandbox— a throwaway git repo on branchmainwith a deterministic identity. Build scenarios through the convenience steps (commit_file,branch,checkout,rev_parse) plus the rawgitescape hatch for anything unmodelled.JjSandbox— the same shape for a jj (git-backed) workspace:describe,new_change,bookmark, and the rawjjhatch.BareRemote— a populated bare git repo, a local clone/fetch/push source with no network.BareRemote::seededgives one commit onmaincontainingseed.txt;urlyields a string remote URL.configure_identity— stamp a git repo with a deterministic identity and byte-stable behaviour (user.*,commit.gpgsign=false,core.autocrlf=false). Standalone, for tests whose subject isinit.- Raw steps
git/jj— run one command in anydir, panicking on failure: for scenario steps in directories no sandbox owns (linked worktrees, fresh clones, repos the code under test initialised).
§Recipes
These are sync — no async wrapper, no Result (fixtures panic). They are
no_run: they really create temp dirs and shell out to git/jj, so they
compile here but only run under a binary-equipped #[test].
Build a git scenario — write + stage + commit is one step:
use vcs_testkit::GitSandbox;
let repo = GitSandbox::init("scenario");
repo.commit_file("a.txt", "one\n", "first"); // write + add -A + commit
repo.branch("feature");
repo.checkout("feature");
repo.commit_file("sub/b.txt", "two\n", "second");
let head = repo.rev_parse("HEAD");
assert_eq!(head.len(), 40);
assert_ne!(head, repo.rev_parse("main")); // feature has divergedSeed a bare remote and fetch from it — drop to raw git for the remote wiring:
use vcs_testkit::{BareRemote, GitSandbox};
let repo = GitSandbox::init("local");
repo.commit_file("a.txt", "one\n", "first");
let remote = BareRemote::seeded("origin");
repo.git(&["remote", "add", "origin", remote.url().as_str()]);
repo.git(&["fetch", "-q", "origin"]);
assert_eq!(repo.rev_parse("origin/main").len(), 40); // seed commit fetched§In-depth guide
Beyond this page, this crate ships a full how-to guide — rendered on docs.rs
from docs/. See the guide module (and its cross-cutting
testing sub-guide on the trait / mock / runner
seams that let most tests skip real binaries entirely).
Modules§
- guide
- vcs-testkit — test fixtures guide
Structs§
- Bare
Remote - A populated bare git repository — a local clone/fetch/push source for
integration tests (no network). Seeded with one commit on
maincontainingseed.txt. - GitSandbox
- A throwaway git repository: owns its
TempDir, initialised on branchmainwith a deterministic identity (seeconfigure_identity). - JjSandbox
- A throwaway jj repository (git-backed) with a repo-scoped identity.
- TempDir
- A unique temporary directory, removed on drop.
Functions§
- configure_
identity - Give the git repository at
dira deterministic identity and byte-stable behaviour:user.name/user.email,commit.gpgsign=false(no keychain prompts), andcore.autocrlf=false(no CRLF rewriting under content assertions on Windows). - git
- Run
git <args>indir, panicking on failure — for scenario steps in directories not owned by aGitSandbox(linked worktrees, fresh clones, repos initialised by the code under test). - jj
- Run
jj <args>indir, panicking on failure (seegit).