message-driver 0.3.0 → 0.4.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +160 -0
- data/.travis.yml +5 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +9 -8
- data/Guardfile +14 -7
- data/README.md +2 -0
- data/Rakefile +16 -10
- data/examples/basic_producer_and_consumer/Gemfile +2 -2
- data/examples/basic_producer_and_consumer/common.rb +3 -3
- data/examples/basic_producer_and_consumer/consumer.rb +5 -5
- data/examples/basic_producer_and_consumer/producer.rb +7 -7
- data/features/CHANGELOG.md +5 -0
- data/features/message_consumers/transactional_ack_consumers.feature +1 -0
- data/features/rabbitmq_specific_features/publisher_acknowledgements.feature +51 -0
- data/features/step_definitions/error_handling_steps.rb +2 -2
- data/features/step_definitions/logging_steps.rb +4 -4
- data/features/step_definitions/message_consumers_steps.rb +8 -8
- data/features/step_definitions/rabbitmq_specific_steps.rb +10 -0
- data/features/step_definitions/steps.rb +15 -15
- data/features/support/env.rb +3 -0
- data/features/support/firewall_helper.rb +5 -6
- data/features/support/message_table_matcher.rb +3 -4
- data/features/support/no_error_matcher.rb +3 -3
- data/features/support/test_runner.rb +11 -3
- data/features/support/transforms.rb +1 -1
- data/lib/message-driver.rb +1 -1
- data/lib/message_driver.rb +0 -1
- data/lib/message_driver/adapters/base.rb +10 -10
- data/lib/message_driver/adapters/bunny_adapter.rb +57 -30
- data/lib/message_driver/adapters/in_memory_adapter.rb +4 -5
- data/lib/message_driver/adapters/stomp_adapter.rb +4 -6
- data/lib/message_driver/broker.rb +5 -4
- data/lib/message_driver/client.rb +6 -6
- data/lib/message_driver/destination.rb +2 -2
- data/lib/message_driver/errors.rb +1 -4
- data/lib/message_driver/logging.rb +1 -1
- data/lib/message_driver/message.rb +2 -2
- data/lib/message_driver/subscription.rb +1 -1
- data/lib/message_driver/version.rb +1 -1
- data/lib/{message_driver/vendor → vendor}/.document +0 -0
- data/lib/vendor/nesty.rb +1 -0
- data/lib/vendor/nesty/nested_error.rb +28 -0
- data/message-driver.gemspec +15 -14
- data/spec/integration/bunny/amqp_integration_spec.rb +43 -43
- data/spec/integration/bunny/bunny_adapter_spec.rb +117 -101
- data/spec/integration/in_memory/in_memory_adapter_spec.rb +35 -35
- data/spec/integration/stomp/stomp_adapter_spec.rb +42 -42
- data/spec/spec_helper.rb +4 -1
- data/spec/support/shared/adapter_examples.rb +7 -7
- data/spec/support/shared/client_ack_examples.rb +6 -6
- data/spec/support/shared/context_examples.rb +4 -4
- data/spec/support/shared/destination_examples.rb +10 -10
- data/spec/support/shared/subscription_examples.rb +29 -29
- data/spec/support/shared/transaction_examples.rb +10 -10
- data/spec/units/message_driver/adapters/base_spec.rb +19 -19
- data/spec/units/message_driver/broker_spec.rb +57 -58
- data/spec/units/message_driver/client_spec.rb +84 -84
- data/spec/units/message_driver/destination_spec.rb +4 -4
- data/spec/units/message_driver/message_spec.rb +19 -19
- data/spec/units/message_driver/subscription_spec.rb +4 -4
- data/test_lib/broker_config.rb +2 -2
- metadata +27 -6
- data/lib/message_driver/vendor/nesty.rb +0 -1
- data/lib/message_driver/vendor/nesty/nested_error.rb +0 -26
@@ -7,33 +7,33 @@ module MessageDriver::Adapters
|
|
7
7
|
|
8
8
|
let(:valid_connection_attrs) { BrokerConfig.config }
|
9
9
|
|
10
|
-
describe
|
11
|
-
context
|
12
|
-
let(:broker) { double(
|
13
|
-
shared_examples
|
14
|
-
it
|
15
|
-
stub_const(
|
10
|
+
describe '#initialize' do
|
11
|
+
context 'differing bunny versions' do
|
12
|
+
let(:broker) { double('broker') }
|
13
|
+
shared_examples 'raises an error' do
|
14
|
+
it 'raises an error' do
|
15
|
+
stub_const('Bunny::VERSION', version)
|
16
16
|
expect {
|
17
17
|
described_class.new(broker, valid_connection_attrs)
|
18
|
-
}.to raise_error MessageDriver::Error,
|
18
|
+
}.to raise_error MessageDriver::Error, 'bunny 1.2.2 or later is required for the bunny adapter'
|
19
19
|
end
|
20
20
|
end
|
21
21
|
shared_examples "doesn't raise an error" do
|
22
22
|
it "doesn't raise an an error" do
|
23
|
-
stub_const(
|
23
|
+
stub_const('Bunny::VERSION', version)
|
24
24
|
adapter = nil
|
25
25
|
expect {
|
26
26
|
adapter = described_class.new(broker, valid_connection_attrs)
|
27
27
|
}.to_not raise_error
|
28
28
|
end
|
29
29
|
end
|
30
|
-
%w(0.8.0
|
30
|
+
%w(0.8.0 0.9.0 0.9.8 0.10.7 1.0.3 1.1.2 1.2.1).each do |v|
|
31
31
|
context "bunny version #{v}" do
|
32
32
|
let(:version) { v }
|
33
|
-
include_examples
|
33
|
+
include_examples 'raises an error'
|
34
34
|
end
|
35
35
|
end
|
36
|
-
%w(1.1.3 1.
|
36
|
+
%w(1.2.2 1.3.2 1.4.0).each do |v|
|
37
37
|
context "bunny version #{v}" do
|
38
38
|
let(:version) { v }
|
39
39
|
include_examples "doesn't raise an error"
|
@@ -41,7 +41,7 @@ module MessageDriver::Adapters
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
it
|
44
|
+
it 'connects to the rabbit broker' do
|
45
45
|
broker = double(:broker)
|
46
46
|
adapter = described_class.new(broker, valid_connection_attrs)
|
47
47
|
|
@@ -49,7 +49,7 @@ module MessageDriver::Adapters
|
|
49
49
|
expect(adapter.connection).to be_open
|
50
50
|
end
|
51
51
|
|
52
|
-
it
|
52
|
+
it 'connects to the rabbit broker lazily' do
|
53
53
|
broker = double(:broker)
|
54
54
|
adapter = described_class.new(broker, valid_connection_attrs)
|
55
55
|
|
@@ -57,7 +57,7 @@ module MessageDriver::Adapters
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
shared_context
|
60
|
+
shared_context 'a connected bunny adapter' do
|
61
61
|
let(:broker) { MessageDriver::Broker.configure(valid_connection_attrs) }
|
62
62
|
subject(:adapter) { broker.adapter }
|
63
63
|
let(:connection) { adapter.connection }
|
@@ -67,43 +67,47 @@ module MessageDriver::Adapters
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
shared_context
|
71
|
-
include_context
|
70
|
+
shared_context 'with a queue' do
|
71
|
+
include_context 'a connected bunny adapter'
|
72
72
|
|
73
73
|
let(:channel) { connection.create_channel }
|
74
|
-
let(:tmp_queue_name) {
|
74
|
+
let(:tmp_queue_name) { 'my_temp_queue' }
|
75
75
|
let(:tmp_queue) { channel.queue(tmp_queue_name, exclusive: true) }
|
76
76
|
end
|
77
77
|
|
78
|
-
it_behaves_like
|
79
|
-
include_context
|
78
|
+
it_behaves_like 'an adapter' do
|
79
|
+
include_context 'a connected bunny adapter'
|
80
80
|
end
|
81
81
|
|
82
|
-
describe
|
83
|
-
include_context
|
82
|
+
describe '#new_context' do
|
83
|
+
include_context 'a connected bunny adapter'
|
84
84
|
|
85
|
-
it
|
85
|
+
it 'returns a BunnyAdapter::BunnyContext' do
|
86
86
|
expect(subject.new_context).to be_a BunnyAdapter::BunnyContext
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
90
|
describe BunnyAdapter::BunnyContext do
|
91
|
-
include_context
|
91
|
+
include_context 'a connected bunny adapter'
|
92
92
|
subject(:adapter_context) { adapter.new_context }
|
93
|
+
around(:each) do |ex|
|
94
|
+
MessageDriver::Client.with_adapter_context(adapter_context) do
|
95
|
+
ex.run
|
96
|
+
end
|
97
|
+
end
|
93
98
|
|
94
|
-
it_behaves_like
|
95
|
-
it_behaves_like
|
96
|
-
it_behaves_like
|
97
|
-
it_behaves_like
|
99
|
+
it_behaves_like 'an adapter context'
|
100
|
+
it_behaves_like 'transactions are supported'
|
101
|
+
it_behaves_like 'client acks are supported'
|
102
|
+
it_behaves_like 'subscriptions are supported', BunnyAdapter::Subscription
|
98
103
|
|
99
|
-
describe
|
100
|
-
include_context
|
101
|
-
it
|
104
|
+
describe '#pop_message' do
|
105
|
+
include_context 'with a queue'
|
106
|
+
it 'needs some real tests'
|
102
107
|
end
|
103
108
|
|
104
|
-
|
105
|
-
|
106
|
-
it "closes the channel" do
|
109
|
+
describe '#invalidate' do
|
110
|
+
it 'closes the channel' do
|
107
111
|
subject.with_channel(false) do |ch|
|
108
112
|
expect(ch).to be_open
|
109
113
|
end
|
@@ -112,26 +116,36 @@ module MessageDriver::Adapters
|
|
112
116
|
end
|
113
117
|
end
|
114
118
|
|
115
|
-
describe
|
119
|
+
describe '#create_destination' do
|
116
120
|
|
117
|
-
context
|
118
|
-
context
|
119
|
-
let(:dest_name) {
|
121
|
+
context 'with defaults' do
|
122
|
+
context 'the resulting destination' do
|
123
|
+
let(:dest_name) { 'my_dest' }
|
120
124
|
subject(:result) { adapter_context.create_destination(dest_name, exclusive: true) }
|
121
125
|
|
122
126
|
it { should be_a BunnyAdapter::QueueDestination }
|
123
127
|
end
|
124
128
|
end
|
125
129
|
|
126
|
-
|
127
|
-
|
128
|
-
|
130
|
+
shared_examples 'supports publisher confirmations' do
|
131
|
+
let(:properties) { {persistent: false, confirm: true} }
|
132
|
+
it 'switches the channel to confirms mode' do
|
133
|
+
expect(adapter_context.channel.using_publisher_confirms?).to eq(true)
|
134
|
+
end
|
135
|
+
it 'waits until the confirm comes in' do
|
136
|
+
expect(adapter_context.channel.unconfirmed_set).to be_empty
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context 'the type is queue' do
|
141
|
+
context 'and there is no destination name given' do
|
142
|
+
subject(:destination) { adapter_context.create_destination('', type: :queue, exclusive: true) }
|
129
143
|
it { should be_a BunnyAdapter::QueueDestination }
|
130
144
|
its(:name) { should be_a String }
|
131
145
|
its(:name) { should_not be_empty }
|
132
146
|
end
|
133
|
-
context
|
134
|
-
let(:dest_name) {
|
147
|
+
context 'the resulting destination' do
|
148
|
+
let(:dest_name) { 'my_dest' }
|
135
149
|
subject(:destination) { adapter_context.create_destination(dest_name, type: :queue, exclusive: true) }
|
136
150
|
before do
|
137
151
|
destination
|
@@ -141,83 +155,84 @@ module MessageDriver::Adapters
|
|
141
155
|
its(:name) { should be_a String }
|
142
156
|
its(:name) { should eq(dest_name) }
|
143
157
|
|
144
|
-
include_examples
|
158
|
+
include_examples 'supports #message_count'
|
145
159
|
|
146
160
|
it "strips off the type so it isn't set on the destination" do
|
147
161
|
expect(subject.dest_options).to_not have_key :type
|
148
162
|
end
|
149
|
-
it
|
163
|
+
it 'ensures the queue is declared' do
|
150
164
|
expect {
|
151
165
|
connection.with_channel do |ch|
|
152
166
|
ch.queue(dest_name, passive: true)
|
153
167
|
end
|
154
168
|
}.to_not raise_error
|
155
169
|
end
|
156
|
-
context
|
157
|
-
let(:body) {
|
158
|
-
let(:headers) { {
|
170
|
+
context 'publishing a message' do
|
171
|
+
let(:body) { 'Testing the QueueDestination' }
|
172
|
+
let(:headers) { {'foo' => 'bar'} }
|
159
173
|
let(:properties) { {persistent: false} }
|
160
174
|
before do
|
161
175
|
subject.publish(body, headers, properties)
|
162
176
|
end
|
163
|
-
it
|
177
|
+
it 'publishes via the default exchange' do
|
164
178
|
msg = subject.pop_message
|
165
179
|
expect(msg.body).to eq(body)
|
166
180
|
expect(msg.headers).to eq(headers)
|
167
181
|
expect(msg.properties[:delivery_mode]).to eq(1)
|
168
|
-
expect(msg.delivery_info.exchange).to eq(
|
182
|
+
expect(msg.delivery_info.exchange).to eq('')
|
169
183
|
expect(msg.delivery_info.routing_key).to eq(subject.name)
|
170
184
|
end
|
185
|
+
include_examples 'supports publisher confirmations'
|
171
186
|
end
|
172
|
-
it_behaves_like
|
187
|
+
it_behaves_like 'a destination'
|
173
188
|
end
|
174
|
-
context
|
175
|
-
let(:dest_name) {
|
176
|
-
let(:exchange) { adapter_context.create_destination(
|
189
|
+
context 'and bindings are provided' do
|
190
|
+
let(:dest_name) { 'binding_test_queue' }
|
191
|
+
let(:exchange) { adapter_context.create_destination('amq.direct', type: :exchange) }
|
177
192
|
|
178
193
|
it "raises an exception if you don't provide a source" do
|
179
194
|
expect {
|
180
|
-
adapter_context.create_destination(
|
195
|
+
adapter_context.create_destination('bad_bind_queue', type: :queue, exclusive: true, bindings: [{args: {routing_key: 'test_exchange_bind'}}])
|
181
196
|
}.to raise_error MessageDriver::Error, /must provide a source/
|
182
197
|
end
|
183
198
|
|
184
|
-
it
|
185
|
-
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source:
|
186
|
-
exchange.publish(
|
199
|
+
it 'routes message to the queue through the exchange' do
|
200
|
+
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source: 'amq.direct', args: {routing_key: 'test_queue_bind'}}])
|
201
|
+
exchange.publish('test queue bindings', {}, routing_key: 'test_queue_bind')
|
187
202
|
message = destination.pop_message
|
188
203
|
expect(message).to_not be_nil
|
189
|
-
expect(message.body).to eq(
|
204
|
+
expect(message.body).to eq('test queue bindings')
|
190
205
|
end
|
191
206
|
end
|
192
207
|
|
193
|
-
context
|
208
|
+
context 'we are not yet connected to the broker and :no_declare is provided' do
|
194
209
|
it "doesn't cause a connection to the broker" do
|
195
210
|
connection.stop
|
196
|
-
adapter_context.create_destination(
|
211
|
+
adapter_context.create_destination('test_queue', no_declare: true, type: :queue, exclusive: true)
|
197
212
|
expect(adapter.connection(false)).to_not be_open
|
198
213
|
end
|
199
214
|
|
200
|
-
context
|
201
|
-
it
|
215
|
+
context 'with a server-named queue' do
|
216
|
+
it 'raises an error' do
|
202
217
|
expect {
|
203
|
-
adapter_context.create_destination(
|
204
|
-
}.to raise_error MessageDriver::Error,
|
218
|
+
adapter_context.create_destination('', no_declare: true, type: :queue, exclusive: true)
|
219
|
+
}.to raise_error MessageDriver::Error, 'server-named queues must be declared, but you provided :no_declare => true'
|
205
220
|
end
|
206
221
|
end
|
207
222
|
|
208
|
-
context
|
209
|
-
it
|
223
|
+
context 'with bindings' do
|
224
|
+
it 'raises an error' do
|
210
225
|
expect {
|
211
|
-
adapter_context.create_destination(
|
212
|
-
}.to raise_error MessageDriver::Error,
|
226
|
+
adapter_context.create_destination('tmp_queue', no_declare: true, bindings: [{source: 'amq.fanout'}], type: :queue, exclusive: true)
|
227
|
+
}.to raise_error MessageDriver::Error, 'queues with bindings must be declared, but you provided :no_declare => true'
|
213
228
|
end
|
214
229
|
end
|
215
230
|
end
|
216
231
|
end
|
217
232
|
|
218
|
-
context
|
219
|
-
context
|
220
|
-
let(:dest_name) {
|
233
|
+
context 'the type is exchange' do
|
234
|
+
context 'the resulting destination' do
|
235
|
+
let(:dest_name) { 'my_dest' }
|
221
236
|
subject(:destination) { adapter_context.create_destination(dest_name, type: :exchange) }
|
222
237
|
|
223
238
|
it { should be_a BunnyAdapter::ExchangeDestination }
|
@@ -227,21 +242,21 @@ module MessageDriver::Adapters
|
|
227
242
|
expect(subject.dest_options).to_not have_key :type
|
228
243
|
end
|
229
244
|
|
230
|
-
it
|
245
|
+
it 'raises an error when pop_message is called' do
|
231
246
|
expect {
|
232
247
|
subject.pop_message(dest_name)
|
233
248
|
}.to raise_error MessageDriver::Error, "You can't pop a message off an exchange"
|
234
249
|
end
|
235
250
|
|
236
|
-
context
|
237
|
-
let(:body) {
|
238
|
-
let(:headers) { {
|
251
|
+
context 'publishing a message' do
|
252
|
+
let(:body) { 'Testing the ExchangeDestination' }
|
253
|
+
let(:headers) { {'foo' => 'bar'} }
|
239
254
|
let(:properties) { {persistent: false} }
|
240
255
|
before { connection.with_channel { |ch| ch.fanout(dest_name, auto_delete: true) } }
|
241
256
|
let!(:queue) do
|
242
257
|
q = nil
|
243
258
|
connection.with_channel do |ch|
|
244
|
-
q = ch.queue(
|
259
|
+
q = ch.queue('', exclusive: true)
|
245
260
|
q.bind(dest_name)
|
246
261
|
end
|
247
262
|
q
|
@@ -250,7 +265,7 @@ module MessageDriver::Adapters
|
|
250
265
|
subject.publish(body, headers, properties)
|
251
266
|
end
|
252
267
|
|
253
|
-
it
|
268
|
+
it 'publishes to the specified exchange' do
|
254
269
|
connection.with_channel do |ch|
|
255
270
|
q = ch.queue(queue.name, passive: true)
|
256
271
|
msg = q.pop
|
@@ -260,19 +275,20 @@ module MessageDriver::Adapters
|
|
260
275
|
expect(msg[1][:delivery_mode]).to eq(1)
|
261
276
|
end
|
262
277
|
end
|
278
|
+
include_examples 'supports publisher confirmations'
|
263
279
|
end
|
264
280
|
end
|
265
281
|
|
266
|
-
context
|
267
|
-
let(:dest_name) {
|
282
|
+
context 'declaring an exchange on the broker' do
|
283
|
+
let(:dest_name) { 'my.cool.exchange' }
|
268
284
|
|
269
285
|
it "creates the exchange if you include 'declare' in the options" do
|
270
286
|
exchange = adapter_context.create_destination(dest_name, type: :exchange, declare: {type: :fanout, auto_delete: true})
|
271
|
-
queue = adapter_context.create_destination(
|
272
|
-
exchange.publish(
|
287
|
+
queue = adapter_context.create_destination('', type: :queue, exclusive: true, bindings: [{source: dest_name}])
|
288
|
+
exchange.publish('test declaring exchange')
|
273
289
|
message = queue.pop_message
|
274
290
|
expect(message).to_not be_nil
|
275
|
-
expect(message.body).to eq(
|
291
|
+
expect(message.body).to eq('test declaring exchange')
|
276
292
|
end
|
277
293
|
|
278
294
|
it "raises an error if you don't provide a type" do
|
@@ -283,51 +299,51 @@ module MessageDriver::Adapters
|
|
283
299
|
|
284
300
|
end
|
285
301
|
|
286
|
-
context
|
287
|
-
let(:dest_name) {
|
288
|
-
let(:exchange) { adapter_context.create_destination(
|
302
|
+
context 'and bindings are provided' do
|
303
|
+
let(:dest_name) { 'binding_exchange_queue' }
|
304
|
+
let(:exchange) { adapter_context.create_destination('amq.direct', type: :exchange) }
|
289
305
|
|
290
306
|
it "raises an exception if you don't provide a source" do
|
291
307
|
expect {
|
292
|
-
adapter_context.create_destination(
|
308
|
+
adapter_context.create_destination('amq.fanout', type: :exchange, bindings: [{args: {routing_key: 'test_exchange_bind'}}])
|
293
309
|
}.to raise_error MessageDriver::Error, /must provide a source/
|
294
310
|
end
|
295
311
|
|
296
|
-
it
|
297
|
-
adapter_context.create_destination(
|
298
|
-
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source:
|
299
|
-
exchange.publish(
|
312
|
+
it 'routes message to the queue through the exchange' do
|
313
|
+
adapter_context.create_destination('amq.fanout', type: :exchange, bindings: [{source: 'amq.direct', args: {routing_key: 'test_exchange_bind'}}])
|
314
|
+
destination = adapter_context.create_destination(dest_name, type: :queue, exclusive: true, bindings: [{source: 'amq.fanout'}])
|
315
|
+
exchange.publish('test exchange bindings', {}, routing_key: 'test_exchange_bind')
|
300
316
|
message = destination.pop_message
|
301
317
|
expect(message).to_not be_nil
|
302
|
-
expect(message.body).to eq(
|
318
|
+
expect(message.body).to eq('test exchange bindings')
|
303
319
|
end
|
304
320
|
end
|
305
321
|
|
306
|
-
context
|
322
|
+
context 'we are not yet connected to the broker' do
|
307
323
|
it "doesn't cause a connection to the broker" do
|
308
324
|
connection.stop
|
309
|
-
adapter_context.create_destination(
|
325
|
+
adapter_context.create_destination('amq.fanout', type: :exchange)
|
310
326
|
expect(adapter.connection(false)).to_not be_open
|
311
327
|
end
|
312
328
|
end
|
313
329
|
end
|
314
330
|
|
315
|
-
context
|
316
|
-
it
|
331
|
+
context 'the type is invalid' do
|
332
|
+
it 'raises in an error' do
|
317
333
|
expect {
|
318
|
-
adapter_context.create_destination(
|
334
|
+
adapter_context.create_destination('my_dest', type: :foo_bar)
|
319
335
|
}.to raise_error MessageDriver::Error, "invalid destination type #{:foo_bar}"
|
320
336
|
end
|
321
337
|
end
|
322
338
|
end
|
323
339
|
|
324
|
-
describe
|
325
|
-
context
|
326
|
-
let(:dest_name) {
|
340
|
+
describe '#subscribe' do
|
341
|
+
context 'the destination is an ExchangeDestination' do
|
342
|
+
let(:dest_name) { 'my_dest' }
|
327
343
|
let(:destination) { adapter_context.create_destination(dest_name, type: :exchange) }
|
328
|
-
let(:consumer) { lambda do |
|
344
|
+
let(:consumer) { lambda do |_|; end }
|
329
345
|
|
330
|
-
it
|
346
|
+
it 'raises an error' do
|
331
347
|
expect {
|
332
348
|
adapter_context.subscribe(destination, &consumer)
|
333
349
|
}.to raise_error MessageDriver::Error, /QueueDestination/
|
@@ -4,39 +4,39 @@ require 'message_driver/adapters/in_memory_adapter'
|
|
4
4
|
|
5
5
|
module MessageDriver::Adapters
|
6
6
|
describe InMemoryAdapter, :in_memory, type: :integration do
|
7
|
-
let(:broker) { double(
|
7
|
+
let(:broker) { double('broker') }
|
8
8
|
subject(:adapter) { described_class.new(broker) }
|
9
9
|
|
10
|
-
describe
|
11
|
-
it
|
10
|
+
describe '#new_context' do
|
11
|
+
it 'returns a InMemoryAdapter::InMemoryContext' do
|
12
12
|
expect(subject.new_context).to be_a InMemoryAdapter::InMemoryContext
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
it_behaves_like
|
16
|
+
it_behaves_like 'an adapter'
|
17
17
|
|
18
18
|
describe InMemoryAdapter::InMemoryContext do
|
19
19
|
subject(:adapter_context) { adapter.new_context }
|
20
20
|
|
21
|
-
it_behaves_like
|
22
|
-
it_behaves_like
|
23
|
-
it_behaves_like
|
24
|
-
it_behaves_like
|
21
|
+
it_behaves_like 'an adapter context'
|
22
|
+
it_behaves_like 'transactions are not supported'
|
23
|
+
it_behaves_like 'client acks are not supported'
|
24
|
+
it_behaves_like 'subscriptions are supported', InMemoryAdapter::Subscription
|
25
25
|
end
|
26
26
|
|
27
|
-
describe
|
28
|
-
describe
|
29
|
-
subject(:destination) { adapter.create_destination(
|
27
|
+
describe '#create_destination' do
|
28
|
+
describe 'the resulting destination' do
|
29
|
+
subject(:destination) { adapter.create_destination('my_test_dest') }
|
30
30
|
|
31
31
|
it { should be_a InMemoryAdapter::Destination }
|
32
32
|
|
33
|
-
it_behaves_like
|
34
|
-
include_examples
|
33
|
+
it_behaves_like 'a destination'
|
34
|
+
include_examples 'supports #message_count'
|
35
35
|
end
|
36
36
|
|
37
|
-
context
|
38
|
-
it
|
39
|
-
queue_name =
|
37
|
+
context 'when creating two destinations for the same queue' do
|
38
|
+
it 'creates seperate destination instances' do
|
39
|
+
queue_name = 'my_queue'
|
40
40
|
dest1 = adapter.create_destination(queue_name)
|
41
41
|
dest2 = adapter.create_destination(queue_name)
|
42
42
|
expect(dest1).to_not be(dest2)
|
@@ -44,8 +44,8 @@ module MessageDriver::Adapters
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
-
describe
|
48
|
-
it
|
47
|
+
describe '#reset_after_tests' do
|
48
|
+
it 'empties all the destination queues' do
|
49
49
|
destinations = (1..3).map(&adapter.method(:create_destination))
|
50
50
|
destinations.each do |destination|
|
51
51
|
destination.publish("There's always money in the banana stand!", {}, {})
|
@@ -58,9 +58,9 @@ module MessageDriver::Adapters
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
it
|
61
|
+
it 'removes any existing subscriptions' do
|
62
62
|
destinations = (1..3).map(&adapter.method(:create_destination))
|
63
|
-
consumer = lambda do |
|
63
|
+
consumer = lambda do |_| end
|
64
64
|
destinations.each do |destination|
|
65
65
|
destination.subscribe(&consumer)
|
66
66
|
end
|
@@ -74,43 +74,43 @@ module MessageDriver::Adapters
|
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
|
-
describe
|
78
|
-
let(:queue_name) {
|
77
|
+
describe 'accessing the same queue from two destinations' do
|
78
|
+
let(:queue_name) { 'my_queue' }
|
79
79
|
let(:dest1) { adapter.create_destination(queue_name) }
|
80
80
|
let(:dest2) { adapter.create_destination(queue_name) }
|
81
81
|
|
82
|
-
context
|
83
|
-
let(:consumer) { lambda do |
|
82
|
+
context 'when I have a consumer on one destination' do
|
83
|
+
let(:consumer) { lambda do |_| end }
|
84
84
|
before do
|
85
85
|
dest1.subscribe(&consumer)
|
86
86
|
end
|
87
|
-
it
|
87
|
+
it 'is the same consumer on the other destination' do
|
88
88
|
expect(dest2.subscription.consumer).to be(consumer)
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
|
-
context
|
93
|
-
it
|
92
|
+
context 'when I publish a message to one destination' do
|
93
|
+
it 'changes the message_count on the other' do
|
94
94
|
expect {
|
95
|
-
dest1.publish(
|
95
|
+
dest1.publish('my test message')
|
96
96
|
}.to change{dest2.message_count}.from(0).to(1)
|
97
97
|
end
|
98
98
|
|
99
|
-
it
|
100
|
-
dest1.publish(
|
99
|
+
it 'can be popped off the other' do
|
100
|
+
dest1.publish('my test message')
|
101
101
|
msg = dest2.pop_message
|
102
102
|
expect(msg).to_not be_nil
|
103
|
-
expect(msg.body).to eq(
|
103
|
+
expect(msg.body).to eq('my test message')
|
104
104
|
end
|
105
105
|
end
|
106
106
|
|
107
|
-
context
|
108
|
-
let(:message_body) {
|
107
|
+
context 'when I pop a message off one destination' do
|
108
|
+
let(:message_body) { 'test popping a message' }
|
109
109
|
before do
|
110
110
|
dest2.publish(message_body)
|
111
111
|
end
|
112
112
|
|
113
|
-
it
|
113
|
+
it 'changes the message_count on the other' do
|
114
114
|
expect {
|
115
115
|
dest1.pop_message
|
116
116
|
}.to change{dest2.message_count}.from(1).to(0)
|
@@ -118,7 +118,7 @@ module MessageDriver::Adapters
|
|
118
118
|
end
|
119
119
|
end
|
120
120
|
|
121
|
-
describe
|
121
|
+
describe 'subscribing a consumer' do
|
122
122
|
let(:destination) { adapter.create_destination(:my_queue) }
|
123
123
|
|
124
124
|
let(:subscription_type) { MessageDriver::Adapters::InMemoryAdapter::Subscription }
|