package sdlc import "testing" func TestAddTask(t *testing.T) { tasks := AddTask(nil, "Create user model") tasks = AddTask(tasks, "Add validation") if len(tasks) != 2 { t.Fatalf("len = %d, want 2", len(tasks)) } if tasks[0].ID != "task-001" { t.Errorf("tasks[0].ID = %q, want task-001", tasks[0].ID) } if tasks[1].ID != "task-002" { t.Errorf("tasks[1].ID = %q, want task-002", tasks[1].ID) } if tasks[0].Status != TaskPending { t.Errorf("tasks[0].Status = %q, want pending", tasks[0].Status) } } func TestStartTask(t *testing.T) { tasks := AddTask(nil, "Task 1") tasks, err := StartTask(tasks, "task-001") if err != nil { t.Fatalf("StartTask: %v", err) } if tasks[0].Status != TaskInProgress { t.Errorf("Status = %q, want in_progress", tasks[0].Status) } if tasks[0].StartedAt == nil { t.Error("StartedAt is nil") } } func TestStartTaskNotFound(t *testing.T) { tasks := AddTask(nil, "Task 1") _, err := StartTask(tasks, "task-999") if err != ErrTaskNotFound { t.Errorf("err = %v, want ErrTaskNotFound", err) } } func TestStartTaskWrongStatus(t *testing.T) { tasks := AddTask(nil, "Task 1") tasks, _ = StartTask(tasks, "task-001") tasks, _ = CompleteTask(tasks, "task-001") _, err := StartTask(tasks, "task-001") if err == nil { t.Error("StartTask on complete task should fail") } } func TestCompleteTask(t *testing.T) { tasks := AddTask(nil, "Task 1") tasks, _ = StartTask(tasks, "task-001") tasks, err := CompleteTask(tasks, "task-001") if err != nil { t.Fatalf("CompleteTask: %v", err) } if tasks[0].Status != TaskComplete { t.Errorf("Status = %q, want complete", tasks[0].Status) } if tasks[0].DoneAt == nil { t.Error("DoneAt is nil") } } func TestCompleteTaskWrongStatus(t *testing.T) { tasks := AddTask(nil, "Task 1") _, err := CompleteTask(tasks, "task-001") if err == nil { t.Error("CompleteTask on pending task should fail") } } func TestBlockTask(t *testing.T) { tasks := AddTask(nil, "Task 1") tasks, err := BlockTask(tasks, "task-001") if err != nil { t.Fatalf("BlockTask: %v", err) } if tasks[0].Status != TaskBlocked { t.Errorf("Status = %q, want blocked", tasks[0].Status) } } func TestPendingTasks(t *testing.T) { tasks := AddTask(nil, "Task 1") tasks = AddTask(tasks, "Task 2") tasks = AddTask(tasks, "Task 3") tasks, _ = StartTask(tasks, "task-001") tasks, _ = CompleteTask(tasks, "task-001") pending := PendingTasks(tasks) if len(pending) != 2 { t.Errorf("PendingTasks len = %d, want 2", len(pending)) } } func TestNextTask(t *testing.T) { tasks := AddTask(nil, "Task 1") tasks = AddTask(tasks, "Task 2") tasks, _ = StartTask(tasks, "task-001") tasks, _ = CompleteTask(tasks, "task-001") next := NextTask(tasks) if next == nil { t.Fatal("NextTask = nil, want task-002") } if next.ID != "task-002" { t.Errorf("NextTask.ID = %q, want task-002", next.ID) } } func TestAllTasksComplete(t *testing.T) { if AllTasksComplete(nil) { t.Error("AllTasksComplete(nil) = true, want false") } tasks := AddTask(nil, "Task 1") tasks = AddTask(tasks, "Task 2") if AllTasksComplete(tasks) { t.Error("AllTasksComplete = true with pending tasks") } tasks, _ = StartTask(tasks, "task-001") tasks, _ = CompleteTask(tasks, "task-001") tasks, _ = StartTask(tasks, "task-002") tasks, _ = CompleteTask(tasks, "task-002") if !AllTasksComplete(tasks) { t.Error("AllTasksComplete = false with all complete") } } func TestSummarizeTasks(t *testing.T) { tasks := AddTask(nil, "Task 1") tasks = AddTask(tasks, "Task 2") tasks = AddTask(tasks, "Task 3") tasks, _ = StartTask(tasks, "task-001") tasks, _ = CompleteTask(tasks, "task-001") tasks, _ = StartTask(tasks, "task-002") s := SummarizeTasks(tasks) if s.Total != 3 { t.Errorf("Total = %d, want 3", s.Total) } if s.Completed != 1 { t.Errorf("Completed = %d, want 1", s.Completed) } if s.InProgress != 1 { t.Errorf("InProgress = %d, want 1", s.InProgress) } if s.Pending != 1 { t.Errorf("Pending = %d, want 1", s.Pending) } }