Rewrite swarm tests to use beads-backed API (gt-kc7yj.4)
- Add LoadSwarm method for loading swarms from beads - Rewrite tests to use LoadSwarm, GetSwarm, GetReadyTasks, IsComplete - Remove tests for deprecated Create, Start, UpdateState methods - Keep E2E lifecycle documentation test 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
+21
-144
@@ -6,183 +6,60 @@ import (
|
|||||||
"github.com/steveyegge/gastown/internal/rig"
|
"github.com/steveyegge/gastown/internal/rig"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestManagerCreate(t *testing.T) {
|
// TestLoadSwarmNotFound tests that LoadSwarm returns error for missing epic.
|
||||||
|
func TestLoadSwarmNotFound(t *testing.T) {
|
||||||
r := &rig.Rig{
|
r := &rig.Rig{
|
||||||
Name: "test-rig",
|
Name: "test-rig",
|
||||||
Path: "/tmp/test-rig",
|
Path: "/tmp/test-rig",
|
||||||
}
|
}
|
||||||
m := NewManager(r)
|
m := NewManager(r)
|
||||||
|
|
||||||
swarm, err := m.Create("epic-1", []string{"Toast", "Nux"}, "main")
|
// LoadSwarm for non-existent epic should fail (no beads available)
|
||||||
if err != nil {
|
_, err := m.LoadSwarm("nonexistent-epic")
|
||||||
t.Fatalf("Create failed: %v", err)
|
if err == nil {
|
||||||
}
|
t.Error("LoadSwarm should fail for non-existent epic")
|
||||||
|
|
||||||
if swarm.ID != "epic-1" {
|
|
||||||
t.Errorf("ID = %q, want %q", swarm.ID, "epic-1")
|
|
||||||
}
|
|
||||||
if swarm.State != SwarmCreated {
|
|
||||||
t.Errorf("State = %q, want %q", swarm.State, SwarmCreated)
|
|
||||||
}
|
|
||||||
if len(swarm.Workers) != 2 {
|
|
||||||
t.Errorf("Workers = %d, want 2", len(swarm.Workers))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManagerCreateDuplicate(t *testing.T) {
|
// TestGetSwarmNotFound tests that GetSwarm returns error for missing swarm.
|
||||||
|
func TestGetSwarmNotFound(t *testing.T) {
|
||||||
r := &rig.Rig{
|
r := &rig.Rig{
|
||||||
Name: "test-rig",
|
Name: "test-rig",
|
||||||
Path: "/tmp/test-rig",
|
Path: "/tmp/test-rig",
|
||||||
}
|
}
|
||||||
m := NewManager(r)
|
m := NewManager(r)
|
||||||
|
|
||||||
_, err := m.Create("epic-1", []string{"Toast"}, "main")
|
_, err := m.GetSwarm("nonexistent")
|
||||||
if err != nil {
|
if err == nil {
|
||||||
t.Fatalf("First Create failed: %v", err)
|
t.Error("GetSwarm for nonexistent should return error")
|
||||||
}
|
|
||||||
|
|
||||||
_, err = m.Create("epic-1", []string{"Nux"}, "main")
|
|
||||||
if err != ErrSwarmExists {
|
|
||||||
t.Errorf("Create duplicate = %v, want ErrSwarmExists", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManagerStateTransitions(t *testing.T) {
|
// TestGetReadyTasksNotFound tests that GetReadyTasks returns error for missing swarm.
|
||||||
|
func TestGetReadyTasksNotFound(t *testing.T) {
|
||||||
r := &rig.Rig{
|
r := &rig.Rig{
|
||||||
Name: "test-rig",
|
Name: "test-rig",
|
||||||
Path: "/tmp/test-rig",
|
Path: "/tmp/test-rig",
|
||||||
}
|
}
|
||||||
m := NewManager(r)
|
m := NewManager(r)
|
||||||
|
|
||||||
swarm, _ := m.Create("epic-1", []string{"Toast"}, "main")
|
_, err := m.GetReadyTasks("nonexistent")
|
||||||
|
if err != ErrSwarmNotFound {
|
||||||
// Start
|
t.Errorf("GetReadyTasks = %v, want ErrSwarmNotFound", err)
|
||||||
if err := m.Start(swarm.ID); err != nil {
|
|
||||||
t.Errorf("Start failed: %v", err)
|
|
||||||
}
|
|
||||||
s, _ := m.GetSwarm(swarm.ID)
|
|
||||||
if s.State != SwarmActive {
|
|
||||||
t.Errorf("State after Start = %q, want %q", s.State, SwarmActive)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't start again
|
|
||||||
if err := m.Start(swarm.ID); err == nil {
|
|
||||||
t.Error("Start from Active should fail")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transition to Merging
|
|
||||||
if err := m.UpdateState(swarm.ID, SwarmMerging); err != nil {
|
|
||||||
t.Errorf("UpdateState to Merging failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Transition to Landed
|
|
||||||
if err := m.UpdateState(swarm.ID, SwarmLanded); err != nil {
|
|
||||||
t.Errorf("UpdateState to Landed failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can't transition from terminal
|
|
||||||
if err := m.UpdateState(swarm.ID, SwarmActive); err == nil {
|
|
||||||
t.Error("UpdateState from Landed should fail")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestManagerCancel(t *testing.T) {
|
// TestIsCompleteNotFound tests that IsComplete returns error for missing swarm.
|
||||||
|
func TestIsCompleteNotFound(t *testing.T) {
|
||||||
r := &rig.Rig{
|
r := &rig.Rig{
|
||||||
Name: "test-rig",
|
Name: "test-rig",
|
||||||
Path: "/tmp/test-rig",
|
Path: "/tmp/test-rig",
|
||||||
}
|
}
|
||||||
m := NewManager(r)
|
m := NewManager(r)
|
||||||
|
|
||||||
swarm, _ := m.Create("epic-1", []string{"Toast"}, "main")
|
_, err := m.IsComplete("nonexistent")
|
||||||
_ = m.Start(swarm.ID)
|
if err != ErrSwarmNotFound {
|
||||||
|
t.Errorf("IsComplete = %v, want ErrSwarmNotFound", err)
|
||||||
if err := m.Cancel(swarm.ID, "user requested"); err != nil {
|
|
||||||
t.Errorf("Cancel failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
s, _ := m.GetSwarm(swarm.ID)
|
|
||||||
if s.State != SwarmCancelled {
|
|
||||||
t.Errorf("State after Cancel = %q, want %q", s.State, SwarmCancelled)
|
|
||||||
}
|
|
||||||
if s.Error != "user requested" {
|
|
||||||
t.Errorf("Error = %q, want %q", s.Error, "user requested")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestManagerTaskOperations(t *testing.T) {
|
|
||||||
r := &rig.Rig{
|
|
||||||
Name: "test-rig",
|
|
||||||
Path: "/tmp/test-rig",
|
|
||||||
}
|
|
||||||
m := NewManager(r)
|
|
||||||
|
|
||||||
swarm, _ := m.Create("epic-1", []string{"Toast"}, "main")
|
|
||||||
|
|
||||||
// Manually add tasks (normally loaded from beads)
|
|
||||||
swarm.Tasks = []SwarmTask{
|
|
||||||
{IssueID: "task-1", Title: "Task 1", State: TaskPending},
|
|
||||||
{IssueID: "task-2", Title: "Task 2", State: TaskPending},
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get ready tasks
|
|
||||||
ready, err := m.GetReadyTasks(swarm.ID)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("GetReadyTasks failed: %v", err)
|
|
||||||
}
|
|
||||||
if len(ready) != 2 {
|
|
||||||
t.Errorf("GetReadyTasks = %d, want 2", len(ready))
|
|
||||||
}
|
|
||||||
|
|
||||||
// Assign task
|
|
||||||
if err := m.AssignTask(swarm.ID, "task-1", "Toast"); err != nil {
|
|
||||||
t.Errorf("AssignTask failed: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check assignment
|
|
||||||
s, _ := m.GetSwarm(swarm.ID)
|
|
||||||
if s.Tasks[0].Assignee != "Toast" {
|
|
||||||
t.Errorf("Assignee = %q, want %q", s.Tasks[0].Assignee, "Toast")
|
|
||||||
}
|
|
||||||
if s.Tasks[0].State != TaskAssigned {
|
|
||||||
t.Errorf("State = %q, want %q", s.Tasks[0].State, TaskAssigned)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update state
|
|
||||||
if err := m.UpdateTaskState(swarm.ID, "task-1", TaskMerged); err != nil {
|
|
||||||
t.Errorf("UpdateTaskState failed: %v", err)
|
|
||||||
}
|
|
||||||
s, _ = m.GetSwarm(swarm.ID)
|
|
||||||
if s.Tasks[0].State != TaskMerged {
|
|
||||||
t.Errorf("State = %q, want %q", s.Tasks[0].State, TaskMerged)
|
|
||||||
}
|
|
||||||
if s.Tasks[0].MergedAt == nil {
|
|
||||||
t.Error("MergedAt should be set")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestManagerIsComplete(t *testing.T) {
|
|
||||||
r := &rig.Rig{
|
|
||||||
Name: "test-rig",
|
|
||||||
Path: "/tmp/test-rig",
|
|
||||||
}
|
|
||||||
m := NewManager(r)
|
|
||||||
|
|
||||||
swarm, _ := m.Create("epic-1", []string{"Toast"}, "main")
|
|
||||||
swarm.Tasks = []SwarmTask{
|
|
||||||
{IssueID: "task-1", State: TaskPending},
|
|
||||||
{IssueID: "task-2", State: TaskMerged},
|
|
||||||
}
|
|
||||||
|
|
||||||
complete, _ := m.IsComplete(swarm.ID)
|
|
||||||
if complete {
|
|
||||||
t.Error("IsComplete should be false with pending task")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Complete the pending task
|
|
||||||
_ = m.UpdateTaskState(swarm.ID, "task-1", TaskMerged)
|
|
||||||
complete, _ = m.IsComplete(swarm.ID)
|
|
||||||
if !complete {
|
|
||||||
t.Error("IsComplete should be true when all tasks merged")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user