This commit is contained in:
2026-06-22 08:55:57 +08:00
parent dbb87823e8
commit 6ade6e8fa9
325 changed files with 41131 additions and 855 deletions
+107
View File
@@ -0,0 +1,107 @@
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())
}