1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
package task
import (
"strings"
"testing"
)
func validTask() *Task {
return &Task{
ID: "test-id",
Name: "Valid Task",
Claude: ClaudeConfig{
Instructions: "do something",
ProjectDir: "/tmp",
},
Priority: PriorityNormal,
Retry: RetryConfig{MaxAttempts: 1, Backoff: "exponential"},
}
}
func TestValidate_ValidTask_NoError(t *testing.T) {
task := validTask()
if err := Validate(task); err != nil {
t.Errorf("expected no error, got: %v", err)
}
}
func TestValidate_MissingName_ReturnsError(t *testing.T) {
task := validTask()
task.Name = ""
err := Validate(task)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "name is required") {
t.Errorf("expected 'name is required' in error, got: %v", err)
}
}
func TestValidate_MissingInstructions_ReturnsError(t *testing.T) {
task := validTask()
task.Claude.Instructions = ""
err := Validate(task)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "instructions is required") {
t.Errorf("expected 'instructions is required' in error, got: %v", err)
}
}
func TestValidate_NegativeBudget_ReturnsError(t *testing.T) {
task := validTask()
task.Claude.MaxBudgetUSD = -1.0
err := Validate(task)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "max_budget_usd") {
t.Errorf("expected budget error, got: %v", err)
}
}
func TestValidate_InvalidBackoff_ReturnsError(t *testing.T) {
task := validTask()
task.Retry.Backoff = "random"
err := Validate(task)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "backoff") {
t.Errorf("expected backoff error, got: %v", err)
}
}
func TestValidate_InvalidPriority_ReturnsError(t *testing.T) {
task := validTask()
task.Priority = "urgent"
err := Validate(task)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "invalid priority") {
t.Errorf("expected priority error, got: %v", err)
}
}
func TestValidate_InvalidPermissionMode_ReturnsError(t *testing.T) {
task := validTask()
task.Claude.PermissionMode = "yolo"
err := Validate(task)
if err == nil {
t.Fatal("expected error")
}
if !strings.Contains(err.Error(), "permission_mode") {
t.Errorf("expected permission_mode error, got: %v", err)
}
}
func TestValidate_MultipleErrors(t *testing.T) {
task := &Task{
Retry: RetryConfig{MaxAttempts: 0, Backoff: "bad"},
}
err := Validate(task)
if err == nil {
t.Fatal("expected error")
}
ve, ok := err.(*ValidationError)
if !ok {
t.Fatalf("expected *ValidationError, got %T", err)
}
if len(ve.Errors) < 3 {
t.Errorf("expected at least 3 errors, got %d: %v", len(ve.Errors), ve.Errors)
}
}
|