| package state_machine |
| |
| import ( |
| "context" |
| "fmt" |
| "testing" |
| |
| "github.com/stretchr/testify/require" |
| "go.skia.org/infra/go/gcs/mem_gcsclient" |
| ) |
| |
| func TestStateMachine(t *testing.T) { |
| |
| ctx := context.Background() |
| |
| gcsClient := mem_gcsclient.New("test-bucket") |
| file := "test_state_machine" |
| |
| b := NewBuilder() |
| b.T("15", "16", "noop") |
| b.T("16", "17", "err") |
| |
| b.F("noop", nil) |
| b.F("err", func(ctx context.Context) error { |
| return fmt.Errorf("nope") |
| }) |
| b.SetInitial("85") |
| s, err := b.Build(ctx, gcsClient, file) |
| require.EqualError(t, err, "Initial state \"85\" is not defined!") |
| b.SetInitial("15") |
| s, err = b.Build(ctx, gcsClient, file) |
| require.EqualError(t, err, "No transitions defined from state \"17\"") |
| b.T("17", "17", "noop") |
| b.T("18", "17", "noop") |
| s, err = b.Build(ctx, gcsClient, file) |
| require.EqualError(t, err, "No transitions defined to state \"18\"") |
| b.T("15", "18", "noop") |
| s, err = b.Build(ctx, gcsClient, file) |
| require.NoError(t, err) |
| require.Equal(t, "15", s.Current()) |
| name, err := s.GetTransitionName("16") |
| require.NoError(t, err) |
| require.Equal(t, "noop", name) |
| require.NoError(t, s.Transition(ctx, "16")) |
| require.Equal(t, "16", s.Current()) |
| name, err = s.GetTransitionName("17") |
| require.NoError(t, err) |
| require.Equal(t, "err", name) |
| require.EqualError(t, s.Transition(ctx, "17"), "Failed to transition from \"16\" to \"17\": nope") |
| require.Equal(t, "16", s.Current()) |
| |
| b.T("16", "17", "noop") |
| p, err := b.Build(ctx, gcsClient, file) |
| require.EqualError(t, err, "Multiple defined transitions from \"16\" to \"17\": \"err\", \"noop\"") |
| splitIdx := -1 |
| for i, t := range b.transitions { |
| if t.from == "16" && t.to == "17" && t.fn == "err" { |
| splitIdx = i |
| break |
| } |
| } |
| require.False(t, splitIdx < 0) |
| b.transitions = append(b.transitions[:splitIdx], b.transitions[splitIdx+1:]...) |
| p, err = b.Build(ctx, gcsClient, file) |
| require.NoError(t, err) |
| |
| require.Equal(t, "16", p.Current()) |
| name, err = p.GetTransitionName("17") |
| require.NoError(t, err) |
| require.Equal(t, "noop", name) |
| require.NoError(t, p.Transition(ctx, "17")) |
| require.Equal(t, "17", p.Current()) |
| p2, err := b.Build(ctx, gcsClient, file) |
| require.NoError(t, err) |
| require.Equal(t, p.Current(), p2.Current()) |
| } |