go-eventbus/basic_test.go
Łukasz Magiera 258d9068d3 MVP
2019-06-13 08:51:54 +02:00

141 lines
2.0 KiB
Go

package event
import (
"sync"
"testing"
"time"
)
type EventA struct{}
type EventB int
func TestEmit(t *testing.T) {
bus := NewBus()
events, cancel, err := bus.Subscribe(new(EventA))
if err != nil {
t.Fatal(err)
}
go func() {
defer cancel()
<-events
}()
emit, cancel, err := bus.Emitter(new(EventA))
if err != nil {
t.Fatal(err)
}
defer cancel()
emit(EventA{})
}
func TestSub(t *testing.T) {
bus := NewBus()
events, cancel, err := bus.Subscribe(new(EventB))
if err != nil {
t.Fatal(err)
}
var event EventB
var wait sync.WaitGroup
wait.Add(1)
go func() {
defer cancel()
event = (<-events).(EventB)
wait.Done()
}()
emit, cancel, err := bus.Emitter(new(EventB))
if err != nil {
t.Fatal(err)
}
defer cancel()
emit(EventB(7))
wait.Wait()
if event != 7 {
t.Error("got wrong event")
}
}
func TestEmitNoSubNoBlock(t *testing.T) {
bus := NewBus()
emit, cancel, err := bus.Emitter(new(EventA))
if err != nil {
t.Fatal(err)
}
defer cancel()
emit(EventA{})
}
func TestEmitOnClosed(t *testing.T) {
bus := NewBus()
emit, cancel, err := bus.Emitter(new(EventA))
if err != nil {
t.Fatal(err)
}
cancel()
defer func() {
r := recover()
if r == nil {
t.Errorf("expected panic")
}
if r.(string) != "emitter is closed" {
t.Error("unexpected message")
}
}()
emit(EventA{})
}
func TestClosingRaces(t *testing.T) {
subs := 50000
emits := 50000
var wg sync.WaitGroup
var lk sync.RWMutex
lk.Lock()
wg.Add(subs + emits)
bus := NewBus()
for i := 0; i < subs; i++ {
go func() {
lk.RLock()
defer lk.RUnlock()
_, cancel, _ := bus.Subscribe(new(EventA))
time.Sleep(10 * time.Millisecond)
cancel()
wg.Done()
}()
}
for i := 0; i < emits; i++ {
go func() {
lk.RLock()
defer lk.RUnlock()
_, cancel, _ := bus.Emitter(new(EventA))
time.Sleep(10 * time.Millisecond)
cancel()
wg.Done()
}()
}
time.Sleep(10 * time.Millisecond)
lk.Unlock() // start everything
wg.Wait()
}