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/spec/receiptor_spec.rb
DELETED
@@ -1,35 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
describe Receiptor do
|
5
|
-
class MockConcreteReceipter
|
6
|
-
include Stomper::Receiptor
|
7
|
-
end
|
8
|
-
|
9
|
-
before(:each) do
|
10
|
-
@client = MockConcreteReceipter.new
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "expected interface" do
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "receipt handling" do
|
17
|
-
before(:each) do
|
18
|
-
@client.should_receive(:connected?).any_number_of_times.and_return(true)
|
19
|
-
@client.should_receive(:send_without_receipt_handler).with('/queue/to','message body',a_kind_of(Hash)).at_least(:once).and_return(nil)
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should dispatch a receipt when sent with a block" do
|
23
|
-
@client.should_receive(:receive_without_receipt_dispatch).once.and_return(Stomper::Frames::Receipt.new({ :'receipt-id' => 'msg-0001' }, ''))
|
24
|
-
receipt_processed = false
|
25
|
-
@client.send('/queue/to', 'message body', :receipt => 'msg-0001') do |r|
|
26
|
-
receipt_processed = true
|
27
|
-
end
|
28
|
-
@client.receipt_handlers.size.should == 1
|
29
|
-
@client.receive_with_receipt_dispatch
|
30
|
-
receipt_processed.should be_true
|
31
|
-
@client.receipt_handlers.size.should == 0
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
shared_examples_for "All Client Connections" do
|
2
|
-
describe "connection initializers" do
|
3
|
-
describe "from uri" do
|
4
|
-
it "should accept the stomp:/// uri (no host specified)" do
|
5
|
-
lambda { @connection.class.new("stomp:///") }.should_not raise_error
|
6
|
-
end
|
7
|
-
|
8
|
-
it "should accept a uri specifying just the host" do
|
9
|
-
lambda { @connection.class.new("stomp://localhost/") }.should_not raise_error
|
10
|
-
end
|
11
|
-
|
12
|
-
it "should accept a uri specifying host and port" do
|
13
|
-
lambda { @connection.class.new("stomp://localhost:61613/") }.should_not raise_error
|
14
|
-
end
|
15
|
-
|
16
|
-
it "should accept a uri specifying host, port and credentials" do
|
17
|
-
lambda { @connection.class.new("stomp://test_user:s3cr3tz@localhost:61613/") }.should_not raise_error
|
18
|
-
end
|
19
|
-
|
20
|
-
it "should accept a uri specifying a secure connection" do
|
21
|
-
lambda { @connection.class.new("stomp+ssl://localhost") }.should_not raise_error
|
22
|
-
end
|
23
|
-
|
24
|
-
it "should not accept a bogus URI" do
|
25
|
-
lambda { @connection.class.new("stomp://localhost:garbage") }.should raise_error
|
26
|
-
end
|
27
|
-
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "connection control" do
|
32
|
-
it "should provide the appropriate all connection control and status methods" do
|
33
|
-
@connection.should respond_to(:connect)
|
34
|
-
@connection.should respond_to(:disconnect)
|
35
|
-
@connection.should respond_to(:close)
|
36
|
-
@connection.should respond_to(:connected?)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should not report it is connected after close is called" do
|
40
|
-
@connection.connect
|
41
|
-
@connection.connected?.should be_true
|
42
|
-
@connection.close
|
43
|
-
@connection.connected?.should be_false
|
44
|
-
end
|
45
|
-
|
46
|
-
it "should not report it is connected after disconnect is called" do
|
47
|
-
@connection.connect
|
48
|
-
@connection.connected?.should be_true
|
49
|
-
@connection.disconnect
|
50
|
-
@connection.connected?.should be_false
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
describe "connection IO" do
|
55
|
-
it "should provide methods for receiving frames and writing frames" do
|
56
|
-
@connection.should respond_to(:transmit)
|
57
|
-
@connection.should respond_to(:receive)
|
58
|
-
end
|
59
|
-
it "should transmit frames" do
|
60
|
-
@connection.connect
|
61
|
-
@frame = nil
|
62
|
-
@connection.transmit(Stomper::Frames::Subscribe.new("/topic/test_topic"))
|
63
|
-
@connection.transmit(Stomper::Frames::Send.new("/topic/test_topic", "hello"))
|
64
|
-
@frame = @connection.receive while @frame.nil?
|
65
|
-
@frame.should be_an_instance_of(Stomper::Frames::Message)
|
66
|
-
@frame.body.should == "hello"
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
describe "exception handling" do
|
71
|
-
it "should close and propagate when an exception is raised on transmit" do
|
72
|
-
pending
|
73
|
-
end
|
74
|
-
|
75
|
-
it "should close and propagate when an exception is raised on receive" do
|
76
|
-
pending
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
data/spec/subscriber_spec.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
describe Subscriber do
|
5
|
-
class MockConcreteSubscriber
|
6
|
-
include Stomper::Subscriber
|
7
|
-
end
|
8
|
-
|
9
|
-
before(:each) do
|
10
|
-
@client = MockConcreteSubscriber.new
|
11
|
-
end
|
12
|
-
|
13
|
-
describe "expected interface" do
|
14
|
-
it "should provide a subscribe method" do
|
15
|
-
@client.should respond_to(:subscribe)
|
16
|
-
@client.should_receive(:transmit).with(an_instance_of(Stomper::Frames::Subscribe)).twice.and_return(nil)
|
17
|
-
@client.subscribe("/queue/to", {:additional => 'header'})
|
18
|
-
@client.subscribe("/queue/to")
|
19
|
-
end
|
20
|
-
it "should provide an unsubscribe method" do
|
21
|
-
@client.should respond_to(:unsubscribe)
|
22
|
-
@client.should_receive(:transmit).with(an_instance_of(Stomper::Frames::Subscribe)).twice.and_return(nil)
|
23
|
-
@client.subscribe("/queue/to", {:id => 'subscription-id'})
|
24
|
-
@client.subscribe("/queue/to")
|
25
|
-
@client.should_receive(:transmit).with(an_instance_of(Stomper::Frames::Unsubscribe)).twice.and_return(nil)
|
26
|
-
@client.unsubscribe("/queue/to", 'subscription-id')
|
27
|
-
@client.unsubscribe("/queue/to")
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
describe "subscribing to queue" do
|
32
|
-
before(:each) do
|
33
|
-
@message_sent = Stomper::Frames::Message.new({:destination => "/queue/test"}, "test message")
|
34
|
-
@client.should_receive(:connected?).any_number_of_times.and_return(true)
|
35
|
-
@client.should_receive(:transmit).with(a_kind_of(Stomper::Frames::ClientFrame)).at_least(:once).and_return(nil)
|
36
|
-
end
|
37
|
-
|
38
|
-
it "should subscribe to a destination with a block" do
|
39
|
-
@client.should_receive(:receive_without_message_dispatch).once.and_return(@message_sent)
|
40
|
-
@message_received = nil
|
41
|
-
@client.subscribe("/queue/test") do |msg|
|
42
|
-
@message_received = msg
|
43
|
-
end
|
44
|
-
@client.receive_with_message_dispatch
|
45
|
-
@message_received.should == @message_sent
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should not unsubscribe from all destinations when a subscription id is provided" do
|
49
|
-
@client.subscribe("/queue/test", { :id => 'subscription-1' }) do |msg|
|
50
|
-
@message_received = msg
|
51
|
-
end
|
52
|
-
@client.subscribe("/queue/test") do |msg|
|
53
|
-
@message_received = msg
|
54
|
-
end
|
55
|
-
@client.subscribe("/queue/test", :id => 'subscription-2') do |msg|
|
56
|
-
@message_received = msg
|
57
|
-
end
|
58
|
-
@client.unsubscribe("/queue/test", 'subscription-1')
|
59
|
-
@client.subscriptions.size.should == 2
|
60
|
-
end
|
61
|
-
|
62
|
-
it "should not unsubscribe from non-naive subscriptions when only a destination is supplied" do
|
63
|
-
@client.subscribe("/queue/test", { :id => 'subscription-1' }) do |msg|
|
64
|
-
@message_received = msg
|
65
|
-
end
|
66
|
-
@client.subscribe("/queue/test") do |msg|
|
67
|
-
@message_received = msg
|
68
|
-
end
|
69
|
-
@client.subscribe("/queue/test") do |msg|
|
70
|
-
@message_received = msg
|
71
|
-
end
|
72
|
-
@client.unsubscribe("/queue/test")
|
73
|
-
@client.subscriptions.size.should == 1
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
data/spec/subscription_spec.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
describe Subscription do
|
5
|
-
before(:each) do
|
6
|
-
@subscription = Subscription.new("/queue/test/1", 'subscription-1')
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "basic expectations" do
|
10
|
-
it "should be constructable from a parameter list, providing sensible defaults for omitted arguments" do
|
11
|
-
@subscription.destination.should == "/queue/test/1"
|
12
|
-
@subscription.ack.should == :auto
|
13
|
-
@subscription.selector.should be_nil
|
14
|
-
|
15
|
-
@subscription = Subscription.new("/queue/test/2", 'subscription-1', 'client', 'a > 3')
|
16
|
-
@subscription.destination.should == "/queue/test/2"
|
17
|
-
@subscription.ack.should == :client
|
18
|
-
@subscription.selector.should == 'a > 3'
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should be constructable from a hash, providing sensible defaults for omitted arguments" do
|
22
|
-
@subscription = Subscription.new({ :destination => '/queue/test/2' })
|
23
|
-
@subscription.destination.should == "/queue/test/2"
|
24
|
-
@subscription.ack.should == :auto
|
25
|
-
|
26
|
-
@subscription = Subscription.new({:destination => "/queue/test/3", :ack => :client, :id => 'subscription-3', :selector => 'b < 10' })
|
27
|
-
@subscription.destination.should == "/queue/test/3"
|
28
|
-
@subscription.ack.should == :client
|
29
|
-
@subscription.id.should_not be_nil
|
30
|
-
@subscription.selector.should == "b < 10"
|
31
|
-
end
|
32
|
-
|
33
|
-
it "should use the specified ID for subscribing and unsubscribing" do
|
34
|
-
@subscription.id.should_not be_nil
|
35
|
-
@subscription.id.should_not be_empty
|
36
|
-
@subscription.id.should == @subscription.to_subscribe.id
|
37
|
-
@subscription.id.should == @subscription.to_unsubscribe.id
|
38
|
-
end
|
39
|
-
|
40
|
-
it "should provide a meaningful ID when the ack mode is not auto" do
|
41
|
-
@client_ack_subscription = Subscription.new("/queue/test/1",nil,'client')
|
42
|
-
@client_ack_subscription.id.should_not be_nil
|
43
|
-
end
|
44
|
-
|
45
|
-
it "should provide a meaningful ID when the selector is specified" do
|
46
|
-
@selector_subscription = Subscription.new("/queue/test/1",nil,'auto',"a > 3.5")
|
47
|
-
@selector_subscription.id.should_not be_nil
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should provide a SUBSCRIBE frame" do
|
51
|
-
@subscription.should respond_to(:to_subscribe)
|
52
|
-
@frame = @subscription.to_subscribe
|
53
|
-
@frame.destination.should == "/queue/test/1"
|
54
|
-
@frame.id.should_not be_nil
|
55
|
-
@frame.ack.should == "auto"
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "message acceptance" do
|
60
|
-
it "should accept a message without a subscription header only when the subscription is 'naive'" do
|
61
|
-
@matching_subscription_1 = Subscription.new("/queue/test/1")
|
62
|
-
@matching_subscription_2 = Subscription.new("/queue/test/1", nil, :auto)
|
63
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1'},"test message")
|
64
|
-
@subscription.accepts?(@message).should be_false
|
65
|
-
@matching_subscription_1.accepts?(@message).should be_true
|
66
|
-
@matching_subscription_2.accepts?(@message).should be_true
|
67
|
-
end
|
68
|
-
|
69
|
-
it "should be able to accept messages by destination" do
|
70
|
-
@non_matching_subscription = Subscription.new("/queue/test/another")
|
71
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1', :subscription => @subscription.id},"test message")
|
72
|
-
@subscription.accepts?(@message).should be_true
|
73
|
-
@non_matching_subscription.accepts?(@message).should be_false
|
74
|
-
end
|
75
|
-
|
76
|
-
it "should accept messages only if the same destination and subscription" do
|
77
|
-
@alternate_subscription = Subscription.new("/queue/test/1", 'subscription-2')
|
78
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1', :subscription => @subscription.id},"test message")
|
79
|
-
@subscription.accepts?(@message).should be_true
|
80
|
-
@alternate_subscription.accepts?(@message).should be_false
|
81
|
-
end
|
82
|
-
|
83
|
-
it "should accept messages by the subscription id if the message has a subscription" do
|
84
|
-
@non_matching_subscription = Subscription.new("/queue/test/1")
|
85
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1', :subscription => @subscription.id},"test message")
|
86
|
-
@subscription.accepts?(@message).should be_true
|
87
|
-
@non_matching_subscription.accepts?(@message).should be_false
|
88
|
-
end
|
89
|
-
|
90
|
-
it "should not accept messages with the same destination when its ack mode is not 'auto' and no subscription header was specified" do
|
91
|
-
@non_matching_subscription = Subscription.new("/queue/test/1", nil, 'client')
|
92
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1'},"test message")
|
93
|
-
@non_matching_subscription.accepts?(@message).should be_false
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should not accept messages with the same destination when it has a selector and no subscription header was specified" do
|
97
|
-
@non_matching_subscription = Subscription.new("/queue/test/1", nil, 'auto', 'rating > 3.0')
|
98
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1'},"test message")
|
99
|
-
@non_matching_subscription.accepts?(@message).should be_false
|
100
|
-
end
|
101
|
-
|
102
|
-
# Either insist that the #id method return something meaningful in non-trivial situations
|
103
|
-
# as part of the expected behavior of the interface, or change this test!
|
104
|
-
# We now insist on it, so this test is valid.
|
105
|
-
it "should accept messages when it has a selector and the subscription header was specified" do
|
106
|
-
@non_matching_subscription = Subscription.new("/queue/test/1", nil, 'auto', 'rating > 3.0')
|
107
|
-
# To test this without insisting that the #id field be equivalent to the subscribe frame's header
|
108
|
-
# go this way:
|
109
|
-
|
110
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1', :subscription => @non_matching_subscription.id},"test message")
|
111
|
-
@non_matching_subscription.accepts?(@message).should be_true
|
112
|
-
end
|
113
|
-
end
|
114
|
-
|
115
|
-
describe "message delivery" do
|
116
|
-
it "should call its callback when an applicable message arrives for its destination" do
|
117
|
-
called_back = false
|
118
|
-
@subscription_with_block = Subscription.new("/queue/test/1", 'subscription-test') do |msg|
|
119
|
-
called_back = (msg == @message)
|
120
|
-
end
|
121
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1', :subscription => @subscription_with_block.id},"test message")
|
122
|
-
@subscription_with_block.perform(@message)
|
123
|
-
called_back.should be_true
|
124
|
-
end
|
125
|
-
|
126
|
-
it "should not call its callback when given a message for a different destination" do
|
127
|
-
called_back = false
|
128
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1'},"test message")
|
129
|
-
@subscription_with_block = Subscription.new("/queue/test/another", 'subscription-test') do |msg|
|
130
|
-
called_back = (msg == @message)
|
131
|
-
end
|
132
|
-
@subscription_with_block.perform(@message)
|
133
|
-
called_back.should be_false
|
134
|
-
end
|
135
|
-
|
136
|
-
it "should call its callback when a message arrives for its subscription id" do
|
137
|
-
called_back = false
|
138
|
-
@subscription_with_block = Subscription.new("/queue/test/another", 'subscription-test') do |msg|
|
139
|
-
called_back = (msg == @message)
|
140
|
-
end
|
141
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1', :subscription => @subscription_with_block.id},"test message")
|
142
|
-
@subscription_with_block.perform(@message)
|
143
|
-
called_back.should be_true
|
144
|
-
end
|
145
|
-
|
146
|
-
it "should not call its callback when a message arrives for its subscription id, even on the same " do
|
147
|
-
called_back = false
|
148
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1', :subscription => 'subscription-not-test'},"test message")
|
149
|
-
@subscription_with_block = Subscription.new("/queue/test/another", 'subscription-test') do |msg|
|
150
|
-
called_back = (msg == @message)
|
151
|
-
end
|
152
|
-
@subscription_with_block.perform(@message)
|
153
|
-
called_back.should be_false
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
data/spec/subscriptions_spec.rb
DELETED
@@ -1,145 +0,0 @@
|
|
1
|
-
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
2
|
-
|
3
|
-
module Stomper
|
4
|
-
describe Subscriptions do
|
5
|
-
before(:each) do
|
6
|
-
@subscriptions = Subscriptions.new
|
7
|
-
end
|
8
|
-
|
9
|
-
describe "adding subscriptions" do
|
10
|
-
it "should add a subscription given a subscription object" do
|
11
|
-
@subscriptions << Subscription.new('/queue/test/3', 'subscription-3', nil, 'b < 10')
|
12
|
-
@subscriptions.size.should == 1
|
13
|
-
@subscriptions.first.destination.should == "/queue/test/3"
|
14
|
-
@subscriptions.first.ack.should == :auto
|
15
|
-
@subscriptions.first.selector.should == 'b < 10'
|
16
|
-
@subscriptions.first.id.should_not be_nil
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
describe "enumerable" do
|
21
|
-
it "should provide an each method" do
|
22
|
-
@subscriptions.should respond_to(:each)
|
23
|
-
end
|
24
|
-
it "should be enumerable" do
|
25
|
-
@subscriptions.is_a?(Enumerable).should be_true
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "thread safe" do
|
30
|
-
# How do you test this?
|
31
|
-
it "should synchronize adding subscriptions" do
|
32
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
33
|
-
@subscriptions << Subscription.new("/queue/test/2")
|
34
|
-
@subscriptions << Subscription.new("/queue/test/3")
|
35
|
-
Thread.new { sleep(0.1); @subscriptions << Subscription.new("/queue/test/4") }
|
36
|
-
# In general, this next step should execute before the thread has a chance to
|
37
|
-
# but the sleep in the map should mean that our thread gets woken up before
|
38
|
-
# map finishes. However, destinations should NEVER contain "/queue/test/4"
|
39
|
-
# because map should be synchronized.
|
40
|
-
destinations = @subscriptions.map { |sub| sleep(0.1); sub.destination }
|
41
|
-
destinations.size.should == 3
|
42
|
-
destinations.should == ['/queue/test/1', '/queue/test/2', '/queue/test/3']
|
43
|
-
@subscriptions.size.should == 4
|
44
|
-
@subscriptions.last.destination.should == "/queue/test/4"
|
45
|
-
end
|
46
|
-
|
47
|
-
it "should synchronize removing subscriptions" do
|
48
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
49
|
-
@subscriptions << Subscription.new("/queue/test/2")
|
50
|
-
@subscriptions << Subscription.new("/queue/test/3")
|
51
|
-
sync_thread = Thread.new { sleep(0.1); @subscriptions.remove("/queue/test/1") }
|
52
|
-
destinations = @subscriptions.map { |sub| sleep(0.1); sub.destination }
|
53
|
-
destinations.size.should == 3
|
54
|
-
destinations.should == ['/queue/test/1', '/queue/test/2', '/queue/test/3']
|
55
|
-
sync_thread.join
|
56
|
-
@subscriptions.size.should == 2
|
57
|
-
@subscriptions.first.destination.should == "/queue/test/2"
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
describe "message delivery" do
|
63
|
-
it "should deliver messages to matching subscriptions" do
|
64
|
-
received_1 = false
|
65
|
-
received_2 = false
|
66
|
-
received_3 = false
|
67
|
-
@subscriptions << Subscription.new("/queue/test/1") { |msg| received_1 = true }
|
68
|
-
@subscriptions << Subscription.new("/queue/test/1", 'subscription-2') { |msg| received_2 = true }
|
69
|
-
@subscriptions << Subscription.new("/queue/test/2") { |msg| received_3 = true }
|
70
|
-
@message = Stomper::Frames::Message.new({:destination => '/queue/test/1'},"test message")
|
71
|
-
@subscriptions.perform(@message)
|
72
|
-
received_1.should be_true
|
73
|
-
received_2.should be_false
|
74
|
-
received_3.should be_false
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
describe "unsubscribing" do
|
79
|
-
it "should remove all naive subscriptions when unsubscribing with a string destination" do
|
80
|
-
@removed_subscriptions = [Subscription.new("/queue/test/1"), Subscription.new("/queue/test/1")]
|
81
|
-
@removed_subscriptions.each { |sub| @subscriptions << sub }
|
82
|
-
@subscriptions << Subscription.new("/queue/test/2")
|
83
|
-
@subscriptions << Subscription.new("/queue/test/1", 'subscription-4')
|
84
|
-
@to_remove = @subscriptions.remove("/queue/test/1")
|
85
|
-
@subscriptions.size.should == 2
|
86
|
-
@subscriptions.should_not include(@removed_subscriptions.first)
|
87
|
-
@subscriptions.should_not include(@removed_subscriptions.last)
|
88
|
-
@to_remove.size.should == 2
|
89
|
-
@to_remove.should include(@removed_subscriptions.first)
|
90
|
-
@to_remove.should include(@removed_subscriptions.last)
|
91
|
-
end
|
92
|
-
it "should remove all subscriptions that accept messages for a supplied subscription ID" do
|
93
|
-
@removed_subscription = Subscription.new("/queue/test/1", 'subscription-4')
|
94
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
95
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
96
|
-
@subscriptions << Subscription.new("/queue/test/2")
|
97
|
-
@subscriptions << @removed_subscription
|
98
|
-
@to_remove = @subscriptions.remove(nil, @removed_subscription.id)
|
99
|
-
@subscriptions.size.should == 3
|
100
|
-
@subscriptions.should_not include(@removed_subscription)
|
101
|
-
@to_remove.size.should == 1
|
102
|
-
@to_remove.should include(@removed_subscription)
|
103
|
-
end
|
104
|
-
it "should remove subscriptions as expected when parameter is a hash specifying the ID" do
|
105
|
-
@removed_subscription = Subscription.new("/queue/test/1", 'subscription-4')
|
106
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
107
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
108
|
-
@subscriptions << Subscription.new("/queue/test/2")
|
109
|
-
@subscriptions << @removed_subscription
|
110
|
-
@to_remove = @subscriptions.remove({ :id => @removed_subscription.id })
|
111
|
-
@subscriptions.size.should == 3
|
112
|
-
@subscriptions.should_not include(@removed_subscription)
|
113
|
-
@to_remove.size.should == 1
|
114
|
-
@to_remove.should include(@removed_subscription)
|
115
|
-
end
|
116
|
-
it "should remove subscriptions as expected when parameter is a hash specifying the destination" do
|
117
|
-
@removed_subscriptions = [Subscription.new("/queue/test/1"), Subscription.new("/queue/test/1")]
|
118
|
-
@removed_subscriptions.each { |sub| @subscriptions << sub }
|
119
|
-
@subscriptions << Subscription.new("/queue/test/2")
|
120
|
-
@subscriptions << Subscription.new("/queue/test/1", 'subscription-4')
|
121
|
-
@to_remove = @subscriptions.remove( { :destination => "/queue/test/1" })
|
122
|
-
@subscriptions.size.should == 2
|
123
|
-
@subscriptions.should_not include(@removed_subscriptions.first)
|
124
|
-
@subscriptions.should_not include(@removed_subscriptions.last)
|
125
|
-
@to_remove.size.should == 2
|
126
|
-
@to_remove.should include(@removed_subscriptions.first)
|
127
|
-
@to_remove.should include(@removed_subscriptions.last)
|
128
|
-
end
|
129
|
-
it "should remove subscriptions as expected when parameter is a Subscription" do
|
130
|
-
@removed_subscription = Subscription.new("/queue/test/1", 'subscription-4')
|
131
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
132
|
-
@subscriptions << Subscription.new("/queue/test/1")
|
133
|
-
@subscriptions << Subscription.new("/queue/test/2")
|
134
|
-
@subscriptions << @removed_subscription
|
135
|
-
@to_remove = @subscriptions.remove(@removed_subscription)
|
136
|
-
@to_remove.size.should == 1
|
137
|
-
@to_remove.should include(@removed_subscription)
|
138
|
-
@to_remove = @subscriptions.remove(Subscription.new("/queue/test/1", nil, :client))
|
139
|
-
@to_remove.should be_empty
|
140
|
-
@subscriptions.size.should == 3
|
141
|
-
@subscriptions.should_not include(@removed_subscription)
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|