92 lines
2.8 KiB
Go
92 lines
2.8 KiB
Go
package flow
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"testing"
|
|
)
|
|
|
|
func TestRunRecordsOrderAndHooks(t *testing.T) {
|
|
reg := NewRegistry()
|
|
var trace []string
|
|
reg.Action("a", func(_ context.Context, _ *State, _ json.RawMessage) error {
|
|
trace = append(trace, "a")
|
|
return nil
|
|
})
|
|
reg.Action("b", func(_ context.Context, _ *State, _ json.RawMessage) error {
|
|
trace = append(trace, "b")
|
|
return nil
|
|
})
|
|
reg.Hook("rec", func(_ context.Context, _ *State, info HookInfo, _ json.RawMessage) error {
|
|
trace = append(trace, string(info.Phase)+":"+info.Step)
|
|
return nil
|
|
})
|
|
|
|
def := &Definition{Name: "t", Steps: []Step{
|
|
{Name: "s1", Action: "a", Hooks: Hooks{Before: []HookRef{{Type: "rec"}}, After: []HookRef{{Type: "rec"}}}},
|
|
{Name: "s2", Action: "b"},
|
|
}}
|
|
res, err := NewEngine(reg, nil).Run(context.Background(), def, NewState(1, nil))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if res.Failed || len(res.Steps) != 2 {
|
|
t.Fatalf("unexpected result %+v", res)
|
|
}
|
|
want := []string{"before:s1", "a", "after:s1", "b"}
|
|
if fmt.Sprint(trace) != fmt.Sprint(want) {
|
|
t.Fatalf("trace = %v, want %v", trace, want)
|
|
}
|
|
}
|
|
|
|
func TestPredicateSkipsStep(t *testing.T) {
|
|
reg := NewRegistry()
|
|
ran := false
|
|
reg.Action("a", func(_ context.Context, _ *State, _ json.RawMessage) error { ran = true; return nil })
|
|
reg.Predicate("never", func(_ context.Context, _ *State) (bool, error) { return false, nil })
|
|
|
|
def := &Definition{Name: "t", Steps: []Step{{Name: "s1", Action: "a", When: "never"}}}
|
|
res, err := NewEngine(reg, nil).Run(context.Background(), def, NewState(1, nil))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if ran {
|
|
t.Fatal("action ran despite predicate=false")
|
|
}
|
|
if !res.Steps[0].Skipped {
|
|
t.Fatal("step not marked skipped")
|
|
}
|
|
}
|
|
|
|
func TestContinueOnError(t *testing.T) {
|
|
reg := NewRegistry()
|
|
reg.Action("boom", func(_ context.Context, _ *State, _ json.RawMessage) error { return fmt.Errorf("x") })
|
|
reg.Action("ok", func(_ context.Context, _ *State, _ json.RawMessage) error { return nil })
|
|
|
|
def := &Definition{Name: "t", Steps: []Step{
|
|
{Name: "s1", Action: "boom", ContinueOnError: true},
|
|
{Name: "s2", Action: "ok"},
|
|
}}
|
|
res, err := NewEngine(reg, nil).Run(context.Background(), def, NewState(1, nil))
|
|
if err != nil {
|
|
t.Fatalf("continue-on-error should not abort: %v", err)
|
|
}
|
|
if res.Steps[0].Error == "" || res.Steps[1].Error != "" {
|
|
t.Fatalf("unexpected step results %+v", res.Steps)
|
|
}
|
|
}
|
|
|
|
func TestValidateCatchesUnknownRefs(t *testing.T) {
|
|
reg := NewRegistry()
|
|
reg.Action("a", func(_ context.Context, _ *State, _ json.RawMessage) error { return nil })
|
|
eng := NewEngine(reg, nil)
|
|
|
|
if err := eng.Validate(&Definition{Name: "t", Steps: []Step{{Name: "s", Action: "missing"}}}); err == nil {
|
|
t.Fatal("expected unknown-action error")
|
|
}
|
|
if err := eng.Validate(&Definition{Name: "t", Steps: []Step{{Name: "s", Action: "a"}}}); err != nil {
|
|
t.Fatalf("valid def rejected: %v", err)
|
|
}
|
|
}
|