You've already forked agentic-coding-workflow
108 lines
3.3 KiB
Go
108 lines
3.3 KiB
Go
package brief
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/yan1h/agent-coding-workflow/internal/infra/git"
|
|
)
|
|
|
|
func gitAvailable(t *testing.T) {
|
|
t.Helper()
|
|
if _, err := exec.LookPath("git"); err != nil {
|
|
t.Skip("git not found in PATH")
|
|
}
|
|
}
|
|
|
|
func mustGit(t *testing.T, dir string, args ...string) {
|
|
t.Helper()
|
|
c := exec.Command("git", args...)
|
|
c.Dir = dir
|
|
out, err := c.CombinedOutput()
|
|
require.NoError(t, err, "git %v: %s", args, string(out))
|
|
}
|
|
|
|
// makeWorkRepo 在临时目录里建一个有 N 次提交、可选脏文件的工作仓库,返回路径。
|
|
func makeWorkRepo(t *testing.T, commits int, dirty bool) string {
|
|
t.Helper()
|
|
gitAvailable(t)
|
|
dir := t.TempDir()
|
|
mustGit(t, dir, "init", "-b", "main")
|
|
mustGit(t, dir, "config", "user.email", "test@example.com")
|
|
mustGit(t, dir, "config", "user.name", "Test")
|
|
for i := 0; i < commits; i++ {
|
|
name := filepath.Join(dir, "f"+string(rune('a'+i))+".txt")
|
|
require.NoError(t, os.WriteFile(name, []byte("v"), 0o644))
|
|
mustGit(t, dir, "add", ".")
|
|
mustGit(t, dir, "commit", "-m", "commit "+string(rune('a'+i)))
|
|
}
|
|
if dirty {
|
|
require.NoError(t, os.WriteFile(filepath.Join(dir, "dirty.txt"), []byte("x"), 0o644))
|
|
}
|
|
return dir
|
|
}
|
|
|
|
func TestRepoOrienter_RealRepo(t *testing.T) {
|
|
t.Parallel()
|
|
dir := makeWorkRepo(t, 3, true)
|
|
o := NewRepoOrienter(git.NewDefaultRunner(git.Config{Binary: "git", TmpDir: t.TempDir()}))
|
|
|
|
got := o.Orient(context.Background(), dir, "main", 10, 10)
|
|
assert.Equal(t, "main", got.Branch)
|
|
assert.Len(t, got.RecentCommits, 3)
|
|
// 脏文件含未跟踪的 dirty.txt。
|
|
require.NotEmpty(t, got.DirtyFiles)
|
|
assert.Contains(t, got.DirtyFiles, "dirty.txt")
|
|
}
|
|
|
|
func TestRepoOrienter_BoundsCommits(t *testing.T) {
|
|
t.Parallel()
|
|
dir := makeWorkRepo(t, 5, false)
|
|
o := NewRepoOrienter(git.NewDefaultRunner(git.Config{Binary: "git", TmpDir: t.TempDir()}))
|
|
|
|
got := o.Orient(context.Background(), dir, "main", 2, 10)
|
|
assert.LessOrEqual(t, len(got.RecentCommits), 2)
|
|
}
|
|
|
|
func TestRepoOrienter_NonexistentDirReturnsPartialNoFailure(t *testing.T) {
|
|
t.Parallel()
|
|
gitAvailable(t)
|
|
o := NewRepoOrienter(git.NewDefaultRunner(git.Config{Binary: "git", TmpDir: t.TempDir()}))
|
|
|
|
// 不存在的目录:git 调用失败,但 orienter 不 panic、不返回错误,分支仍带入。
|
|
got := o.Orient(context.Background(), filepath.Join(t.TempDir(), "nope"), "wip", 10, 10)
|
|
assert.Equal(t, "wip", got.Branch)
|
|
assert.Empty(t, got.RecentCommits)
|
|
assert.Empty(t, got.DirtyFiles)
|
|
}
|
|
|
|
func TestRepoOrienter_EmptyDirSkips(t *testing.T) {
|
|
t.Parallel()
|
|
o := NewRepoOrienter(git.NewDefaultRunner(git.Config{Binary: "git", TmpDir: t.TempDir()}))
|
|
got := o.Orient(context.Background(), "", "main", 10, 10)
|
|
assert.Equal(t, "main", got.Branch)
|
|
assert.Empty(t, got.RecentCommits)
|
|
assert.Empty(t, got.DirtyFiles)
|
|
}
|
|
|
|
func TestRepoOrienter_NilGitClient(t *testing.T) {
|
|
t.Parallel()
|
|
o := NewRepoOrienter(nil)
|
|
got := o.Orient(context.Background(), "/tmp/x", "main", 10, 10)
|
|
assert.Equal(t, "main", got.Branch)
|
|
assert.Empty(t, got.RecentCommits)
|
|
}
|
|
|
|
func TestRepoOrientation_IsEmpty(t *testing.T) {
|
|
t.Parallel()
|
|
assert.True(t, RepoOrientation{}.IsEmpty())
|
|
assert.False(t, RepoOrientation{Branch: "x"}.IsEmpty())
|
|
assert.False(t, RepoOrientation{RecentCommits: []string{"a"}}.IsEmpty())
|
|
}
|