package zitcli
import (
"context"
"os"
"os/exec"
"path/filepath"
"strings"
"testing"
)
// hashOf is the full hash a name resolves to in repo.
func hashOf(t *testing.T, repo, name string) string {
t.Helper()
cmd := exec.Command("zit", "info", name)
cmd.Dir = repo
out, err := cmd.Output()
if err != nil {
t.Fatalf("zit info %s: %v", name, err)
}
first, _, _ := strings.Cut(string(out), "\n")
return strings.TrimSpace(first)
}
// A MERGE CHECK-IN HAS ITS PAIR'S TREE UNLESS SOMEBODY CHANGED IT.
//
// Equal means every path and its content hash: the merge zit writes
// from the two tips is its pair's tree, and the same merge with one
// more edit, or a check-in that is no merge of them, is not.
func TestSameTreeIsThePairsTree(t *testing.T) {
repo := t.TempDir()
run(t, repo, "init", ".")
writeZ(t, repo, "f.txt", "top\nMID\nbottom\n")
writeZ(t, repo, "g.txt", "base\n")
if err := os.MkdirAll(filepath.Join(repo, "d"), 0o755); err != nil {
t.Fatal(err)
}
writeZ(t, repo, "d/h.txt", "deep\n")
run(t, repo, "add", "f.txt", "g.txt", "d/h.txt")
run(t, repo, "commit", "-m", "root", "--user", "u")
writeZ(t, repo, "f.txt", "top\nMID\nBOTTOM\n")
writeZ(t, repo, "new.txt", "from the branch\n")
run(t, repo, "add", "new.txt")
run(t, repo, "commit", "-m", "b", "--branch", "feat", "--user", "u")
branch := hashOf(t, repo, "feat")
run(t, repo, "update", "trunk")
writeZ(t, repo, "f.txt", "TOP\nMID\nbottom\n")
run(t, repo, "commit", "-m", "t", "--user", "u")
target := hashOf(t, repo, "trunk")
run(t, repo, "merge", "feat")
run(t, repo, "commit", "-m", "land feat", "--user", "u")
merged := hashOf(t, repo, "trunk")
c := New(repo)
ctx := context.Background()
if same, err := c.SameTree(ctx, merged, branch, target); err != nil || !same {
t.Fatalf("FAIL: the merge of feat into trunk answered same=%v err=%v; want its pair's tree", same, err)
}
if same, err := c.SameTree(ctx, target, branch, target); err != nil || same {
t.Fatalf("FAIL: trunk before the merge answered same=%v err=%v; want a different tree", same, err)
}
run(t, repo, "update", target)
run(t, repo, "merge", "feat")
writeZ(t, repo, "g.txt", "edited in the merge\n")
run(t, repo, "commit", "-m", "land feat, edited", "--branch", "edited", "--user", "u")
edited := hashOf(t, repo, "edited")
if same, err := c.SameTree(ctx, edited, branch, target); err != nil || same {
t.Fatalf("FAIL: a merge with an edit answered same=%v err=%v; want a different tree", same, err)
}
t.Log("ok: the merge is its pair's tree; an edit or another check-in is not")
}