onstomp 1.0.0pre1
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/.autotest +2 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.yardopts +5 -0
- data/CHANGELOG.md +4 -0
- data/DeveloperNarrative.md +15 -0
- data/Gemfile +4 -0
- data/LICENSE.md +221 -0
- data/README.md +73 -0
- data/Rakefile +6 -0
- data/UserNarrative.md +8 -0
- data/examples/basic.rb +40 -0
- data/examples/events.rb +72 -0
- data/lib/onstomp/client.rb +152 -0
- data/lib/onstomp/components/frame.rb +108 -0
- data/lib/onstomp/components/frame_headers.rb +212 -0
- data/lib/onstomp/components/nil_processor.rb +20 -0
- data/lib/onstomp/components/scopes/header_scope.rb +25 -0
- data/lib/onstomp/components/scopes/receipt_scope.rb +25 -0
- data/lib/onstomp/components/scopes/transaction_scope.rb +191 -0
- data/lib/onstomp/components/scopes.rb +45 -0
- data/lib/onstomp/components/subscription.rb +30 -0
- data/lib/onstomp/components/threaded_processor.rb +62 -0
- data/lib/onstomp/components/uri.rb +30 -0
- data/lib/onstomp/components.rb +13 -0
- data/lib/onstomp/connections/base.rb +208 -0
- data/lib/onstomp/connections/heartbeating.rb +82 -0
- data/lib/onstomp/connections/serializers/stomp_1.rb +166 -0
- data/lib/onstomp/connections/serializers/stomp_1_0.rb +41 -0
- data/lib/onstomp/connections/serializers/stomp_1_1.rb +134 -0
- data/lib/onstomp/connections/serializers.rb +9 -0
- data/lib/onstomp/connections/stomp_1.rb +69 -0
- data/lib/onstomp/connections/stomp_1_0.rb +28 -0
- data/lib/onstomp/connections/stomp_1_1.rb +65 -0
- data/lib/onstomp/connections.rb +119 -0
- data/lib/onstomp/interfaces/client_configurable.rb +55 -0
- data/lib/onstomp/interfaces/client_events.rb +168 -0
- data/lib/onstomp/interfaces/connection_events.rb +62 -0
- data/lib/onstomp/interfaces/event_manager.rb +69 -0
- data/lib/onstomp/interfaces/frame_methods.rb +190 -0
- data/lib/onstomp/interfaces/receipt_manager.rb +33 -0
- data/lib/onstomp/interfaces/subscription_manager.rb +48 -0
- data/lib/onstomp/interfaces/uri_configurable.rb +106 -0
- data/lib/onstomp/interfaces.rb +14 -0
- data/lib/onstomp/version.rb +13 -0
- data/lib/onstomp.rb +147 -0
- data/onstomp.gemspec +29 -0
- data/spec/onstomp/client_spec.rb +265 -0
- data/spec/onstomp/components/frame_headers_spec.rb +163 -0
- data/spec/onstomp/components/frame_spec.rb +144 -0
- data/spec/onstomp/components/nil_processor_spec.rb +32 -0
- data/spec/onstomp/components/scopes/header_scope_spec.rb +27 -0
- data/spec/onstomp/components/scopes/receipt_scope_spec.rb +33 -0
- data/spec/onstomp/components/scopes/transaction_scope_spec.rb +227 -0
- data/spec/onstomp/components/scopes_spec.rb +63 -0
- data/spec/onstomp/components/subscription_spec.rb +58 -0
- data/spec/onstomp/components/threaded_processor_spec.rb +92 -0
- data/spec/onstomp/components/uri_spec.rb +33 -0
- data/spec/onstomp/connections/base_spec.rb +349 -0
- data/spec/onstomp/connections/heartbeating_spec.rb +132 -0
- data/spec/onstomp/connections/serializers/stomp_1_0_spec.rb +50 -0
- data/spec/onstomp/connections/serializers/stomp_1_1_spec.rb +99 -0
- data/spec/onstomp/connections/serializers/stomp_1_spec.rb +104 -0
- data/spec/onstomp/connections/stomp_1_0_spec.rb +54 -0
- data/spec/onstomp/connections/stomp_1_1_spec.rb +137 -0
- data/spec/onstomp/connections/stomp_1_spec.rb +113 -0
- data/spec/onstomp/connections_spec.rb +135 -0
- data/spec/onstomp/interfaces/client_events_spec.rb +108 -0
- data/spec/onstomp/interfaces/connection_events_spec.rb +55 -0
- data/spec/onstomp/interfaces/event_manager_spec.rb +72 -0
- data/spec/onstomp/interfaces/frame_methods_spec.rb +109 -0
- data/spec/onstomp/interfaces/receipt_manager_spec.rb +53 -0
- data/spec/onstomp/interfaces/subscription_manager_spec.rb +64 -0
- data/spec/onstomp_spec.rb +15 -0
- data/spec/spec_helper.rb +12 -0
- data/spec/support/custom_argument_matchers.rb +51 -0
- data/spec/support/frame_matchers.rb +88 -0
- data/spec/support/shared_frame_method_examples.rb +116 -0
- data/yard_extensions.rb +32 -0
- metadata +219 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
module OnStomp::Components::Scopes
|
|
5
|
+
describe ReceiptScope do
|
|
6
|
+
let(:client) {
|
|
7
|
+
OnStomp::Client.new("stomp:///")
|
|
8
|
+
}
|
|
9
|
+
let(:receipt_back) {
|
|
10
|
+
lambda { |r| true }
|
|
11
|
+
}
|
|
12
|
+
let(:scope) {
|
|
13
|
+
ReceiptScope.new receipt_back, client
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let(:frame_method_interface) { scope }
|
|
17
|
+
it_should_behave_like "frame method interfaces"
|
|
18
|
+
|
|
19
|
+
describe ".transmit" do
|
|
20
|
+
it "should add its receipt callback to frames transmitted without one" do
|
|
21
|
+
frame = OnStomp::Components::Frame.new('COMMAND', {:header2 => 'my value'})
|
|
22
|
+
client.should_receive(:transmit).with(frame, { :receipt => receipt_back })
|
|
23
|
+
scope.transmit frame
|
|
24
|
+
end
|
|
25
|
+
it "should not add its receipt callback if one was already present" do
|
|
26
|
+
alt_receipt_back = lambda { |r| false }
|
|
27
|
+
frame = OnStomp::Components::Frame.new('COMMAND', {:header2 => 'my value'})
|
|
28
|
+
client.should_receive(:transmit).with(frame, { :receipt => alt_receipt_back })
|
|
29
|
+
scope.transmit frame, :receipt => alt_receipt_back
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
module OnStomp::Components::Scopes
|
|
5
|
+
describe TransactionScope do
|
|
6
|
+
let(:client) {
|
|
7
|
+
OnStomp::Client.new("stomp:///").tap do |c|
|
|
8
|
+
c.stub(:connection => OnStomp::Connections::Stomp_1_1.new(mock('io'), c))
|
|
9
|
+
end
|
|
10
|
+
}
|
|
11
|
+
let(:scope) {
|
|
12
|
+
TransactionScope.new 't-1234', client
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe ".begin" do
|
|
16
|
+
it "should use the scope's transaction id by default" do
|
|
17
|
+
frame = scope.begin :header1 => 'value 1'
|
|
18
|
+
frame.should have_headers(:header1 => 'value 1',
|
|
19
|
+
:transaction => 't-1234')
|
|
20
|
+
end
|
|
21
|
+
it "should use a supplied transaction ID" do
|
|
22
|
+
frame = scope.begin 't-5678', :header1 => 'value 1'
|
|
23
|
+
frame.should have_headers(:header1 => 'value 1',
|
|
24
|
+
:transaction => 't-5678')
|
|
25
|
+
end
|
|
26
|
+
it "should raise an error if the transaction has been started and not finished" do
|
|
27
|
+
scope.begin :header1 => 'value 1'
|
|
28
|
+
lambda {
|
|
29
|
+
scope.begin
|
|
30
|
+
}.should raise_error(OnStomp::TransactionError)
|
|
31
|
+
end
|
|
32
|
+
it "should not raise an error if the transaction has been finished" do
|
|
33
|
+
scope.begin :header1 => 'value 1'
|
|
34
|
+
scope.commit
|
|
35
|
+
lambda {
|
|
36
|
+
scope.begin
|
|
37
|
+
}.should_not raise_error
|
|
38
|
+
end
|
|
39
|
+
it "should generate a new transaction ID after completing" do
|
|
40
|
+
scope.begin :header1 => 'value 1'
|
|
41
|
+
scope.commit
|
|
42
|
+
next_begin = scope.begin
|
|
43
|
+
next_begin[:transaction].should_not be_empty
|
|
44
|
+
next_begin[:transaction].should_not == 't-1234'
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
describe ".commit" do
|
|
49
|
+
it "should use the scope's transaction id" do
|
|
50
|
+
scope.begin
|
|
51
|
+
scope.commit('t-5678', :header1 => 'value 1').should have_headers(
|
|
52
|
+
:header1 => 'value 1',
|
|
53
|
+
:transaction => 't-1234'
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
it "should raise an error if the transaction has not been started" do
|
|
57
|
+
lambda {
|
|
58
|
+
scope.commit
|
|
59
|
+
}.should raise_error(OnStomp::TransactionError)
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
describe ".abort" do
|
|
64
|
+
it "should use the scope's transaction id" do
|
|
65
|
+
scope.begin
|
|
66
|
+
scope.abort('t-5678', :header1 => 'value 1').should have_headers(
|
|
67
|
+
:header1 => 'value 1',
|
|
68
|
+
:transaction => 't-1234'
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
it "should raise an error if the transaction has not been started" do
|
|
72
|
+
lambda {
|
|
73
|
+
scope.abort
|
|
74
|
+
}.should raise_error(OnStomp::TransactionError)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
describe ".send" do
|
|
79
|
+
it "should generate a SEND frame with the transaction header" do
|
|
80
|
+
scope.begin
|
|
81
|
+
scope.send('/queue/test', 'body of message').should have_headers(:transaction => 't-1234')
|
|
82
|
+
end
|
|
83
|
+
it "should work with :puts, too!" do
|
|
84
|
+
scope.begin
|
|
85
|
+
scope.puts('/queue/test', 'body of message').should have_headers(:transaction => 't-1234')
|
|
86
|
+
end
|
|
87
|
+
it "should not include the transaction header if the transaction has not started" do
|
|
88
|
+
scope.send('/queue/test', 'body of message').should_not have_header_named(:transaction)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe ".ack" do
|
|
93
|
+
it "should generate a SEND frame with the transaction header" do
|
|
94
|
+
scope.begin
|
|
95
|
+
scope.ack('m-1234', 's-1234').should have_headers(:transaction => 't-1234')
|
|
96
|
+
end
|
|
97
|
+
it "should not include the transaction header if the transaction has not started" do
|
|
98
|
+
scope.ack('m-1234', 's-1234').should_not have_header_named(:transaction)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
describe ".nack" do
|
|
103
|
+
it "should generate a NACK frame with the transaction header" do
|
|
104
|
+
scope.begin
|
|
105
|
+
scope.nack('m-1234', 's-1234').should have_headers(:transaction => 't-1234')
|
|
106
|
+
end
|
|
107
|
+
it "should not include the transaction header if the transaction has not started" do
|
|
108
|
+
scope.nack('m-1234', 's-1234').should_not have_header_named(:transaction)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
describe "non-transactional frames" do
|
|
113
|
+
it "should not add a transaction header to SUBSCRIBE" do
|
|
114
|
+
scope.begin
|
|
115
|
+
scope.subscribe("/queue/test").should_not have_header_named(:transaction)
|
|
116
|
+
end
|
|
117
|
+
it "should not add a transaction header to UNSUBSCRIBE" do
|
|
118
|
+
scope.begin
|
|
119
|
+
scope.unsubscribe("s-1234").should_not have_header_named(:transaction)
|
|
120
|
+
end
|
|
121
|
+
it "should not add a transaction header to DISCONNECT" do
|
|
122
|
+
scope.begin
|
|
123
|
+
scope.disconnect.should_not have_header_named(:transaction)
|
|
124
|
+
end
|
|
125
|
+
it "should not add a transaction header to heartbeats" do
|
|
126
|
+
scope.begin
|
|
127
|
+
scope.beat.should_not have_header_named(:transaction)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
describe ".perform" do
|
|
132
|
+
it "should begin an un-started transaction and commit it when the block completes" do
|
|
133
|
+
client.should_receive(:transmit).with(an_onstomp_frame('BEGIN',
|
|
134
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
135
|
+
client.should_receive(:transmit).with(an_onstomp_frame('COMMIT',
|
|
136
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
137
|
+
client.should_receive(:transmit).with(an_onstomp_frame('SEND',
|
|
138
|
+
{:destination => '/queue/test', :transaction => 't-1234'},
|
|
139
|
+
'my body'), an_instance_of(Hash)).and_return { |f| f }
|
|
140
|
+
|
|
141
|
+
scope.perform { |t| t.send("/queue/test", "my body") }
|
|
142
|
+
end
|
|
143
|
+
it "should not begin an already started transaction" do
|
|
144
|
+
scope.begin
|
|
145
|
+
client.should_receive(:transmit).with(an_onstomp_frame('COMMIT',
|
|
146
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
147
|
+
client.should_receive(:transmit).with(an_onstomp_frame('SEND',
|
|
148
|
+
{:destination => '/queue/test', :transaction => 't-1234'},
|
|
149
|
+
'my body'), an_instance_of(Hash)).and_return { |f| f }
|
|
150
|
+
|
|
151
|
+
scope.perform { |t| t.send("/queue/test", "my body") }
|
|
152
|
+
end
|
|
153
|
+
it "should not commit an already commited transaction" do
|
|
154
|
+
client.should_receive(:transmit).with(an_onstomp_frame('BEGIN',
|
|
155
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
156
|
+
client.should_receive(:transmit).with(an_onstomp_frame('COMMIT',
|
|
157
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
158
|
+
client.should_receive(:transmit).with(an_onstomp_frame('SEND',
|
|
159
|
+
{:destination => '/queue/test', :transaction => 't-1234'},
|
|
160
|
+
'my body'), an_instance_of(Hash)).and_return { |f| f }
|
|
161
|
+
|
|
162
|
+
scope.perform { |t| t.send("/queue/test", "my body"); t.commit }
|
|
163
|
+
end
|
|
164
|
+
it "should not commit an already aborted transaction" do
|
|
165
|
+
client.should_receive(:transmit).with(an_onstomp_frame('BEGIN',
|
|
166
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
167
|
+
client.should_receive(:transmit).with(an_onstomp_frame('ABORT',
|
|
168
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
169
|
+
client.should_receive(:transmit).with(an_onstomp_frame('SEND',
|
|
170
|
+
{:destination => '/queue/test', :transaction => 't-1234'},
|
|
171
|
+
'my body'), an_instance_of(Hash)).and_return { |f| f }
|
|
172
|
+
|
|
173
|
+
scope.perform { |t| t.send("/queue/test", "my body"); t.abort }
|
|
174
|
+
end
|
|
175
|
+
it "should abort if the block raises an error, and re-raise it" do
|
|
176
|
+
client.should_receive(:transmit).with(an_onstomp_frame('BEGIN',
|
|
177
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
178
|
+
client.should_receive(:transmit).with(an_onstomp_frame('ABORT',
|
|
179
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
180
|
+
client.should_receive(:transmit).with(an_onstomp_frame('SEND',
|
|
181
|
+
{:destination => '/queue/test', :transaction => 't-1234'},
|
|
182
|
+
'my body'), an_instance_of(Hash)).and_return { |f| f }
|
|
183
|
+
|
|
184
|
+
lambda {
|
|
185
|
+
scope.perform { |t|
|
|
186
|
+
t.send("/queue/test", "my body")
|
|
187
|
+
raise ArgumentError
|
|
188
|
+
}
|
|
189
|
+
}.should raise_error(ArgumentError)
|
|
190
|
+
end
|
|
191
|
+
it "should not abort if the block raises an error after being aborted" do
|
|
192
|
+
client.should_receive(:transmit).with(an_onstomp_frame('BEGIN',
|
|
193
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
194
|
+
client.should_receive(:transmit).with(an_onstomp_frame('ABORT',
|
|
195
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
196
|
+
client.should_receive(:transmit).with(an_onstomp_frame('SEND',
|
|
197
|
+
{:destination => '/queue/test', :transaction => 't-1234'},
|
|
198
|
+
'my body'), an_instance_of(Hash)).and_return { |f| f }
|
|
199
|
+
|
|
200
|
+
lambda {
|
|
201
|
+
scope.perform { |t|
|
|
202
|
+
t.send("/queue/test", "my body")
|
|
203
|
+
t.abort
|
|
204
|
+
raise ArgumentError
|
|
205
|
+
}
|
|
206
|
+
}.should raise_error(ArgumentError)
|
|
207
|
+
end
|
|
208
|
+
it "should not abort if the block raises an error after being committed" do
|
|
209
|
+
client.should_receive(:transmit).with(an_onstomp_frame('BEGIN',
|
|
210
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
211
|
+
client.should_receive(:transmit).with(an_onstomp_frame('COMMIT',
|
|
212
|
+
:transaction => 't-1234')).and_return { |f| f }
|
|
213
|
+
client.should_receive(:transmit).with(an_onstomp_frame('SEND',
|
|
214
|
+
{:destination => '/queue/test', :transaction => 't-1234'},
|
|
215
|
+
'my body'), an_instance_of(Hash)).and_return { |f| f }
|
|
216
|
+
|
|
217
|
+
lambda {
|
|
218
|
+
scope.perform { |t|
|
|
219
|
+
t.send("/queue/test", "my body")
|
|
220
|
+
t.commit
|
|
221
|
+
raise ArgumentError
|
|
222
|
+
}
|
|
223
|
+
}.should raise_error(ArgumentError)
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
end
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
module OnStomp::Components
|
|
5
|
+
describe Scopes do
|
|
6
|
+
let(:connection) {
|
|
7
|
+
mock('connection')
|
|
8
|
+
}
|
|
9
|
+
let(:scoper) {
|
|
10
|
+
mock('scoper').tap do |m|
|
|
11
|
+
m.extend Scopes
|
|
12
|
+
end
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe ".with_headers" do
|
|
16
|
+
before(:each) do
|
|
17
|
+
scoper.stub :connection => connection
|
|
18
|
+
end
|
|
19
|
+
it "should create a new Header Scope" do
|
|
20
|
+
scoper.with_headers(:header1 => 'value 1', 'header2' => 'value 2').
|
|
21
|
+
should be_a_header_scope(:header1 => 'value 1',
|
|
22
|
+
'header2' => 'value 2')
|
|
23
|
+
end
|
|
24
|
+
it "should yield the scope to a given block" do
|
|
25
|
+
yielded = nil
|
|
26
|
+
scoper.with_headers :header1 => 'value 1', 'header2' => 'value 2' do |h|
|
|
27
|
+
yielded = h
|
|
28
|
+
end
|
|
29
|
+
yielded.should be_a_header_scope(:header1 => 'value 1',
|
|
30
|
+
'header2' => 'value 2')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe ".with_receipt" do
|
|
35
|
+
before(:each) do
|
|
36
|
+
scoper.stub :connection => connection
|
|
37
|
+
end
|
|
38
|
+
it "should create a new Receipt Scope" do
|
|
39
|
+
callback = lambda { |r| true }
|
|
40
|
+
scoper.with_receipt(&callback).should be_a_receipt_scope(callback)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe ".transaction" do
|
|
45
|
+
before(:each) do
|
|
46
|
+
scoper.stub(:connection => OnStomp::Connections::Stomp_1_1.new(
|
|
47
|
+
mock('io'), scoper))
|
|
48
|
+
end
|
|
49
|
+
it "should create a new transaction scope" do
|
|
50
|
+
scoper.transaction('t-1234').should be_a_transaction_scope('t-1234')
|
|
51
|
+
end
|
|
52
|
+
it "should evaluate a given block within the transaction" do
|
|
53
|
+
performed = nil
|
|
54
|
+
scoper.should_receive(:transmit).with(an_onstomp_frame('BEGIN'))
|
|
55
|
+
scoper.should_receive(:transmit).with(an_onstomp_frame('COMMIT'))
|
|
56
|
+
scoper.transaction('t-5678') do |t|
|
|
57
|
+
performed = t
|
|
58
|
+
end
|
|
59
|
+
performed.should be_a_transaction_scope
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
module OnStomp::Components
|
|
5
|
+
describe Subscription do
|
|
6
|
+
let(:frame) {
|
|
7
|
+
mock('frame')
|
|
8
|
+
}
|
|
9
|
+
let(:callback) {
|
|
10
|
+
mock('callback')
|
|
11
|
+
}
|
|
12
|
+
let(:subscription) {
|
|
13
|
+
Subscription.new frame, callback
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe ".initialize" do
|
|
17
|
+
it "should take a frame and a callback" do
|
|
18
|
+
subscription.frame.should == frame
|
|
19
|
+
subscription.callback.should == callback
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe ".id" do
|
|
24
|
+
it "should pull the id header from its frame" do
|
|
25
|
+
frame.stub(:[]).with(:id).and_return('s-1234')
|
|
26
|
+
subscription.id.should == 's-1234'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
describe ".destination" do
|
|
31
|
+
it "should pull the destination header from its frame" do
|
|
32
|
+
frame.stub(:[]).with(:destination).and_return('some.path.to.write')
|
|
33
|
+
subscription.destination.should == 'some.path.to.write'
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
describe ".call" do
|
|
38
|
+
it "should invoke its callback with the supplied frame" do
|
|
39
|
+
callback.should_receive(:call).with(frame)
|
|
40
|
+
subscription.call(frame)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
describe ".include?" do
|
|
45
|
+
it "should return true if the supplied frame's destination matches its destination" do
|
|
46
|
+
subscription.stub(:destination => 'some.path.to.write')
|
|
47
|
+
frame.stub(:[]).with(:destination).and_return('some.path.to.write')
|
|
48
|
+
subscription.should include(frame)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
it "should return false if the supplied frame's destination does not match its destination" do
|
|
52
|
+
subscription.stub(:destination => 'some.other.path.to.write')
|
|
53
|
+
frame.stub(:[]).with(:destination).and_return('some.path.to.write')
|
|
54
|
+
subscription.should_not include(frame)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
module OnStomp::Components
|
|
5
|
+
describe ThreadedProcessor do
|
|
6
|
+
let(:processor) {
|
|
7
|
+
ThreadedProcessor.new(client)
|
|
8
|
+
}
|
|
9
|
+
let(:client) {
|
|
10
|
+
mock("client", :connection => connection, :connected? => false)
|
|
11
|
+
}
|
|
12
|
+
let(:connection) {
|
|
13
|
+
mock("connection", :io_process => nil)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
describe ".start / .stop" do
|
|
17
|
+
it "should start and stop the processor" do
|
|
18
|
+
checked_client = false
|
|
19
|
+
client.stub(:connected?).and_return do
|
|
20
|
+
checked_client = true
|
|
21
|
+
Thread.stop
|
|
22
|
+
end
|
|
23
|
+
processor.start
|
|
24
|
+
Thread.pass until checked_client
|
|
25
|
+
processor.running?.should be_true
|
|
26
|
+
processor.stop
|
|
27
|
+
processor.running?.should be_false
|
|
28
|
+
end
|
|
29
|
+
it "should raise any IOErrors raised in the thread, if the client is alive" do
|
|
30
|
+
client.stub(:connected? => true)
|
|
31
|
+
connection.stub(:io_process) do
|
|
32
|
+
raise IOError
|
|
33
|
+
end
|
|
34
|
+
processor.start
|
|
35
|
+
Thread.pass while processor.running?
|
|
36
|
+
lambda { processor.stop }.should raise_error(IOError)
|
|
37
|
+
end
|
|
38
|
+
it "should raise any SystemCallErrors raised in the thread, if the client is alive" do
|
|
39
|
+
client.stub(:connected? => true)
|
|
40
|
+
connection.stub(:io_process) do
|
|
41
|
+
raise SystemCallError.new('blather', 13)
|
|
42
|
+
end
|
|
43
|
+
processor.start
|
|
44
|
+
Thread.pass while processor.running?
|
|
45
|
+
lambda { processor.stop }.should raise_error(SystemCallError)
|
|
46
|
+
end
|
|
47
|
+
it "should not raise any IOErrors raised in the thread, if the client is dead" do
|
|
48
|
+
client.stub(:connected? => true)
|
|
49
|
+
connection.stub(:io_process) do
|
|
50
|
+
raise IOError
|
|
51
|
+
end
|
|
52
|
+
processor.start
|
|
53
|
+
Thread.pass while processor.running?
|
|
54
|
+
client.stub(:connected? => false)
|
|
55
|
+
lambda { processor.stop }.should_not raise_error
|
|
56
|
+
end
|
|
57
|
+
it "should not raise any SystemCallErrors raised in the thread, if the client is dead" do
|
|
58
|
+
client.stub(:connected? => true)
|
|
59
|
+
connection.stub(:io_process) do
|
|
60
|
+
raise SystemCallError.new('blather', 13)
|
|
61
|
+
end
|
|
62
|
+
processor.start
|
|
63
|
+
Thread.pass while processor.running?
|
|
64
|
+
client.stub(:connected? => false)
|
|
65
|
+
lambda { processor.stop }.should_not raise_error
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
describe ".join" do
|
|
70
|
+
it "should block the current thread until connection is no longer alive" do
|
|
71
|
+
joined_properly = false
|
|
72
|
+
joining = false
|
|
73
|
+
spun_up = false
|
|
74
|
+
client_alive = true
|
|
75
|
+
join_tester = Thread.new do
|
|
76
|
+
Thread.pass until joining
|
|
77
|
+
sleep(0.1)
|
|
78
|
+
client.stub(:connected? => false)
|
|
79
|
+
joined_properly = true
|
|
80
|
+
end
|
|
81
|
+
client.stub(:connected?).and_return do
|
|
82
|
+
spun_up = true
|
|
83
|
+
end
|
|
84
|
+
processor.start
|
|
85
|
+
Thread.pass until spun_up
|
|
86
|
+
joining = true
|
|
87
|
+
processor.join
|
|
88
|
+
joined_properly.should be_true
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
|
2
|
+
require 'spec_helper'
|
|
3
|
+
|
|
4
|
+
module OnStomp::Components
|
|
5
|
+
describe URI do
|
|
6
|
+
it "should make stomp:// strings parseable" do
|
|
7
|
+
::URI.parse("stomp:///").should be_a_kind_of(OnStomp::Components::URI::STOMP)
|
|
8
|
+
end
|
|
9
|
+
it "should make stomp+ssl:// strings parseable" do
|
|
10
|
+
::URI.parse("stomp+ssl:///").should be_a_kind_of(OnStomp::Components::URI::STOMP_SSL)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe URI::STOMP do
|
|
14
|
+
let(:uri) { ::URI.parse("stomp:///") }
|
|
15
|
+
it "should have a default port of 61613" do
|
|
16
|
+
uri.port.should == 61613
|
|
17
|
+
end
|
|
18
|
+
it "should have an onstomp_socket_type of :tcp" do
|
|
19
|
+
uri.onstomp_socket_type.should == :tcp
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
describe URI::STOMP_SSL do
|
|
24
|
+
let(:uri) { ::URI.parse("stomp+ssl:///") }
|
|
25
|
+
it "should have a default port of 61612" do
|
|
26
|
+
uri.port.should == 61612
|
|
27
|
+
end
|
|
28
|
+
it "should have an onstomp_socket_type of :ssl" do
|
|
29
|
+
uri.onstomp_socket_type.should == :ssl
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|