package ingest
import (
"context"
"os"
"os/exec"
"path/filepath"
"testing"
"craftdesign.group/quarry/internal/index"
"craftdesign.group/quarry/internal/zitcli"
)
// An index folded before counts existed fills them from one crosslink
// pass: the check-in folded without counts reads as counted after it.
// The first check-in stays uncounted (rootless).
func TestBackfillFillsCountsFromCrosslink(t *testing.T) {
if _, err := exec.LookPath("zit"); err != nil {
t.Skip("zit not on PATH")
}
dir := t.TempDir()
z := func(args ...string) {
cmd := exec.Command("zit", args...)
cmd.Dir = dir
if out, err := cmd.CombinedOutput(); err != nil {
t.Fatalf("zit %v: %v\n%s", args, err, out)
}
}
z("init", ".")
if err := os.WriteFile(filepath.Join(dir, "a.txt"), []byte("1\n2\n3\n"), 0o644); err != nil {
t.Fatal(err)
}
z("add", "a.txt")
z("commit", "-m", "three lines", "--user", "u")
cli := zitcli.New(dir)
root, _, err := cli.Info(context.Background(), "trunk")
if err != nil {
t.Fatal(err)
}
if err := os.WriteFile(filepath.Join(dir, "a.txt"), []byte("1\n2\n3\n4\n5\n"), 0o644); err != nil {
t.Fatal(err)
}
z("commit", "-m", "two more", "--user", "u")
tip, _, err := cli.Info(context.Background(), "trunk")
if err != nil {
t.Fatal(err)
}
ix, err := index.Open(filepath.Join(t.TempDir(), "index.db"))
if err != nil {
t.Fatal(err)
}
defer ix.Close()
if err := ix.FoldCheckins([]index.CheckinRecord{
{Hash: root, Date: "2026-10-01T10:00:00", Comment: "three lines", Changes: []string{"a.txt"}},
{Hash: tip, Date: "2026-10-01T11:00:00", Comment: "two more", Parents: []string{root}, Changes: []string{"a.txt"}},
}); err != nil {
t.Fatal(err)
}
if st, _ := ix.ChangeStats([]string{tip}, ""); st[tip].Counted {
t.Fatal("the fixture should start uncounted")
}
if _, err := fillLineCounts(cli, ix); err != nil {
t.Fatal(err)
}
st, _ := ix.ChangeStats([]string{root, tip}, "")
if st[tip] != (index.ChangeStat{Files: 1, Added: 2, Counted: true}) {
t.Errorf("FAIL: after the backfill: %+v", st[tip])
}
if st[root].Counted {
t.Errorf("FAIL: the first check-in was counted, which a live fold cannot do: %+v", st[root])
}
}