Add new file
This commit is contained in:
@@ -0,0 +1,206 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/rockliang/poimen/workflows/action"
|
||||
)
|
||||
|
||||
func TestGitCloneAndFetch(t *testing.T) {
|
||||
// Create a temporary directory for the test
|
||||
tmpDir := t.TempDir()
|
||||
sourceDir := filepath.Join(tmpDir, "source")
|
||||
targetDir := filepath.Join(tmpDir, "target")
|
||||
|
||||
// Initialize source repo
|
||||
if err := os.MkdirAll(sourceDir, 0755); err != nil {
|
||||
t.Fatalf("failed to create source dir: %v", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("git", "init", sourceDir)
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git init failed: %v", err)
|
||||
}
|
||||
|
||||
// Configure git user
|
||||
exec.Command("git", "-C", sourceDir, "config", "user.email", "[email protected]").Run()
|
||||
exec.Command("git", "-C", sourceDir, "config", "user.name", "Test User").Run()
|
||||
|
||||
// Create initial commit
|
||||
testFile := filepath.Join(sourceDir, "test.txt")
|
||||
if err := os.WriteFile(testFile, []byte("test content"), 0644); err != nil {
|
||||
t.Fatalf("failed to create test file: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", sourceDir, "add", "test.txt")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git add failed: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", sourceDir, "commit", "-m", "initial commit")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git commit failed: %v", err)
|
||||
}
|
||||
|
||||
// Test clone into empty path
|
||||
ctx := context.Background()
|
||||
err := action.CloneRepoActivity(ctx, action.CloneRepoInput{
|
||||
RemoteURL: sourceDir,
|
||||
TargetRepoPath: targetDir,
|
||||
})
|
||||
assert.NoError(t, err, "clone should succeed")
|
||||
|
||||
// Verify .git exists
|
||||
gitDir := filepath.Join(targetDir, ".git")
|
||||
_, err = os.Stat(gitDir)
|
||||
assert.NoError(t, err, ".git directory should exist")
|
||||
|
||||
// Verify test.txt was cloned
|
||||
targetTestFile := filepath.Join(targetDir, "test.txt")
|
||||
_, err = os.Stat(targetTestFile)
|
||||
assert.NoError(t, err, "test.txt should exist in target")
|
||||
|
||||
// Add another commit to source
|
||||
testFile2 := filepath.Join(sourceDir, "test2.txt")
|
||||
if err := os.WriteFile(testFile2, []byte("test content 2"), 0644); err != nil {
|
||||
t.Fatalf("failed to create test2 file: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", sourceDir, "add", "test2.txt")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git add failed: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", sourceDir, "commit", "-m", "second commit")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git commit failed: %v", err)
|
||||
}
|
||||
|
||||
// Test fetch on existing repo
|
||||
err = action.CloneRepoActivity(ctx, action.CloneRepoInput{
|
||||
RemoteURL: sourceDir,
|
||||
TargetRepoPath: targetDir,
|
||||
})
|
||||
assert.NoError(t, err, "fetch should succeed")
|
||||
}
|
||||
|
||||
func TestGitWorktreeAdd(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
repoDir := filepath.Join(tmpDir, "repo")
|
||||
|
||||
// Initialize repo
|
||||
if err := os.MkdirAll(repoDir, 0755); err != nil {
|
||||
t.Fatalf("failed to create repo dir: %v", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("git", "init", repoDir)
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git init failed: %v", err)
|
||||
}
|
||||
|
||||
// Configure git user
|
||||
exec.Command("git", "-C", repoDir, "config", "user.email", "[email protected]").Run()
|
||||
exec.Command("git", "-C", repoDir, "config", "user.name", "Test User").Run()
|
||||
|
||||
// Create initial commit
|
||||
testFile := filepath.Join(repoDir, "test.txt")
|
||||
if err := os.WriteFile(testFile, []byte("test"), 0644); err != nil {
|
||||
t.Fatalf("failed to create test file: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", repoDir, "add", "test.txt")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git add failed: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", repoDir, "commit", "-m", "initial")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git commit failed: %v", err)
|
||||
}
|
||||
|
||||
// Test worktree add
|
||||
ctx := context.Background()
|
||||
worktreePath, err := action.GitWorktreeAddActivity(ctx, action.GitWorktreeAddInput{
|
||||
RepoPath: repoDir,
|
||||
TaskID: "T0.1",
|
||||
})
|
||||
assert.NoError(t, err, "worktree add should succeed")
|
||||
assert.NotEmpty(t, worktreePath, "worktree path should not be empty")
|
||||
|
||||
// Verify worktree directory exists
|
||||
_, err = os.Stat(worktreePath)
|
||||
assert.NoError(t, err, "worktree directory should exist")
|
||||
|
||||
// Verify branch exists
|
||||
cmd = exec.Command("git", "-C", repoDir, "branch", "--list", "task/T0.1")
|
||||
output, err := cmd.CombinedOutput()
|
||||
assert.NoError(t, err, "git branch check should succeed")
|
||||
assert.Contains(t, string(output), "task/T0.1", "task/T0.1 branch should exist")
|
||||
}
|
||||
|
||||
func TestGitCommit(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
repoDir := filepath.Join(tmpDir, "repo")
|
||||
|
||||
// Initialize repo
|
||||
if err := os.MkdirAll(repoDir, 0755); err != nil {
|
||||
t.Fatalf("failed to create repo dir: %v", err)
|
||||
}
|
||||
|
||||
cmd := exec.Command("git", "init", repoDir)
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git init failed: %v", err)
|
||||
}
|
||||
|
||||
// Configure git user
|
||||
exec.Command("git", "-C", repoDir, "config", "user.email", "[email protected]").Run()
|
||||
exec.Command("git", "-C", repoDir, "config", "user.name", "Test User").Run()
|
||||
|
||||
// Create initial commit
|
||||
testFile := filepath.Join(repoDir, "test.txt")
|
||||
if err := os.WriteFile(testFile, []byte("test"), 0644); err != nil {
|
||||
t.Fatalf("failed to create test file: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", repoDir, "add", "test.txt")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git add failed: %v", err)
|
||||
}
|
||||
|
||||
cmd = exec.Command("git", "-C", repoDir, "commit", "-m", "initial")
|
||||
if err := cmd.Run(); err != nil {
|
||||
t.Fatalf("git commit failed: %v", err)
|
||||
}
|
||||
|
||||
// Create a worktree
|
||||
ctx := context.Background()
|
||||
worktreePath, err := action.GitWorktreeAddActivity(ctx, action.GitWorktreeAddInput{
|
||||
RepoPath: repoDir,
|
||||
TaskID: "T0.1",
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
// Create a new file in the worktree
|
||||
newFile := filepath.Join(worktreePath, "new.txt")
|
||||
if err := os.WriteFile(newFile, []byte("new content"), 0644); err != nil {
|
||||
t.Fatalf("failed to create new file: %v", err)
|
||||
}
|
||||
|
||||
// Commit changes
|
||||
err = action.GitCommitActivity(ctx, action.GitCommitInput{
|
||||
WorktreePath: worktreePath,
|
||||
Message: "Add new file",
|
||||
})
|
||||
assert.NoError(t, err, "commit should succeed")
|
||||
|
||||
// Verify commit exists
|
||||
cmd = exec.Command("git", "-C", worktreePath, "log", "--oneline")
|
||||
output, err := cmd.CombinedOutput()
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, string(output), "Add new file", "commit message should be in log")
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
new content
|
||||
@@ -0,0 +1,3 @@
|
||||
package tests
|
||||
|
||||
// Empty stub - will be filled in T0.7
|
||||
@@ -0,0 +1,3 @@
|
||||
package tests
|
||||
|
||||
// Empty stub - will be filled in T0.6
|
||||
@@ -0,0 +1,94 @@
|
||||
package tests
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/rockliang/poimen/workflows/statemachine"
|
||||
)
|
||||
|
||||
func TestTypesDefaults(t *testing.T) {
|
||||
// Test PiRetryPolicy defaults
|
||||
pr := statemachine.NewPiRetryPolicy()
|
||||
assert.Equal(t, 5*time.Minute, pr.ScheduleToCloseTimeout, "ScheduleToCloseTimeout should be 5m")
|
||||
assert.Equal(t, 2*time.Second, pr.InitialInterval, "InitialInterval should be 2s")
|
||||
assert.Equal(t, 30*time.Second, pr.MaximumInterval, "MaximumInterval should be 30s")
|
||||
assert.Equal(t, 2.0, pr.BackoffCoefficient, "BackoffCoefficient should be 2.0")
|
||||
assert.Equal(t, 30*time.Second, pr.StreamTimeout, "StreamTimeout should be 30s")
|
||||
assert.Equal(t, 2*time.Minute, pr.StreamTimeoutMax, "StreamTimeoutMax should be 2m")
|
||||
|
||||
// Test ActivityTuning defaults
|
||||
at := statemachine.NewActivityTuning()
|
||||
assert.Equal(t, 10*time.Minute, at.ImplementerBaseTimeout, "ImplementerBaseTimeout should be 10m")
|
||||
assert.Equal(t, 3, at.ImplementerMaxRetries, "ImplementerMaxRetries should be 3")
|
||||
assert.Equal(t, 5*time.Minute, at.JudgeTimeout, "JudgeTimeout should be 5m")
|
||||
|
||||
// Test nested PiRetry in ActivityTuning
|
||||
assert.Equal(t, 5*time.Minute, at.PiRetry.ScheduleToCloseTimeout)
|
||||
assert.Equal(t, 30*time.Second, at.PiRetry.StreamTimeout)
|
||||
assert.Equal(t, 2*time.Minute, at.PiRetry.StreamTimeoutMax)
|
||||
}
|
||||
|
||||
func TestModelSpec(t *testing.T) {
|
||||
spec := statemachine.ModelSpec{
|
||||
ModelID: "claude-opus-5",
|
||||
Thinking: "adaptive",
|
||||
Effort: "high",
|
||||
}
|
||||
assert.Equal(t, "claude-opus-5", spec.ModelID)
|
||||
assert.Equal(t, "adaptive", spec.Thinking)
|
||||
assert.Equal(t, "high", spec.Effort)
|
||||
}
|
||||
|
||||
func TestPromptSpec(t *testing.T) {
|
||||
spec := statemachine.PromptSpec{
|
||||
TemplateRef: "planner/default.tmpl",
|
||||
RawTemplate: "",
|
||||
Variables: map[string]any{
|
||||
"key": "value",
|
||||
},
|
||||
Model: statemachine.ModelSpec{
|
||||
ModelID: "claude-opus-5",
|
||||
},
|
||||
LessonsRef: "T0.1",
|
||||
}
|
||||
assert.Equal(t, "planner/default.tmpl", spec.TemplateRef)
|
||||
assert.Empty(t, spec.RawTemplate)
|
||||
assert.Equal(t, "value", spec.Variables["key"])
|
||||
assert.Equal(t, "claude-opus-5", spec.Model.ModelID)
|
||||
assert.Equal(t, "T0.1", spec.LessonsRef)
|
||||
}
|
||||
|
||||
func TestOrchestratorConfig(t *testing.T) {
|
||||
cfg := statemachine.OrchestratorConfig{
|
||||
SystemPrompt: "You are an expert",
|
||||
Skills: []statemachine.SkillRef{
|
||||
{Name: "golang-skills", URL: "https://example.com/skill1"},
|
||||
},
|
||||
RolePrompts: map[string]statemachine.PromptSpec{
|
||||
"planner": {
|
||||
TemplateRef: "planner/default.tmpl",
|
||||
Model: statemachine.ModelSpec{ModelID: "claude-opus-5"},
|
||||
},
|
||||
},
|
||||
Tuning: statemachine.NewActivityTuning(),
|
||||
}
|
||||
assert.Equal(t, "You are an expert", cfg.SystemPrompt)
|
||||
assert.Len(t, cfg.Skills, 1)
|
||||
assert.NotEmpty(t, cfg.RolePrompts)
|
||||
assert.Equal(t, 10*time.Minute, cfg.Tuning.ImplementerBaseTimeout)
|
||||
}
|
||||
|
||||
func TestTaskUnitInput(t *testing.T) {
|
||||
input := statemachine.TaskUnitInput{
|
||||
TaskID: "T0.1",
|
||||
TargetRepoPath: "/tmp/repo",
|
||||
BaseTimeout: 10 * time.Minute,
|
||||
MaxJudgeRetries: 3,
|
||||
}
|
||||
assert.Equal(t, "T0.1", input.TaskID)
|
||||
assert.Equal(t, "/tmp/repo", input.TargetRepoPath)
|
||||
assert.Equal(t, 10*time.Minute, input.BaseTimeout)
|
||||
assert.Equal(t, 3, input.MaxJudgeRetries)
|
||||
}
|
||||
Reference in New Issue
Block a user