client_for_poslynx 0.9.0 → 1.0.0.pre

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.
@@ -1,5 +1,5 @@
1
1
  # coding: utf-8
2
2
 
3
3
  module ClientForPoslynx
4
- VERSION = '0.9.0'
4
+ VERSION = '1.0.0.pre'
5
5
  end
@@ -0,0 +1,624 @@
1
+ # coding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ module ClientForPoslynx
6
+
7
+ describe Net::EM_Connector do
8
+ describe "default initialization" do
9
+ subject { described_class.new( :the_server, :the_port ) }
10
+
11
+ it "Has ::EM as its em_system" do
12
+ expect( subject.em_system ).to eq( ::EM )
13
+ end
14
+
15
+ it "Has Net::EM_Connector::ConnectionHandler as its connection_handler" do
16
+ expect( subject.handler_class ).to eq( Net::EM_Connector::ConnectionHandler )
17
+ end
18
+
19
+ it "Sets the connection status to :initial" do
20
+ expect( subject.connection_status ).to eq( :initial )
21
+ end
22
+ end
23
+
24
+ context "actions and events" do
25
+ subject { described_class.new(
26
+ :the_server, :the_port,
27
+ encryption: encryption,
28
+ em_system: em_system,
29
+ handler: handler_class
30
+ ) }
31
+
32
+ let( :em_system ) { double( :em_system ) }
33
+ let( :handler_class ) { Class.new do
34
+ include Net::EM_Connector::HandlesConnection
35
+ end }
36
+
37
+ describe '#connect' do
38
+ context "without SSL" do
39
+ let( :encryption ) { :none }
40
+ before do
41
+ @handler_instance = nil
42
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
43
+ @handler_instance = handler.new( *handler_args )
44
+ nil
45
+ end
46
+ end
47
+
48
+ let( :on_success ) { double(:on_success, call: nil) }
49
+ let( :on_failure ) { double(:on_failure, call: nil) }
50
+
51
+ context "initial connection" do
52
+ before do
53
+ subject.connect on_success: on_success, on_failure: on_failure
54
+ end
55
+
56
+ it "tries to open an EM connection using the connector's handler class" do
57
+ expect( em_system ).to have_received( :connect ) do |server, port, handler, *handler_args|
58
+ expect( server ).to eq( :the_server )
59
+ expect( port ).to eq( :the_port )
60
+ expect( handler ).to eq( handler_class )
61
+ end
62
+ end
63
+
64
+ it "exposes the handler instance" do
65
+ expect( subject.connection ).to eq( @handler_instance )
66
+ end
67
+
68
+ it "sets the connection status to :connecting" do
69
+ expect( subject.connection_status ).to eq( :connecting )
70
+ end
71
+
72
+ context "when connection is completed" do
73
+ before do
74
+ @handler_instance.connection_completed
75
+ end
76
+
77
+ it "reports success and not failure" do
78
+ expect( on_success ).to have_received( :call )
79
+ expect( on_failure ).not_to have_received( :call )
80
+ end
81
+
82
+ it "sets the connection status to :connected" do
83
+ expect( subject.connection_status ).to eq( :connected )
84
+ end
85
+ end
86
+
87
+ context "when the connection attempt fails" do
88
+ before do
89
+ @handler_instance.unbind
90
+ end
91
+
92
+ it "reports failure and not success" do
93
+ expect( on_failure ).to have_received(:call)
94
+ expect( on_success ).not_to have_received(:call)
95
+ end
96
+
97
+ it "sets the connection status to :disconnected" do
98
+ expect( subject.connection_status ).to eq( :disconnected )
99
+ end
100
+ end
101
+
102
+ context "following successful connection" do
103
+ before do
104
+ @handler_instance.connection_completed
105
+ end
106
+
107
+ it "does not report failure later when subsequently disconnected" do
108
+ @handler_instance.unbind
109
+ expect( on_failure ).not_to have_received(:call)
110
+ end
111
+ end
112
+ end
113
+
114
+ context "when previously connected" do
115
+ before do
116
+ # Establish previous connection.
117
+ subject.connect
118
+ @handler_instance.connection_completed
119
+ end
120
+
121
+ context "when currently connected" do
122
+ before do
123
+ subject.connect on_success: on_success, on_failure: on_failure
124
+ end
125
+
126
+ it "reports success and not failure" do
127
+ expect( on_success ).to have_received( :call )
128
+ expect( on_failure ).not_to have_received( :call )
129
+ end
130
+ end
131
+
132
+ context "when not currently connected" do
133
+ before do
134
+ @handler_instance.unbind
135
+ allow( @handler_instance ).to receive( :reconnect )
136
+
137
+ subject.connect on_success: on_success, on_failure: on_failure
138
+ expect( on_success ).not_to have_received( :call ) # Sanity check.
139
+ end
140
+
141
+ it "reconnects" do
142
+ expect( @handler_instance ).to have_received( :reconnect ).with( :the_server, :the_port )
143
+ end
144
+
145
+ it "reports success and not failure when connected" do
146
+ @handler_instance.connection_completed
147
+ expect( on_success ).to have_received( :call )
148
+ expect( on_failure ).not_to have_received( :call )
149
+ end
150
+
151
+ it "reports failure and not success when unbound" do
152
+ @handler_instance.unbind
153
+ expect( on_failure ).to have_received( :call )
154
+ expect( on_success ).not_to have_received( :call )
155
+ end
156
+ end
157
+ end
158
+
159
+ context "when a pending connection is in progress" do
160
+ before do
161
+ # Initiate previously pending connection.
162
+ subject.connect(
163
+ on_success: on_success_of_pending,
164
+ on_failure: on_failure_of_pending,
165
+ )
166
+
167
+ subject.connect on_success: on_success, on_failure: on_failure
168
+ end
169
+
170
+ let( :on_success_of_pending ) { double(:on_success_of_pending, call: nil) }
171
+ let( :on_failure_of_pending ) { double(:on_failure_of_pending, call: nil) }
172
+
173
+ it "does not issue its own separate EM connection request" do
174
+ expect( em_system ).to have_received( :connect ).once
175
+ end
176
+
177
+ context "when connection is completed" do
178
+ before do
179
+ @handler_instance.connection_completed
180
+ end
181
+
182
+ it "reports success for previously pending request" do
183
+ expect( on_success_of_pending ).to have_received( :call )
184
+ end
185
+
186
+ it "reports success for current request" do
187
+ expect( on_success ).to have_received( :call )
188
+ end
189
+ end
190
+
191
+ context "when the connection attempt fails" do
192
+ before do
193
+ @handler_instance.unbind
194
+ end
195
+
196
+ it "reports failure for previously pending request" do
197
+ expect( on_failure_of_pending ).to have_received( :call )
198
+ end
199
+
200
+ it "reports failure for current request" do
201
+ expect( on_failure ).to have_received( :call )
202
+ end
203
+ end
204
+
205
+ end
206
+ end
207
+
208
+ context "with SSL" do
209
+ let( :encryption ) { :use_ssl }
210
+ before do
211
+ @handler_instance = nil
212
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
213
+ @handler_instance = handler.new( *handler_args )
214
+ allow( @handler_instance ).to receive( :start_tls )
215
+ nil
216
+ end
217
+ end
218
+
219
+ let( :on_success ) { double(:on_success, call: nil) }
220
+ let( :on_failure ) { double(:on_failure, call: nil) }
221
+
222
+ context "initial connection" do
223
+ before do
224
+ subject.connect on_success: on_success, on_failure: on_failure
225
+ end
226
+
227
+ it "tries to open an EM connection using the connector's handler class" do
228
+ expect( em_system ).to have_received( :connect ) do |server, port, handler, *handler_args|
229
+ expect( server ).to eq( :the_server )
230
+ expect( port ).to eq( :the_port )
231
+ expect( handler ).to eq( handler_class )
232
+ end
233
+ end
234
+
235
+ it "exposes the handler instance" do
236
+ expect( subject.connection ).to eq( @handler_instance )
237
+ end
238
+
239
+ it "sets the connection status to :connecting" do
240
+ expect( subject.connection_status ).to eq( :connecting )
241
+ end
242
+
243
+ context "when the EM HTTP connection is completed" do
244
+ before do
245
+ @handler_instance.connection_completed
246
+ end
247
+
248
+ it "tries to initiate TLS/SSL on the connection" do
249
+ expect( @handler_instance ).to have_received( :start_tls )
250
+ end
251
+
252
+ context "when the SSL handshake is completed" do
253
+ before do
254
+ @handler_instance.ssl_handshake_completed
255
+ end
256
+
257
+ it "reports success and not failure" do
258
+ expect( on_success ).to have_received( :call )
259
+ expect( on_failure ).not_to have_received( :call )
260
+ end
261
+
262
+ it "sets the connection status to :connected" do
263
+ expect( subject.connection_status ).to eq( :connected )
264
+ end
265
+ end
266
+
267
+ context "when the HTTP connection is lost" do
268
+ before do
269
+ @handler_instance.unbind
270
+ end
271
+
272
+ it "reports failure and not success" do
273
+ expect( on_failure ).to have_received(:call)
274
+ expect( on_success ).not_to have_received(:call)
275
+ end
276
+
277
+ it "sets the connection status to :disconnected" do
278
+ expect( subject.connection_status ).to eq( :disconnected )
279
+ end
280
+ end
281
+
282
+ end
283
+
284
+ context "when the EM HTTP connection attempt fails" do
285
+ before do
286
+ @handler_instance.unbind
287
+ end
288
+
289
+ it "reports failure and not success" do
290
+ expect( on_failure ).to have_received(:call)
291
+ expect( on_success ).not_to have_received(:call)
292
+ end
293
+
294
+ it "sets the connection status to :disconnected" do
295
+ expect( subject.connection_status ).to eq( :disconnected )
296
+ end
297
+ end
298
+
299
+ context "following successful connection and SSL handshake" do
300
+ before do
301
+ @handler_instance.connection_completed
302
+ @handler_instance.ssl_handshake_completed
303
+ end
304
+
305
+ it "does not report failure later when subsequently disconnected" do
306
+ @handler_instance.unbind
307
+ expect( on_failure ).not_to have_received(:call)
308
+ end
309
+ end
310
+ end
311
+ end
312
+ end
313
+
314
+ context "when an open connection is lost or remotely disconnected" do
315
+ let( :encryption ) { :none }
316
+ before do
317
+ @handler_instance = nil
318
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
319
+ @handler_instance = handler.new( *handler_args )
320
+ nil
321
+ end
322
+ subject.connect
323
+ @handler_instance.connection_completed
324
+ @handler_instance.unbind
325
+ end
326
+
327
+ it "sets the connection status to :disconnected" do
328
+ expect( subject.connection_status ).to eq( :disconnected )
329
+ end
330
+ end
331
+
332
+ describe '#disconnect' do
333
+ let( :encryption ) { :none }
334
+ let( :on_completed ) { double(:on_completed, call: nil) }
335
+
336
+ context "when has never been connected" do
337
+ before do
338
+ subject.disconnect on_completed: on_completed
339
+ end
340
+
341
+ it "reports completion" do
342
+ expect( on_completed ).to have_received( :call )
343
+ end
344
+
345
+ it "leaves connection status as :initial" do
346
+ expect( subject.connection_status ).to eq( :initial )
347
+ end
348
+ end
349
+
350
+ context "when previously connected" do
351
+ before do
352
+ @handler_instance = nil
353
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
354
+ @handler_instance = handler.new( *handler_args )
355
+ nil
356
+ end
357
+ subject.connect
358
+ @handler_instance.connection_completed
359
+ end
360
+
361
+ context "when not currently connected" do
362
+ before do
363
+ @handler_instance.unbind
364
+ subject.disconnect on_completed: on_completed
365
+ end
366
+
367
+ it "reports completion" do
368
+ expect( on_completed ).to have_received( :call )
369
+ end
370
+
371
+ it "leaves the connection status as :disconnected" do
372
+ expect( subject.connection_status ).to eq( :disconnected )
373
+ end
374
+ end
375
+
376
+ context "when currently connected" do
377
+ before do
378
+ allow( @handler_instance ).to receive( :close_connection )
379
+ subject.disconnect on_completed: on_completed
380
+ end
381
+
382
+ it "closes the open connection" do
383
+ expect( @handler_instance ).to have_received( :close_connection )
384
+ end
385
+
386
+ it "sets the connection status to :disconnecting" do
387
+ expect( subject.connection_status ).to eq( :disconnecting )
388
+ end
389
+
390
+ context "when done disconnecting" do
391
+ it "reports completion" do
392
+ expect( on_completed ).not_to have_received( :call ) # Sanity check.
393
+ @handler_instance.unbind
394
+ expect( on_completed ).to have_received( :call )
395
+ end
396
+
397
+ it "sets the connection status to :disconnected" do
398
+ @handler_instance.unbind
399
+ expect( subject.connection_status ).to eq( :disconnected )
400
+ end
401
+ end
402
+ end
403
+
404
+ end
405
+ end
406
+
407
+ describe '#send_request' do
408
+ let( :encryption ) { :none }
409
+ let( :opts_for_send_request ) {
410
+ { on_response: on_response, on_failure: on_failure }
411
+ }
412
+ let( :on_response ) { double(:on_response, call: nil) }
413
+ let( :on_failure ) { double(:on_failure , call: nil) }
414
+
415
+ context "while not connected" do
416
+ it "reports failure" do
417
+ subject.send_request :the_request_data, opts_for_send_request
418
+ expect( on_failure ).to have_received( :call )
419
+ end
420
+ end
421
+
422
+ context "while connected" do
423
+ before do
424
+ @handler_instance = nil
425
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
426
+ @handler_instance = handler.new( *handler_args )
427
+ nil
428
+ end
429
+ subject.connect
430
+ @handler_instance.connection_completed
431
+ allow( @handler_instance ).to receive( :send_request )
432
+ subject.send_request :the_request_data, opts_for_send_request
433
+ end
434
+
435
+ it "sends a request to the POSLynx" do
436
+ expect( @handler_instance ).to have_received( :send_request ).with( :the_request_data )
437
+ end
438
+
439
+ it "records the pending request state" do
440
+ expect( subject.latest_request ).to eq( Net::EMC.RequestCall(
441
+ :the_request_data, opts_for_send_request
442
+ ) )
443
+ expect( subject.status_of_request ).to eq( :pending )
444
+ end
445
+
446
+ context "when a response is received" do
447
+ before do
448
+ @handler_instance.receive_response :the_response_data
449
+ end
450
+
451
+ it "records the got-response request state" do
452
+ expect( subject.status_of_request ).to eq( :got_response )
453
+ end
454
+
455
+ it "reports the response data" do
456
+ expect( on_response ).to have_received( :call ).with( :the_response_data )
457
+ end
458
+ end
459
+
460
+ context "when connection is lost w/o response" do
461
+ before do
462
+ @handler_instance.unbind
463
+ end
464
+
465
+ it "records the failed request state" do
466
+ expect( subject.status_of_request ).to eq( :failed )
467
+ end
468
+
469
+ it "reports failure" do
470
+ expect( on_failure ).to have_received( :call )
471
+ end
472
+ end
473
+
474
+ end
475
+ end
476
+
477
+ describe '#get_response' do
478
+ let( :encryption ) { :none }
479
+ let( :opts_for_get_response ) {
480
+ { on_response: on_response, on_failure: on_failure }
481
+ }
482
+ let( :on_response ) { double(:on_response, call: nil) }
483
+ let( :on_failure ) { double(:on_failure , call: nil) }
484
+
485
+ context "while not connected" do
486
+ it "reports failure" do
487
+ subject.get_response opts_for_get_response
488
+ expect( on_failure ).to have_received( :call )
489
+ end
490
+ end
491
+
492
+ context "while connected" do
493
+ before do
494
+ @handler_instance = nil
495
+ allow( em_system ).to receive( :connect ) do |server, port, handler, *handler_args|
496
+ @handler_instance = handler.new( *handler_args )
497
+ nil
498
+ end
499
+ subject.connect
500
+ @handler_instance.connection_completed
501
+ end
502
+
503
+ context "when no request has been previously sent" do
504
+ it "reports failure" do
505
+ subject.get_response opts_for_get_response
506
+ expect( on_failure ).to have_received( :call )
507
+ end
508
+ end
509
+
510
+ context "when a previous request is still pending" do
511
+ before do
512
+ allow( @handler_instance ).to receive( :send_request )
513
+ subject.send_request :prev_request_data, some_prev_option: :some_prev_value
514
+ end
515
+
516
+ it "replaces the previous request options" do
517
+ subject.get_response opts_for_get_response
518
+ expect( subject.latest_request ).to eq( Net::EMC.RequestCall(
519
+ :prev_request_data, opts_for_get_response
520
+ ) )
521
+ end
522
+
523
+ context "when a response is received" do
524
+ before do
525
+ subject.get_response opts_for_get_response
526
+ @handler_instance.receive_response :the_response_data
527
+ end
528
+
529
+ it "records the got-response request state" do
530
+ expect( subject.status_of_request ).to eq( :got_response )
531
+ end
532
+
533
+ it "reports the response data" do
534
+ expect( on_response ).to have_received( :call ).with( :the_response_data )
535
+ end
536
+ end
537
+
538
+ context "when connection is lost w/o response" do
539
+ before do
540
+ subject.get_response opts_for_get_response
541
+ @handler_instance.unbind
542
+ end
543
+
544
+ it "records the failed request state" do
545
+ expect( subject.status_of_request ).to eq( :failed )
546
+ end
547
+
548
+ it "reports failure" do
549
+ expect( on_failure ).to have_received( :call )
550
+ end
551
+ end
552
+ end
553
+
554
+ context "when the previous request failed, there is an open connection" do
555
+ before do
556
+ allow( @handler_instance ).to receive( :send_request )
557
+ subject.send_request :prev_request_data
558
+ @handler_instance.unbind
559
+ @handler_instance.connection_completed
560
+ end
561
+
562
+ it "reports failure" do
563
+ subject.get_response opts_for_get_response
564
+ expect( on_failure ).to have_received( :call )
565
+ end
566
+ end
567
+
568
+ context "when the previous request has completed" do
569
+ before do
570
+ allow( @handler_instance ).to receive( :send_request )
571
+ subject.send_request :prev_request_data, some_prev_option: :some_prev_value
572
+ @handler_instance.receive_response :the_previous_response
573
+ end
574
+
575
+ it "replaces the previous request options" do
576
+ subject.get_response opts_for_get_response
577
+ expect( subject.latest_request ).to eq( Net::EMC.RequestCall(
578
+ :prev_request_data, opts_for_get_response
579
+ ) )
580
+ end
581
+
582
+ it "reverts to a request status of pending" do
583
+ subject.get_response opts_for_get_response
584
+ expect( subject.status_of_request ).to eq( :pending )
585
+ end
586
+
587
+ context "when a response is received" do
588
+ before do
589
+ subject.get_response opts_for_get_response
590
+ @handler_instance.receive_response :the_response_data
591
+ end
592
+
593
+ it "records the got-response request state" do
594
+ expect( subject.status_of_request ).to eq( :got_response )
595
+ end
596
+
597
+ it "reports the response data" do
598
+ expect( on_response ).to have_received( :call ).with( :the_response_data )
599
+ end
600
+ end
601
+
602
+ context "when connection is lost w/o response" do
603
+ before do
604
+ subject.get_response opts_for_get_response
605
+ @handler_instance.unbind
606
+ end
607
+
608
+ it "records the failed request state" do
609
+ expect( subject.status_of_request ).to eq( :failed )
610
+ end
611
+
612
+ it "reports failure" do
613
+ expect( on_failure ).to have_received( :call )
614
+ end
615
+ end
616
+ end
617
+
618
+ end
619
+ end
620
+
621
+ end
622
+ end
623
+
624
+ end