broker_test.gno
6.05 Kb ยท 313 lines
1package message_test
2
3import (
4 "testing"
5
6 "gno.land/p/jeronimoalbi/expect"
7 "gno.land/p/jeronimo000/message"
8)
9
10var (
11 _ message.Subscriber = (*message.Broker)(nil)
12 _ message.Publisher = (*message.Broker)(nil)
13)
14
15func TestBrokerTopics(t *testing.T) {
16 broker := message.NewBroker()
17 expect.
18 Value(t, len(broker.Topics())).
19 AsInt().
20 ToEqual(0)
21
22 cb := func(message.Message) {}
23 broker.Subscribe("foo", cb)
24 broker.Subscribe("bar", cb)
25 broker.Subscribe("baz", cb)
26 broker.Subscribe(message.TopicAll, cb)
27 topics := broker.Topics()
28
29 expect.
30 Value(t, len(topics)).
31 AsInt().
32 ToEqual(3)
33 expect.
34 Value(t, string(topics[0])).
35 AsString().
36 ToEqual("bar")
37 expect.
38 Value(t, string(topics[1])).
39 AsString().
40 ToEqual("baz")
41 expect.
42 Value(t, string(topics[2])).
43 AsString().
44 ToEqual("foo")
45}
46
47func TestBrokerPublish(t *testing.T) {
48 tests := []struct {
49 name string
50 subscribe, publish message.Topic
51 data any
52 message *message.Message
53 err error
54 }{
55 {
56 name: "publishes subscribed topic",
57 subscribe: "foo",
58 publish: "foo",
59 data: "foo's data",
60 message: &message.Message{
61 Topic: "foo",
62 Data: "foo's data",
63 },
64 },
65 {
66 name: "publishes all topics",
67 subscribe: message.TopicAll,
68 publish: "foo",
69 data: "foo's data",
70 message: &message.Message{
71 Topic: "foo",
72 Data: "foo's data",
73 },
74 },
75 {
76 name: "invalid topic",
77 subscribe: "foo",
78 publish: message.TopicAll,
79 err: message.ErrInvalidTopic,
80 },
81 {
82 name: "no topic",
83 subscribe: "foo",
84 publish: "",
85 err: message.ErrRequiredTopic,
86 },
87 }
88
89 for _, tt := range tests {
90 t.Run(tt.name, func(t *testing.T) {
91 // Arrange
92 var msg *message.Message
93 broker := message.NewBroker()
94 broker.Subscribe(tt.subscribe, func(m message.Message) { msg = &m })
95
96 // Act
97 err := broker.Publish(tt.publish, tt.data)
98
99 // Assert
100 if tt.err != nil {
101 expect.
102 Func(t, func() error { return err }).
103 WithFailPrefix("expect a publish error").
104 ToFail().
105 WithError(tt.err)
106 expect.
107 Value(t, istypednil(msg)).
108 WithFailPrefix("expect callback not to be called").
109 AsBoolean().
110 ToBeTruthy()
111 return
112 }
113
114 expect.
115 Value(t, err).
116 WithFailPrefix("expect no publish error").
117 ToBeNil()
118 expect.
119 Value(t, msg).
120 WithFailPrefix("expect callback to be called").
121 Not().ToBeNil()
122 expect.
123 Value(t, string(msg.Topic)).
124 WithFailPrefix("expect message topic to match").
125 AsString().
126 ToEqual(string(tt.message.Topic))
127 expect.
128 Value(t, msg.Data).
129 WithFailPrefix("expect message data to match").
130 AsString().
131 ToEqual(tt.message.Data.(string))
132 })
133 }
134}
135
136func TestBrokerSubscribe(t *testing.T) {
137 cb := func(message.Message) {}
138 tests := []struct {
139 name string
140 setup func(*message.Broker)
141 topic message.Topic
142 id int64
143 callback message.Callback
144 err error
145 }{
146 {
147 name: "single subscription",
148 topic: "foo",
149 id: 1,
150 callback: cb,
151 },
152 {
153 name: "existing subscriptions",
154 setup: func(b *message.Broker) {
155 b.Subscribe("foo", cb)
156 },
157 topic: "foo",
158 id: 2,
159 callback: cb,
160 },
161 {
162 name: "other subscription topics",
163 setup: func(b *message.Broker) {
164 b.Subscribe("foo", cb)
165 },
166 topic: "bar",
167 id: 1,
168 callback: cb,
169 },
170 {
171 name: "no topic",
172 topic: "",
173 err: message.ErrRequiredTopic,
174 },
175 {
176 name: "no callback",
177 topic: "foo",
178 callback: nil,
179 err: message.ErrRequiredCallback,
180 },
181 }
182
183 for _, tt := range tests {
184 t.Run(tt.name, func(t *testing.T) {
185 // Arrange
186 broker := message.NewBroker()
187 if tt.setup != nil {
188 tt.setup(broker)
189 }
190
191 // Act
192 id, err := broker.Subscribe(tt.topic, tt.callback)
193
194 // Assert
195 if tt.err != nil {
196 expect.
197 Func(t, func() error { return err }).
198 WithFailPrefix("expect a subscribe error").
199 ToFail().
200 WithError(tt.err)
201 expect.
202 Value(t, id).
203 WithFailPrefix("expect zero ID").
204 AsInt().
205 ToEqual(0)
206 return
207 }
208
209 expect.
210 Value(t, err).
211 WithFailPrefix("expect no subscribe error").
212 ToBeNil()
213 expect.
214 Value(t, id).
215 WithFailPrefix("expect ID to match").
216 AsInt().
217 ToEqual(tt.id)
218 })
219 }
220}
221
222func TestBrokerUnsubscribe(t *testing.T) {
223 cb := func(message.Message) {}
224 tests := []struct {
225 name string
226 setup func(*message.Broker)
227 topic message.Topic
228 id int
229 errMsg string
230 }{
231 {
232 name: "single subscription",
233 setup: func(b *message.Broker) {
234 b.Subscribe("foo", cb)
235 },
236 topic: "foo",
237 id: 1,
238 },
239 {
240 name: "multiple subscriptions",
241 setup: func(b *message.Broker) {
242 b.Subscribe("foo", cb)
243 b.Subscribe("foo", cb)
244 },
245 topic: "foo",
246 id: 2,
247 },
248 {
249 name: "other subscription topics",
250 setup: func(b *message.Broker) {
251 b.Subscribe("foo", cb)
252 b.Subscribe("bar", cb)
253 },
254 topic: "foo",
255 id: 1,
256 },
257 {
258 name: "not found",
259 topic: "foo",
260 id: 1,
261 errMsg: "message topic not found: foo",
262 },
263 {
264 name: "no topic",
265 topic: "",
266 errMsg: message.ErrRequiredTopic.Error(),
267 },
268 {
269 name: "no subscription ID",
270 topic: "foo",
271 id: 0,
272 errMsg: message.ErrRequiredSubscriptionID.Error(),
273 },
274 }
275
276 for _, tt := range tests {
277 t.Run(tt.name, func(t *testing.T) {
278 // Arrange
279 broker := message.NewBroker()
280 if tt.setup != nil {
281 tt.setup(broker)
282 }
283
284 // Act
285 unsubscribed, err := broker.Unsubscribe(tt.topic, tt.id)
286
287 // Assert
288 if tt.errMsg != "" {
289 expect.
290 Func(t, func() error { return err }).
291 WithFailPrefix("expect a subscribe error").
292 ToFail().
293 WithMessage(tt.errMsg)
294 expect.
295 Value(t, unsubscribed).
296 WithFailPrefix("expect unsubscribe to fail").
297 AsBoolean().
298 ToBeFalsy()
299 return
300 }
301
302 expect.
303 Value(t, err).
304 WithFailPrefix("expect no unsubscribe error").
305 ToBeNil()
306 expect.
307 Value(t, unsubscribed).
308 WithFailPrefix("expect unsubscribe to succeed").
309 AsBoolean().
310 ToBeTruthy()
311 })
312 }
313}