stomper 1.0.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/{spec/spec.opts → .rspec} +0 -2
- data/Gemfile +4 -0
- data/LICENSE +201 -201
- data/README.md +130 -0
- data/Rakefile +5 -0
- data/examples/basic.rb +38 -0
- data/examples/events.rb +54 -0
- data/features/acking_messages.feature +147 -0
- data/features/disconnecting.feature +12 -0
- data/features/establish_connection.feature +44 -0
- data/features/protocol_version_negotiation.feature +61 -0
- data/features/receipts.feature +72 -0
- data/features/scopes.feature +32 -0
- data/features/secure_connections.feature +38 -0
- data/features/send_and_message.feature +28 -0
- data/features/steps/acking_messages_steps.rb +39 -0
- data/features/steps/disconnecting_steps.rb +8 -0
- data/features/steps/establish_connection_steps.rb +74 -0
- data/features/steps/frame_transmission_steps.rb +35 -0
- data/features/steps/protocol_version_negotiation_steps.rb +15 -0
- data/features/steps/receipts_steps.rb +79 -0
- data/features/steps/scopes_steps.rb +52 -0
- data/features/steps/secure_connections_steps.rb +41 -0
- data/features/steps/send_and_message_steps.rb +35 -0
- data/features/steps/subscribing_steps.rb +36 -0
- data/features/steps/threaded_receiver_steps.rb +8 -0
- data/features/steps/transactions_steps.rb +0 -0
- data/features/subscribing.feature +151 -0
- data/features/support/env.rb +11 -0
- data/features/support/header_helpers.rb +12 -0
- data/features/support/ssl/README +6 -0
- data/features/support/ssl/broker_cert.csr +17 -0
- data/features/support/ssl/broker_cert.pem +72 -0
- data/features/support/ssl/broker_key.pem +27 -0
- data/features/support/ssl/client_cert.csr +17 -0
- data/features/support/ssl/client_cert.pem +72 -0
- data/features/support/ssl/client_key.pem +27 -0
- data/features/support/ssl/demoCA/cacert.pem +17 -0
- data/features/support/ssl/demoCA/index.txt +2 -0
- data/features/support/ssl/demoCA/index.txt.attr +1 -0
- data/features/support/ssl/demoCA/index.txt.attr.old +1 -0
- data/features/support/ssl/demoCA/index.txt.old +1 -0
- data/features/support/ssl/demoCA/newcerts/01.pem +72 -0
- data/features/support/ssl/demoCA/newcerts/02.pem +72 -0
- data/features/support/ssl/demoCA/private/cakey.pem +17 -0
- data/features/support/ssl/demoCA/serial +1 -0
- data/features/support/ssl/demoCA/serial.old +1 -0
- data/features/support/test_stomp_server.rb +150 -0
- data/features/threaded_receiver.feature +11 -0
- data/features/transactions.feature +66 -0
- data/lib/stomper.rb +30 -20
- data/lib/stomper/connection.rb +442 -102
- data/lib/stomper/errors.rb +59 -0
- data/lib/stomper/extensions.rb +10 -0
- data/lib/stomper/extensions/common.rb +258 -0
- data/lib/stomper/extensions/events.rb +213 -0
- data/lib/stomper/extensions/heartbeat.rb +101 -0
- data/lib/stomper/extensions/scoping.rb +56 -0
- data/lib/stomper/frame.rb +54 -0
- data/lib/stomper/frame_serializer.rb +217 -0
- data/lib/stomper/headers.rb +15 -0
- data/lib/stomper/receipt_manager.rb +36 -0
- data/lib/stomper/receivers.rb +7 -0
- data/lib/stomper/receivers/threaded.rb +71 -0
- data/lib/stomper/scopes.rb +9 -0
- data/lib/stomper/scopes/header_scope.rb +49 -0
- data/lib/stomper/scopes/receipt_scope.rb +44 -0
- data/lib/stomper/scopes/transaction_scope.rb +109 -0
- data/lib/stomper/sockets.rb +66 -28
- data/lib/stomper/subscription_manager.rb +79 -0
- data/lib/stomper/support.rb +68 -0
- data/lib/stomper/support/1.8/frame_serializer.rb +53 -0
- data/lib/stomper/support/1.8/headers.rb +183 -0
- data/lib/stomper/support/1.9/frame_serializer.rb +64 -0
- data/lib/stomper/support/1.9/headers.rb +172 -0
- data/lib/stomper/support/ruby.rb +13 -0
- data/lib/stomper/uris.rb +49 -0
- data/lib/stomper/version.rb +7 -0
- data/spec/spec_helper.rb +13 -9
- data/spec/stomper/connection_spec.rb +712 -0
- data/spec/stomper/extensions/common_spec.rb +187 -0
- data/spec/stomper/extensions/events_spec.rb +78 -0
- data/spec/stomper/extensions/heartbeat_spec.rb +103 -0
- data/spec/stomper/extensions/scoping_spec.rb +21 -0
- data/spec/stomper/frame_serializer_1.8_spec.rb +318 -0
- data/spec/stomper/frame_serializer_spec.rb +316 -0
- data/spec/stomper/frame_spec.rb +36 -0
- data/spec/stomper/headers_spec.rb +224 -0
- data/spec/stomper/receipt_manager_spec.rb +91 -0
- data/spec/stomper/receivers/threaded_spec.rb +116 -0
- data/spec/stomper/scopes/header_scope_spec.rb +42 -0
- data/spec/stomper/scopes/receipt_scope_spec.rb +51 -0
- data/spec/stomper/scopes/transaction_scope_spec.rb +183 -0
- data/spec/stomper/sockets_spec.rb +113 -0
- data/spec/stomper/subscription_manager_spec.rb +107 -0
- data/spec/stomper/support_spec.rb +69 -0
- data/spec/stomper/uris_spec.rb +54 -0
- data/spec/stomper_spec.rb +9 -0
- data/spec/support/custom_argument_matchers.rb +57 -0
- data/spec/support/existential_frame_matchers.rb +19 -0
- data/spec/support/frame_header_matchers.rb +10 -0
- data/stomper.gemspec +30 -0
- metadata +272 -97
- data/AUTHORS +0 -21
- data/CHANGELOG +0 -20
- data/README.rdoc +0 -120
- data/lib/stomper/client.rb +0 -34
- data/lib/stomper/frame_reader.rb +0 -73
- data/lib/stomper/frame_writer.rb +0 -21
- data/lib/stomper/frames.rb +0 -39
- data/lib/stomper/frames/abort.rb +0 -10
- data/lib/stomper/frames/ack.rb +0 -25
- data/lib/stomper/frames/begin.rb +0 -11
- data/lib/stomper/frames/client_frame.rb +0 -89
- data/lib/stomper/frames/commit.rb +0 -10
- data/lib/stomper/frames/connect.rb +0 -10
- data/lib/stomper/frames/connected.rb +0 -30
- data/lib/stomper/frames/disconnect.rb +0 -10
- data/lib/stomper/frames/error.rb +0 -21
- data/lib/stomper/frames/message.rb +0 -48
- data/lib/stomper/frames/receipt.rb +0 -19
- data/lib/stomper/frames/send.rb +0 -10
- data/lib/stomper/frames/server_frame.rb +0 -38
- data/lib/stomper/frames/subscribe.rb +0 -42
- data/lib/stomper/frames/unsubscribe.rb +0 -19
- data/lib/stomper/open_uri_interface.rb +0 -41
- data/lib/stomper/receipt_handlers.rb +0 -23
- data/lib/stomper/receiptor.rb +0 -38
- data/lib/stomper/subscriber.rb +0 -76
- data/lib/stomper/subscription.rb +0 -128
- data/lib/stomper/subscriptions.rb +0 -95
- data/lib/stomper/threaded_receiver.rb +0 -59
- data/lib/stomper/transaction.rb +0 -185
- data/lib/stomper/transactor.rb +0 -50
- data/lib/stomper/uri.rb +0 -55
- data/spec/client_spec.rb +0 -29
- data/spec/connection_spec.rb +0 -22
- data/spec/frame_reader_spec.rb +0 -37
- data/spec/frame_writer_spec.rb +0 -27
- data/spec/frames/client_frame_spec.rb +0 -66
- data/spec/frames/indirect_frame_spec.rb +0 -45
- data/spec/frames/server_frame_spec.rb +0 -85
- data/spec/open_uri_interface_spec.rb +0 -132
- data/spec/receiptor_spec.rb +0 -35
- data/spec/shared_connection_examples.rb +0 -79
- data/spec/subscriber_spec.rb +0 -77
- data/spec/subscription_spec.rb +0 -157
- data/spec/subscriptions_spec.rb +0 -145
- data/spec/threaded_receiver_spec.rb +0 -33
- data/spec/transaction_spec.rb +0 -139
- data/spec/transactor_spec.rb +0 -46
@@ -0,0 +1,113 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Stomper
|
5
|
+
describe Sockets do
|
6
|
+
describe Sockets::TCP do
|
7
|
+
before(:each) do
|
8
|
+
@tcp_socket = mock('tcp socket')
|
9
|
+
::TCPSocket.stub(:new => @tcp_socket)
|
10
|
+
@tcp = ::Stomper::Sockets::TCP.new('host', 12345)
|
11
|
+
end
|
12
|
+
it "should create a new instance that delegates to TCPSocket" do
|
13
|
+
@tcp_socket.should_receive(:ready?).and_return(true)
|
14
|
+
@tcp_socket.should_receive(:read).and_return('this is what we read')
|
15
|
+
@tcp_socket.should_receive(:write).with('blather').and_return(42)
|
16
|
+
|
17
|
+
@tcp.ready?.should be_true
|
18
|
+
@tcp.read.should == 'this is what we read'
|
19
|
+
@tcp.write('blather').should == 42
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe Sockets::SSL do
|
24
|
+
before(:each) do
|
25
|
+
@tcp_socket = mock('tcp socket')
|
26
|
+
::TCPSocket.stub(:new => @tcp_socket)
|
27
|
+
@ssl_socket = mock('ssl socket', :sync_close= => true, :connect => true, :io => @tcp_socket)
|
28
|
+
::OpenSSL::SSL::SSLSocket.stub(:new => @ssl_socket)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should use the underlying TCP socket for :ready?" do
|
32
|
+
@ssl_socket.should_receive(:post_connection_check).with('host').and_return(true)
|
33
|
+
@ssl = ::Stomper::Sockets::SSL.new('host', 56789)
|
34
|
+
@tcp_socket.should_receive(:ready?).and_return(true)
|
35
|
+
|
36
|
+
@ssl.ready?.should be_true
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should use the underlying TCP socket for :shutdown" do
|
40
|
+
@ssl_socket.should_receive(:post_connection_check).with('host').and_return(true)
|
41
|
+
@ssl = ::Stomper::Sockets::SSL.new('host', 56789)
|
42
|
+
@tcp_socket.should_receive(:shutdown).with('args').and_return(true)
|
43
|
+
|
44
|
+
@ssl.shutdown('args').should be_true
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should delegate unknown methods to SSLSocket" do
|
48
|
+
@ssl_socket.should_receive(:post_connection_check).with('host').and_return(true)
|
49
|
+
@ssl = ::Stomper::Sockets::SSL.new('host', 56789)
|
50
|
+
@ssl_socket.should_receive(:read).and_return('this is what we read')
|
51
|
+
@ssl_socket.should_receive(:write).with('blather').and_return(42)
|
52
|
+
|
53
|
+
@ssl.read.should == 'this is what we read'
|
54
|
+
@ssl.write('blather').should == 42
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should not perform a post_connection_check if option value is nil or false" do
|
58
|
+
@ssl_socket.should_not_receive(:post_connection_check)
|
59
|
+
@ssl = ::Stomper::Sockets::SSL.new('host', 56789, { :post_connection_check => false })
|
60
|
+
@ssl = ::Stomper::Sockets::SSL.new('host', 56789, { :post_connection_check => nil })
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should perform a post_connection_check against the host if the option value is true" do
|
64
|
+
@ssl_socket.should_receive(:post_connection_check).with('host.name.tld').and_return(true)
|
65
|
+
@ssl = ::Stomper::Sockets::SSL.new('host.name.tld', 56789, { :post_connection_check => true })
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should perform a post_connection_check against the option value otherwise" do
|
69
|
+
@ssl_socket.should_receive(:post_connection_check).with('user specified name').and_return(true)
|
70
|
+
@ssl = ::Stomper::Sockets::SSL.new('host.name.tld', 56789, { :post_connection_check => 'user specified name' })
|
71
|
+
|
72
|
+
@ssl_socket.should_receive(:post_connection_check).with(66).and_return(true)
|
73
|
+
@ssl = ::Stomper::Sockets::SSL.new('host.name.tld', 56789, { :post_connection_check => 66 })
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "SSL Context Options" do
|
77
|
+
before(:each) do
|
78
|
+
@ssl_context = mock('context')
|
79
|
+
::OpenSSL::SSL::SSLContext.stub(:new => @ssl_context)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should apply sensible defaults when no options are specified" do
|
83
|
+
@ssl_context.should_receive(:verify_mode=).with(::OpenSSL::SSL::VERIFY_PEER |
|
84
|
+
::OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT)
|
85
|
+
@ssl_context.should_receive(:ca_file=).with(nil)
|
86
|
+
@ssl_context.should_receive(:ca_path=).with(nil)
|
87
|
+
@ssl_context.should_receive(:cert=).with(nil)
|
88
|
+
@ssl_context.should_receive(:key=).with(nil)
|
89
|
+
|
90
|
+
@ssl_socket.should_receive(:post_connection_check).with('host').and_return(true)
|
91
|
+
@ssl = ::Stomper::Sockets::SSL.new('host', 56789)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should override sensible defaults with supplied options" do
|
95
|
+
@ssl_context.should_receive(:verify_mode=).with("kage")
|
96
|
+
@ssl_context.should_receive(:ca_file=).with("jables")
|
97
|
+
@ssl_context.should_receive(:ca_path=).with("the d")
|
98
|
+
@ssl_context.should_receive(:cert=).with("scepter")
|
99
|
+
@ssl_context.should_receive(:key=).with("key")
|
100
|
+
|
101
|
+
@ssl_socket.should_receive(:post_connection_check).with('host').and_return(true)
|
102
|
+
@ssl = ::Stomper::Sockets::SSL.new('host', 56789, {
|
103
|
+
:verify_mode => "kage",
|
104
|
+
:ca_file => "jables",
|
105
|
+
:ca_path => "the d",
|
106
|
+
:cert => "scepter",
|
107
|
+
:key => "key"
|
108
|
+
})
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Stomper
|
5
|
+
describe SubscriptionManager do
|
6
|
+
before(:each) do
|
7
|
+
@connection = mock("connection")
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should bind to the on_receipt event handler" do
|
11
|
+
receipt = mock('receipt')
|
12
|
+
@connection.should_receive(:on_message)
|
13
|
+
@connection.should_receive(:on_unsubscribe)
|
14
|
+
@subscription_manager = SubscriptionManager.new(@connection)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "usage" do
|
18
|
+
before(:each) do
|
19
|
+
@connection.extend ::Stomper::Extensions::Events
|
20
|
+
@subscription_manager = SubscriptionManager.new(@connection)
|
21
|
+
@subscribe_frame = ::Stomper::Frame.new('SUBSCRIBE', {:id => '1234', :destination => '/queue/testing'})
|
22
|
+
@unsubscribe_frame = ::Stomper::Frame.new('UNSUBSCRIBE', {:id => '1234'})
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should correctly report subscribed IDs" do
|
26
|
+
@subscription_manager.add(@subscribe_frame, lambda { |m| true })
|
27
|
+
@subscription_manager.subscribed_id?('1234').should be_true
|
28
|
+
@subscription_manager.subscribed_id?('4321').should be_false
|
29
|
+
@subscription_manager.__send__(:remove, @unsubscribe_frame)
|
30
|
+
@subscription_manager.subscribed_id?('1234').should be_false
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should correctly report subscribed destinations" do
|
34
|
+
@subscription_manager.add(@subscribe_frame, lambda { |m| true })
|
35
|
+
@subscription_manager.subscribed_destination?('/queue/testing').should be_true
|
36
|
+
@subscription_manager.subscribed_destination?('/queue/test').should be_false
|
37
|
+
@subscription_manager.__send__(:remove, @unsubscribe_frame)
|
38
|
+
@subscription_manager.subscribed_destination?('/queue/testing').should be_false
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should correctly map subscribed destinations to their IDs" do
|
42
|
+
alt_subscribe_frame = ::Stomper::Frame.new('SUBSCRIBE', {:id => '4567', :destination => '/queue/testing'})
|
43
|
+
alt_unsubscribe_frame = ::Stomper::Frame.new('UNSUBSCRIBE', {:id => '4567'})
|
44
|
+
@subscription_manager.add(@subscribe_frame, lambda { |m| true })
|
45
|
+
@subscription_manager.add(alt_subscribe_frame, lambda { |m| true })
|
46
|
+
@subscription_manager.ids_for_destination('/queue/testing').should == ['1234', '4567']
|
47
|
+
@subscription_manager.ids_for_destination('/queue/test').should be_nil
|
48
|
+
@subscription_manager.__send__(:remove, @unsubscribe_frame)
|
49
|
+
@subscription_manager.ids_for_destination('/queue/testing').should == ['4567']
|
50
|
+
@subscription_manager.__send__(:remove, alt_unsubscribe_frame)
|
51
|
+
@subscription_manager.ids_for_destination('/queue/testing').should be_nil
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should allow a subscription handler to be registered within a callback" do
|
55
|
+
alt_subscribe_frame = ::Stomper::Frame.new('SUBSCRIBE', {:id => '4567', :destination => '/queue/testing'})
|
56
|
+
triggered = [false, false]
|
57
|
+
callback = lambda do |m|
|
58
|
+
triggered[0] = true
|
59
|
+
@subscription_manager.add(alt_subscribe_frame, lambda { |m| triggered[1] = true })
|
60
|
+
end
|
61
|
+
@subscription_manager.add(@subscribe_frame, callback)
|
62
|
+
@connection.__send__(:trigger_received_frame, ::Stomper::Frame.new('MESSAGE', { :subscription => '1234' }))
|
63
|
+
@connection.__send__(:trigger_received_frame, ::Stomper::Frame.new('MESSAGE', { :subscription => '4567' }))
|
64
|
+
triggered.should == [true, true]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should allow a subscription to be removed within a callback" do
|
68
|
+
triggered = 0
|
69
|
+
callback = lambda do |m|
|
70
|
+
triggered += 1
|
71
|
+
@connection.__send__(:trigger_received_frame, ::Stomper::Frame.new('UNSUBSCRIBE', { :id => '1234' }))
|
72
|
+
end
|
73
|
+
@subscription_manager.add(@subscribe_frame, callback)
|
74
|
+
@connection.__send__(:trigger_received_frame, ::Stomper::Frame.new('MESSAGE', { :subscription => '1234' }))
|
75
|
+
@connection.__send__(:trigger_received_frame, ::Stomper::Frame.new('MESSAGE', { :subscription => '1234' }))
|
76
|
+
triggered.should == 1
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should allow a receipt handler to be registered within a callback in separate threads" do
|
80
|
+
alt_subscribe_frame = ::Stomper::Frame.new('SUBSCRIBE', {:id => '4567', :destination => '/queue/testing'})
|
81
|
+
triggered = [false, false]
|
82
|
+
started_r1 = false
|
83
|
+
callback = lambda do |r|
|
84
|
+
triggered[0] = true
|
85
|
+
Thread.stop
|
86
|
+
end
|
87
|
+
@subscription_manager.add(@subscribe_frame, callback)
|
88
|
+
r_1 = Thread.new(@connection) do |c|
|
89
|
+
started_r1 = true
|
90
|
+
Thread.stop
|
91
|
+
c.__send__(:trigger_received_frame, ::Stomper::Frame.new('MESSAGE', { :subscription => '1234' }))
|
92
|
+
end
|
93
|
+
r_2 = Thread.new(@connection) do |c|
|
94
|
+
Thread.pass until triggered[0]
|
95
|
+
@subscription_manager.add(alt_subscribe_frame, lambda { |r| triggered[1] = true })
|
96
|
+
r_1.run
|
97
|
+
c.__send__(:trigger_received_frame, ::Stomper::Frame.new('MESSAGE', { :subscription => '4567' }))
|
98
|
+
end
|
99
|
+
Thread.pass until started_r1
|
100
|
+
r_1.run
|
101
|
+
r_1.join
|
102
|
+
r_2.join
|
103
|
+
triggered.should == [true, true]
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module Stomper
|
5
|
+
describe Support do
|
6
|
+
before(:each) do
|
7
|
+
@hash = {
|
8
|
+
'a' => 'value 1',
|
9
|
+
:somekey => ['a', :set, 'of values', 33],
|
10
|
+
'13' => nil
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "keys_to_sym" do
|
15
|
+
it "should symbolize the keys of a hash without changing the original hash" do
|
16
|
+
symbolized_hash = Support.keys_to_sym(@hash)
|
17
|
+
|
18
|
+
@hash['a'].should == 'value 1'
|
19
|
+
@hash[:somekey].should == ['a', :set, 'of values', 33]
|
20
|
+
@hash['13'].should be_nil
|
21
|
+
|
22
|
+
symbolized_hash.keys.sort.should == [ :'13', :a, :somekey ]
|
23
|
+
symbolized_hash[:a].should == 'value 1'
|
24
|
+
symbolized_hash[:somekey].should == ['a', :set, 'of values', 33]
|
25
|
+
symbolized_hash[:'13'].should be_nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "keys_to_sym!" do
|
30
|
+
it "should symbolize the keys of a hash and replace the existing hash" do
|
31
|
+
Support.keys_to_sym!(@hash)
|
32
|
+
@hash.keys.sort.should == [ :'13', :a, :somekey ]
|
33
|
+
@hash[:a].should == 'value 1'
|
34
|
+
@hash[:somekey].should == ['a', :set, 'of values', 33]
|
35
|
+
@hash[:'13'].should be_nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "next_serial" do
|
40
|
+
it "should generate sequential numbers" do
|
41
|
+
first = Support.next_serial.to_i
|
42
|
+
second = Support.next_serial.to_i
|
43
|
+
third = Support.next_serial.to_i
|
44
|
+
first.should == second - 1
|
45
|
+
second.should == third - 1
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "constantize" do
|
50
|
+
it "should constantize a Class" do
|
51
|
+
Support.constantize(Class).should == ::Class
|
52
|
+
Support.constantize(::Stomper::Extensions::Events).should == ::Stomper::Extensions::Events
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should constantize string representations of known classes" do
|
56
|
+
Support.constantize("Module").should == ::Module
|
57
|
+
Support.constantize("::Module").should == ::Module
|
58
|
+
Support.constantize("::Stomper::Extensions").should == ::Stomper::Extensions
|
59
|
+
Support.constantize("Stomper::Receivers::Threaded").should == ::Stomper::Receivers::Threaded
|
60
|
+
end
|
61
|
+
|
62
|
+
it "should fail to constantize un-resolvable classes" do
|
63
|
+
lambda { Support.constantize("::Not::::Valid") }.should raise_error(NameError)
|
64
|
+
lambda { Support.constantize("Module::Does::Not::Exist") }.should raise_error(NameError)
|
65
|
+
lambda { Support.constantize("::Stomper::FrameSerializer::Nada") }.should raise_error(NameError)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
module URI
|
5
|
+
describe STOMP do
|
6
|
+
before(:each) do
|
7
|
+
@uri = ::URI.parse('stomp:///')
|
8
|
+
@uri_host = ::URI.parse('stomp://host.domain.tld:12345')
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should be the class of URIs with a scheme of 'stomp' parsed by URI.parse" do
|
12
|
+
@uri.should be_an_instance_of(::URI::STOMP)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should use port 61613 as a default if no port is specified" do
|
16
|
+
@uri.port.should == 61613
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should respond to :create_socket and return a TCP/IP socket built from its socket_factory" do
|
20
|
+
socket = mock('socket')
|
21
|
+
host_socket = mock('socket with host')
|
22
|
+
::Stomper::Sockets::TCP.should_receive(:new).with('localhost', 61613).and_return(socket)
|
23
|
+
::Stomper::Sockets::TCP.should_receive(:new).with('host.domain.tld', 12345).and_return(host_socket)
|
24
|
+
|
25
|
+
@uri.create_socket.should equal(socket)
|
26
|
+
@uri_host.create_socket.should equal(host_socket)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe STOMP_SSL do
|
31
|
+
before(:each) do
|
32
|
+
@uri = ::URI.parse("stomp+ssl:///")
|
33
|
+
@uri_host = ::URI.parse('stomp+ssl://other.domain.tld:98765')
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be the class of URIs with a scheme of 'stomp+ssl' parsed by URI.parse" do
|
37
|
+
@uri.should be_an_instance_of(::URI::STOMP_SSL)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use port 61612 as a default if no port is specified" do
|
41
|
+
@uri.port.should == 61612
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should respond to :create_socket and return a TCP/IP socket built from its socket_factory" do
|
45
|
+
socket = mock('socket')
|
46
|
+
host_socket = mock('socket with host')
|
47
|
+
::Stomper::Sockets::SSL.should_receive(:new).with('localhost', 61612, {}).and_return(socket)
|
48
|
+
::Stomper::Sockets::SSL.should_receive(:new).with('other.domain.tld', 98765, {}).and_return(host_socket)
|
49
|
+
|
50
|
+
@uri.create_socket.should equal(socket)
|
51
|
+
@uri_host.create_socket.should equal(host_socket)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module RSpec
|
3
|
+
module Mocks
|
4
|
+
module ArgumentMatchers
|
5
|
+
def stomper_frame_with_headers(*args)
|
6
|
+
command = args.last.is_a?(String) ? args.pop : nil
|
7
|
+
StomperFrameMatcher.new(command, nil, anythingize_lonely_keys(*args))
|
8
|
+
end
|
9
|
+
|
10
|
+
def stomper_frame_with_body(body, command=nil)
|
11
|
+
StomperFrameMatcher.new(command, body, nil)
|
12
|
+
end
|
13
|
+
|
14
|
+
def stomper_frame(body, *args)
|
15
|
+
command = args.last.is_a?(String) ? args.pop : nil
|
16
|
+
StomperFrameMatcher.new(command, body, anythingize_lonely_keys(*args))
|
17
|
+
end
|
18
|
+
|
19
|
+
def stomper_heartbeat_frame
|
20
|
+
StomperFrameMatcher.new(nil, nil, {})
|
21
|
+
end
|
22
|
+
|
23
|
+
class StomperFrameMatcher
|
24
|
+
def initialize(e_command, e_body, e_headers)
|
25
|
+
@expected_command = e_command && e_command.upcase
|
26
|
+
@expected_body = e_body
|
27
|
+
@expected_headers = e_headers
|
28
|
+
end
|
29
|
+
|
30
|
+
def ==(actual)
|
31
|
+
if @expected_command
|
32
|
+
return false unless @expected_command == actual.command
|
33
|
+
end
|
34
|
+
if @expected_body
|
35
|
+
return false unless @expected_body == actual.body
|
36
|
+
end
|
37
|
+
if @expected_headers
|
38
|
+
@expected_headers.each do |key, val|
|
39
|
+
return false unless actual[key] == val.to_s
|
40
|
+
end
|
41
|
+
end
|
42
|
+
true
|
43
|
+
rescue NoMethodError => ex
|
44
|
+
return false
|
45
|
+
end
|
46
|
+
|
47
|
+
def description
|
48
|
+
frame_name = @expected_command || 'Any frame'
|
49
|
+
with_headers = @expected_headers ? "with headers (#{@expected_headers.inspect.sub(/^\{/,"").sub(/\}$/,"")})" : nil
|
50
|
+
with_body = @expected_body ? "with body (#{@expected_body})" : nil
|
51
|
+
additional_desc = [with_headers, with_body].compact.join(' and ')
|
52
|
+
"#{frame_name} #{additional_desc}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
# Spec::Matchers.define :be_a_registered_server_frame do
|
3
|
+
# match do |actual|
|
4
|
+
# command_name = actual.name.split('::').last.upcase
|
5
|
+
# frame = Stomp::Frames::ServerFrame.build(command_name, { :a_header => 'test' }, 'body')
|
6
|
+
# frame.should be_an_instance_of(actual)
|
7
|
+
# frame.command.should == command_name
|
8
|
+
# frame.headers[:a_header].should == 'test'
|
9
|
+
# frame.body.should == 'test body'
|
10
|
+
# end
|
11
|
+
# end
|
12
|
+
#
|
13
|
+
# Spec::Matchers.define :be_able_to_access_header_values_like_a_hash do
|
14
|
+
# match do |actual|
|
15
|
+
# frame = actual.new( { :header_1 => 1, :header_2 => 'test' })
|
16
|
+
# frame[:header_1].should == 1
|
17
|
+
# frame[:header_2].should == 'test'
|
18
|
+
# end
|
19
|
+
# end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
RSpec::Matchers.define :have_header do |header_name, expected|
|
3
|
+
match do |actual|
|
4
|
+
actual[header_name.to_sym] == expected
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
RSpec::Matchers.define :have_transaction_header do |expected|
|
9
|
+
have_frame_header :transaction, expected
|
10
|
+
end
|