gitfixture_test.go
package main
import (
"os"
"os/exec"
"path/filepath"
"testing"
)
// fixtureEnv pins every input that could make fixture repo shas vary between runs or hosts:
// user and system git config are nulled, and authorship names, emails, and dates are fixed.
// With these pinned, fixture shas are byte-stable, so tests assert them as literals
// (the fixtureSha* consts); any drift in those assertions means the hermeticity broke.
var fixtureEnv = []string{
"GIT_CONFIG_GLOBAL=/dev/null",
"GIT_CONFIG_SYSTEM=/dev/null",
"GIT_CONFIG_NOSYSTEM=1",
"GIT_ATTR_NOSYSTEM=1",
"GIT_AUTHOR_NAME=Ada Fixture",
"GIT_AUTHOR_EMAIL=ada@fixture.example",
"GIT_AUTHOR_DATE=2026-01-02T03:04:05Z",
"GIT_COMMITTER_NAME=Ada Fixture",
"GIT_COMMITTER_EMAIL=ada@fixture.example",
"GIT_COMMITTER_DATE=2026-01-02T03:04:05Z",
}
// The shas of the fixture repo built by buildFixtureRepo, byte-stable by construction.
const (
fixtureShaMain = "ced91a8519b59966124301e6383532f24223528b" // tip of main (the second commit); also what v1.0 peels to
fixtureShaRoot = "64ac67a35d36079e167cb8f929fd57f859c8b5d1" // the first commit, parent of main
fixtureShaDev = "9b492196b444f712640f1755e048d90d8c51de2e" // tip of the dev branch
)
// fixtureReadme is the README content at the tip of main (dev's tip rewrites it).
const fixtureReadme = "# Fixturama\n\nA repo that exists to be looked at.\n"
// gitFixture runs one git command while building a fixture, failing the test on any problem.
func gitFixture(t *testing.T, dir string, args ...string) {
t.Helper()
cmd := exec.Command("git", args...)
cmd.Dir = dir
cmd.Env = append(os.Environ(), fixtureEnv...)
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("fixture git %v: %v\n%s", args, err, out)
}
}
// writeFixtureFile writes one file into a fixture worktree, creating parent dirs as needed.
func writeFixtureFile(t *testing.T, dir, path, content string) {
t.Helper()
abs := filepath.Join(dir, path)
if err := os.MkdirAll(filepath.Dir(abs), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(abs, []byte(content), 0o644); err != nil {
t.Fatal(err)
}
}
// buildFixtureRepo creates the standard hermetic fixture repo and returns its worktree path.
//
// History: two commits on main (a README, then docs/ and src/), an annotated tag v1.0
// on main's tip, and a dev branch one commit ahead of main (rewriting the README).
// HEAD is left on main. A filename with a space is included deliberately:
// path handling has to survive it.
// The src/ code files, vendor/, and .gitignore exist for language classification:
// Go dominant, Rust (an extension that needs a content sniff to classify), CSS (markup),
// and two paths the meter must skip (vendored, dotfile).
func buildFixtureRepo(t *testing.T) string {
t.Helper()
dir := t.TempDir()
gitFixture(t, dir, "init", "-q", "-b", "main", "--object-format=sha1", ".")
writeFixtureFile(t, dir, "README.md", fixtureReadme)
gitFixture(t, dir, "add", "-A")
gitFixture(t, dir, "commit", "-q", "-m", "inaugurate with a readme")
writeFixtureFile(t, dir, "docs/notes.md", "Notes live here.\n")
writeFixtureFile(t, dir, "docs/with space.txt", "even this filename works\n")
writeFixtureFile(t, dir, "src/hello.txt", "hello from the fixture\n")
writeFixtureFile(t, dir, "src/hello.go", "package hello\n\nimport \"fmt\"\n\n// Greet says hello from the fixture, at some length:\n// the meter wants Go to dominate this repo's composition.\nfunc Greet(name string) string {\n\treturn fmt.Sprintf(\"hello, %s, from the fixture\", name)\n}\n")
writeFixtureFile(t, dir, "src/lib.rs", "pub fn greet(name: &str) -> String {\n format!(\"hello, {name}\")\n}\n")
writeFixtureFile(t, dir, "src/style.css", ".hello { color: rebeccapurple; }\n")
writeFixtureFile(t, dir, "vendor/mini.js", "export const mini = () => 'vendored';\n")
writeFixtureFile(t, dir, ".gitignore", "/dist/\n")
gitFixture(t, dir, "add", "-A")
gitFixture(t, dir, "commit", "-q", "-m", "add docs and src")
gitFixture(t, dir, "tag", "-a", "v1.0", "-m", "the first showing")
gitFixture(t, dir, "checkout", "-q", "-b", "dev")
writeFixtureFile(t, dir, "README.md", "# Fixturama\n\nNow with more verve.\n")
gitFixture(t, dir, "add", "-A")
gitFixture(t, dir, "commit", "-q", "-m", "sharpen the readme")
gitFixture(t, dir, "checkout", "-q", "main")
return dir
}
// fixtureRepo builds the fixture and opens it, the common prelude of the read-op tests.
func fixtureRepo(t *testing.T) *repo {
t.Helper()
dir := buildFixtureRepo(t)
r, err := openRepo("fixturama", repoConfig{Path: dir, Description: "the fixture"})
if err != nil {
t.Fatalf("opening fixture: %v", err)
}
return r
}
gitfixture_test.go · 4.6 KiB · 6b3477bda1