Skip to content

Commit 2ad37f9

Browse files
committed
fix: TrackingTarget.UnsubscribeAll does not remove handlers
Handlers are unsubscribed from a wrapped target, but the subscription list is not cleared.
1 parent 6048270 commit 2ad37f9

File tree

2 files changed

+157
-0
lines changed

2 files changed

+157
-0
lines changed

pievent/pievent.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,5 @@ func (t *TrackingTarget[T]) UnsubscribeAll() {
218218
for _, handler := range t.handlers {
219219
t.wrappedTarget.Unsubscribe(handler)
220220
}
221+
t.handlers = nil
221222
}

pievent/pievent_test.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,91 @@ import (
77
"testing"
88

99
"github.com/stretchr/testify/assert"
10+
"github.com/stretchr/testify/require"
1011

1112
"github.com/elgopher/pi/pievent"
1213
)
1314

15+
const event = "event"
16+
17+
func TestTarget_Publish(t *testing.T) {
18+
t.Run("should publish event to subscriber synchronously", func(t *testing.T) {
19+
target := pievent.NewTarget[string]()
20+
var subscriber Subscriber
21+
target.Subscribe(event, subscriber.Handler)
22+
// when
23+
target.Publish(event)
24+
// then
25+
subscriber.AssertEventReceived(t, event)
26+
})
27+
28+
t.Run("should publish event to all subscribers", func(t *testing.T) {
29+
var subscriber1, subscriber2 Subscriber
30+
31+
target := pievent.NewTarget[string]()
32+
target.Subscribe(event, subscriber1.Handler)
33+
target.Subscribe(event, subscriber2.Handler)
34+
// when
35+
target.Publish(event)
36+
// then
37+
subscriber1.AssertEventReceived(t, event)
38+
subscriber2.AssertEventReceived(t, event)
39+
})
40+
41+
t.Run("should not publish event to subscriber listening to a different event", func(t *testing.T) {
42+
var subscriber1, subscriber2 Subscriber
43+
44+
target := pievent.NewTarget[string]()
45+
target.Subscribe(event, subscriber1.Handler)
46+
target.Subscribe("other", subscriber2.Handler)
47+
// when
48+
target.Publish(event)
49+
// then
50+
subscriber2.AssertNoEventReceived(t)
51+
})
52+
53+
t.Run("should publish event to subscriber listening for all events", func(t *testing.T) {
54+
t.Run("subscribe with zero-value event", func(t *testing.T) {
55+
var subscriber Subscriber
56+
57+
target := pievent.NewTarget[string]()
58+
target.Subscribe("", subscriber.Handler) // zero-value string register subscriber for all events
59+
// when
60+
target.Publish(event)
61+
// then
62+
subscriber.AssertEventReceived(t, event)
63+
})
64+
65+
t.Run("subscribe all", func(t *testing.T) {
66+
var subscriber Subscriber
67+
68+
target := pievent.NewTarget[string]()
69+
target.SubscribeAll(subscriber.Handler)
70+
// when
71+
target.Publish(event)
72+
// then
73+
subscriber.AssertEventReceived(t, event)
74+
})
75+
})
76+
}
77+
78+
func TestTarget_IsSubscribed(t *testing.T) {
79+
t.Run("should return true if subscriber is subscribed", func(t *testing.T) {
80+
target := pievent.NewTarget[string]()
81+
var subscriber Subscriber
82+
handler := target.Subscribe("", subscriber.Handler)
83+
assert.True(t, target.IsSubscribed(handler))
84+
})
85+
86+
t.Run("should return false if subscriber is no longer subscribed", func(t *testing.T) {
87+
target := pievent.NewTarget[string]()
88+
var subscriber Subscriber
89+
handler := target.Subscribe("", subscriber.Handler)
90+
target.Unsubscribe(handler)
91+
assert.False(t, target.IsSubscribed(handler))
92+
})
93+
}
94+
1495
func TestEventHandler_Unsubscribe(t *testing.T) {
1596
t.Run("should not unsubscribe other handler", func(t *testing.T) {
1697
target := pievent.NewTarget[string]()
@@ -25,3 +106,78 @@ func TestEventHandler_Unsubscribe(t *testing.T) {
25106
assert.True(t, eventReceived)
26107
})
27108
}
109+
110+
func TestTrackingTarget_Subscribe(t *testing.T) {
111+
t.Run("should return all subscription handlers", func(t *testing.T) {
112+
var subscriber1, subscriber2 Subscriber
113+
114+
target := pievent.NewTarget[string]()
115+
trackedTarget := pievent.Track(target)
116+
// when
117+
handler1 := trackedTarget.Subscribe("1", subscriber1.Handler)
118+
handler2 := trackedTarget.Subscribe("2", subscriber2.Handler)
119+
// then
120+
handlers := trackedTarget.Handlers()
121+
assert.Equal(t, []pievent.Handler{handler1, handler2}, handlers)
122+
// and
123+
assert.True(t, trackedTarget.IsSubscribed(handler1))
124+
assert.True(t, trackedTarget.IsSubscribed(handler2))
125+
})
126+
}
127+
128+
func TestTrackingTarget_UnsubscribeAll(t *testing.T) {
129+
t.Run("should unsubscribe all handlers", func(t *testing.T) {
130+
var subscriber1, subscriber2 Subscriber
131+
132+
target := pievent.NewTarget[string]()
133+
trackedTarget := pievent.Track(target)
134+
handler1 := trackedTarget.Subscribe(event, subscriber1.Handler)
135+
handler2 := trackedTarget.Subscribe(event, subscriber2.Handler)
136+
// when
137+
trackedTarget.UnsubscribeAll()
138+
// then
139+
assert.Empty(t, trackedTarget.Handlers())
140+
// and
141+
assert.False(t, trackedTarget.IsSubscribed(handler1))
142+
assert.False(t, trackedTarget.IsSubscribed(handler2))
143+
// and
144+
target.Publish(event)
145+
subscriber1.AssertNoEventReceived(t)
146+
subscriber2.AssertNoEventReceived(t)
147+
})
148+
}
149+
150+
func TestTrackingTarget_Unsubscribe(t *testing.T) {
151+
t.Run("should unsubscribe handler", func(t *testing.T) {
152+
var subscriber Subscriber
153+
154+
target := pievent.NewTarget[string]()
155+
trackedTarget := pievent.Track(target)
156+
handler := trackedTarget.Subscribe(event, subscriber.Handler)
157+
// when
158+
trackedTarget.Unsubscribe(handler)
159+
// then
160+
assert.Empty(t, trackedTarget.Handlers())
161+
// and
162+
target.Publish(event)
163+
subscriber.AssertNoEventReceived(t)
164+
assert.False(t, trackedTarget.IsSubscribed(handler))
165+
})
166+
}
167+
168+
type Subscriber struct {
169+
eventReceived []string
170+
}
171+
172+
func (s *Subscriber) Handler(e string, handler pievent.Handler) {
173+
s.eventReceived = append(s.eventReceived, e)
174+
}
175+
176+
func (s *Subscriber) AssertEventReceived(t *testing.T, event string) {
177+
require.Len(t, s.eventReceived, 1)
178+
assert.Equal(t, event, s.eventReceived[0])
179+
}
180+
181+
func (s *Subscriber) AssertNoEventReceived(t *testing.T) {
182+
require.Len(t, s.eventReceived, 0)
183+
}

0 commit comments

Comments
 (0)