Search Apps Documentation Source Content File Folder Download Copy Actions Download

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}