Files
event/manager_test.go
inhere ab0d946a81 feat: add support with context for fire event. see issues #78
- add new method: FireCtx, FireEventCtx
2025-08-21 22:01:10 +08:00

394 lines
10 KiB
Go

package event_test
import (
"bytes"
"fmt"
"strings"
"sync"
"testing"
"time"
"github.com/gookit/event"
"github.com/gookit/goutil/testutil/assert"
)
func TestManager_FireEvent(t *testing.T) {
em := event.NewManager("test")
em.EnableLock = true
e1 := event.NewBasic("e1", nil)
assert.NoErr(t, em.AddEvent(e1))
em.On("e1", &testListener{"HI"}, event.Min)
em.On("e1", &testListener{"WEL"}, event.High)
em.AddListener("e1", &testListener{"COM"}, event.BelowNormal)
err := em.FireEvent(e1)
assert.NoError(t, err)
assert.Equal(t, "handled: e1(WEL) -> e1(COM) -> e1(HI)", e1.Get("result"))
// not exist
err = em.FireEvent(e1.SetName("e2"))
assert.NoError(t, err)
em.Clear()
}
func TestManager_FireEvent2(t *testing.T) {
buf := new(bytes.Buffer)
mgr := event.NewM("test")
evt1 := event.New("evt1", nil).Fill(nil, event.M{"n": "inhere"})
assert.NoErr(t, mgr.AddEvent(evt1))
assert.True(t, mgr.HasEvent("evt1"))
assert.False(t, mgr.HasEvent("not-exist"))
mgr.On("evt1", event.ListenerFunc(func(e event.Event) error {
_, _ = fmt.Fprintf(buf, "event: %s, params: n=%s", e.Name(), e.Get("n"))
return nil
}), event.Normal)
assert.True(t, mgr.HasListeners("evt1"))
assert.False(t, mgr.HasListeners("not-exist"))
err := mgr.FireEvent(evt1)
assert.NoError(t, err)
assert.Equal(t, "event: evt1, params: n=inhere", buf.String())
buf.Reset()
mgr.On(event.Wildcard, event.ListenerFunc(func(e event.Event) error {
buf.WriteString("|Wildcard handler")
return nil
}))
err = mgr.FireEvent(evt1)
assert.NoError(t, err)
assert.Equal(t, "event: evt1, params: n=inhere|Wildcard handler", buf.String())
}
func TestManager_AsyncFire(t *testing.T) {
em := event.NewManager("test")
em.On("e1", event.ListenerFunc(func(e event.Event) error {
assert.Equal(t, map[string]any{"k": "v"}, e.Data())
e.Set("nk", "nv")
return nil
}))
e1 := event.NewBasic("e1", event.M{"k": "v"})
em.AsyncFire(e1)
time.Sleep(time.Second / 10)
assert.Equal(t, "nv", e1.Get("nk"))
var wg sync.WaitGroup
em.On("e2", event.ListenerFunc(func(e event.Event) error {
defer wg.Done()
assert.Equal(t, "v", e.Get("k"))
return nil
}))
wg.Add(1)
em.AsyncFire(e1.SetName("e2"))
wg.Wait()
em.Clear()
}
func TestManager_AwaitFire(t *testing.T) {
em := event.NewManager("test")
em.On("e1", event.ListenerFunc(func(e event.Event) error {
assert.Equal(t, map[string]any{"k": "v"}, e.Data())
e.Set("nk", "nv")
return nil
}))
e1 := event.NewBasic("e1", event.M{"k": "v"})
err := em.AwaitFire(e1)
assert.NoError(t, err)
assert.Contains(t, e1.Data(), "nk")
assert.Equal(t, "nv", e1.Get("nk"))
}
func TestManager_AddSubscriber(t *testing.T) {
em := event.NewManager("test")
em.AddSubscriber(&testSubscriber{})
assert.True(t, em.HasListeners("e1"))
assert.True(t, em.HasListeners("e2"))
assert.True(t, em.HasListeners("e3"))
ers := em.FireBatch("e1", event.NewBasic("e2", nil))
assert.Len(t, ers, 1)
assert.Panics(t, func() {
em.AddSubscriber(testSubscriber2{})
})
em.Clear()
}
func TestManager_ListenGroupEvent(t *testing.T) {
em := event.NewManager("test")
e1 := event.NewBasic("app.evt1", event.M{"buf": new(bytes.Buffer)})
err := e1.AttachTo(em)
assert.NoError(t, err)
l2 := event.ListenerFunc(func(e event.Event) error {
e.Get("buf").(*bytes.Buffer).WriteString(" > 2 " + e.Name())
return nil
})
l3 := event.ListenerFunc(func(e event.Event) error {
e.Get("buf").(*bytes.Buffer).WriteString(" > 3 " + e.Name())
return nil
})
em.On("app.evt1", event.ListenerFunc(func(e event.Event) error {
e.Get("buf").(*bytes.Buffer).WriteString("Hi > 1 " + e.Name())
return nil
}))
em.On("app.*", l2)
em.On("*", l3)
buf := e1.Get("buf").(*bytes.Buffer)
err, e := em.Fire("app.evt1", nil)
assert.NoError(t, err)
assert.Equal(t, "app.evt1", e.Name())
// assert.Equal(t, e1, e)
assert.Equal(t, "Hi > 1 app.evt1 > 2 app.evt1 > 3 app.evt1", buf.String())
em.RemoveListener("app.*", l2)
assert.Len(t, em.ListenedNames(), 2)
em.On("app.*", event.ListenerFunc(func(e event.Event) error {
return fmt.Errorf("an error")
}))
buf.Reset()
err, e = em.Fire("app.evt1", nil)
assert.Error(t, err)
assert.Equal(t, "Hi > 1 app.evt1", buf.String())
em.RemoveListeners("app.*")
em.RemoveListener("", l3)
em.On("app.*", l2) // re-add
em.On("*", event.ListenerFunc(func(e event.Event) error {
return fmt.Errorf("an error")
}))
assert.Len(t, em.ListenedNames(), 3)
buf.Reset()
err, e = em.Trigger("app.evt1", nil)
assert.Error(t, err)
// assert.Equal(t, e1, e)
assert.Equal(t, "app.evt1", e.Name())
assert.Equal(t, "Hi > 1 app.evt1 > 2 app.evt1", buf.String())
em.RemoveListener("", nil)
// clear
em.Clear()
buf.Reset()
}
func TestManager_Fire_WithWildcard(t *testing.T) {
buf := new(bytes.Buffer)
mgr := event.NewManager("test")
const Event2FurcasTicketCreate = "kapal.furcas.ticket.create"
handler := event.ListenerFunc(func(e event.Event) error {
_, _ = fmt.Fprintf(buf, "%s-%s|", e.Name(), e.Get("user"))
return nil
})
mgr.On("kapal.furcas.ticket.*", handler)
mgr.On(Event2FurcasTicketCreate, handler)
err, _ := mgr.Fire(Event2FurcasTicketCreate, event.M{"user": "inhere"})
assert.NoError(t, err)
assert.Equal(
t,
"kapal.furcas.ticket.create-inhere|kapal.furcas.ticket.create-inhere|",
buf.String(),
)
buf.Reset()
// add Wildcard listen
mgr.On("*", handler)
err, _ = mgr.Trigger(Event2FurcasTicketCreate, event.M{"user": "inhere"})
assert.NoError(t, err)
assert.Equal(
t,
"kapal.furcas.ticket.create-inhere|kapal.furcas.ticket.create-inhere|kapal.furcas.ticket.create-inhere|",
buf.String(),
)
}
func TestManager_Fire_usePathMode(t *testing.T) {
buf := new(bytes.Buffer)
em := event.NewManager("test", event.UsePathMode, event.EnableLock(true))
em.Listen("db.user.*", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("db.user.*|")
return nil
}))
em.Listen("db.**", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("db.**|")
return nil
}), 1)
em.Listen("db.user.add", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("db.user.add|")
return nil
}), 2)
assert.True(t, em.HasListeners("db.user.*"))
t.Run("fire case1", func(t *testing.T) {
err, e := em.Fire("db.user.add", event.M{"user": "inhere"})
assert.NoError(t, err)
assert.Equal(t, "db.user.add", e.Name())
assert.Equal(t, "inhere", e.Get("user"))
str := buf.String()
fmt.Println(str)
assert.Contains(t, str, "db.**|")
assert.Contains(t, str, "db.user.*|")
assert.Contains(t, str, "db.user.add|")
assert.True(t, strings.Count(str, "|") == 3)
})
buf.Reset()
t.Run("fire case2", func(t *testing.T) {
err, e := em.Fire("db.user.del", event.M{"user": "inhere"})
assert.NoError(t, err)
assert.Equal(t, "inhere", e.Get("user"))
str := buf.String()
fmt.Println(str)
assert.Contains(t, str, "db.**|")
assert.Contains(t, str, "db.user.*|")
assert.True(t, strings.Count(str, "|") == 2)
})
buf.Reset()
em.RemoveListeners("db.user.*")
assert.False(t, em.HasListeners("db.user.*"))
em.Listen("*", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("*|")
return nil
}), 3)
em.Listen("db.*.update", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("db.*.update|")
return nil
}), 4)
t.Run("fire case3", func(t *testing.T) {
err, e := em.Fire("db.user.update", event.M{"user": "inhere"})
assert.NoError(t, err)
assert.Equal(t, "inhere", e.Get("user"))
str := buf.String()
fmt.Println(str)
assert.Contains(t, str, "*|")
assert.Contains(t, str, "db.**|")
assert.Contains(t, str, "db.*.update|")
assert.True(t, strings.Count(str, "|") == 3)
})
buf.Reset()
t.Run("not-exist", func(t *testing.T) {
err, e := em.Fire("not-exist", event.M{"user": "inhere"})
assert.NoError(t, err)
assert.Equal(t, "inhere", e.Get("user"))
str := buf.String()
fmt.Println(str)
assert.Equal(t, "*|", str)
})
}
func TestManager_Fire_AllNode(t *testing.T) {
em := event.NewManager("test", event.UsePathMode, event.EnableLock(false))
buf := new(bytes.Buffer)
em.Listen("**.add", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("**.add|")
return nil
}))
err, e := em.Trigger("db.user.add", event.M{"user": "inhere"})
assert.NoError(t, err)
assert.Equal(t, "inhere", e.Get("user"))
str := buf.String()
assert.Equal(t, "**.add|", str)
}
func TestManager_FireC(t *testing.T) {
em := event.NewManager("test", event.UsePathMode, event.EnableLock(true))
defer func(em *event.Manager) {
_ = em.Close()
}(em)
buf := new(bytes.Buffer)
em.Listen("db.user.*", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("db.user.*|")
return nil
}))
em.Listen("db.**", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("db.**|")
return nil
}), 1)
em.Listen("db.user.add", event.ListenerFunc(func(e event.Event) error {
_, _ = buf.WriteString("db.user.add|")
return nil
}), 2)
assert.True(t, em.HasListeners("db.user.*"))
em.FireC("db.user.add", event.M{"user": "inhere"})
time.Sleep(time.Millisecond * 100) // wait for async
str := buf.String()
fmt.Println(str)
assert.Contains(t, str, "db.**|")
assert.Contains(t, str, "db.user.*|")
assert.Contains(t, str, "db.user.add|")
assert.True(t, strings.Count(str, "|") == 3)
buf.Reset()
em.WithOptions(func(o *event.Options) {
o.ChannelSize = 0
o.ConsumerNum = 0
})
em.Async("not-exist", event.M{"user": "inhere"})
time.Sleep(time.Millisecond * 100) // wait for async
assert.Empty(t, buf.String())
}
func TestManager_Wait(t *testing.T) {
em := event.NewManager("test", event.UsePathMode)
buf := new(bytes.Buffer)
em.Listen("db.user.*", event.ListenerFunc(func(e event.Event) error {
time.Sleep(time.Millisecond * 200)
_, _ = buf.WriteString("db.user.*|")
return nil
}))
assert.True(t, em.HasListeners("db.user.*"))
em.Async("db.user.add", event.M{"user": "inhere"})
assert.NoError(t, em.CloseWait())
str := buf.String()
fmt.Println(str)
assert.Equal(t, "db.user.*|", str)
buf.Reset()
}
func TestManager_Once(t *testing.T) {
em := event.NewManager("test")
em.Once("evt1", event.ListenerFunc(emptyListener))
assert.True(t, em.HasListeners("evt1"))
em.Trigger("evt1", nil)
assert.False(t, em.HasListeners("evt1"))
}