package task import ( "testing" "time" ) func TestValidTransition_AllowedTransitions(t *testing.T) { tests := []struct { name string from State to State }{ {"pending to queued", StatePending, StateQueued}, {"pending to cancelled", StatePending, StateCancelled}, {"queued to running", StateQueued, StateRunning}, {"queued to cancelled", StateQueued, StateCancelled}, {"running to completed", StateRunning, StateCompleted}, {"running to failed", StateRunning, StateFailed}, {"running to timed out", StateRunning, StateTimedOut}, {"running to cancelled", StateRunning, StateCancelled}, {"running to budget exceeded", StateRunning, StateBudgetExceeded}, {"failed to queued (retry)", StateFailed, StateQueued}, {"timed out to queued (retry)", StateTimedOut, StateQueued}, {"running to blocked (question)", StateRunning, StateBlocked}, {"blocked to queued (answer resume)", StateBlocked, StateQueued}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if !ValidTransition(tt.from, tt.to) { t.Errorf("expected transition %s -> %s to be valid", tt.from, tt.to) } }) } } func TestValidTransition_DisallowedTransitions(t *testing.T) { tests := []struct { name string from State to State }{ {"pending to running", StatePending, StateRunning}, {"pending to completed", StatePending, StateCompleted}, {"queued to completed", StateQueued, StateCompleted}, {"completed to running", StateCompleted, StateRunning}, {"completed to queued", StateCompleted, StateQueued}, {"failed to completed", StateFailed, StateCompleted}, {"timed out to completed", StateTimedOut, StateCompleted}, {"ready to queued", StateReady, StateQueued}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { if ValidTransition(tt.from, tt.to) { t.Errorf("expected transition %s -> %s to be invalid", tt.from, tt.to) } }) } } func TestValidTransition_ReadyState(t *testing.T) { valid := []struct{ from, to State }{ {StateRunning, StateReady}, {StateReady, StateCompleted}, {StateReady, StatePending}, } for _, tt := range valid { if !ValidTransition(tt.from, tt.to) { t.Errorf("expected transition %s -> %s to be valid", tt.from, tt.to) } } } func TestDuration_UnmarshalYAML(t *testing.T) { var d Duration unmarshal := func(v interface{}) error { ptr := v.(*string) *ptr = "30m" return nil } if err := d.UnmarshalYAML(unmarshal); err != nil { t.Fatalf("unexpected error: %v", err) } if d.Duration != 30*time.Minute { t.Errorf("expected 30m, got %v", d.Duration) } } func TestDuration_MarshalYAML(t *testing.T) { d := Duration{Duration: 15 * time.Minute} v, err := d.MarshalYAML() if err != nil { t.Fatalf("unexpected error: %v", err) } if v != "15m0s" { t.Errorf("expected '15m0s', got %v", v) } }