package git import ( "context" "os" "os/exec" "path/filepath" "runtime" "strings" "testing" "time" ) func TestCallRejectsEmptyCommand(t *testing.T) { tool := New(t.TempDir(), 3*time.Second, 4000, nil) _, err := tool.Call(context.Background(), " ") if err == nil { t.Fatal("expected error for empty command") } } func TestCallRejectsUnsupportedSubcommand(t *testing.T) { repo := initTestRepo(t) tool := New(repo, 5*time.Second, 4000, nil) _, err := tool.Call(context.Background(), "bisect start") if err == nil { t.Fatal("expected unsupported subcommand error") } if !strings.Contains(err.Error(), "unsupported git subcommand") { t.Fatalf("unexpected error: %v", err) } } func TestStatusAndLog(t *testing.T) { repo := initTestRepo(t) tool := New(repo, 5*time.Second, 4000, nil) status, err := tool.Call(context.Background(), "status --short") if err != nil { t.Fatalf("status failed: %v", err) } if strings.TrimSpace(status) != "" && status != "ok" { t.Fatalf("expected clean status output, got: %q", status) } logOut, err := tool.Call(context.Background(), "git log --oneline -n 1") if err != nil { t.Fatalf("log failed: %v", err) } if !strings.Contains(logOut, "initial commit") { t.Fatalf("expected initial commit in log output, got: %q", logOut) } } func TestAddCommitAndDiff(t *testing.T) { repo := initTestRepo(t) tool := New(repo, 8*time.Second, 8000, nil) file := filepath.Join(repo, "note.txt") if err := os.WriteFile(file, []byte("v1\n"), 0o644); err != nil { t.Fatalf("write file failed: %v", err) } _, err := tool.Call(context.Background(), "add note.txt") if err != nil { t.Fatalf("add failed: %v", err) } _, err = tool.Call(context.Background(), "commit -m add-note") if err != nil { t.Fatalf("commit failed: %v", err) } if err := os.WriteFile(file, []byte("v2\n"), 0o644); err != nil { t.Fatalf("rewrite file failed: %v", err) } diffOut, err := tool.Call(context.Background(), "diff -- note.txt") if err != nil { t.Fatalf("diff failed: %v", err) } if !strings.Contains(diffOut, "-v1") || !strings.Contains(diffOut, "+v2") { t.Fatalf("expected diff output with v1/v2 changes, got: %q", diffOut) } } func initTestRepo(t *testing.T) string { t.Helper() if _, err := exec.LookPath("git"); err != nil { t.Skip("git is not installed") } repo := t.TempDir() runGit(t, repo, "init") runGit(t, repo, "config", "user.name", "test-user") runGit(t, repo, "config", "user.email", "test@example.com") readme := filepath.Join(repo, "README.md") if err := os.WriteFile(readme, []byte("hello\n"), 0o644); err != nil { t.Fatalf("write readme failed: %v", err) } runGit(t, repo, "add", "README.md") runGit(t, repo, "commit", "-m", "initial commit") return repo } func runGit(t *testing.T, repo string, args ...string) { t.Helper() ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() cmd := exec.CommandContext(ctx, "git", args...) cmd.Dir = repo cmd.Env = append(cmd.Environ(), "GIT_TERMINAL_PROMPT=0", "GIT_PAGER=cat", "GIT_EDITOR=true", ) if runtime.GOOS == "windows" { // Keep default behavior; this branch documents cross-platform intent. } out, err := cmd.CombinedOutput() if err != nil { t.Fatalf("git %s failed: %v\n%s", strings.Join(args, " "), err, string(out)) } }