Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pievent/pievent.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,4 +218,5 @@ func (t *TrackingTarget[T]) UnsubscribeAll() {
for _, handler := range t.handlers {
t.wrappedTarget.Unsubscribe(handler)
}
t.handlers = nil
}
158 changes: 158 additions & 0 deletions pievent/pievent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,91 @@ import (
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"github.com/elgopher/pi/pievent"
)

const event = "event"

func TestTarget_Publish(t *testing.T) {
t.Run("should publish event to subscriber synchronously", func(t *testing.T) {
target := pievent.NewTarget[string]()
var subscriber Subscriber
target.Subscribe(event, subscriber.Handler)
// when
target.Publish(event)
// then
subscriber.AssertEventReceived(t, event)
})

t.Run("should publish event to all subscribers", func(t *testing.T) {
var subscriber1, subscriber2 Subscriber

target := pievent.NewTarget[string]()
target.Subscribe(event, subscriber1.Handler)
target.Subscribe(event, subscriber2.Handler)
// when
target.Publish(event)
// then
subscriber1.AssertEventReceived(t, event)
subscriber2.AssertEventReceived(t, event)
})

t.Run("should not publish event to subscriber listening to a different event", func(t *testing.T) {
var subscriber1, subscriber2 Subscriber

target := pievent.NewTarget[string]()
target.Subscribe(event, subscriber1.Handler)
target.Subscribe("other", subscriber2.Handler)
// when
target.Publish(event)
// then
subscriber2.AssertNoEventReceived(t)
})

t.Run("should publish event to subscriber listening for all events", func(t *testing.T) {
t.Run("subscribe with zero-value event", func(t *testing.T) {
var subscriber Subscriber

target := pievent.NewTarget[string]()
target.Subscribe("", subscriber.Handler) // zero-value string register subscriber for all events
// when
target.Publish(event)
// then
subscriber.AssertEventReceived(t, event)
})

t.Run("subscribe all", func(t *testing.T) {
var subscriber Subscriber

target := pievent.NewTarget[string]()
target.SubscribeAll(subscriber.Handler)
// when
target.Publish(event)
// then
subscriber.AssertEventReceived(t, event)
})
})
}

func TestTarget_IsSubscribed(t *testing.T) {
t.Run("should return true if subscriber is subscribed", func(t *testing.T) {
target := pievent.NewTarget[string]()
var subscriber Subscriber
handler := target.Subscribe("", subscriber.Handler)
assert.True(t, target.IsSubscribed(handler))
})

t.Run("should return false if subscriber is no longer subscribed", func(t *testing.T) {
target := pievent.NewTarget[string]()
var subscriber Subscriber
handler := target.Subscribe("", subscriber.Handler)
target.Unsubscribe(handler)
assert.False(t, target.IsSubscribed(handler))
})
}

func TestEventHandler_Unsubscribe(t *testing.T) {
t.Run("should not unsubscribe other handler", func(t *testing.T) {
target := pievent.NewTarget[string]()
Expand All @@ -25,3 +106,80 @@ func TestEventHandler_Unsubscribe(t *testing.T) {
assert.True(t, eventReceived)
})
}

func TestTrackingTarget_Subscribe(t *testing.T) {
t.Run("should return all subscription handlers", func(t *testing.T) {
var subscriber1, subscriber2 Subscriber

target := pievent.NewTarget[string]()
trackedTarget := pievent.Track(target)
// when
handler1 := trackedTarget.Subscribe("1", subscriber1.Handler)
handler2 := trackedTarget.Subscribe("2", subscriber2.Handler)
// then
handlers := trackedTarget.Handlers()
assert.Equal(t, []pievent.Handler{handler1, handler2}, handlers)
// and
assert.True(t, trackedTarget.IsSubscribed(handler1))
assert.True(t, trackedTarget.IsSubscribed(handler2))
})
}

func TestTrackingTarget_UnsubscribeAll(t *testing.T) {
t.Run("should unsubscribe all handlers", func(t *testing.T) {
var subscriber1, subscriber2 Subscriber

target := pievent.NewTarget[string]()
trackedTarget := pievent.Track(target)
handler1 := trackedTarget.Subscribe(event, subscriber1.Handler)
handler2 := trackedTarget.Subscribe(event, subscriber2.Handler)
// when
trackedTarget.UnsubscribeAll()
// then
assert.Empty(t, trackedTarget.Handlers())
// and
assert.False(t, trackedTarget.IsSubscribed(handler1))
assert.False(t, trackedTarget.IsSubscribed(handler2))
// and
target.Publish(event)
subscriber1.AssertNoEventReceived(t)
subscriber2.AssertNoEventReceived(t)
})
}

func TestTrackingTarget_Unsubscribe(t *testing.T) {
t.Run("should unsubscribe handler", func(t *testing.T) {
var subscriber Subscriber

target := pievent.NewTarget[string]()
trackedTarget := pievent.Track(target)
handler := trackedTarget.Subscribe(event, subscriber.Handler)
// when
trackedTarget.Unsubscribe(handler)
// then
assert.Empty(t, trackedTarget.Handlers())
// and
target.Publish(event)
subscriber.AssertNoEventReceived(t)
assert.False(t, trackedTarget.IsSubscribed(handler))
})
}

type Subscriber struct {
eventReceived []string
}

func (s *Subscriber) Handler(e string, handler pievent.Handler) {
s.eventReceived = append(s.eventReceived, e)
}

func (s *Subscriber) AssertEventReceived(t *testing.T, event string) {
t.Helper()
require.Len(t, s.eventReceived, 1)
assert.Equal(t, event, s.eventReceived[0])
}

func (s *Subscriber) AssertNoEventReceived(t *testing.T) {
t.Helper()
require.Empty(t, s.eventReceived)
}