fsm: improve and convert to interface
Signed-off-by: Vasiliy Tolstov <v.tolstov@unistack.org>
This commit is contained in:
@@ -1,63 +1,72 @@
|
||||
package fsm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"go.unistack.org/micro/v3/logger"
|
||||
)
|
||||
|
||||
func TestFSMStart(t *testing.T) {
|
||||
ctx := context.TODO()
|
||||
buf := bytes.NewBuffer(nil)
|
||||
pfb := func(_ context.Context, state string, _ interface{}) {
|
||||
fmt.Fprintf(buf, "before state %s\n", state)
|
||||
|
||||
if err := logger.DefaultLogger.Init(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
pfa := func(_ context.Context, state string, _ interface{}) {
|
||||
fmt.Fprintf(buf, "after state %s\n", state)
|
||||
|
||||
wrapper := func(next StateFunc) StateFunc {
|
||||
return func(sctx context.Context, s State, opts ...StateOption) (State, error) {
|
||||
sctx = logger.NewContext(sctx, logger.Fields("state", s.Name()))
|
||||
return next(sctx, s, opts...)
|
||||
}
|
||||
}
|
||||
f := New(InitialState("1"), HookBefore(pfb), HookAfter(pfa))
|
||||
f1 := func(_ context.Context, req interface{}, _ ...StateOption) (string, interface{}, error) {
|
||||
args := req.(map[string]interface{})
|
||||
|
||||
f := NewFSM(InitialState("1"), WrapState(wrapper))
|
||||
f1 := func(sctx context.Context, s State, opts ...StateOption) (State, error) {
|
||||
_, ok := logger.FromContext(sctx)
|
||||
if !ok {
|
||||
t.Fatal("f1 context does not have logger")
|
||||
}
|
||||
args := s.Body().(map[string]interface{})
|
||||
if v, ok := args["request"].(string); !ok || v == "" {
|
||||
return "", nil, fmt.Errorf("empty request")
|
||||
return nil, fmt.Errorf("empty request")
|
||||
}
|
||||
return "2", map[string]interface{}{"response": "test2"}, nil
|
||||
return &state{name: "", body: map[string]interface{}{"response": "state1"}}, nil
|
||||
}
|
||||
f2 := func(_ context.Context, req interface{}, _ ...StateOption) (string, interface{}, error) {
|
||||
args := req.(map[string]interface{})
|
||||
if v, ok := args["response"].(string); !ok || v == "" {
|
||||
return "", nil, fmt.Errorf("empty response")
|
||||
f2 := func(sctx context.Context, s State, opts ...StateOption) (State, error) {
|
||||
_, ok := logger.FromContext(sctx)
|
||||
if !ok {
|
||||
t.Fatal("f2 context does not have logger")
|
||||
}
|
||||
return "", map[string]interface{}{"response": "test"}, nil
|
||||
args := s.Body().(map[string]interface{})
|
||||
if v, ok := args["response"].(string); !ok || v == "" {
|
||||
return nil, fmt.Errorf("empty response")
|
||||
}
|
||||
return &state{name: "", body: map[string]interface{}{"response": "state2"}}, nil
|
||||
}
|
||||
f3 := func(_ context.Context, req interface{}, _ ...StateOption) (string, interface{}, error) {
|
||||
args := req.(map[string]interface{})
|
||||
if v, ok := args["response"].(string); !ok || v == "" {
|
||||
return "", nil, fmt.Errorf("empty response")
|
||||
f3 := func(sctx context.Context, s State, opts ...StateOption) (State, error) {
|
||||
_, ok := logger.FromContext(sctx)
|
||||
if !ok {
|
||||
t.Fatal("f3 context does not have logger")
|
||||
}
|
||||
return StateEnd, map[string]interface{}{"response": "test_last"}, nil
|
||||
args := s.Body().(map[string]interface{})
|
||||
if v, ok := args["response"].(string); !ok || v == "" {
|
||||
return nil, fmt.Errorf("empty response")
|
||||
}
|
||||
return &state{name: StateEnd, body: map[string]interface{}{"response": "state3"}}, nil
|
||||
}
|
||||
f.State("1", f1)
|
||||
f.State("2", f2)
|
||||
f.State("3", f3)
|
||||
rsp, err := f.Start(ctx, map[string]interface{}{"request": "test1"})
|
||||
rsp, err := f.Start(ctx, map[string]interface{}{"request": "state"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
args := rsp.(map[string]interface{})
|
||||
if v, ok := args["response"].(string); !ok || v == "" {
|
||||
t.Fatalf("nil rsp: %#+v", args)
|
||||
} else if v != "test_last" {
|
||||
} else if v != "state3" {
|
||||
t.Fatalf("invalid rsp %#+v", args)
|
||||
}
|
||||
|
||||
if !bytes.Contains(buf.Bytes(), []byte(`before state 1`)) ||
|
||||
!bytes.Contains(buf.Bytes(), []byte(`before state 2`)) ||
|
||||
!bytes.Contains(buf.Bytes(), []byte(`after state 1`)) ||
|
||||
!bytes.Contains(buf.Bytes(), []byte(`after state 2`)) ||
|
||||
!bytes.Contains(buf.Bytes(), []byte(`after state 3`)) ||
|
||||
!bytes.Contains(buf.Bytes(), []byte(`after state 3`)) {
|
||||
t.Fatalf("fsm not works properly or hooks error, buf: %s", buf.Bytes())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user