package events import ( "encoding/json" "sync/atomic" "testing" ) func TestMatch(t *testing.T) { tests := []struct { label, pattern string want bool }{ {"chat.message.abc", "chat.message.abc", true}, {"chat.message.abc", "chat.message.*", true}, {"chat.message.abc", "chat.*", true}, {"chat.message.abc", "*", true}, {"chat.message.abc", "chat.message.xyz", false}, {"chat.message.abc", "channel.message.*", false}, {"chat.message.abc", "chat.message", false}, {"ping", "ping", true}, {"ping", "pong", false}, {"plugin.hook.pre_completion", "plugin.hook.*", true}, {"plugin.hook.pre_completion", "plugin.*", true}, } for _, tt := range tests { got := match(tt.label, tt.pattern) if got != tt.want { t.Errorf("match(%q, %q) = %v, want %v", tt.label, tt.pattern, got, tt.want) } } } func TestBusPublishExact(t *testing.T) { bus := NewBus() var count int32 bus.Subscribe("chat.message.abc", func(e Event) { atomic.AddInt32(&count, 1) }) bus.Publish(Event{Label: "chat.message.abc", Payload: json.RawMessage(`{}`)}) bus.Publish(Event{Label: "chat.message.xyz", Payload: json.RawMessage(`{}`)}) if atomic.LoadInt32(&count) != 1 { t.Errorf("expected 1 dispatch, got %d", count) } } func TestBusPublishWildcard(t *testing.T) { bus := NewBus() var count int32 bus.Subscribe("chat.message.*", func(e Event) { atomic.AddInt32(&count, 1) }) bus.Publish(Event{Label: "chat.message.abc", Payload: json.RawMessage(`{}`)}) bus.Publish(Event{Label: "chat.message.xyz", Payload: json.RawMessage(`{}`)}) bus.Publish(Event{Label: "chat.typing.abc", Payload: json.RawMessage(`{}`)}) if atomic.LoadInt32(&count) != 2 { t.Errorf("expected 2 dispatches, got %d", count) } } func TestBusUnsubscribe(t *testing.T) { bus := NewBus() var count int32 unsub := bus.Subscribe("test.event", func(e Event) { atomic.AddInt32(&count, 1) }) bus.Publish(Event{Label: "test.event", Payload: json.RawMessage(`{}`)}) unsub() bus.Publish(Event{Label: "test.event", Payload: json.RawMessage(`{}`)}) if atomic.LoadInt32(&count) != 1 { t.Errorf("expected 1 dispatch after unsub, got %d", count) } } func TestBusGlobalWildcard(t *testing.T) { bus := NewBus() var count int32 bus.Subscribe("*", func(e Event) { atomic.AddInt32(&count, 1) }) bus.Publish(Event{Label: "chat.message.abc", Payload: json.RawMessage(`{}`)}) bus.Publish(Event{Label: "system.notify", Payload: json.RawMessage(`{}`)}) bus.Publish(Event{Label: "plugin.hook.pre_completion", Payload: json.RawMessage(`{}`)}) if atomic.LoadInt32(&count) != 3 { t.Errorf("expected 3 dispatches, got %d", count) } } func TestRouteFor(t *testing.T) { tests := []struct { label string want Direction }{ {"chat.message.abc", DirBoth}, {"chat.typing.abc", DirBoth}, {"system.notify", DirToClient}, {"plugin.hook.pre_completion", DirLocal}, {"internal.db.write", DirLocal}, {"unknown.event", DirLocal}, // default {"ping", DirFromClient}, {"pong", DirToClient}, } for _, tt := range tests { got := RouteFor(tt.label) if got != tt.want { t.Errorf("RouteFor(%q) = %d, want %d", tt.label, got, tt.want) } } }