UNPKG

8.47 kBtext/coffeescriptView Raw
1should = require 'should'
2_ = require 'lodash'
3logger = require 'torch'
4{focus} = require 'qi'
5{join} = require 'path'
6
7bus = require '../lib/bus'
8core = require '../lib/core'
9
10mockRetriever = require './helpers/mockRetriever'
11
12describe 'core.request', ->
13 beforeEach (done) ->
14
15 core.init {timeout: 20}, mockRetriever()
16 @moduleName = 'server'
17 @serviceName = 'start'
18 @channel = "#{@moduleName}.#{@serviceName}"
19 @data =
20 x: 2
21 y: 'hello'
22
23 done()
24
25 afterEach ->
26 core.reset()
27
28 it 'should receive exactly one valid response', (done) ->
29 core.respond @channel, (message, done) ->
30 done null, message
31
32 core.request @channel, @data, (err, message) =>
33 should.not.exist err
34
35 should.exist message
36 message.should.eql @data
37
38 done()
39
40 it 'should pass an error to the callback the response returns one', (done) ->
41 testError = new Error 'testError'
42 bus.subscribe
43 channel: @channel
44 topic: 'request.#'
45 callback: (message, envelope) ->
46 bus.publish
47 channel: envelope.replyTo.channel
48 topic: envelope.replyTo.topic.err
49 data: testError
50
51 core.request @channel, @data, (err, message) =>
52 should.exist err
53 should.not.exist message
54
55 err.should.eql testError
56
57 done()
58
59 it 'should invoke the success callback exactly once, then discard all', (done) ->
60 core.respond @channel, (message, finished) =>
61 finished()
62
63 test = (err, data) ->
64 bus.publish
65 channel: @channel
66 topic: replyTo.topic.err
67 data: new Error 'should not see'
68 done()
69
70 replyTo = core.request @channel, @data, test
71
72 it 'should return a timeout error when it times out', (done) ->
73 core.respond @channel, -> # I can't hear you
74 core.request @channel, @data, (err, result) =>
75 should.exist err
76 err.message.should.eql "Request timed out on channel '#{@channel}'"
77 should.not.exist result
78 done()
79
80 it 'should return immediately if there are no listeners', (done) ->
81 core.request @channel, @data, (err, result) =>
82 should.exist err
83 expectedMsg = "No responders for request: '#{@channel}'"
84 err.message.should.eql expectedMsg
85
86 should.not.exist result
87
88 done()
89
90
91describe 'core.response', ->
92 afterEach ->
93 core.reset()
94
95 beforeEach (done) ->
96
97 core.init {timeout: 20}, mockRetriever()
98 @channel = 'testChannel'
99 @data =
100 x: 2
101 y: 'hello'
102 done()
103
104 it 'should send exactly one valid response', (done) ->
105 echo = (message, next) -> next null, message
106 core.respond @channel, echo
107
108 bus.subscribe
109 channel: @channel
110 topic: "success.123"
111 callback: (message) =>
112 should.exist message
113 message.should.eql @data
114 done()
115
116 bus.publish
117 channel: @channel
118 topic: "request.123"
119 data: @data
120 replyTo:
121 channel: @channel
122 topic:
123 success: "success.123"
124
125
126describe 'core.delegate', ->
127 afterEach ->
128 core.reset()
129
130 beforeEach (done) ->
131 core.init {timeout: 20}, mockRetriever()
132 done()
133
134 it 'should should return if there are no responders', (done) ->
135 channel = 'testChannel'
136
137 core.delegate channel, {}, (err, results) ->
138 should.not.exist err
139 done()
140
141 it 'responders on another channel should not interfere', (done) ->
142 channel = 'testChannel'
143
144 core.respond 'fooChannel', (message, next) ->
145 next null, {helloFrom: 'fooChannel'}
146
147 core.delegate channel, {}, (err, results) ->
148 should.not.exist err
149 done()
150
151 it 'should should receive multiple responses', (done) ->
152 channel = 'testChannel'
153
154 core.respond channel, (message, next) ->
155 next null, {helloFrom: 'responderA'}
156
157 core.respond channel, (message, next) ->
158 next null, {helloFrom: 'responderB'}
159
160 core.delegate channel, {}, (err, results) ->
161 should.not.exist err
162 should.exist results
163
164 values = _.values results
165 should.exist values
166
167 data = _.pluck values, 'data'
168 should.exist data
169
170 data.should.eql [
171 { helloFrom: 'responderA' }
172 { helloFrom: 'responderB' }
173 ]
174
175 done()
176
177 it 'should return an err when a responder returns one', (done) ->
178 channel = 'testChannel'
179
180 testResponse = {message: 'this works'}
181 core.respond channel, (message, next) ->
182 next null, testResponse
183
184 testError = new Error 'Expect this error'
185 core.respond channel, (message, next) ->
186 next testError, {}
187
188 core.delegate channel, {}, (err, results) ->
189 should.exist err
190 expectedMsg = "Errors returned by responders on channel '#{channel}'"
191 err.message.should.eql expectedMsg
192
193 should.exist err.errors
194 subErrors = (e.err for e in _.values err.errors)
195 should.exist subErrors
196 [subErr] = subErrors
197 should.exist subErr
198 subErr.should.eql testError
199
200 should.exist results
201 values = _.values results
202 should.exist values
203 [result] = values
204 should.exist result
205 result.data.should.eql testResponse
206
207 done()
208
209 it 'should return a timeout err when an implied request times out', (done) ->
210 channel = 'testChannel'
211
212 wontTimeOutMsg = {message: "I won't time out"}
213 core.respond channel, (message, next) ->
214 next null, wontTimeOutMsg
215
216 # This WILL time out
217 core.respond channel, (message, next) ->
218 # next() will never get called.
219
220 core.delegate channel, {}, (err, results) ->
221 should.exist err
222 expectedMsg = "Errors returned by responders on channel '#{channel}'"
223 err.message.should.eql expectedMsg
224
225 should.exist err.errors
226
227 [responderId] = _.keys err.errors
228 should.exist responderId
229
230 subErr = err.errors[responderId]?.err
231 should.exist subErr
232
233 errMsg = "Responder with id #{responderId} timed out on channel '#{channel}'"
234 subErr.message.should.eql errMsg
235
236 should.exist results
237 [result] = _.values results
238 should.exist result
239 should.exist result.data
240 result.data.should.eql wontTimeOutMsg
241
242 done()
243
244describe 'core.listen', ->
245 afterEach ->
246 core.reset()
247
248 beforeEach (done) ->
249
250 core.init {timeout: 20}, mockRetriever()
251 @channelA = 'testChannelA'
252 @channelB = 'testChannelB'
253 @dataA =
254 x: 2
255 y: 'hello'
256 @dataB =
257 x: 111
258 y: 'goodbye'
259 @topicA = 'info.A'
260 @topicB = 'info.B'
261
262 done()
263
264 it 'should listen with a standard-signature callback', (done) ->
265 core.listen @channelA, @topicA, (err, result) =>
266 should.not.exist err
267 should.exist result
268 {data} = result
269 should.exist data
270 data.should.eql @dataA
271 done()
272
273 bus.publish
274 channel: @channelA
275 data: @dataA
276 topic: @topicA
277
278 it 'should listen to two topics on one channel', (done) ->
279 cb = focus (err, results) =>
280 should.not.exist err
281
282 should.exist results
283
284 [resultA, resultB] = results
285 should.exist resultA
286 should.exist resultB
287
288 dataA = resultA.data
289 should.exist dataA
290 dataA.should.eql @dataA
291
292 dataB = resultB.data
293 should.exist dataB
294 dataB.should.eql @dataB
295
296 done()
297
298 core.listen @channelA, @topicA, cb()
299
300 core.listen @channelA, @topicB, cb()
301
302 bus.publish
303 channel: @channelA
304 data: @dataA
305 topic: @topicA
306
307 bus.publish
308 channel: @channelA
309 data: @dataB
310 topic: @topicB
311
312 it 'should listen to two topics on two channels', (done) ->
313 cb = focus (err, results) =>
314 should.not.exist err
315
316 should.exist results
317
318 [resultA, resultB] = results
319 should.exist resultA
320 should.exist resultB
321
322 dataA = resultA.data
323 should.exist dataA
324 dataA.should.eql @dataA
325
326 dataB = resultB.data
327 should.exist dataB
328 dataB.should.eql @dataB
329
330 done()
331
332 core.listen @channelA, @topicA, cb()
333
334 core.listen @channelB, @topicB, cb()
335
336 bus.publish
337 channel: @channelA
338 data: @dataA
339 topic: @topicA
340
341 bus.publish
342 channel: @channelB
343 data: @dataB
344 topic: @topicB
345
346 it 'should listen to any topic on one channel', (done) ->
347 core.listen @channelA, '#', (err, result) =>
348 should.not.exist err
349 should.exist result
350
351 {data} = result
352 should.exist data
353 data.should.eql @dataA
354
355 done()
356
357 bus.publish
358 channel: @channelA
359 data: @dataA
360 topic: @topicA