comq 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yaml +1 -1
- package/features/rpc.streams.feature +9 -9
- package/features/rpc.streams.shards.feature +3 -3
- package/features/steps/broker.js +3 -3
- package/features/steps/events.js +2 -1
- package/features/steps/rpc.js +6 -6
- package/lerna.json +1 -1
- package/package.json +10 -9
- package/readme.md +4 -17
- package/source/.io/ReplyStream.js +12 -15
- package/source/channel.js +11 -10
- package/source/connection.js +7 -14
- package/source/io.js +56 -36
- package/source/shards/channel.js +6 -6
- package/types/io.d.ts +1 -4
- package/features/steps/.test/backpressure.test.js +0 -79
- package/features/steps/.test/broker.test.js +0 -101
- package/features/steps/.test/command.mock.js +0 -5
- package/features/steps/.test/comq.mock.js +0 -10
- package/features/steps/.test/connection.test.js +0 -285
- package/features/steps/.test/context.mock.js +0 -14
- package/features/steps/.test/context.test.js +0 -74
- package/features/steps/.test/events.test.js +0 -279
- package/features/steps/.test/io.mock.js +0 -14
- package/features/steps/.test/poison.test.js +0 -40
- package/features/steps/.test/rpc.test.js +0 -261
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { AssertionError } = require('node:assert')
|
|
4
|
-
const { randomBytes } = require('node:crypto')
|
|
5
|
-
const { generate } = require('randomstring')
|
|
6
|
-
const { promex, timeout, random } = require('@toa.io/generic')
|
|
7
|
-
const tomato = require('@toa.io/tomato')
|
|
8
|
-
const { dump } = require('@toa.io/yaml')
|
|
9
|
-
const { io } = require('./io.mock')
|
|
10
|
-
const mock = { tomato }
|
|
11
|
-
|
|
12
|
-
jest.mock('@cucumber/cucumber', () => mock.tomato)
|
|
13
|
-
|
|
14
|
-
require('../events')
|
|
15
|
-
|
|
16
|
-
/** @type {comq.features.Context} */
|
|
17
|
-
let context
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
jest.clearAllMocks()
|
|
21
|
-
|
|
22
|
-
context = /** @type {comq.features.Context} */ { io }
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
describe('Given (that ){token} is consuming events from the {token} exchange', () => {
|
|
26
|
-
const step = tomato.steps.Gi('(that ){token} is consuming events from the {token} exchange')
|
|
27
|
-
|
|
28
|
-
it('should be', async () => undefined)
|
|
29
|
-
|
|
30
|
-
const exchange = generate()
|
|
31
|
-
const group = generate()
|
|
32
|
-
|
|
33
|
-
let consumer
|
|
34
|
-
|
|
35
|
-
beforeEach(async () => {
|
|
36
|
-
await step.call(context, group, exchange)
|
|
37
|
-
|
|
38
|
-
consumer = io.consume.mock.calls[0]?.[2]
|
|
39
|
-
|
|
40
|
-
expect(consumer).toBeInstanceOf(Function)
|
|
41
|
-
})
|
|
42
|
-
|
|
43
|
-
it('should consume', async () => {
|
|
44
|
-
expect(io.consume).toHaveBeenCalledTimes(1)
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
it('should store event in context', async () => {
|
|
48
|
-
const payload = generate()
|
|
49
|
-
|
|
50
|
-
await consumer(payload)
|
|
51
|
-
|
|
52
|
-
expect(context.consumed[group]).toStrictEqual(expect.objectContaining({ payload }))
|
|
53
|
-
})
|
|
54
|
-
|
|
55
|
-
it('should store event properties', async () => {
|
|
56
|
-
const payload = generate()
|
|
57
|
-
const properties = generate()
|
|
58
|
-
|
|
59
|
-
await consumer(payload, properties)
|
|
60
|
-
|
|
61
|
-
expect(context.consumed[group]).toStrictEqual({ payload, properties })
|
|
62
|
-
})
|
|
63
|
-
})
|
|
64
|
-
|
|
65
|
-
describe('Given {token} consuming events from the {token} exchange is expected', () => {
|
|
66
|
-
tomato.steps.Gi('{token} consuming events from the {token} exchange is expected')
|
|
67
|
-
|
|
68
|
-
it('should be', async () => undefined)
|
|
69
|
-
})
|
|
70
|
-
|
|
71
|
-
describe('Given (that )events are exclusively consumed from the {token} exchange', () => {
|
|
72
|
-
tomato.steps.Gi('(that )events are exclusively consumed from the {token} exchange')
|
|
73
|
-
|
|
74
|
-
it('should be', async () => undefined)
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
describe('When an event is emitted to the {token} exchange', () => {
|
|
78
|
-
const step = tomato.steps.Wh('an event is emitted to the {token} exchange')
|
|
79
|
-
|
|
80
|
-
it('should be', async () => undefined)
|
|
81
|
-
|
|
82
|
-
const exchange = generate()
|
|
83
|
-
|
|
84
|
-
beforeEach(async () => {
|
|
85
|
-
await step.call(context, exchange)
|
|
86
|
-
})
|
|
87
|
-
|
|
88
|
-
it('should store event', async () => {
|
|
89
|
-
expect(context.published).toBeDefined()
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
it('should emit event', async () => {
|
|
93
|
-
expect(io.emit.mock.calls[0][0]).toStrictEqual(exchange)
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
it('should wait for context.expected', async () => {
|
|
97
|
-
jest.clearAllMocks()
|
|
98
|
-
|
|
99
|
-
context.consumptionPromise = promex()
|
|
100
|
-
|
|
101
|
-
let resolved = false
|
|
102
|
-
|
|
103
|
-
setImmediate(() => {
|
|
104
|
-
expect(io.emit).not.toHaveBeenCalled()
|
|
105
|
-
|
|
106
|
-
resolved = true
|
|
107
|
-
context.consumptionPromise.resolve()
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
await step.call(context, exchange)
|
|
111
|
-
|
|
112
|
-
expect(io.emit).toHaveBeenCalled()
|
|
113
|
-
expect(resolved).toStrictEqual(true)
|
|
114
|
-
})
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
describe('When an event is emitted to the {token} exchange with properties:', () => {
|
|
118
|
-
const step = tomato.steps.Wh('an event is emitted to the {token} exchange with properties:')
|
|
119
|
-
|
|
120
|
-
it('should be', async () => undefined)
|
|
121
|
-
|
|
122
|
-
const exchange = generate()
|
|
123
|
-
const properties = { [generate()]: generate() }
|
|
124
|
-
const yaml = dump(properties)
|
|
125
|
-
|
|
126
|
-
beforeEach(async () => {
|
|
127
|
-
await step.call(context, exchange, yaml)
|
|
128
|
-
})
|
|
129
|
-
|
|
130
|
-
it('should store event', async () => {
|
|
131
|
-
expect(context.published).toBeDefined()
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
it('should emit event', async () => {
|
|
135
|
-
expect(io.emit).toHaveBeenCalledWith(exchange, expect.anything(), properties)
|
|
136
|
-
})
|
|
137
|
-
})
|
|
138
|
-
|
|
139
|
-
describe('Then {token} receives the event', () => {
|
|
140
|
-
const step = tomato.steps.Th('{token} receives the event')
|
|
141
|
-
|
|
142
|
-
const payload = randomBytes(8)
|
|
143
|
-
const group = generate()
|
|
144
|
-
|
|
145
|
-
beforeEach(() => {
|
|
146
|
-
context.consumed = { [group]: { payload } }
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
it('should be', async () => undefined)
|
|
150
|
-
|
|
151
|
-
it('should throw if not consumed', async () => {
|
|
152
|
-
context.published = randomBytes(8)
|
|
153
|
-
|
|
154
|
-
await expect(step.call(context, group)).rejects.toThrow(AssertionError)
|
|
155
|
-
})
|
|
156
|
-
|
|
157
|
-
it('should pass if consumed', async () => {
|
|
158
|
-
context.published = payload
|
|
159
|
-
|
|
160
|
-
await expect(step.call(context, group)).resolves.not.toThrow()
|
|
161
|
-
})
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
describe('Then {token} receives the event with properties:', () => {
|
|
165
|
-
const step = tomato.steps.Th('{token} receives the event with properties:')
|
|
166
|
-
|
|
167
|
-
it('should be', async () => undefined)
|
|
168
|
-
|
|
169
|
-
const payload = randomBytes(8)
|
|
170
|
-
const properties = { headers: { [generate()]: generate() } }
|
|
171
|
-
const yaml = dump(properties)
|
|
172
|
-
const group = generate()
|
|
173
|
-
|
|
174
|
-
beforeEach(() => {
|
|
175
|
-
context.consumed = { [group]: { payload, properties } }
|
|
176
|
-
context.published = payload
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
it('should throw if does not match', async () => {
|
|
180
|
-
const properties = { headers: { [generate()]: generate() } }
|
|
181
|
-
const yaml = dump(properties)
|
|
182
|
-
|
|
183
|
-
await expect(step.call(context, group, yaml)).rejects.toThrow(AssertionError)
|
|
184
|
-
})
|
|
185
|
-
|
|
186
|
-
it('should pass if matches', async () => {
|
|
187
|
-
await expect(step.call(context, group, yaml)).resolves.not.toThrow()
|
|
188
|
-
})
|
|
189
|
-
})
|
|
190
|
-
|
|
191
|
-
describe('Then the event is received', () => {
|
|
192
|
-
const step = tomato.steps.Th('the event is received')
|
|
193
|
-
|
|
194
|
-
const payload = randomBytes(8)
|
|
195
|
-
const group = undefined
|
|
196
|
-
|
|
197
|
-
beforeEach(() => {
|
|
198
|
-
context.consumed = { [group]: { payload } }
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
it('should be', async () => undefined)
|
|
202
|
-
|
|
203
|
-
it('should throw if not consumed', async () => {
|
|
204
|
-
context.published = randomBytes(8)
|
|
205
|
-
|
|
206
|
-
await expect(step.call(context, group)).rejects.toThrow(AssertionError)
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
it('should pass if consumed', async () => {
|
|
210
|
-
context.published = payload
|
|
211
|
-
|
|
212
|
-
await expect(step.call(context, group)).resolves.not.toThrow()
|
|
213
|
-
})
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
describe('Given I\'m publishing {quantity}B events to the {token} exchange at {quantity}Hz', () => {
|
|
218
|
-
const step = tomato.steps.Gi('I\'m publishing {quantity}B events to the {token} exchange at {quantity}Hz')
|
|
219
|
-
|
|
220
|
-
it('should be', async () => undefined)
|
|
221
|
-
|
|
222
|
-
it('should publish events continuously', async () => {
|
|
223
|
-
context = /** @type {comq.features.Context} */ {
|
|
224
|
-
io: /** @type {jest.MockedObject<comq.IO>} */ { emit: jest.fn() },
|
|
225
|
-
requestsSent: [],
|
|
226
|
-
eventsPublishedCount: 0
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const bytesQ = '1k'
|
|
230
|
-
const exchange = generate()
|
|
231
|
-
const frequencyQ = '100'
|
|
232
|
-
|
|
233
|
-
step.call(context, bytesQ, exchange, frequencyQ)
|
|
234
|
-
|
|
235
|
-
await timeout(100)
|
|
236
|
-
|
|
237
|
-
const callsAmountExpected = [8, 9, 10, 11]
|
|
238
|
-
|
|
239
|
-
expect(callsAmountExpected).toContain(context.io.emit.mock.calls.length)
|
|
240
|
-
expect(context.publishing).toBeDefined()
|
|
241
|
-
expect(callsAmountExpected).toContain(context.eventsPublishedCount)
|
|
242
|
-
|
|
243
|
-
clearInterval(context.publishing)
|
|
244
|
-
})
|
|
245
|
-
})
|
|
246
|
-
|
|
247
|
-
describe('Then all events have been received', () => {
|
|
248
|
-
const step = tomato.steps.Th('all events have been received')
|
|
249
|
-
|
|
250
|
-
/** @type {jest.MockedObject<comq.features.Context>} */
|
|
251
|
-
let context
|
|
252
|
-
|
|
253
|
-
it('should be', async () => undefined)
|
|
254
|
-
|
|
255
|
-
beforeEach(async () => {
|
|
256
|
-
context = /** @type {jest.MockedObject<comq.features.Context>} */ {
|
|
257
|
-
eventsPublishedCount: random(100),
|
|
258
|
-
eventsConsumedCount: 100 + random()
|
|
259
|
-
}
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
it('should pass if events received', async () => {
|
|
263
|
-
context.eventsConsumedCount = context.eventsPublishedCount
|
|
264
|
-
|
|
265
|
-
await expect(step.call(context)).resolves.not.toThrow()
|
|
266
|
-
})
|
|
267
|
-
|
|
268
|
-
it('should fail if events are not received', async () => {
|
|
269
|
-
await expect(step.call(context)).rejects.toThrow(AssertionError)
|
|
270
|
-
})
|
|
271
|
-
|
|
272
|
-
it('should wait for last events (50ms)', async () => {
|
|
273
|
-
setTimeout(() => {
|
|
274
|
-
context.eventsConsumedCount = context.eventsPublishedCount
|
|
275
|
-
}, 49)
|
|
276
|
-
|
|
277
|
-
await expect(step.call(context)).resolves.not.toThrow()
|
|
278
|
-
})
|
|
279
|
-
})
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { generate } = require('randomstring')
|
|
4
|
-
|
|
5
|
-
const io = /** @type {jest.MockedObject<comq.IO>} */ {
|
|
6
|
-
reply: jest.fn(async () => undefined),
|
|
7
|
-
request: jest.fn(async () => generate()),
|
|
8
|
-
consume: jest.fn(async () => generate()),
|
|
9
|
-
emit: jest.fn(async () => generate()),
|
|
10
|
-
close: jest.fn(async () => undefined),
|
|
11
|
-
diagnose: jest.fn(() => undefined)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
exports.io = io
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { AssertionError } = require('node:assert')
|
|
4
|
-
const tomato = require('@toa.io/tomato')
|
|
5
|
-
const mock = { tomato }
|
|
6
|
-
|
|
7
|
-
jest.mock('@cucumber/cucumber', () => mock.tomato)
|
|
8
|
-
|
|
9
|
-
require('../poison')
|
|
10
|
-
|
|
11
|
-
/** @type {comq.features.Context} */
|
|
12
|
-
let context
|
|
13
|
-
|
|
14
|
-
beforeEach(() => {
|
|
15
|
-
context = /** @type {comq.features.Context} */ { events: {} }
|
|
16
|
-
})
|
|
17
|
-
|
|
18
|
-
describe('Then the message is discarded', () => {
|
|
19
|
-
const step = tomato.steps.Th('the message is discarded')
|
|
20
|
-
|
|
21
|
-
it('should be', async () => undefined)
|
|
22
|
-
|
|
23
|
-
it('should throw if not discarded', async () => {
|
|
24
|
-
await expect(step.call(context)).rejects.toThrow(AssertionError)
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
it('should not throw if discarded', async () => {
|
|
28
|
-
context.events.discard = true
|
|
29
|
-
|
|
30
|
-
await expect(step.call(context)).resolves.not.toThrow()
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
it('should wait for discard event', async () => {
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
context.events.discard = true
|
|
36
|
-
}, 10)
|
|
37
|
-
|
|
38
|
-
await expect(step.call(context)).resolves.not.toThrow()
|
|
39
|
-
})
|
|
40
|
-
})
|
|
@@ -1,261 +0,0 @@
|
|
|
1
|
-
'use strict'
|
|
2
|
-
|
|
3
|
-
const { AssertionError } = require('node:assert')
|
|
4
|
-
const { generate } = require('randomstring')
|
|
5
|
-
const { promex, timeout } = require('@toa.io/generic')
|
|
6
|
-
const { dump } = require('@toa.io/yaml')
|
|
7
|
-
const tomato = require('@toa.io/tomato')
|
|
8
|
-
const { io } = require('./io.mock')
|
|
9
|
-
const mock = { tomato }
|
|
10
|
-
|
|
11
|
-
jest.mock('@cucumber/cucumber', () => mock.tomato)
|
|
12
|
-
|
|
13
|
-
require('../rpc')
|
|
14
|
-
|
|
15
|
-
/** @type {comq.features.Context} */
|
|
16
|
-
let context
|
|
17
|
-
|
|
18
|
-
const queue = generate()
|
|
19
|
-
|
|
20
|
-
beforeEach(() => {
|
|
21
|
-
jest.clearAllMocks()
|
|
22
|
-
|
|
23
|
-
context = /** @type {comq.features.Context} */ { io }
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
describe('Given function replying {token} queue:', () => {
|
|
27
|
-
const step = tomato.steps.Gi('function replying {token} queue:')
|
|
28
|
-
|
|
29
|
-
it('should be', () => undefined)
|
|
30
|
-
|
|
31
|
-
it('should assign given function as producer', async () => {
|
|
32
|
-
const javascript = '({ a, b }) => a + b'
|
|
33
|
-
|
|
34
|
-
await step.call(context, queue, javascript)
|
|
35
|
-
|
|
36
|
-
expect(io.reply).toHaveBeenCalledWith(queue, expect.any(Function))
|
|
37
|
-
|
|
38
|
-
const producer = io.reply.mock.calls[0][1]
|
|
39
|
-
const sum = producer({ a: 1, b: 2 })
|
|
40
|
-
|
|
41
|
-
expect(sum).toStrictEqual(3)
|
|
42
|
-
})
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
describe('Given a producer replying {token} queue', () => {
|
|
46
|
-
const step = tomato.steps.Gi('a producer replying {token} queue')
|
|
47
|
-
|
|
48
|
-
it('should be', async () => undefined)
|
|
49
|
-
|
|
50
|
-
it('should reply', async () => {
|
|
51
|
-
await step.call(context, queue)
|
|
52
|
-
|
|
53
|
-
expect(io.reply).toHaveBeenCalledWith(queue, expect.any(Function))
|
|
54
|
-
|
|
55
|
-
const producer = io.reply.mock.calls[0][1]
|
|
56
|
-
const message = generate()
|
|
57
|
-
const reply = await producer(message)
|
|
58
|
-
|
|
59
|
-
expect(reply).toStrictEqual(message)
|
|
60
|
-
})
|
|
61
|
-
})
|
|
62
|
-
|
|
63
|
-
describe('Given function replying {token} queue is expected:', () => {
|
|
64
|
-
tomato.steps.Gi('function replying {token} queue is expected:')
|
|
65
|
-
|
|
66
|
-
it('should be', () => undefined)
|
|
67
|
-
})
|
|
68
|
-
|
|
69
|
-
describe('When the consumer sends the following request to the {token} queue:', () => {
|
|
70
|
-
const step = tomato.steps.Wh('the consumer sends the following request to the {token} queue:')
|
|
71
|
-
|
|
72
|
-
it('should be', async () => undefined)
|
|
73
|
-
|
|
74
|
-
const payload = { [generate()]: generate() }
|
|
75
|
-
const yaml = dump(payload)
|
|
76
|
-
|
|
77
|
-
beforeEach(async () => {
|
|
78
|
-
await step.call(context, queue, yaml)
|
|
79
|
-
})
|
|
80
|
-
|
|
81
|
-
it('should send request', async () => {
|
|
82
|
-
expect(io.request).toHaveBeenCalledWith(queue, payload)
|
|
83
|
-
})
|
|
84
|
-
|
|
85
|
-
it('should store reply promise', async () => {
|
|
86
|
-
const reply = await io.request.mock.results[0].value
|
|
87
|
-
|
|
88
|
-
expect(await context.reply).toStrictEqual(reply)
|
|
89
|
-
})
|
|
90
|
-
|
|
91
|
-
it('should wait for context.expected', async () => {
|
|
92
|
-
context.expected = promex()
|
|
93
|
-
|
|
94
|
-
let completed = false
|
|
95
|
-
|
|
96
|
-
setImmediate(() => {
|
|
97
|
-
expect(completed).toStrictEqual(false)
|
|
98
|
-
|
|
99
|
-
completed = true
|
|
100
|
-
|
|
101
|
-
context.expected.resolve()
|
|
102
|
-
})
|
|
103
|
-
|
|
104
|
-
await step.call(context, queue, yaml)
|
|
105
|
-
|
|
106
|
-
expect(completed).toStrictEqual(true)
|
|
107
|
-
})
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
describe('When the consumer sends a request to the {token} queue', () => {
|
|
111
|
-
const step = tomato.steps.Wh('the consumer sends a request to the {token} queue')
|
|
112
|
-
|
|
113
|
-
it('should be', async () => undefined)
|
|
114
|
-
|
|
115
|
-
it('should send request', async () => {
|
|
116
|
-
await step.call(context, queue)
|
|
117
|
-
|
|
118
|
-
expect(io.request).toHaveBeenCalledWith(queue, expect.any(Buffer))
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
describe('Then the consumer receives the reply:', () => {
|
|
123
|
-
const step = tomato.steps.Th('the consumer receives the reply:')
|
|
124
|
-
|
|
125
|
-
it('should be', async () => undefined)
|
|
126
|
-
|
|
127
|
-
const replies = [
|
|
128
|
-
['primitive', generate()],
|
|
129
|
-
['object', { ok: 1 }],
|
|
130
|
-
['array', [1, 'foo']]
|
|
131
|
-
]
|
|
132
|
-
|
|
133
|
-
describe.each(replies)('%s reply comparison', (type, value) => {
|
|
134
|
-
let yaml
|
|
135
|
-
|
|
136
|
-
beforeEach(() => {
|
|
137
|
-
yaml = dump(value)
|
|
138
|
-
})
|
|
139
|
-
|
|
140
|
-
it('should throw if differ', async () => {
|
|
141
|
-
const promise = promex()
|
|
142
|
-
|
|
143
|
-
context.reply = promise
|
|
144
|
-
promise.resolve(generate())
|
|
145
|
-
|
|
146
|
-
await expect(step.call(context, yaml)).rejects.toThrow(AssertionError)
|
|
147
|
-
})
|
|
148
|
-
|
|
149
|
-
it('should pass if equals', async () => {
|
|
150
|
-
const promise = promex()
|
|
151
|
-
|
|
152
|
-
context.reply = promise
|
|
153
|
-
|
|
154
|
-
promise.resolve(value)
|
|
155
|
-
|
|
156
|
-
await expect(step.call(context, yaml)).resolves.not.toThrow()
|
|
157
|
-
})
|
|
158
|
-
})
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
describe('Then the consumer receives the reply', () => {
|
|
162
|
-
const step = tomato.steps.Th('the consumer receives the reply')
|
|
163
|
-
|
|
164
|
-
it('should be', async () => undefined)
|
|
165
|
-
|
|
166
|
-
it('should await reply', async () => {
|
|
167
|
-
context.reply = promex()
|
|
168
|
-
|
|
169
|
-
let completed = false
|
|
170
|
-
|
|
171
|
-
setImmediate(() => {
|
|
172
|
-
expect(completed).toStrictEqual(false)
|
|
173
|
-
|
|
174
|
-
context.reply.resolve()
|
|
175
|
-
|
|
176
|
-
completed = true
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
await step.call(context)
|
|
180
|
-
|
|
181
|
-
expect(completed).toStrictEqual(true)
|
|
182
|
-
})
|
|
183
|
-
})
|
|
184
|
-
|
|
185
|
-
describe('Then the consumer does not receive the reply', () => {
|
|
186
|
-
const step = tomato.steps.Th('the consumer does not receive the reply')
|
|
187
|
-
|
|
188
|
-
it('should be', async () => undefined)
|
|
189
|
-
|
|
190
|
-
it('should throw if reply is received within 50ms', async () => {
|
|
191
|
-
context.reply = promex()
|
|
192
|
-
|
|
193
|
-
setTimeout(() => {
|
|
194
|
-
context.reply.resolve(generate())
|
|
195
|
-
}, 10)
|
|
196
|
-
|
|
197
|
-
await expect(step.call(context)).rejects.toThrow(AssertionError)
|
|
198
|
-
})
|
|
199
|
-
|
|
200
|
-
it('should not throw if reply is not received', async () => {
|
|
201
|
-
await expect(step.call(context)).resolves.not.toThrow(AssertionError)
|
|
202
|
-
})
|
|
203
|
-
})
|
|
204
|
-
|
|
205
|
-
describe('Given I\'m sending {quantity}B requests to the {token} queue at {quantity}Hz', () => {
|
|
206
|
-
const step = tomato.steps.Gi('I\'m sending {quantity}B requests to the {token} queue at {quantity}Hz')
|
|
207
|
-
|
|
208
|
-
it('should be', async () => undefined)
|
|
209
|
-
|
|
210
|
-
it('should send requests continuously', async () => {
|
|
211
|
-
context = /** @type {comq.features.Context} */ {
|
|
212
|
-
io: /** @type {jest.MockedObject<comq.IO>} */ { request: jest.fn() },
|
|
213
|
-
requestsSent: []
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
const bytesQ = '1k'
|
|
217
|
-
const queue = generate()
|
|
218
|
-
const frequencyQ = '100'
|
|
219
|
-
|
|
220
|
-
step.call(context, bytesQ, queue, frequencyQ)
|
|
221
|
-
|
|
222
|
-
await timeout(100 + 12)
|
|
223
|
-
|
|
224
|
-
const callsAmountExpected = [9, 10, 11, 12]
|
|
225
|
-
|
|
226
|
-
expect(callsAmountExpected).toContain(context.io.request.mock.calls.length)
|
|
227
|
-
expect(context.sending).toBeDefined()
|
|
228
|
-
expect(callsAmountExpected).toContain(context.requestsSent.length)
|
|
229
|
-
|
|
230
|
-
clearInterval(context.sending)
|
|
231
|
-
})
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
describe('Then all replies have been received', () => {
|
|
235
|
-
const step = tomato.steps.Th('all replies have been received')
|
|
236
|
-
|
|
237
|
-
/** @type {jest.MockedObject<comq.features.Context>} */
|
|
238
|
-
let context
|
|
239
|
-
|
|
240
|
-
it('should be', async () => undefined)
|
|
241
|
-
|
|
242
|
-
beforeEach(async () => {
|
|
243
|
-
context = /** @type {jest.MockedObject<comq.features.Context>} */ {
|
|
244
|
-
requestsSent: [promex(), promex()]
|
|
245
|
-
}
|
|
246
|
-
})
|
|
247
|
-
|
|
248
|
-
it('should pass if replies received', async () => {
|
|
249
|
-
let completed = false
|
|
250
|
-
|
|
251
|
-
setImmediate(() => {
|
|
252
|
-
completed = true
|
|
253
|
-
|
|
254
|
-
for (const promise of context.requestsSent) promise.resolve()
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
await step.call(context)
|
|
258
|
-
|
|
259
|
-
expect(completed).toStrictEqual(true)
|
|
260
|
-
})
|
|
261
|
-
})
|