stomper 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,54 @@
1
+ require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))
2
+
3
+ module Stomper::Frames
4
+ describe Headers do
5
+ before(:each) do
6
+ @headers = Headers.new
7
+ end
8
+
9
+ it "should set a header by a string key, accessible by all" do
10
+ @test_value = "a test"
11
+ @headers['testing'] = @test_value
12
+ @headers['testing'].should == @test_value
13
+ @headers[:testing].should == @test_value
14
+ @headers.testing.should == @test_value
15
+ @headers.send(:testing).should == @test_value
16
+ end
17
+
18
+ it "should set a header by a symbol key, accessible by all" do
19
+ @test_value = "another test"
20
+ @headers[:some_key] = @test_value
21
+ @headers['some_key'].should == @test_value
22
+ @headers[:some_key].should == @test_value
23
+ @headers.some_key.should == @test_value
24
+ @headers.send(:some_key).should == @test_value
25
+ end
26
+
27
+ it "should set a header by a method, accessible by all" do
28
+ @test_value = "yet more testing"
29
+ @headers.another_key = @test_value
30
+ @headers['another_key'].should == @test_value
31
+ @headers[:another_key].should == @test_value
32
+ @headers.another_key.should == @test_value
33
+ @headers.send(:another_key).should == @test_value
34
+ end
35
+
36
+ it "should override the default id getter and provide a setter" do
37
+ @test_value = "my id"
38
+ @headers.id = @test_value
39
+ @headers.id.should == @test_value
40
+ @headers['id'].should == @test_value
41
+ @headers[:id].should == @test_value
42
+ @headers.send(:id).should == @test_value
43
+ end
44
+
45
+ it "should provide method to convert to stomp compatible headers" do
46
+ @headers.to_stomp.should be_empty
47
+ @headers.ack = 'auto'
48
+ @headers.destination = '/queue/test/1'
49
+ @headers.to_stomp.should == "ack:auto\ndestination:/queue/test/1\n"
50
+ end
51
+
52
+
53
+ end
54
+ end
@@ -0,0 +1,86 @@
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 provide a method for subclasses to register the command they handle" do
11
+ ServerFrame.should respond_to(:factory_for)
12
+ end
13
+
14
+ it "should build an appropriate object for a given server frame" do
15
+ @built_frame = ServerFrame.build("MESSAGE", {'message-id' => 'msg-001' ,'transaction' => 'tx-test', 'subscription' => 'sub-test'}, "message body")
16
+ @built_frame.should be_an_instance_of(Message)
17
+ @built_frame.headers.transaction.should == "tx-test"
18
+ @built_frame.headers.subscription.should == "sub-test"
19
+ @built_frame.headers[:'message-id'].should == "msg-001"
20
+ @built_frame.body.should == "message body"
21
+ @built_frame = ServerFrame.build("AN UNKNOWN COMMAND", {:a_header => "test"}, "a body")
22
+ @built_frame.should be_an_instance_of(ServerFrame)
23
+ @built_frame.command.should == "AN UNKNOWN COMMAND"
24
+ @built_frame.headers.a_header.should == "test"
25
+ @built_frame.body.should == "a body"
26
+ class MockServerFrame < ServerFrame
27
+ factory_for :testing
28
+ def initialize(headers, body)
29
+ super('TESTING', headers, body)
30
+ end
31
+ end
32
+ @built_frame = ServerFrame.build("TESTING", {:a_header => "test"}, "a body")
33
+ @built_frame.should be_an_instance_of(MockServerFrame)
34
+ @built_frame.headers.a_header.should == "test"
35
+ @built_frame.body.should == "a body"
36
+ end
37
+
38
+ describe "server frames" do
39
+ describe Connected do
40
+ it "should be registered" do
41
+ @server_frame = ServerFrame.build("CONNECTED", {:a_header => 'test'}, "test body")
42
+ @server_frame.should be_an_instance_of(Connected)
43
+ @server_frame.headers.a_header.should == "test"
44
+ @server_frame.body.should == "test body"
45
+ end
46
+ end
47
+ describe Error do
48
+ it "should be registered" do
49
+ @server_frame = ServerFrame.build("ERROR", {:a_header => 'test'}, "test body")
50
+ @server_frame.should be_an_instance_of(Error)
51
+ @server_frame.headers.a_header.should == "test"
52
+ @server_frame.body.should == "test body"
53
+ end
54
+ end
55
+ describe Message do
56
+ it "should be registered" do
57
+ @server_frame = ServerFrame.build("MESSAGE", {:a_header => 'test'}, "test body")
58
+ @server_frame.should be_an_instance_of(Message)
59
+ @server_frame.headers.a_header.should == "test"
60
+ @server_frame.body.should == "test body"
61
+ end
62
+
63
+ it "should provide the convenience attributes" do
64
+ @message = Message.new({:destination => '/queue/testing', :subscription => 'sub-001', :'message-id' => 'msg-001'}, "test body")
65
+ @message.id.should == "msg-001"
66
+ @message.destination.should == "/queue/testing"
67
+ @message.subscription.should == "sub-001"
68
+ end
69
+ end
70
+ describe Receipt do
71
+ it "should be registered" do
72
+ @server_frame = ServerFrame.build("RECEIPT", {:a_header => 'test'}, "test body")
73
+ @server_frame.should be_an_instance_of(Receipt)
74
+ @server_frame.headers.a_header.should == "test"
75
+ @server_frame.body.should == "test body"
76
+ end
77
+
78
+ it "should provide the convenience attributes" do
79
+ @receipt = Receipt.new({:'receipt-id' => 'who the receipt is for'}, "test body")
80
+ @receipt.for.should == "who the receipt is for"
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,84 @@
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 "secure connection" do
71
+ before(:each) do
72
+ @secure_connection = @connection.class.new("stomp+ssl:///")
73
+ end
74
+ it "should transmit frames" do
75
+ @connection.connect
76
+ @frame = nil
77
+ @connection.transmit(Stomper::Frames::Subscribe.new("/topic/test_topic"))
78
+ @connection.transmit(Stomper::Frames::Send.new("/topic/test_topic", "hello"))
79
+ @frame = @connection.receive while @frame.nil?
80
+ @frame.should be_an_instance_of(Stomper::Frames::Message)
81
+ @frame.body.should == "hello"
82
+ end
83
+ end
84
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,10 @@
1
+ #begin
2
+ # require 'spec'
3
+ #rescue LoadError
4
+ # require 'rubygems'
5
+ # #gem 'rspec'
6
+ # require 'spec'
7
+ #end
8
+
9
+ require 'stomper'
10
+
@@ -0,0 +1,157 @@
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
@@ -0,0 +1,148 @@
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
+ Thread.new { sleep(0.1); @subscriptions.remove("/queue/test/1") }
52
+ # In general, this next step should execute before the thread has a chance to
53
+ # but the sleep in the map should mean that our thread gets woken up before
54
+ # map finishes. However, destinations should NEVER contain "/queue/test/4"
55
+ # because map should be synchronized.
56
+ destinations = @subscriptions.map { |sub| sleep(0.1); sub.destination }
57
+ destinations.size.should == 3
58
+ destinations.should == ['/queue/test/1', '/queue/test/2', '/queue/test/3']
59
+ @subscriptions.size.should == 2
60
+ @subscriptions.first.destination.should == "/queue/test/2"
61
+ end
62
+
63
+ end
64
+
65
+ describe "message delivery" do
66
+ it "should deliver messages to matching subscriptions" do
67
+ received_1 = false
68
+ received_2 = false
69
+ received_3 = false
70
+ @subscriptions << Subscription.new("/queue/test/1") { |msg| received_1 = true }
71
+ @subscriptions << Subscription.new("/queue/test/1", 'subscription-2') { |msg| received_2 = true }
72
+ @subscriptions << Subscription.new("/queue/test/2") { |msg| received_3 = true }
73
+ @message = Stomper::Frames::Message.new({'destination' => '/queue/test/1'},"test message")
74
+ @subscriptions.perform(@message)
75
+ received_1.should be_true
76
+ received_2.should be_false
77
+ received_3.should be_false
78
+ end
79
+ end
80
+
81
+ describe "unsubscribing" do
82
+ it "should remove all naive subscriptions when unsubscribing with a string destination" do
83
+ @removed_subscriptions = [Subscription.new("/queue/test/1"), Subscription.new("/queue/test/1")]
84
+ @removed_subscriptions.each { |sub| @subscriptions << sub }
85
+ @subscriptions << Subscription.new("/queue/test/2")
86
+ @subscriptions << Subscription.new("/queue/test/1", 'subscription-4')
87
+ @to_remove = @subscriptions.remove("/queue/test/1")
88
+ @subscriptions.size.should == 2
89
+ @subscriptions.should_not include(@removed_subscriptions.first)
90
+ @subscriptions.should_not include(@removed_subscriptions.last)
91
+ @to_remove.size.should == 2
92
+ @to_remove.should include(@removed_subscriptions.first)
93
+ @to_remove.should include(@removed_subscriptions.last)
94
+ end
95
+ it "should remove all subscriptions that accept messages for a supplied subscription ID" do
96
+ @removed_subscription = Subscription.new("/queue/test/1", 'subscription-4')
97
+ @subscriptions << Subscription.new("/queue/test/1")
98
+ @subscriptions << Subscription.new("/queue/test/1")
99
+ @subscriptions << Subscription.new("/queue/test/2")
100
+ @subscriptions << @removed_subscription
101
+ @to_remove = @subscriptions.remove(nil, @removed_subscription.id)
102
+ @subscriptions.size.should == 3
103
+ @subscriptions.should_not include(@removed_subscription)
104
+ @to_remove.size.should == 1
105
+ @to_remove.should include(@removed_subscription)
106
+ end
107
+ it "should remove subscriptions as expected when parameter is a hash specifying the ID" do
108
+ @removed_subscription = Subscription.new("/queue/test/1", 'subscription-4')
109
+ @subscriptions << Subscription.new("/queue/test/1")
110
+ @subscriptions << Subscription.new("/queue/test/1")
111
+ @subscriptions << Subscription.new("/queue/test/2")
112
+ @subscriptions << @removed_subscription
113
+ @to_remove = @subscriptions.remove({ :id => @removed_subscription.id })
114
+ @subscriptions.size.should == 3
115
+ @subscriptions.should_not include(@removed_subscription)
116
+ @to_remove.size.should == 1
117
+ @to_remove.should include(@removed_subscription)
118
+ end
119
+ it "should remove subscriptions as expected when parameter is a hash specifying the destination" do
120
+ @removed_subscriptions = [Subscription.new("/queue/test/1"), Subscription.new("/queue/test/1")]
121
+ @removed_subscriptions.each { |sub| @subscriptions << sub }
122
+ @subscriptions << Subscription.new("/queue/test/2")
123
+ @subscriptions << Subscription.new("/queue/test/1", 'subscription-4')
124
+ @to_remove = @subscriptions.remove( { :destination => "/queue/test/1" })
125
+ @subscriptions.size.should == 2
126
+ @subscriptions.should_not include(@removed_subscriptions.first)
127
+ @subscriptions.should_not include(@removed_subscriptions.last)
128
+ @to_remove.size.should == 2
129
+ @to_remove.should include(@removed_subscriptions.first)
130
+ @to_remove.should include(@removed_subscriptions.last)
131
+ end
132
+ it "should remove subscriptions as expected when parameter is a Subscription" do
133
+ @removed_subscription = Subscription.new("/queue/test/1", 'subscription-4')
134
+ @subscriptions << Subscription.new("/queue/test/1")
135
+ @subscriptions << Subscription.new("/queue/test/1")
136
+ @subscriptions << Subscription.new("/queue/test/2")
137
+ @subscriptions << @removed_subscription
138
+ @to_remove = @subscriptions.remove(@removed_subscription)
139
+ @to_remove.size.should == 1
140
+ @to_remove.should include(@removed_subscription)
141
+ @to_remove = @subscriptions.remove(Subscription.new("/queue/test/1", nil, :client))
142
+ @to_remove.should be_empty
143
+ @subscriptions.size.should == 3
144
+ @subscriptions.should_not include(@removed_subscription)
145
+ end
146
+ end
147
+ end
148
+ end