ajhahn.de
← eeco
Go 126 lines
package workflow

import (
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"testing"
)

func TestHandover_NoGitStillWritesAndQueues(t *testing.T) {
	cfg := newCfg(t) // temp dir, not a git repo
	res, err := handoverRefresh{}.Run(Env{Config: cfg})
	if err != nil {
		t.Fatal(err)
	}
	if res.Code != CodeClean {
		t.Fatalf("code = %d, want %d (clean)", res.Code, CodeClean)
	}
	dir := filepath.Join(cfg.Workspace, "docs", handoverDir)
	ents, err := os.ReadDir(dir)
	if err != nil || len(ents) != 1 {
		t.Fatalf("want 1 handover note, got %v (err %v)", ents, err)
	}
	b, _ := os.ReadFile(filepath.Join(dir, ents[0].Name()))
	note := string(b)
	if !strings.Contains(note, "## Changes since last handover") ||
		!strings.Contains(note, "head: unknown") {
		t.Errorf("note without git should still be well-formed:\n%s", note)
	}
	q, _ := os.ReadFile(filepath.Join(cfg.Workspace, "state", "queue.md"))
	if !strings.Contains(string(q), "handover") {
		t.Errorf("handover not queued:\n%s", q)
	}
}

func TestHandover_NeverOverwrites(t *testing.T) {
	cfg := newCfg(t)
	for range 2 {
		if _, err := (handoverRefresh{}).Run(Env{Config: cfg}); err != nil {
			t.Fatal(err)
		}
	}
	dir := filepath.Join(cfg.Workspace, "docs", handoverDir)
	ents, err := os.ReadDir(dir)
	if err != nil {
		t.Fatal(err)
	}
	if len(ents) != 2 {
		t.Fatalf("two runs must yield two distinct notes, got %d: %v", len(ents), names(ents))
	}
}

func TestHandover_GitChangeSummary(t *testing.T) {
	if _, err := exec.LookPath("git"); err != nil {
		t.Skip("git not available")
	}
	cfg := newCfg(t)
	root := cfg.RepoRoot
	gitRun(t, root, "init", "-q")
	gitRun(t, root, "config", "user.email", "[email protected]")
	gitRun(t, root, "config", "user.name", "t")
	writeRepoFile(t, root, "f.txt", "one\n")
	gitRun(t, root, "add", "-A")
	gitRun(t, root, "commit", "-q", "-m", "first commit")

	if _, err := (handoverRefresh{}).Run(Env{Config: cfg}); err != nil {
		t.Fatal(err)
	}
	dir := filepath.Join(cfg.Workspace, "docs", handoverDir)
	first := latestNote(t, dir)
	if !strings.Contains(first, "first handover") {
		t.Errorf("first note should mark the baseline:\n%s", first)
	}

	writeRepoFile(t, root, "f.txt", "one\ntwo\n")
	gitRun(t, root, "add", "-A")
	gitRun(t, root, "commit", "-q", "-m", "second commit changes things")

	if _, err := (handoverRefresh{}).Run(Env{Config: cfg}); err != nil {
		t.Fatal(err)
	}
	second := latestNote(t, dir)
	if !strings.Contains(second, "second commit changes things") {
		t.Errorf("second note should summarise the new commit:\n%s", second)
	}
}

// --- helpers ---

func gitRun(t *testing.T, dir string, args ...string) {
	t.Helper()
	cmd := exec.Command("git", args...)
	cmd.Dir = dir
	if out, err := cmd.CombinedOutput(); err != nil {
		t.Fatalf("git %v: %v\n%s", args, err, out)
	}
}

func names(ents []os.DirEntry) []string {
	var out []string
	for _, e := range ents {
		out = append(out, e.Name())
	}
	return out
}

func latestNote(t *testing.T, dir string) string {
	t.Helper()
	ents, err := os.ReadDir(dir)
	if err != nil {
		t.Fatal(err)
	}
	var latest string
	for _, e := range ents {
		if e.Name() > latest {
			latest = e.Name()
		}
	}
	b, err := os.ReadFile(filepath.Join(dir, latest))
	if err != nil {
		t.Fatal(err)
	}
	return string(b)
}