rjr 0.19.1 → 0.19.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.
- checksums.yaml +4 -4
- data/README.md +3 -0
- data/Rakefile +0 -2
- data/examples/timeout.rb +23 -0
- data/lib/rjr/dispatcher.rb +1 -1
- data/lib/rjr/messages/intermediate.rb +50 -0
- data/lib/rjr/messages/notification.rb +9 -16
- data/lib/rjr/messages/request.rb +14 -20
- data/lib/rjr/messages/response.rb +19 -26
- data/lib/rjr/messages.rb +1 -0
- data/lib/rjr/node.rb +50 -34
- data/lib/rjr/nodes/amqp.rb +19 -3
- data/lib/rjr/nodes/local.rb +12 -5
- data/lib/rjr/nodes/tcp.rb +25 -12
- data/lib/rjr/nodes/web.rb +3 -2
- data/lib/rjr/request.rb +11 -1
- data/lib/rjr/util/json_parser.rb +47 -14
- data/lib/rjr/util/logger.rb +4 -2
- data/lib/rjr/version.rb +1 -1
- data/specs/args_spec.rb +2 -2
- data/specs/dispatcher_spec.rb +9 -9
- data/specs/em_adapter_spec.rb +3 -3
- data/specs/handles_methods_spec.rb +2 -2
- data/specs/json_parser_spec.rb +30 -4
- data/specs/messages/intermediate_spec.rb +58 -0
- data/specs/messages/notification_spec.rb +12 -13
- data/specs/messages/request_spec.rb +16 -16
- data/specs/messages/response_spec.rb +15 -14
- data/specs/node_spec.rb +79 -31
- data/specs/nodes/amqp_spec.rb +1 -1
- data/specs/nodes/local_spec.rb +2 -2
- data/specs/nodes/multi_spec.rb +1 -1
- data/specs/nodes/tcp_spec.rb +116 -27
- data/specs/nodes/web_spec.rb +1 -1
- data/specs/nodes/ws_spec.rb +1 -1
- data/specs/request_spec.rb +19 -0
- metadata +83 -80
data/specs/node_spec.rb
CHANGED
@@ -177,7 +177,9 @@ module RJR
|
|
177
177
|
n = Node.new
|
178
178
|
n.on(:error) {}
|
179
179
|
n.clear_event_handlers
|
180
|
-
n.connection_event_handlers.should == {:
|
180
|
+
n.connection_event_handlers.should == { :opened => [],
|
181
|
+
:closed => [],
|
182
|
+
:error => [] }
|
181
183
|
end
|
182
184
|
end
|
183
185
|
|
@@ -186,7 +188,9 @@ module RJR
|
|
186
188
|
bl = proc{}
|
187
189
|
n = Node.new
|
188
190
|
n.on(:error, &bl)
|
189
|
-
n.connection_event_handlers.should == {:
|
191
|
+
n.connection_event_handlers.should == { :opened => [],
|
192
|
+
:closed => [],
|
193
|
+
:error => [bl] }
|
190
194
|
end
|
191
195
|
end
|
192
196
|
|
@@ -247,6 +251,10 @@ module RJR
|
|
247
251
|
connection = Object.new
|
248
252
|
request = Messages::Request.new :id => 1, :method => 'foo'
|
249
253
|
request_str = request.to_s
|
254
|
+
inter = Messages::Intermediate.parse request_str
|
255
|
+
Messages::Intermediate.should_receive(:parse).
|
256
|
+
with(request_str).
|
257
|
+
and_return(inter)
|
250
258
|
|
251
259
|
node = Node.new
|
252
260
|
node.tp.should_receive(:<<) { |job|
|
@@ -254,7 +262,7 @@ module RJR
|
|
254
262
|
job.exec Mutex.new
|
255
263
|
}
|
256
264
|
|
257
|
-
node.should_receive(:handle_request).with(
|
265
|
+
node.should_receive(:handle_request).with(inter, false, connection)
|
258
266
|
node.send :handle_message, request_str, connection
|
259
267
|
end
|
260
268
|
end
|
@@ -264,6 +272,10 @@ module RJR
|
|
264
272
|
connection = Object.new
|
265
273
|
notification = Messages::Notification.new :method => 'foo'
|
266
274
|
notification_str = notification.to_s
|
275
|
+
inter = Messages::Intermediate.parse notification_str
|
276
|
+
Messages::Intermediate.should_receive(:parse).
|
277
|
+
with(notification_str).
|
278
|
+
and_return(inter)
|
267
279
|
|
268
280
|
node = Node.new
|
269
281
|
node.tp.should_receive(:<<) { |job|
|
@@ -271,8 +283,7 @@ module RJR
|
|
271
283
|
job.exec Mutex.new
|
272
284
|
}
|
273
285
|
|
274
|
-
node.should_receive(:handle_request).
|
275
|
-
with(notification_str, true, connection)
|
286
|
+
node.should_receive(:handle_request).with(inter, true, connection)
|
276
287
|
node.send :handle_message, notification_str, connection
|
277
288
|
end
|
278
289
|
end
|
@@ -281,9 +292,13 @@ module RJR
|
|
281
292
|
it "handles response" do
|
282
293
|
response = Messages::Response.new :result => Result.new
|
283
294
|
response_str = response.to_s
|
295
|
+
inter = Messages::Intermediate.parse response_str
|
296
|
+
Messages::Intermediate.should_receive(:parse).
|
297
|
+
with(response_str).
|
298
|
+
and_return(inter)
|
284
299
|
|
285
300
|
node = Node.new
|
286
|
-
node.should_receive(:handle_response).with(
|
301
|
+
node.should_receive(:handle_response).with(inter)
|
287
302
|
node.send :handle_message, response_str
|
288
303
|
end
|
289
304
|
end
|
@@ -297,6 +312,14 @@ module RJR
|
|
297
312
|
node.send :handle_message, "{}"
|
298
313
|
end
|
299
314
|
end
|
315
|
+
|
316
|
+
it "returns intermediate message" do
|
317
|
+
node = Node.new
|
318
|
+
connection = Object.new
|
319
|
+
inter = Messages::Intermediate.new
|
320
|
+
Messages::Intermediate.should_receive(:parse).and_return(inter)
|
321
|
+
node.send(:handle_message, '', connection).should == inter
|
322
|
+
end
|
300
323
|
end
|
301
324
|
|
302
325
|
describe "#handle_request" do
|
@@ -305,13 +328,14 @@ module RJR
|
|
305
328
|
Messages::Notification.new :method => 'rjr_method1',
|
306
329
|
:args => ['method', 'args'],
|
307
330
|
:headers => {'msg' => 'headers'}
|
308
|
-
|
331
|
+
notification_str = notification.to_s
|
332
|
+
@intermediate = Messages::Intermediate.parse notification_str
|
309
333
|
@node = Node.new
|
310
334
|
end
|
311
335
|
|
312
336
|
it "invokes dispatcher.dispatch" do
|
313
337
|
@node.dispatcher.should_receive(:dispatch)
|
314
|
-
@node.send :handle_request, @
|
338
|
+
@node.send :handle_request, @intermediate, true
|
315
339
|
end
|
316
340
|
|
317
341
|
describe "dispatcher.dispatch args" do
|
@@ -319,21 +343,21 @@ module RJR
|
|
319
343
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
320
344
|
args[:rjr_method].should == 'rjr_method1'
|
321
345
|
}
|
322
|
-
@node.send :handle_request, @
|
346
|
+
@node.send :handle_request, @intermediate, true
|
323
347
|
end
|
324
348
|
|
325
349
|
it "includes :rjr_method_args => msg.jr_args" do
|
326
350
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
327
351
|
args[:rjr_method_args].should == ['method', 'args']
|
328
352
|
}
|
329
|
-
@node.send :handle_request, @
|
353
|
+
@node.send :handle_request, @intermediate, true
|
330
354
|
end
|
331
355
|
|
332
356
|
it "includes :rjr_headers => msg.headers" do
|
333
357
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
334
358
|
args[:rjr_headers].should == {'msg' => 'headers'}
|
335
359
|
}
|
336
|
-
@node.send :handle_request, @
|
360
|
+
@node.send :handle_request, @intermediate, true
|
337
361
|
end
|
338
362
|
|
339
363
|
it "includes :rjr_client_ip => extracted client ip" do
|
@@ -343,7 +367,7 @@ module RJR
|
|
343
367
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
344
368
|
args[:rjr_client_ip].should == '127.0.0.1'
|
345
369
|
}
|
346
|
-
@node.send :handle_request, @
|
370
|
+
@node.send :handle_request, @intermediate, true, connection
|
347
371
|
end
|
348
372
|
|
349
373
|
it "includes :rjr_client_port => extracted client port" do
|
@@ -353,14 +377,14 @@ module RJR
|
|
353
377
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
354
378
|
args[:rjr_client_port].should == 9999
|
355
379
|
}
|
356
|
-
@node.send :handle_request, @
|
380
|
+
@node.send :handle_request, @intermediate, true, connection
|
357
381
|
end
|
358
382
|
|
359
383
|
it "includes :rjr_node => self" do
|
360
384
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
361
385
|
args[:rjr_node].should == @node
|
362
386
|
}
|
363
|
-
@node.send :handle_request, @
|
387
|
+
@node.send :handle_request, @intermediate, true
|
364
388
|
end
|
365
389
|
|
366
390
|
it "includes :rjr_node_id => self.node_id" do
|
@@ -368,7 +392,7 @@ module RJR
|
|
368
392
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
369
393
|
args[:rjr_node_id].should == 'node_id'
|
370
394
|
}
|
371
|
-
@node.send :handle_request, @
|
395
|
+
@node.send :handle_request, @intermediate, true
|
372
396
|
end
|
373
397
|
|
374
398
|
it "includes :rjr_node_type => self.node_type" do
|
@@ -376,14 +400,14 @@ module RJR
|
|
376
400
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
377
401
|
args[:rjr_node_type].should == :nt
|
378
402
|
}
|
379
|
-
@node.send :handle_request, @
|
403
|
+
@node.send :handle_request, @intermediate, true
|
380
404
|
end
|
381
405
|
|
382
406
|
it "includes :rjr_callback => constructed node callback" do
|
383
407
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
384
408
|
args[:rjr_callback].should be_an_instance_of(NodeCallback)
|
385
409
|
}
|
386
|
-
@node.send :handle_request, @
|
410
|
+
@node.send :handle_request, @intermediate, true
|
387
411
|
end
|
388
412
|
|
389
413
|
describe "specified node callback" do
|
@@ -391,7 +415,7 @@ module RJR
|
|
391
415
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
392
416
|
args[:rjr_callback].node.should == @node
|
393
417
|
}
|
394
|
-
@node.send :handle_request, @
|
418
|
+
@node.send :handle_request, @intermediate, true
|
395
419
|
end
|
396
420
|
|
397
421
|
it "has a handle to the connection" do
|
@@ -399,17 +423,18 @@ module RJR
|
|
399
423
|
@node.dispatcher.should_receive(:dispatch) { |args|
|
400
424
|
args[:rjr_callback].connection.should == connection
|
401
425
|
}
|
402
|
-
@node.send :handle_request, @
|
426
|
+
@node.send :handle_request, @intermediate, true, connection
|
403
427
|
end
|
404
428
|
end
|
405
429
|
end
|
406
430
|
|
407
431
|
context "handling request / not a notification" do
|
408
432
|
before(:each) do
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
433
|
+
request = Messages::Request.new :method => 'method1',
|
434
|
+
:args => ['method', 'args'],
|
435
|
+
:headers => {'msg' => 'headers'}
|
436
|
+
request_str = request.to_s
|
437
|
+
@intermediate = Messages::Intermediate.parse request_str
|
413
438
|
|
414
439
|
result = Result.new
|
415
440
|
@expected = Messages::Response.new :result => result,
|
@@ -426,19 +451,19 @@ module RJR
|
|
426
451
|
response.should == @expected.to_s
|
427
452
|
econnection.should == connection
|
428
453
|
}
|
429
|
-
@node.send :handle_request, @
|
454
|
+
@node.send :handle_request, @intermediate, false, connection
|
430
455
|
end
|
431
456
|
|
432
457
|
it "returns response" do
|
433
458
|
@node.should_receive(:send_msg) # stub out
|
434
|
-
response = @node.send(:handle_request, @
|
459
|
+
response = @node.send(:handle_request, @intermediate, false)
|
435
460
|
response.should be_an_instance_of(Messages::Response)
|
436
461
|
response.to_s.should == @expected.to_s
|
437
462
|
end
|
438
463
|
end
|
439
464
|
|
440
465
|
it "returns nil" do
|
441
|
-
@node.send(:handle_request, @
|
466
|
+
@node.send(:handle_request, @intermediate, true).should be_nil
|
442
467
|
end
|
443
468
|
end
|
444
469
|
|
@@ -448,7 +473,8 @@ module RJR
|
|
448
473
|
|
449
474
|
@result = Result.new :result => 42
|
450
475
|
response = Messages::Response.new :id => 'msg1', :result => @result
|
451
|
-
|
476
|
+
response = response.to_s
|
477
|
+
@intermediate = Messages::Intermediate.parse response
|
452
478
|
end
|
453
479
|
|
454
480
|
it "invokes dispatcher.handle_response with response result" do
|
@@ -456,11 +482,11 @@ module RJR
|
|
456
482
|
r.should be_an_instance_of(Result)
|
457
483
|
r.result.should == 42
|
458
484
|
}
|
459
|
-
@node.send :handle_response, @
|
485
|
+
@node.send :handle_response, @intermediate
|
460
486
|
end
|
461
487
|
|
462
488
|
it "adds response msg_id and result to response queue" do
|
463
|
-
@node.send :handle_response, @
|
489
|
+
@node.send :handle_response, @intermediate
|
464
490
|
responses = @node.instance_variable_get(:@responses)
|
465
491
|
responses.size.should == 1
|
466
492
|
responses.first[0].should == 'msg1'
|
@@ -470,7 +496,7 @@ module RJR
|
|
470
496
|
context "response contains error" do
|
471
497
|
it "adds response error to response queue" do
|
472
498
|
@node.dispatcher.should_receive(:handle_response).and_raise(Exception)
|
473
|
-
@node.send :handle_response, @
|
499
|
+
@node.send :handle_response, @intermediate
|
474
500
|
responses = @node.instance_variable_get(:@responses)
|
475
501
|
responses.first[2].should be_an_instance_of(Exception)
|
476
502
|
end
|
@@ -478,7 +504,7 @@ module RJR
|
|
478
504
|
|
479
505
|
it "signals response cv" do
|
480
506
|
@node.instance_variable_get(:@response_cv).should_receive(:broadcast)
|
481
|
-
@node.send :handle_response, @
|
507
|
+
@node.send :handle_response, @intermediate
|
482
508
|
end
|
483
509
|
end
|
484
510
|
|
@@ -513,6 +539,28 @@ module RJR
|
|
513
539
|
node.instance_variable_get(:@response_cv).should_receive(:wait).once
|
514
540
|
node.send(:wait_for_result, @msg)
|
515
541
|
end
|
542
|
+
it "throws an error if it times out" do
|
543
|
+
node = Node.new :timeout => 0.01
|
544
|
+
node.instance_variable_get(:@response_cv).should_receive(:wait).at_least(:once)
|
545
|
+
expect { node.send(:wait_for_result, @msg) }.to raise_error(Exception)
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
context "pruning messages" do
|
550
|
+
it "deletes unrequested messages" do
|
551
|
+
responses = [@response, ['foobar', 'baz']]
|
552
|
+
@node.instance_variable_set(:@responses, responses)
|
553
|
+
@node.send :wait_for_result, @msg
|
554
|
+
@node.instance_variable_get(:@responses).should be_empty
|
555
|
+
end
|
556
|
+
it "deletes timed out messages" do
|
557
|
+
responses = [@response, ['foobar', 'baz']]
|
558
|
+
@node.instance_variable_set(:@timeout, 0.01)
|
559
|
+
@node.instance_variable_set(:@pending, { 'foobar' => Time.at(0) })
|
560
|
+
@node.instance_variable_set(:@responses, responses)
|
561
|
+
@node.send :wait_for_result, @msg
|
562
|
+
@node.instance_variable_get(:@responses).should be_empty
|
563
|
+
end
|
516
564
|
end
|
517
565
|
end
|
518
566
|
end # describe Node
|
data/specs/nodes/amqp_spec.rb
CHANGED
data/specs/nodes/local_spec.rb
CHANGED
data/specs/nodes/multi_spec.rb
CHANGED
@@ -51,7 +51,7 @@ module RJR::Nodes
|
|
51
51
|
:broker => 'localhost'
|
52
52
|
res = amqp_client.invoke 'amqp-queue', 'method1', 'myparam1'
|
53
53
|
res.should == 'retval1'
|
54
|
-
invoked1.should
|
54
|
+
invoked1.should be_truthy
|
55
55
|
rni1.should == 'amqp'
|
56
56
|
rnt1.should == :amqp
|
57
57
|
p1.should == 'myparam1'
|
data/specs/nodes/tcp_spec.rb
CHANGED
@@ -35,41 +35,130 @@ module RJR::Nodes
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
38
|
+
context "simple server" do
|
39
|
+
let(:server) do
|
40
|
+
TCP.new(:node_id => 'tcp',
|
41
|
+
:host => 'localhost',
|
42
|
+
:port => 9987)
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:host) { 'jsonrpc://localhost:9987' }
|
46
|
+
|
47
|
+
let(:client) { TCP.new }
|
48
|
+
|
49
|
+
before(:each) do
|
50
|
+
server.dispatcher.handle('foobar') { |param| 'retval' }
|
45
51
|
server.listen
|
52
|
+
end
|
46
53
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
54
|
+
describe "#invoke" do
|
55
|
+
it "should invoke request" do
|
56
|
+
res = client.invoke host, 'foobar', 'myparam'
|
57
|
+
server.halt.join
|
58
|
+
res.should == 'retval'
|
59
|
+
end
|
51
60
|
end
|
52
|
-
end
|
53
61
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
server.listen
|
62
|
+
describe "#notify" do
|
63
|
+
it "should send notification" do
|
64
|
+
res = client.notify host, 'foobar', 'myparam'
|
65
|
+
server.halt.join
|
66
|
+
res.should == nil
|
67
|
+
end
|
68
|
+
end
|
62
69
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
70
|
+
describe "a node's connections array" do
|
71
|
+
it "should be updated when a connection is opened" do
|
72
|
+
client.invoke host, 'foobar', 'myparam'
|
73
|
+
server.connections.size.should be == 1
|
74
|
+
client.connections.size.should be == 1
|
75
|
+
server.halt.join
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should be updated when a connection is closed" do
|
79
|
+
client.invoke host, 'foobar', 'myparam'
|
80
|
+
client.connections.first.unbind
|
81
|
+
server.connections.first.unbind
|
82
|
+
server.connections.should be_empty
|
83
|
+
client.connections.should be_empty
|
84
|
+
server.halt.join
|
85
|
+
end
|
86
|
+
|
87
|
+
context "with a client already connected" do
|
88
|
+
let(:another_client) { TCP.new }
|
89
|
+
|
90
|
+
before(:each) do
|
91
|
+
client.invoke host, 'foobar', 'myparam'
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should be updated when a new connection is opened" do
|
95
|
+
another_client.invoke host, 'foobar', 'myparam'
|
96
|
+
server.connections.size.should be == 2
|
97
|
+
client.connections.size.should be == 1
|
98
|
+
another_client.connections.size.should be == 1
|
99
|
+
server.halt.join
|
100
|
+
end
|
101
|
+
|
102
|
+
context "with two clients connected" do
|
103
|
+
before(:each) do
|
104
|
+
client.invoke host, 'foobar', 'myparam'
|
105
|
+
another_client.invoke host, 'foobar', 'myparam'
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should be updated when a connection is closed" do
|
109
|
+
another_client.connections.first.unbind
|
110
|
+
server.connections.last.unbind
|
111
|
+
server.connections.size.should be == 1
|
112
|
+
client.connections.size.should be == 1
|
113
|
+
another_client.connections.should be_empty
|
114
|
+
server.halt.join
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
describe "event handlers" do
|
121
|
+
shared_examples "an event handler" do |event|
|
122
|
+
it "should be invoked when event is triggered" do
|
123
|
+
handler_invoked = false
|
124
|
+
server.on(event) { handler_invoked = true }
|
125
|
+
client.invoke host, 'foobar', 'myparam'
|
126
|
+
server.halt.join
|
127
|
+
handler_invoked.should be_truthy
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should receive the node" do
|
131
|
+
node_received = false
|
132
|
+
server.on(event) do |node|
|
133
|
+
node_received = true if node.is_a?(RJR::Node)
|
134
|
+
end
|
135
|
+
client.invoke host, 'foobar', 'myparam'
|
136
|
+
server.halt.join
|
137
|
+
node_received.should be_truthy
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should receive the connection" do
|
141
|
+
connection_received = false
|
142
|
+
server.on(event) do |_, connection|
|
143
|
+
connection_received = true if connection.is_a?(EM::Connection)
|
144
|
+
end
|
145
|
+
client.invoke host, 'foobar', 'myparam'
|
146
|
+
server.halt.join
|
147
|
+
connection_received.should be_truthy
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "opened event handler" do
|
152
|
+
it_behaves_like "an event handler", :opened
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "closed event handler" do
|
156
|
+
it_behaves_like "an event handler", :closed
|
157
|
+
end
|
67
158
|
end
|
68
159
|
end
|
69
160
|
|
70
161
|
# TODO test callbacks over tcp interface
|
71
|
-
# TODO ensure
|
162
|
+
# TODO ensure error event handler is invoked
|
72
163
|
end
|
73
164
|
end
|
74
|
-
|
75
|
-
|
data/specs/nodes/web_spec.rb
CHANGED
data/specs/nodes/ws_spec.rb
CHANGED
data/specs/request_spec.rb
CHANGED
@@ -63,11 +63,30 @@ module RJR
|
|
63
63
|
request.rjr_args.args.should == args
|
64
64
|
end
|
65
65
|
|
66
|
+
it "sets default env to nil" do
|
67
|
+
Request.new.rjr_env.should be_nil
|
68
|
+
end
|
69
|
+
|
66
70
|
it "sets default result to nil" do
|
67
71
|
Request.new.result.should be_nil
|
68
72
|
end
|
69
73
|
end
|
70
74
|
|
75
|
+
describe "#set_env" do
|
76
|
+
it "extends request w/ specified module" do
|
77
|
+
request = Request.new
|
78
|
+
request.should_receive(:extend).with('foobar')
|
79
|
+
request.set_env('foobar')
|
80
|
+
end
|
81
|
+
|
82
|
+
it "sets rjr_env" do
|
83
|
+
request = Request.new
|
84
|
+
request.should_receive(:extend)
|
85
|
+
request.set_env('foobar')
|
86
|
+
request.rjr_env.should == 'foobar'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
71
90
|
describe "#handle" do
|
72
91
|
it "invokes the registered handler with args" do
|
73
92
|
received = nil
|