stomper 1.0.0 → 2.0.0
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.
- 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
data/lib/stomper/transactor.rb
DELETED
@@ -1,50 +0,0 @@
|
|
1
|
-
module Stomper
|
2
|
-
module Transactor
|
3
|
-
# Creates a new Stomper::Transaction object and evaluates
|
4
|
-
# the supplied +block+ within a transactional context. If
|
5
|
-
# the block executes successfully, the transaction is committed,
|
6
|
-
# otherwise it is aborted. This method is meant to provide a less
|
7
|
-
# tedious approach to transactional messaging than the +begin+,
|
8
|
-
# +abort+ and +commit+ methods.
|
9
|
-
#
|
10
|
-
# See also: Stomper::ClientInterface::begin, Stomper::ClientInterface::commit,
|
11
|
-
# Stomper::ClientInterface::abort, Stomper::Transaction
|
12
|
-
def transaction(transaction_id=nil, &block)
|
13
|
-
begin
|
14
|
-
Stomper::Transaction.new(self, transaction_id, &block)
|
15
|
-
rescue Stomper::TransactionAborted
|
16
|
-
nil
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Tells the stomp broker to commit a transaction named by the
|
21
|
-
# supplied +transaction_id+ parameter. When used in conjunction with
|
22
|
-
# +begin+, and +abort+, a means for manually handling transactional
|
23
|
-
# message passing is provided.
|
24
|
-
#
|
25
|
-
# See Also: transaction
|
26
|
-
def commit(transaction_id)
|
27
|
-
transmit(Stomper::Frames::Commit.new(transaction_id))
|
28
|
-
end
|
29
|
-
|
30
|
-
# Tells the stomp broker to abort a transaction named by the
|
31
|
-
# supplied +transaction_id+ parameter. When used in conjunction with
|
32
|
-
# +begin+, and +commit+, a means for manually handling transactional
|
33
|
-
# message passing is provided.
|
34
|
-
#
|
35
|
-
# See Also: transaction
|
36
|
-
def abort(transaction_id)
|
37
|
-
transmit(Stomper::Frames::Abort.new(transaction_id))
|
38
|
-
end
|
39
|
-
|
40
|
-
# Tells the stomp broker to begin a transaction named by the
|
41
|
-
# supplied +transaction_id+ parameter. When used in conjunction with
|
42
|
-
# +commit+, and +abort+, a means for manually handling transactional
|
43
|
-
# message passing is provided.
|
44
|
-
#
|
45
|
-
# See also: transaction
|
46
|
-
def begin(transaction_id)
|
47
|
-
transmit(Stomper::Frames::Begin.new(transaction_id))
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
data/lib/stomper/uri.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
module URI
|
2
|
-
class STOMP < ::URI::Generic
|
3
|
-
# Got to love the magic of URI::Generic.
|
4
|
-
# By setting this constant, you ensure that all
|
5
|
-
# Stomp URI's have this port if one isn't specified.
|
6
|
-
DEFAULT_PORT = 61613
|
7
|
-
|
8
|
-
def initialize(*args)
|
9
|
-
super
|
10
|
-
end
|
11
|
-
|
12
|
-
def create_socket
|
13
|
-
::Stomper::Sockets::TCP.new(self.host||'localhost', self.port)
|
14
|
-
end
|
15
|
-
|
16
|
-
def open(*args)
|
17
|
-
conx = Stomper::Connection.open(self, :threaded_receiver => false)
|
18
|
-
conx.extend Stomper::OpenUriInterface
|
19
|
-
if block_given?
|
20
|
-
begin
|
21
|
-
yield conx
|
22
|
-
ensure
|
23
|
-
conx.disconnect
|
24
|
-
end
|
25
|
-
end
|
26
|
-
conx
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
class STOMP_SSL < STOMP
|
31
|
-
DEFAULT_PORT = 61612
|
32
|
-
|
33
|
-
def initialize(*args)
|
34
|
-
super
|
35
|
-
end
|
36
|
-
|
37
|
-
# Creates a socket from the URI
|
38
|
-
def create_socket
|
39
|
-
::Stomper::Sockets::SSL.new(self.host||'localhost', self.port)
|
40
|
-
end
|
41
|
-
|
42
|
-
# The +uri+ standard library resolves string URI's to concrete classes
|
43
|
-
# by matching the string's schema to the name of a subclass of URI::Generic.
|
44
|
-
# Ruby doesn't support '+' symbols in a class name, so the only way to handle
|
45
|
-
# schemas with odd characters is to override the "to_s" function of the class.
|
46
|
-
#
|
47
|
-
# Why do I get the feeling this might be a bad idea?
|
48
|
-
def self.to_s
|
49
|
-
"URI::STOMP+SSL"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
@@schemes['STOMP'] = STOMP
|
54
|
-
@@schemes['STOMP+SSL'] = STOMP_SSL
|
55
|
-
end
|
data/spec/client_spec.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
describe Client do
|
5
|
-
class MockConcreteClient
|
6
|
-
include Stomper::Client
|
7
|
-
end
|
8
|
-
|
9
|
-
before(:each) do
|
10
|
-
@client = MockConcreteClient.new
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "expected interface" do
|
14
|
-
it "should provide a send method" do
|
15
|
-
@client.should respond_to(:send)
|
16
|
-
@client.should_receive(:transmit).with(an_instance_of(Stomper::Frames::Send)).twice.and_return(nil)
|
17
|
-
@client.send("/queue/to", "message body", {:additional => 'header'})
|
18
|
-
@client.send("/queue/to", "message body")
|
19
|
-
end
|
20
|
-
it "should provide an ack method" do
|
21
|
-
@client.should respond_to(:ack)
|
22
|
-
@client.should_receive(:transmit).with(an_instance_of(Stomper::Frames::Ack)).exactly(3).times.and_return(nil)
|
23
|
-
@client.ack("message-id", {:additional => "header"})
|
24
|
-
@client.ack("message-id")
|
25
|
-
@client.ack(Stomper::Frames::Message.new({:'message-id' => 'msg-001'}, "body"))
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
data/spec/connection_spec.rb
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'shared_connection_examples'))
|
3
|
-
|
4
|
-
module Stomper
|
5
|
-
describe Connection do
|
6
|
-
describe "standard connection" do
|
7
|
-
before(:each) do
|
8
|
-
@connection = Connection.new("stomp:///")
|
9
|
-
end
|
10
|
-
|
11
|
-
it_should_behave_like "All Client Connections"
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "ssl connection" do
|
15
|
-
before(:each) do
|
16
|
-
@connection = Connection.new("stomp+ssl:///")
|
17
|
-
end
|
18
|
-
|
19
|
-
it_should_behave_like "All Client Connections"
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/spec/frame_reader_spec.rb
DELETED
@@ -1,37 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
describe FrameReader do
|
5
|
-
before(:each) do
|
6
|
-
@input_stream = StringIO.new("", "w+")
|
7
|
-
@input_stream.send(:extend, Stomper::FrameReader)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should produce a stomper frame" do
|
11
|
-
@input_stream.string = "CONNECTED\n\n\0"
|
12
|
-
@input_stream.receive_frame.should be_an_instance_of(Stomper::Frames::Connected)
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should read headers appropriately" do
|
16
|
-
@input_stream.string = "CONNECTED\nheader_1:a test value\nheader_2:another test value\nblather:47\n\nthe frame body\0"
|
17
|
-
@frame = @input_stream.receive_frame
|
18
|
-
@frame.headers.map { |(k,v)|
|
19
|
-
[k,v]
|
20
|
-
}.sort { |a, b| a.first.to_s <=> b.first.to_s }.should == [ [:blather, '47'], [:header_1, 'a test value'], [:header_2, 'another test value'] ]
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should raise an exception when an invalid content-length is specified" do
|
24
|
-
@input_stream.string = "CONNECTED\ncontent-length:3\n\nsomething more than 3 bytes long\0"
|
25
|
-
lambda { @input_stream.receive_frame }.should raise_error(Stomper::MalformedFrameError)
|
26
|
-
end
|
27
|
-
|
28
|
-
it "should read the body of a message when a content length is specified" do
|
29
|
-
@input_stream.string = "CONNECTED\ncontent-length:6\n\na test\0followed by trailing nonsense"
|
30
|
-
@input_stream.receive_frame.body.should == "a test"
|
31
|
-
end
|
32
|
-
it "should read the body of a message when no content length is specified" do
|
33
|
-
@input_stream.string = "CONNECTED\n\na bit more text and no direction\0followed by trailing nonsense"
|
34
|
-
@input_stream.receive_frame.body.should == "a bit more text and no direction"
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
data/spec/frame_writer_spec.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
describe FrameWriter do
|
5
|
-
before(:each) do
|
6
|
-
@output_buffer = StringIO.new("", "w+")
|
7
|
-
@output_buffer.send(:extend, Stomper::FrameWriter)
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should write commands appropriately" do
|
11
|
-
@output_buffer.transmit_frame(Stomper::Frames::Send.new('/test/queue','body of message'))
|
12
|
-
@output_buffer.string.should =~ /\ASEND/
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should write headers appropriately" do
|
16
|
-
@output_buffer.transmit_frame(Stomper::Frames::Send.new('/test/queue','body of message', :a_header => "3", :another => 23))
|
17
|
-
split_str = @output_buffer.string.split("\n")
|
18
|
-
split_str.shift
|
19
|
-
headers = ['a_header:3', 'another:23', 'content-length:15', 'destination:/test/queue']
|
20
|
-
until (header_line = split_str.shift).empty?
|
21
|
-
headers.should include(header_line)
|
22
|
-
headers.delete(header_line)
|
23
|
-
end
|
24
|
-
headers.should be_empty
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
@@ -1,66 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
-
|
3
|
-
module Stomper::Frames
|
4
|
-
describe ClientFrame do
|
5
|
-
before(:each) do
|
6
|
-
ClientFrame.generate_content_length = true
|
7
|
-
@client_frame = ClientFrame.new({}, nil, 'COMMAND')
|
8
|
-
end
|
9
|
-
|
10
|
-
def str_size(str)
|
11
|
-
str.respond_to?(:bytesize) ? str.bytesize : str.size
|
12
|
-
end
|
13
|
-
|
14
|
-
describe "generating content-length header" do
|
15
|
-
it "should provide the header by default, overriding any existing header" do
|
16
|
-
@frame_body = 'testing'
|
17
|
-
@client_frame = ClientFrame.new({'content-length' => 1}, @frame_body, "COMMAND")
|
18
|
-
@client_frame.headers[:'content-length'].should == str_size(@frame_body)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should not provide the header if the class option is set to false, unless explicitly set on the frame in particular" do
|
22
|
-
ClientFrame.generate_content_length = false
|
23
|
-
@frame_body = 'testing'
|
24
|
-
@client_frame = ClientFrame.new({}, @frame_body, 'COMMAND')
|
25
|
-
@client_frame.headers[:'content-length'].should be_nil
|
26
|
-
@client_frame = ClientFrame.new({}, @frame_body, 'COMMAND')
|
27
|
-
@client_frame.generate_content_length = true
|
28
|
-
@client_frame.headers[:'content-length'].should == str_size(@frame_body)
|
29
|
-
end
|
30
|
-
|
31
|
-
it "should not provide the header if instance option is set false, when the class option is true" do
|
32
|
-
@frame_body = 'testing'
|
33
|
-
@client_frame = ClientFrame.new({}, @frame_body, 'COMMAND')
|
34
|
-
@client_frame.generate_content_length = false
|
35
|
-
@client_frame.headers[:'content-length'].should be_nil
|
36
|
-
@client_frame = ClientFrame.new({:generate_content_length => false}, @frame_body, 'COMMAND')
|
37
|
-
@client_frame.headers[:'content-length'].should be_nil
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should not overwrite an explicit content-length header when option is off at class or instance level" do
|
41
|
-
@frame_body = 'testing'
|
42
|
-
@client_frame = ClientFrame.new({ :'content-length' => 4}, @frame_body, 'COMMAND')
|
43
|
-
@client_frame.generate_content_length = false
|
44
|
-
@client_frame.headers[:'content-length'].should == 4
|
45
|
-
ClientFrame.generate_content_length = false
|
46
|
-
@client_frame = ClientFrame.new({ :'content-length' => 2}, @frame_body, 'COMMAND')
|
47
|
-
@client_frame.headers[:'content-length'].should == 2
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should scope the class option to the class it is set on" do
|
51
|
-
@frame_body = 'testing'
|
52
|
-
Send.generate_content_length = false
|
53
|
-
@send_frame = Send.new('/queue/test/1', @frame_body)
|
54
|
-
@client_frame = ClientFrame.new({}, @frame_body, 'COMMAND')
|
55
|
-
@client_frame.headers[:'content-length'].should == str_size(@frame_body)
|
56
|
-
@send_frame.headers[:'content-length'].should be_nil
|
57
|
-
Send.generate_content_length = true
|
58
|
-
ClientFrame.generate_content_length = false
|
59
|
-
@send_frame = Send.new('/queue/test/1', @frame_body)
|
60
|
-
@client_frame = ClientFrame.new({}, @frame_body, 'COMMAND')
|
61
|
-
@client_frame.headers[:'content-length'].should be_nil
|
62
|
-
@send_frame.headers[:'content-length'].should == str_size(@frame_body)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
|
2
|
-
module Stomper
|
3
|
-
module Frames
|
4
|
-
describe IndirectFrame do
|
5
|
-
describe "interface" do
|
6
|
-
before(:each) do
|
7
|
-
@indirect_frame = IndirectFrame.new({}, nil, "INDIRECT_COMMAND")
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should provide a command attribute" do
|
11
|
-
@indirect_frame.should respond_to(:command)
|
12
|
-
end
|
13
|
-
it "should provide a body attribute" do
|
14
|
-
@indirect_frame.should respond_to(:body)
|
15
|
-
end
|
16
|
-
it "should provide a headers attribute" do
|
17
|
-
@indirect_frame.should respond_to(:headers)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
describe "command name" do
|
22
|
-
class UnnamedIndirectFrame < IndirectFrame; end
|
23
|
-
class NamedIndirectFrame < IndirectFrame
|
24
|
-
def initialize
|
25
|
-
super({}, nil, :test_command)
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
it "should use its class name if no command is specified" do
|
30
|
-
@indirect_frame = IndirectFrame.new({}, nil)
|
31
|
-
@indirect_frame.command.should == "INDIRECTFRAME"
|
32
|
-
@unnamed_frame = UnnamedIndirectFrame.new
|
33
|
-
@unnamed_frame.command.should == "UNNAMEDINDIRECTFRAME"
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should use a provided command name when it is provided" do
|
37
|
-
@indirect_frame = IndirectFrame.new({}, nil, "MY_COMMAND")
|
38
|
-
@indirect_frame.command.should == "MY_COMMAND"
|
39
|
-
@named_frame = NamedIndirectFrame.new
|
40
|
-
@named_frame.command.should == "TEST_COMMAND"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
module Frames
|
5
|
-
describe ServerFrame do
|
6
|
-
before(:each) do
|
7
|
-
@server_frame = ServerFrame.new("SERVER COMMAND")
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should build an appropriate object for a given server frame" do
|
11
|
-
@built_frame = ServerFrame.build("MESSAGE", {:'message-id' => 'msg-001', :transaction => 'tx-test', :subscription => 'sub-test'}, "message body")
|
12
|
-
@built_frame.should be_an_instance_of(Message)
|
13
|
-
@built_frame.headers[:transaction].should == "tx-test"
|
14
|
-
@built_frame.headers[:subscription].should == "sub-test"
|
15
|
-
@built_frame.headers[:'message-id'].should == "msg-001"
|
16
|
-
@built_frame.body.should == "message body"
|
17
|
-
@built_frame = ServerFrame.build("AN UNKNOWN COMMAND", {:a_header => "test"}, "a body")
|
18
|
-
@built_frame.should be_an_instance_of(ServerFrame)
|
19
|
-
@built_frame.command.should == "AN UNKNOWN COMMAND"
|
20
|
-
@built_frame.headers[:a_header].should == "test"
|
21
|
-
@built_frame.body.should == "a body"
|
22
|
-
class MockServerFrame < ServerFrame
|
23
|
-
def initialize(headers, body)
|
24
|
-
super(headers, body)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
@built_frame = ServerFrame.build("MOCKSERVERFRAME", {:a_header => "test"}, "a body")
|
28
|
-
@built_frame.should be_an_instance_of(MockServerFrame)
|
29
|
-
@built_frame.headers[:a_header].should == "test"
|
30
|
-
@built_frame.body.should == "a body"
|
31
|
-
end
|
32
|
-
|
33
|
-
describe "server frames" do
|
34
|
-
describe Connected do
|
35
|
-
it "should be registered" do
|
36
|
-
@server_frame = ServerFrame.build("CONNECTED", {:a_header => 'test'}, "test body")
|
37
|
-
@server_frame.should be_an_instance_of(Connected)
|
38
|
-
@server_frame.command.should == "CONNECTED"
|
39
|
-
@server_frame.headers[:a_header].should == "test"
|
40
|
-
@server_frame.body.should == "test body"
|
41
|
-
end
|
42
|
-
end
|
43
|
-
describe Error do
|
44
|
-
it "should be registered" do
|
45
|
-
@server_frame = ServerFrame.build("ERROR", {:a_header => 'test'}, "test body")
|
46
|
-
@server_frame.should be_an_instance_of(Error)
|
47
|
-
@server_frame.command.should == "ERROR"
|
48
|
-
@server_frame.headers[:a_header].should == "test"
|
49
|
-
@server_frame.body.should == "test body"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
describe Message do
|
53
|
-
it "should be registered" do
|
54
|
-
@server_frame = ServerFrame.build("MESSAGE", {:a_header => 'test'}, "test body")
|
55
|
-
@server_frame.should be_an_instance_of(Message)
|
56
|
-
@server_frame.command.should == "MESSAGE"
|
57
|
-
@server_frame.headers[:a_header].should == "test"
|
58
|
-
@server_frame.body.should == "test body"
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should provide the convenience attributes" do
|
62
|
-
@message = Message.new({:destination => '/queue/testing', :subscription => 'sub-001', :'message-id' => 'msg-001'}, "test body")
|
63
|
-
@message.id.should == "msg-001"
|
64
|
-
@message.destination.should == "/queue/testing"
|
65
|
-
@message.subscription.should == "sub-001"
|
66
|
-
end
|
67
|
-
end
|
68
|
-
describe Receipt do
|
69
|
-
it "should be registered" do
|
70
|
-
@server_frame = ServerFrame.build("RECEIPT", {:a_header => 'test'}, "test body")
|
71
|
-
@server_frame.should be_an_instance_of(Receipt)
|
72
|
-
@server_frame.command.should == "RECEIPT"
|
73
|
-
@server_frame.headers[:a_header].should == "test"
|
74
|
-
@server_frame.body.should == "test body"
|
75
|
-
end
|
76
|
-
|
77
|
-
it "should provide the convenience attributes" do
|
78
|
-
@receipt = Receipt.new({:'receipt-id' => 'who the receipt is for'}, "test body")
|
79
|
-
@receipt.for.should == "who the receipt is for"
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
@@ -1,132 +0,0 @@
|
|
1
|
-
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
-
require 'open-uri'
|
3
|
-
|
4
|
-
module Stomper
|
5
|
-
describe "Open URI Interface" do
|
6
|
-
describe "basic interface" do
|
7
|
-
it "should be able to connect through open-uri style" do
|
8
|
-
lambda { open("stomp:///") { |s| } }.should_not raise_error
|
9
|
-
end
|
10
|
-
it "should provide a 'put' method" do
|
11
|
-
open("stomp:///") { |s| s.should respond_to(:put) }
|
12
|
-
end
|
13
|
-
it "should provide a 'puts' method" do
|
14
|
-
open("stomp:///") { |s| s.should respond_to(:puts) }
|
15
|
-
end
|
16
|
-
it "should provide a 'write' method" do
|
17
|
-
open("stomp:///") { |s| s.should respond_to(:write) }
|
18
|
-
end
|
19
|
-
it "should provide a 'get' method" do
|
20
|
-
open("stomp:///") { |s| s.should respond_to(:get) }
|
21
|
-
end
|
22
|
-
it "should provide a 'gets' method" do
|
23
|
-
open("stomp:///") { |s| s.should respond_to(:gets) }
|
24
|
-
end
|
25
|
-
it "should provide a 'read' method" do
|
26
|
-
open("stomp:///") { |s| s.should respond_to(:read) }
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
describe "automatic closing" do
|
31
|
-
it "should automatically connect then disconnect when the block completes" do
|
32
|
-
connection = open("stomp:///") { |s| s.connected?.should be_true; s }
|
33
|
-
connection.connected?.should be_false
|
34
|
-
end
|
35
|
-
|
36
|
-
it "should automatically disconnect if the block raises an exception" do
|
37
|
-
connection = nil
|
38
|
-
begin
|
39
|
-
open("stomp:///") { |s| connection = s; raise ArgumentError, "some error" }
|
40
|
-
rescue ArgumentError
|
41
|
-
end
|
42
|
-
connection.connected?.should be_false
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "message sending" do
|
47
|
-
it "should transmit a SEND frame for puts on the URI's specified destination with no content-length" do
|
48
|
-
open("stomp://localhost/queue/testing") do |s|
|
49
|
-
frame = s.puts("a test message")
|
50
|
-
frame.should be_a_kind_of(Stomper::Frames::Send)
|
51
|
-
frame.headers[:destination].should == "/queue/testing"
|
52
|
-
frame.headers[:'content-length'].should be_nil
|
53
|
-
frame.body.should == "a test message"
|
54
|
-
end
|
55
|
-
end
|
56
|
-
it "should transmit a SEND frame for put on the URI's specified destination with no content-length" do
|
57
|
-
open("stomp://localhost/queue/testing") do |s|
|
58
|
-
frame = s.put("a test message")
|
59
|
-
frame.should be_a_kind_of(Stomper::Frames::Send)
|
60
|
-
frame.headers[:destination].should == "/queue/testing"
|
61
|
-
frame.headers[:'content-length'].should be_nil
|
62
|
-
frame.body.should == "a test message"
|
63
|
-
end
|
64
|
-
end
|
65
|
-
it "should transmit a SEND frame for write on the URI's specified destination with a content-length" do
|
66
|
-
open("stomp://localhost/queue/testing") do |s|
|
67
|
-
frame = s.write("a test message")
|
68
|
-
frame.should be_a_kind_of(Stomper::Frames::Send)
|
69
|
-
frame.headers[:destination].should == "/queue/testing"
|
70
|
-
frame.headers[:'content-length'].should == "a test message".length
|
71
|
-
frame.body.should == "a test message"
|
72
|
-
end
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
describe "message receiving" do
|
77
|
-
it "should receive the next message on the queue with gets" do
|
78
|
-
open("stomp://localhost/queue/test_gets") do |s|
|
79
|
-
s.puts "a test message"
|
80
|
-
msg = s.gets
|
81
|
-
msg.should be_a_kind_of(Stomper::Frames::Message)
|
82
|
-
msg.body.should == "a test message"
|
83
|
-
msg.destination.should == "/queue/test_gets"
|
84
|
-
end
|
85
|
-
end
|
86
|
-
it "should receive the next message on the queue with get" do
|
87
|
-
open("stomp://localhost/queue/test_get") do |s|
|
88
|
-
s.puts "a test message"
|
89
|
-
msg = s.get
|
90
|
-
msg.should be_a_kind_of(Stomper::Frames::Message)
|
91
|
-
msg.body.should == "a test message"
|
92
|
-
msg.destination.should == "/queue/test_get"
|
93
|
-
end
|
94
|
-
end
|
95
|
-
it "should receive the next message on the queue with read" do
|
96
|
-
open("stomp://localhost/queue/test_read") do |s|
|
97
|
-
s.puts "a test message"
|
98
|
-
msg = s.read
|
99
|
-
msg.should be_a_kind_of(Stomper::Frames::Message)
|
100
|
-
msg.body.should == "a test message"
|
101
|
-
msg.destination.should == "/queue/test_read"
|
102
|
-
end
|
103
|
-
end
|
104
|
-
it "should receive 4 messages with an optional argument supplied to first" do
|
105
|
-
open("stomp://localhost/queue/test_first_4") do |s|
|
106
|
-
s.puts "test message 1"
|
107
|
-
s.puts "test message 2"
|
108
|
-
s.puts "test message 3"
|
109
|
-
s.puts "test message 4"
|
110
|
-
msgs = s.first(4)
|
111
|
-
msgs.size.should == 4
|
112
|
-
msgs.all? { |m| m.is_a?(Stomper::Frames::Message) }.should be_true
|
113
|
-
msgs.map { |m| m.body }.should == ["test message 1", "test message 2", "test message 3", "test message 4"]
|
114
|
-
end
|
115
|
-
end
|
116
|
-
it "should provide the each iterator" do
|
117
|
-
open("stomp://localhost/queue/test_each") do |s|
|
118
|
-
s.puts "fringe"
|
119
|
-
s.write "dexter"
|
120
|
-
s.put "nip/tuck"
|
121
|
-
s.puts "futurama"
|
122
|
-
s.write "frasier"
|
123
|
-
s.each do |m|
|
124
|
-
m.destination.should == "/queue/test_each"
|
125
|
-
%w(fringe dexter nip/tuck futurama frasier).should include(m.body)
|
126
|
-
break if m.body== "frasier"
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
end
|
131
|
-
end
|
132
|
-
end
|