stomper 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (152) hide show
  1. data/.gitignore +5 -0
  2. data/{spec/spec.opts → .rspec} +0 -2
  3. data/Gemfile +4 -0
  4. data/LICENSE +201 -201
  5. data/README.md +130 -0
  6. data/Rakefile +5 -0
  7. data/examples/basic.rb +38 -0
  8. data/examples/events.rb +54 -0
  9. data/features/acking_messages.feature +147 -0
  10. data/features/disconnecting.feature +12 -0
  11. data/features/establish_connection.feature +44 -0
  12. data/features/protocol_version_negotiation.feature +61 -0
  13. data/features/receipts.feature +72 -0
  14. data/features/scopes.feature +32 -0
  15. data/features/secure_connections.feature +38 -0
  16. data/features/send_and_message.feature +28 -0
  17. data/features/steps/acking_messages_steps.rb +39 -0
  18. data/features/steps/disconnecting_steps.rb +8 -0
  19. data/features/steps/establish_connection_steps.rb +74 -0
  20. data/features/steps/frame_transmission_steps.rb +35 -0
  21. data/features/steps/protocol_version_negotiation_steps.rb +15 -0
  22. data/features/steps/receipts_steps.rb +79 -0
  23. data/features/steps/scopes_steps.rb +52 -0
  24. data/features/steps/secure_connections_steps.rb +41 -0
  25. data/features/steps/send_and_message_steps.rb +35 -0
  26. data/features/steps/subscribing_steps.rb +36 -0
  27. data/features/steps/threaded_receiver_steps.rb +8 -0
  28. data/features/steps/transactions_steps.rb +0 -0
  29. data/features/subscribing.feature +151 -0
  30. data/features/support/env.rb +11 -0
  31. data/features/support/header_helpers.rb +12 -0
  32. data/features/support/ssl/README +6 -0
  33. data/features/support/ssl/broker_cert.csr +17 -0
  34. data/features/support/ssl/broker_cert.pem +72 -0
  35. data/features/support/ssl/broker_key.pem +27 -0
  36. data/features/support/ssl/client_cert.csr +17 -0
  37. data/features/support/ssl/client_cert.pem +72 -0
  38. data/features/support/ssl/client_key.pem +27 -0
  39. data/features/support/ssl/demoCA/cacert.pem +17 -0
  40. data/features/support/ssl/demoCA/index.txt +2 -0
  41. data/features/support/ssl/demoCA/index.txt.attr +1 -0
  42. data/features/support/ssl/demoCA/index.txt.attr.old +1 -0
  43. data/features/support/ssl/demoCA/index.txt.old +1 -0
  44. data/features/support/ssl/demoCA/newcerts/01.pem +72 -0
  45. data/features/support/ssl/demoCA/newcerts/02.pem +72 -0
  46. data/features/support/ssl/demoCA/private/cakey.pem +17 -0
  47. data/features/support/ssl/demoCA/serial +1 -0
  48. data/features/support/ssl/demoCA/serial.old +1 -0
  49. data/features/support/test_stomp_server.rb +150 -0
  50. data/features/threaded_receiver.feature +11 -0
  51. data/features/transactions.feature +66 -0
  52. data/lib/stomper.rb +30 -20
  53. data/lib/stomper/connection.rb +442 -102
  54. data/lib/stomper/errors.rb +59 -0
  55. data/lib/stomper/extensions.rb +10 -0
  56. data/lib/stomper/extensions/common.rb +258 -0
  57. data/lib/stomper/extensions/events.rb +213 -0
  58. data/lib/stomper/extensions/heartbeat.rb +101 -0
  59. data/lib/stomper/extensions/scoping.rb +56 -0
  60. data/lib/stomper/frame.rb +54 -0
  61. data/lib/stomper/frame_serializer.rb +217 -0
  62. data/lib/stomper/headers.rb +15 -0
  63. data/lib/stomper/receipt_manager.rb +36 -0
  64. data/lib/stomper/receivers.rb +7 -0
  65. data/lib/stomper/receivers/threaded.rb +71 -0
  66. data/lib/stomper/scopes.rb +9 -0
  67. data/lib/stomper/scopes/header_scope.rb +49 -0
  68. data/lib/stomper/scopes/receipt_scope.rb +44 -0
  69. data/lib/stomper/scopes/transaction_scope.rb +109 -0
  70. data/lib/stomper/sockets.rb +66 -28
  71. data/lib/stomper/subscription_manager.rb +79 -0
  72. data/lib/stomper/support.rb +68 -0
  73. data/lib/stomper/support/1.8/frame_serializer.rb +53 -0
  74. data/lib/stomper/support/1.8/headers.rb +183 -0
  75. data/lib/stomper/support/1.9/frame_serializer.rb +64 -0
  76. data/lib/stomper/support/1.9/headers.rb +172 -0
  77. data/lib/stomper/support/ruby.rb +13 -0
  78. data/lib/stomper/uris.rb +49 -0
  79. data/lib/stomper/version.rb +7 -0
  80. data/spec/spec_helper.rb +13 -9
  81. data/spec/stomper/connection_spec.rb +712 -0
  82. data/spec/stomper/extensions/common_spec.rb +187 -0
  83. data/spec/stomper/extensions/events_spec.rb +78 -0
  84. data/spec/stomper/extensions/heartbeat_spec.rb +103 -0
  85. data/spec/stomper/extensions/scoping_spec.rb +21 -0
  86. data/spec/stomper/frame_serializer_1.8_spec.rb +318 -0
  87. data/spec/stomper/frame_serializer_spec.rb +316 -0
  88. data/spec/stomper/frame_spec.rb +36 -0
  89. data/spec/stomper/headers_spec.rb +224 -0
  90. data/spec/stomper/receipt_manager_spec.rb +91 -0
  91. data/spec/stomper/receivers/threaded_spec.rb +116 -0
  92. data/spec/stomper/scopes/header_scope_spec.rb +42 -0
  93. data/spec/stomper/scopes/receipt_scope_spec.rb +51 -0
  94. data/spec/stomper/scopes/transaction_scope_spec.rb +183 -0
  95. data/spec/stomper/sockets_spec.rb +113 -0
  96. data/spec/stomper/subscription_manager_spec.rb +107 -0
  97. data/spec/stomper/support_spec.rb +69 -0
  98. data/spec/stomper/uris_spec.rb +54 -0
  99. data/spec/stomper_spec.rb +9 -0
  100. data/spec/support/custom_argument_matchers.rb +57 -0
  101. data/spec/support/existential_frame_matchers.rb +19 -0
  102. data/spec/support/frame_header_matchers.rb +10 -0
  103. data/stomper.gemspec +30 -0
  104. metadata +272 -97
  105. data/AUTHORS +0 -21
  106. data/CHANGELOG +0 -20
  107. data/README.rdoc +0 -120
  108. data/lib/stomper/client.rb +0 -34
  109. data/lib/stomper/frame_reader.rb +0 -73
  110. data/lib/stomper/frame_writer.rb +0 -21
  111. data/lib/stomper/frames.rb +0 -39
  112. data/lib/stomper/frames/abort.rb +0 -10
  113. data/lib/stomper/frames/ack.rb +0 -25
  114. data/lib/stomper/frames/begin.rb +0 -11
  115. data/lib/stomper/frames/client_frame.rb +0 -89
  116. data/lib/stomper/frames/commit.rb +0 -10
  117. data/lib/stomper/frames/connect.rb +0 -10
  118. data/lib/stomper/frames/connected.rb +0 -30
  119. data/lib/stomper/frames/disconnect.rb +0 -10
  120. data/lib/stomper/frames/error.rb +0 -21
  121. data/lib/stomper/frames/message.rb +0 -48
  122. data/lib/stomper/frames/receipt.rb +0 -19
  123. data/lib/stomper/frames/send.rb +0 -10
  124. data/lib/stomper/frames/server_frame.rb +0 -38
  125. data/lib/stomper/frames/subscribe.rb +0 -42
  126. data/lib/stomper/frames/unsubscribe.rb +0 -19
  127. data/lib/stomper/open_uri_interface.rb +0 -41
  128. data/lib/stomper/receipt_handlers.rb +0 -23
  129. data/lib/stomper/receiptor.rb +0 -38
  130. data/lib/stomper/subscriber.rb +0 -76
  131. data/lib/stomper/subscription.rb +0 -128
  132. data/lib/stomper/subscriptions.rb +0 -95
  133. data/lib/stomper/threaded_receiver.rb +0 -59
  134. data/lib/stomper/transaction.rb +0 -185
  135. data/lib/stomper/transactor.rb +0 -50
  136. data/lib/stomper/uri.rb +0 -55
  137. data/spec/client_spec.rb +0 -29
  138. data/spec/connection_spec.rb +0 -22
  139. data/spec/frame_reader_spec.rb +0 -37
  140. data/spec/frame_writer_spec.rb +0 -27
  141. data/spec/frames/client_frame_spec.rb +0 -66
  142. data/spec/frames/indirect_frame_spec.rb +0 -45
  143. data/spec/frames/server_frame_spec.rb +0 -85
  144. data/spec/open_uri_interface_spec.rb +0 -132
  145. data/spec/receiptor_spec.rb +0 -35
  146. data/spec/shared_connection_examples.rb +0 -79
  147. data/spec/subscriber_spec.rb +0 -77
  148. data/spec/subscription_spec.rb +0 -157
  149. data/spec/subscriptions_spec.rb +0 -145
  150. data/spec/threaded_receiver_spec.rb +0 -33
  151. data/spec/transaction_spec.rb +0 -139
  152. data/spec/transactor_spec.rb +0 -46
@@ -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
@@ -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
@@ -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
@@ -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