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
@@ -1,14 +1,14 @@
|
|
1
|
-
shared_examples
|
2
|
-
describe
|
3
|
-
it
|
1
|
+
shared_examples 'transactions are not supported' do
|
2
|
+
describe '#supports_transactions?' do
|
3
|
+
it 'returns false' do
|
4
4
|
expect(subject.supports_transactions?).to eq(false)
|
5
5
|
end
|
6
6
|
end
|
7
7
|
end
|
8
8
|
|
9
|
-
shared_examples
|
10
|
-
describe
|
11
|
-
it
|
9
|
+
shared_examples 'transactions are supported' do
|
10
|
+
describe '#supports_transactions?' do
|
11
|
+
it 'returns true' do
|
12
12
|
expect(subject.supports_transactions?).to eq(true)
|
13
13
|
end
|
14
14
|
end
|
@@ -18,24 +18,24 @@ shared_examples "transactions are supported" do
|
|
18
18
|
it { should respond_to :rollback_transaction }
|
19
19
|
it { should respond_to :in_transaction? }
|
20
20
|
|
21
|
-
describe
|
21
|
+
describe '#in_transaction?' do
|
22
22
|
it "returns false if you aren't in a transaction" do
|
23
23
|
expect(subject.in_transaction?).to eq(false)
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
it
|
27
|
+
it 'raises a MessageDriver::TransactionError error if you begin two transactions' do
|
28
28
|
subject.begin_transaction
|
29
29
|
expect {
|
30
30
|
subject.begin_transaction
|
31
31
|
}.to raise_error MessageDriver::TransactionError
|
32
32
|
end
|
33
|
-
it
|
33
|
+
it 'raises a MessageDriver::TransactionError error if you commit outside of a transaction' do
|
34
34
|
expect {
|
35
35
|
subject.commit_transaction
|
36
36
|
}.to raise_error MessageDriver::TransactionError
|
37
37
|
end
|
38
|
-
it
|
38
|
+
it 'raises a MessageDriver::TransactionError error if you rollback outside of a transaction' do
|
39
39
|
expect {
|
40
40
|
subject.rollback_transaction
|
41
41
|
}.to raise_error MessageDriver::TransactionError
|
@@ -3,16 +3,16 @@ require 'spec_helper'
|
|
3
3
|
module MessageDriver::Adapters
|
4
4
|
describe Base do
|
5
5
|
class TestAdapter < Base
|
6
|
-
def initialize(
|
6
|
+
def initialize(_configuration)
|
7
7
|
end
|
8
8
|
end
|
9
9
|
subject(:adapter) { TestAdapter.new({}) }
|
10
10
|
|
11
|
-
describe
|
12
|
-
it
|
11
|
+
describe '#new_context' do
|
12
|
+
it 'raises an error' do
|
13
13
|
expect {
|
14
14
|
subject.new_context
|
15
|
-
}.to raise_error
|
15
|
+
}.to raise_error 'Must be implemented in subclass'
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -21,32 +21,32 @@ module MessageDriver::Adapters
|
|
21
21
|
end
|
22
22
|
subject(:adapter_context) { TestContext.new(adapter) }
|
23
23
|
|
24
|
-
it_behaves_like
|
25
|
-
it_behaves_like
|
26
|
-
it_behaves_like
|
27
|
-
it_behaves_like
|
24
|
+
it_behaves_like 'an adapter context'
|
25
|
+
it_behaves_like 'transactions are not supported'
|
26
|
+
it_behaves_like 'client acks are not supported'
|
27
|
+
it_behaves_like 'subscriptions are not supported'
|
28
28
|
|
29
|
-
describe
|
30
|
-
it
|
29
|
+
describe '#create_destination' do
|
30
|
+
it 'raises an error' do
|
31
31
|
expect {
|
32
|
-
subject.create_destination(
|
33
|
-
}.to raise_error
|
32
|
+
subject.create_destination('foo')
|
33
|
+
}.to raise_error 'Must be implemented in subclass'
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
describe
|
38
|
-
it
|
37
|
+
describe '#publish' do
|
38
|
+
it 'raises an error' do
|
39
39
|
expect {
|
40
|
-
subject.publish(:destination,
|
41
|
-
}.to raise_error
|
40
|
+
subject.publish(:destination, foo: 'bar')
|
41
|
+
}.to raise_error 'Must be implemented in subclass'
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
describe
|
46
|
-
it
|
45
|
+
describe '#pop_message' do
|
46
|
+
it 'raises an error' do
|
47
47
|
expect {
|
48
48
|
subject.pop_message(:destination)
|
49
|
-
}.to raise_error
|
49
|
+
}.to raise_error 'Must be implemented in subclass'
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -6,8 +6,8 @@ module MessageDriver
|
|
6
6
|
let(:broker_name) { described_class::DEFAULT_BROKER_NAME }
|
7
7
|
let(:options) { { adapter: :in_memory } }
|
8
8
|
|
9
|
-
describe
|
10
|
-
it
|
9
|
+
describe '.configure and .broker' do
|
10
|
+
it 'calls new, passing in the options and saves the instance' do
|
11
11
|
options = {foo: :bar}
|
12
12
|
result = double(described_class).as_null_object
|
13
13
|
described_class.should_receive(:new).with(described_class::DEFAULT_BROKER_NAME, options).and_return(result)
|
@@ -22,15 +22,15 @@ module MessageDriver
|
|
22
22
|
described_class.configure(broker_name, options)
|
23
23
|
expect {
|
24
24
|
described_class.configure(broker_name, options)
|
25
|
-
}.to raise_error MessageDriver::BrokerAlreadyConfigured, match(
|
25
|
+
}.to raise_error MessageDriver::BrokerAlreadyConfigured, match('default')
|
26
26
|
end
|
27
27
|
|
28
|
-
context
|
29
|
-
it
|
28
|
+
context 'when configurating multiple brokers' do
|
29
|
+
it 'allows you to fetch each configured broker through .broker' do
|
30
30
|
options1 = {foo: :bar}
|
31
31
|
options2 = {bar: :baz}
|
32
|
-
result1 = double(
|
33
|
-
result2 = double(
|
32
|
+
result1 = double('result1').as_null_object
|
33
|
+
result2 = double('result2').as_null_object
|
34
34
|
allow(described_class).to receive(:new).with(:result1, options1).and_return(result1)
|
35
35
|
allow(described_class).to receive(:new).with(:result2, options2).and_return(result2)
|
36
36
|
|
@@ -43,7 +43,7 @@ module MessageDriver
|
|
43
43
|
end
|
44
44
|
|
45
45
|
context "when you try to access a broker that isn't configured" do
|
46
|
-
it
|
46
|
+
it 'should raise an error' do
|
47
47
|
expect {
|
48
48
|
described_class.broker(:not_an_adapter)
|
49
49
|
}.to raise_error BrokerNotConfigured
|
@@ -51,8 +51,8 @@ module MessageDriver
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
describe
|
55
|
-
it
|
54
|
+
describe '.reset' do
|
55
|
+
it 'stops and removes all the brokers' do
|
56
56
|
broker1 = described_class.configure(:broker1, adapter: :in_memory)
|
57
57
|
broker2 = described_class.configure(:broker2, adapter: :in_memory)
|
58
58
|
|
@@ -73,12 +73,12 @@ module MessageDriver
|
|
73
73
|
}.to raise_error BrokerNotConfigured
|
74
74
|
end
|
75
75
|
|
76
|
-
context
|
77
|
-
it
|
76
|
+
context 'when one of the brokers raises and error' do
|
77
|
+
it 'still stops all the brokers' do
|
78
78
|
broker1 = described_class.configure(:broker1, adapter: :in_memory)
|
79
79
|
broker2 = described_class.configure(:broker2, adapter: :in_memory)
|
80
80
|
|
81
|
-
allow(broker1).to receive(:stop).and_raise
|
81
|
+
allow(broker1).to receive(:stop).and_raise 'error stopping broker1!'
|
82
82
|
allow(broker2).to receive(:stop).and_call_original
|
83
83
|
|
84
84
|
expect {
|
@@ -99,20 +99,20 @@ module MessageDriver
|
|
99
99
|
end
|
100
100
|
end
|
101
101
|
|
102
|
-
describe
|
102
|
+
describe '.client' do
|
103
103
|
let(:broker_name) { described_class::DEFAULT_BROKER_NAME }
|
104
|
-
it
|
104
|
+
it 'returns a module that extends MessageDriver::Client for the specified broker' do
|
105
105
|
expect(described_class.client(broker_name)).to be_kind_of MessageDriver::Client
|
106
106
|
expect(described_class.client(broker_name).broker_name).to eq(broker_name)
|
107
107
|
end
|
108
108
|
|
109
|
-
it
|
109
|
+
it 'caches the modules' do
|
110
110
|
first = described_class.client(broker_name)
|
111
111
|
second = described_class.client(broker_name)
|
112
112
|
expect(second).to be first
|
113
113
|
end
|
114
114
|
|
115
|
-
context
|
115
|
+
context 'when the broker has a non-default name' do
|
116
116
|
let(:broker_name) { :my_cool_broker }
|
117
117
|
it "returns a module that extends MessageDriver::Client that knows it's broker" do
|
118
118
|
expect(described_class.client(broker_name)).to be_kind_of MessageDriver::Client
|
@@ -121,28 +121,28 @@ module MessageDriver
|
|
121
121
|
end
|
122
122
|
end
|
123
123
|
|
124
|
-
describe
|
124
|
+
describe '#initialize' do
|
125
125
|
it "raises an error if you don't specify an adapter" do
|
126
126
|
expect {
|
127
127
|
described_class.new({})
|
128
128
|
}.to raise_error(/must specify an adapter/)
|
129
129
|
end
|
130
130
|
|
131
|
-
it
|
131
|
+
it 'if you provide an adapter instance, it uses that one' do
|
132
132
|
adapter = Adapters::InMemoryAdapter.new({})
|
133
133
|
|
134
134
|
instance = described_class.new(adapter: adapter)
|
135
135
|
expect(instance.adapter).to be adapter
|
136
136
|
end
|
137
137
|
|
138
|
-
it
|
138
|
+
it 'if you provide an adapter class, it will instansiate it' do
|
139
139
|
adapter = Adapters::InMemoryAdapter
|
140
140
|
|
141
141
|
instance = described_class.new(adapter: adapter)
|
142
142
|
expect(instance.adapter).to be_a adapter
|
143
143
|
end
|
144
144
|
|
145
|
-
it
|
145
|
+
it 'if you provide a symbol, it will try to look up the adapter class' do
|
146
146
|
adapter = :in_memory
|
147
147
|
|
148
148
|
instance = described_class.new(adapter: adapter)
|
@@ -157,14 +157,14 @@ module MessageDriver
|
|
157
157
|
}.to raise_error(/adapter must be a MessageDriver::Adapters::Base/)
|
158
158
|
end
|
159
159
|
|
160
|
-
it
|
160
|
+
it 'starts off with the adapter not stopped' do
|
161
161
|
adapter = :in_memory
|
162
162
|
|
163
163
|
instance = described_class.new(adapter: adapter)
|
164
164
|
expect(instance).not_to be_stopped
|
165
165
|
end
|
166
166
|
|
167
|
-
it
|
167
|
+
it 'has a default name of :default' do
|
168
168
|
adapter = :in_memory
|
169
169
|
|
170
170
|
instance = described_class.new(adapter: adapter)
|
@@ -180,13 +180,12 @@ module MessageDriver
|
|
180
180
|
end
|
181
181
|
end
|
182
182
|
|
183
|
-
|
184
183
|
context do
|
185
184
|
subject!(:broker) { described_class.configure(broker_name, options) }
|
186
185
|
|
187
|
-
describe
|
186
|
+
describe '#stop' do
|
188
187
|
let(:adapter) { broker.adapter }
|
189
|
-
it
|
188
|
+
it 'calls stop on the adapter' do
|
190
189
|
allow(adapter).to receive(:stop).and_call_original
|
191
190
|
|
192
191
|
subject.stop
|
@@ -194,14 +193,14 @@ module MessageDriver
|
|
194
193
|
expect(adapter).to have_received(:stop)
|
195
194
|
end
|
196
195
|
|
197
|
-
it
|
196
|
+
it 'marks the broker as stopped' do
|
198
197
|
expect {
|
199
198
|
subject.stop
|
200
199
|
}.to change { subject.stopped? }.from(false).to(true)
|
201
200
|
end
|
202
201
|
|
203
|
-
it
|
204
|
-
my_ctx = double(
|
202
|
+
it 'invalidates the contexts' do
|
203
|
+
my_ctx = double('context', invalidate: nil)
|
205
204
|
adapter.contexts << my_ctx
|
206
205
|
subject.stop
|
207
206
|
expect(adapter.contexts).to be_empty
|
@@ -209,13 +208,13 @@ module MessageDriver
|
|
209
208
|
end
|
210
209
|
end
|
211
210
|
|
212
|
-
describe
|
211
|
+
describe '#restart' do
|
213
212
|
let!(:original_adapter) { subject.adapter }
|
214
213
|
before do
|
215
214
|
allow(original_adapter).to receive(:stop).and_call_original
|
216
215
|
end
|
217
216
|
|
218
|
-
it
|
217
|
+
it 'reconfigures the adapter' do
|
219
218
|
expect {
|
220
219
|
subject.restart
|
221
220
|
}.to change { subject.adapter }
|
@@ -226,7 +225,7 @@ module MessageDriver
|
|
226
225
|
expect(original_adapter).to have_received(:stop).once
|
227
226
|
end
|
228
227
|
|
229
|
-
it
|
228
|
+
it 'does not stop the adapter again if it has already been stopped' do
|
230
229
|
expect(subject.adapter).to be original_adapter
|
231
230
|
subject.stop
|
232
231
|
expect {
|
@@ -236,30 +235,30 @@ module MessageDriver
|
|
236
235
|
end
|
237
236
|
end
|
238
237
|
|
239
|
-
describe
|
240
|
-
it
|
238
|
+
describe '#configuration' do
|
239
|
+
it 'returns the configuration hash you passed to .configure' do
|
241
240
|
config = {adapter: :in_memory, foo: :bar, baz: :boz}
|
242
241
|
instance = described_class.new(config)
|
243
242
|
expect(instance.configuration).to be config
|
244
243
|
end
|
245
244
|
end
|
246
245
|
|
247
|
-
describe
|
248
|
-
it
|
249
|
-
destination = broker.destination(:my_queue,
|
246
|
+
describe '#destination' do
|
247
|
+
it 'returns the destination' do
|
248
|
+
destination = broker.destination(:my_queue, 'my_queue', exclusive: true)
|
250
249
|
expect(destination).to be_a MessageDriver::Destination::Base
|
251
250
|
end
|
252
251
|
end
|
253
252
|
|
254
|
-
describe
|
255
|
-
it
|
256
|
-
my_destination = broker.destination(:my_queue,
|
253
|
+
describe '#find_destination' do
|
254
|
+
it 'finds the previously defined destination' do
|
255
|
+
my_destination = broker.destination(:my_queue, 'my_queue', exclusive: true)
|
257
256
|
expect(broker.find_destination(:my_queue)).to be(my_destination)
|
258
257
|
end
|
259
258
|
|
260
259
|
context "when the destination can't be found" do
|
261
260
|
let(:bad_dest_name) { :not_a_queue }
|
262
|
-
it
|
261
|
+
it 'raises a MessageDriver:NoSuchDestinationError' do
|
263
262
|
expect {
|
264
263
|
broker.find_destination(bad_dest_name)
|
265
264
|
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
@@ -267,32 +266,32 @@ module MessageDriver
|
|
267
266
|
end
|
268
267
|
end
|
269
268
|
|
270
|
-
describe
|
271
|
-
let(:consumer_double) { lambda do |
|
272
|
-
it
|
269
|
+
describe '#consumer' do
|
270
|
+
let(:consumer_double) { lambda do |_| end }
|
271
|
+
it 'saves the provided consumer' do
|
273
272
|
broker.consumer(:my_consumer, &consumer_double)
|
274
273
|
expect(broker.consumers[:my_consumer]).to be(consumer_double)
|
275
274
|
end
|
276
275
|
|
277
|
-
context
|
278
|
-
it
|
276
|
+
context 'when no consumer is provided' do
|
277
|
+
it 'raises an error' do
|
279
278
|
expect {
|
280
279
|
broker.consumer(:my_consumer)
|
281
|
-
}.to raise_error(MessageDriver::Error,
|
280
|
+
}.to raise_error(MessageDriver::Error, 'you must provide a block')
|
282
281
|
end
|
283
282
|
end
|
284
283
|
end
|
285
284
|
|
286
|
-
describe
|
287
|
-
let(:consumer_double) { lambda do |
|
288
|
-
it
|
285
|
+
describe '#find_consumer' do
|
286
|
+
let(:consumer_double) { lambda do |_| end }
|
287
|
+
it 'finds the previously defined consumer' do
|
289
288
|
my_consumer = broker.consumer(:my_consumer, &consumer_double)
|
290
289
|
expect(broker.find_consumer(:my_consumer)).to be(my_consumer)
|
291
290
|
end
|
292
291
|
|
293
292
|
context "when the consumer can't be found" do
|
294
293
|
let(:bad_consumer_name) { :not_a_queue }
|
295
|
-
it
|
294
|
+
it 'raises a MessageDriver:NoSuchConsumerError' do
|
296
295
|
expect {
|
297
296
|
broker.find_consumer(bad_consumer_name)
|
298
297
|
}.to raise_error(MessageDriver::NoSuchConsumerError, /#{bad_consumer_name}/)
|
@@ -300,14 +299,14 @@ module MessageDriver
|
|
300
299
|
end
|
301
300
|
end
|
302
301
|
|
303
|
-
describe
|
304
|
-
it
|
305
|
-
destination = broker.dynamic_destination(
|
302
|
+
describe '#dynamic_destination' do
|
303
|
+
it 'returns the destination' do
|
304
|
+
destination = broker.dynamic_destination('my_queue', exclusive: true)
|
306
305
|
expect(destination).to be_a MessageDriver::Destination::Base
|
307
306
|
end
|
308
307
|
end
|
309
308
|
|
310
|
-
describe
|
309
|
+
describe '#client' do
|
311
310
|
let(:broker_name) { described_class::DEFAULT_BROKER_NAME }
|
312
311
|
it "returns a module that extends MessageDriver::Client that knows it's broker" do
|
313
312
|
expect(broker.client).to be_kind_of MessageDriver::Client
|
@@ -315,17 +314,17 @@ module MessageDriver
|
|
315
314
|
expect(broker.client.broker).to be(broker)
|
316
315
|
end
|
317
316
|
|
318
|
-
it
|
317
|
+
it 'caches the modules' do
|
319
318
|
first = broker.client
|
320
319
|
second = broker.client
|
321
320
|
expect(second).to be first
|
322
321
|
end
|
323
322
|
|
324
|
-
it
|
323
|
+
it 'returns the same module as .client' do
|
325
324
|
expect(broker.client).to be described_class.client(broker.name)
|
326
325
|
end
|
327
326
|
|
328
|
-
context
|
327
|
+
context 'when the broker has a non-default name' do
|
329
328
|
let(:broker_name) { :my_cool_broker }
|
330
329
|
it "returns a module that extends MessageDriver::Client that knows it's broker" do
|
331
330
|
expect(broker.name).to eq(broker_name)
|
@@ -14,54 +14,54 @@ module MessageDriver
|
|
14
14
|
let(:adapter) { broker.adapter }
|
15
15
|
let(:adapter_context) { adapter.new_context }
|
16
16
|
|
17
|
-
shared_examples
|
18
|
-
describe
|
19
|
-
it
|
17
|
+
shared_examples 'a Client' do
|
18
|
+
describe '#broker' do
|
19
|
+
it 'returns the broker_name' do
|
20
20
|
expect(subject.broker_name).to eq(broker_name)
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
describe
|
24
|
+
describe '#current_adapter_context' do
|
25
25
|
before { subject.clear_context }
|
26
26
|
|
27
|
-
it
|
27
|
+
it 'returns an adapter_context' do
|
28
28
|
expect(subject.current_adapter_context).to be_a Adapters::ContextBase
|
29
29
|
end
|
30
30
|
|
31
|
-
it
|
31
|
+
it 'returns the same adapter context on the second call' do
|
32
32
|
ctx = subject.current_adapter_context
|
33
33
|
expect(subject.current_adapter_context).to be ctx
|
34
34
|
end
|
35
35
|
|
36
|
-
context
|
36
|
+
context 'when called with false' do
|
37
37
|
it "doesn't initialize the adapter context if there isn't one" do
|
38
38
|
expect(subject.current_adapter_context(false)).to be_nil
|
39
39
|
end
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
context
|
43
|
+
context 'with a given adapter_context' do
|
44
44
|
around(:each) do |example|
|
45
45
|
subject.with_adapter_context(adapter_context, &example)
|
46
46
|
end
|
47
47
|
|
48
|
-
describe
|
49
|
-
let(:dest_name) {
|
48
|
+
describe '#dynamic_destination' do
|
49
|
+
let(:dest_name) { 'my_new_queue' }
|
50
50
|
let(:dest_options) { {type: 2} }
|
51
|
-
let(:message_props) { {expires:
|
52
|
-
let(:created_dest) { double(
|
51
|
+
let(:message_props) { {expires: 'soon'} }
|
52
|
+
let(:created_dest) { double('created destination') }
|
53
53
|
before do
|
54
54
|
adapter_context.stub(:create_destination) { created_dest }
|
55
55
|
end
|
56
56
|
|
57
|
-
it
|
57
|
+
it 'delegates to the adapter_context' do
|
58
58
|
result = subject.dynamic_destination(dest_name, dest_options, message_props)
|
59
59
|
expect(result).to be(created_dest)
|
60
60
|
|
61
61
|
adapter_context.should have_received(:create_destination).with(dest_name, dest_options, message_props)
|
62
62
|
end
|
63
63
|
|
64
|
-
it
|
64
|
+
it 'only requires destination name' do
|
65
65
|
result = subject.dynamic_destination(dest_name)
|
66
66
|
expect(result).to be(created_dest)
|
67
67
|
|
@@ -69,26 +69,26 @@ module MessageDriver
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
describe
|
73
|
-
let(:destination) { broker.destination(:my_queue,
|
74
|
-
let(:body) {
|
72
|
+
describe '#publish' do
|
73
|
+
let(:destination) { broker.destination(:my_queue, 'my_queue', exclusive: true) }
|
74
|
+
let(:body) { 'my message' }
|
75
75
|
let(:headers) { {foo: :bar} }
|
76
76
|
let(:properties) { {bar: :baz} }
|
77
77
|
before do
|
78
78
|
adapter_context.stub(:publish)
|
79
79
|
end
|
80
80
|
|
81
|
-
it
|
81
|
+
it 'delegates to the adapter_context' do
|
82
82
|
subject.publish(destination, body, headers, properties)
|
83
83
|
adapter_context.should have_received(:publish).with(destination, body, headers, properties)
|
84
84
|
end
|
85
85
|
|
86
|
-
it
|
86
|
+
it 'only requires destination and body' do
|
87
87
|
subject.publish(destination, body)
|
88
88
|
adapter_context.should have_received(:publish).with(destination, body, {}, {})
|
89
89
|
end
|
90
90
|
|
91
|
-
it
|
91
|
+
it 'looks up the destination if necessary' do
|
92
92
|
destination
|
93
93
|
subject.publish(:my_queue, body, headers, properties)
|
94
94
|
adapter_context.should have_received(:publish).with(destination, body, headers, properties)
|
@@ -96,7 +96,7 @@ module MessageDriver
|
|
96
96
|
|
97
97
|
context "when the destination can't be found" do
|
98
98
|
let(:bad_dest_name) { :not_a_queue }
|
99
|
-
it
|
99
|
+
it 'raises a MessageDriver:NoSuchDestinationError' do
|
100
100
|
expect {
|
101
101
|
subject.publish(bad_dest_name, body, headers, properties)
|
102
102
|
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
@@ -105,20 +105,20 @@ module MessageDriver
|
|
105
105
|
end
|
106
106
|
end
|
107
107
|
|
108
|
-
describe
|
108
|
+
describe '#pop_message' do
|
109
109
|
let(:expected) { double(MessageDriver::Message) }
|
110
|
-
let(:destination) { broker.destination(:my_queue,
|
110
|
+
let(:destination) { broker.destination(:my_queue, 'my_queue', exclusive: true) }
|
111
111
|
let(:options) { {foo: :bar} }
|
112
112
|
before do
|
113
113
|
adapter_context.stub(:pop_message)
|
114
114
|
end
|
115
115
|
|
116
|
-
it
|
116
|
+
it 'delegates to the adapter_context' do
|
117
117
|
subject.pop_message(destination, options)
|
118
118
|
adapter_context.should have_received(:pop_message).with(destination, options)
|
119
119
|
end
|
120
120
|
|
121
|
-
it
|
121
|
+
it 'looks up the destination if necessary' do
|
122
122
|
destination
|
123
123
|
subject.pop_message(:my_queue, options)
|
124
124
|
adapter_context.should have_received(:pop_message).with(destination, options)
|
@@ -126,7 +126,7 @@ module MessageDriver
|
|
126
126
|
|
127
127
|
context "when the destination can't be found" do
|
128
128
|
let(:bad_dest_name) { :not_a_queue }
|
129
|
-
it
|
129
|
+
it 'raises a MessageDriver:NoSuchDestinationError' do
|
130
130
|
expect {
|
131
131
|
subject.pop_message(bad_dest_name, options)
|
132
132
|
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
@@ -134,7 +134,7 @@ module MessageDriver
|
|
134
134
|
end
|
135
135
|
end
|
136
136
|
|
137
|
-
it
|
137
|
+
it 'requires the destination and returns the message' do
|
138
138
|
adapter_context.should_receive(:pop_message).with(destination, {}).and_return(expected)
|
139
139
|
|
140
140
|
actual = subject.pop_message(destination)
|
@@ -142,7 +142,7 @@ module MessageDriver
|
|
142
142
|
expect(actual).to be expected
|
143
143
|
end
|
144
144
|
|
145
|
-
it
|
145
|
+
it 'passes the options through and returns the message' do
|
146
146
|
adapter_context.should_receive(:pop_message).with(destination, options).and_return(expected)
|
147
147
|
|
148
148
|
actual = subject.pop_message(destination, options)
|
@@ -151,18 +151,18 @@ module MessageDriver
|
|
151
151
|
end
|
152
152
|
end
|
153
153
|
|
154
|
-
describe
|
154
|
+
describe '#with_message_transaction' do
|
155
155
|
before do
|
156
156
|
adapter_context.stub(:begin_transaction)
|
157
157
|
adapter_context.stub(:commit_transaction)
|
158
158
|
adapter_context.stub(:rollback_transaction)
|
159
159
|
end
|
160
160
|
|
161
|
-
context
|
161
|
+
context 'when the adapter supports transactions' do
|
162
162
|
before do
|
163
163
|
adapter_context.stub(:supports_transactions?) { true }
|
164
164
|
end
|
165
|
-
it
|
165
|
+
it 'delegates to the adapter context' do
|
166
166
|
expect { |blk|
|
167
167
|
subject.with_message_transaction(&blk)
|
168
168
|
}.to yield_control
|
@@ -170,34 +170,34 @@ module MessageDriver
|
|
170
170
|
adapter_context.should have_received(:commit_transaction)
|
171
171
|
end
|
172
172
|
|
173
|
-
context
|
174
|
-
it
|
173
|
+
context 'when the block raises an error' do
|
174
|
+
it 'calls rollback instead of commit and raises the error' do
|
175
175
|
expect {
|
176
176
|
subject.with_message_transaction do
|
177
|
-
raise
|
177
|
+
raise 'having a tough time'
|
178
178
|
end
|
179
|
-
}.to raise_error
|
179
|
+
}.to raise_error 'having a tough time'
|
180
180
|
adapter_context.should have_received(:begin_transaction)
|
181
181
|
adapter_context.should_not have_received(:commit_transaction)
|
182
182
|
adapter_context.should have_received(:rollback_transaction)
|
183
183
|
end
|
184
184
|
|
185
|
-
context
|
186
|
-
it
|
185
|
+
context 'and the the rollback raises an error' do
|
186
|
+
it 'logs the error from the rollback and raises the original error' do
|
187
187
|
allow(logger).to receive(:error)
|
188
|
-
adapter_context.stub(:rollback_transaction).and_raise(
|
188
|
+
adapter_context.stub(:rollback_transaction).and_raise('rollback failed!')
|
189
189
|
expect {
|
190
190
|
subject.with_message_transaction do
|
191
|
-
raise
|
191
|
+
raise 'having a tough time'
|
192
192
|
end
|
193
|
-
}.to raise_error
|
194
|
-
expect(logger).to have_received(:error).with(match(
|
193
|
+
}.to raise_error 'having a tough time'
|
194
|
+
expect(logger).to have_received(:error).with(match('rollback failed!'))
|
195
195
|
end
|
196
196
|
end
|
197
197
|
end
|
198
198
|
|
199
|
-
context
|
200
|
-
it
|
199
|
+
context 'when the transactions are nested' do
|
200
|
+
it 'only starts and commits once' do
|
201
201
|
expect { |blk|
|
202
202
|
subject.with_message_transaction do
|
203
203
|
subject.with_message_transaction(&blk)
|
@@ -207,15 +207,15 @@ module MessageDriver
|
|
207
207
|
adapter_context.should have_received(:commit_transaction).once
|
208
208
|
end
|
209
209
|
|
210
|
-
context
|
211
|
-
it
|
210
|
+
context 'when the block raises an error' do
|
211
|
+
it 'calls rollback instead of commit and raises the error' do
|
212
212
|
expect {
|
213
213
|
subject.with_message_transaction do
|
214
214
|
subject.with_message_transaction do
|
215
|
-
raise
|
215
|
+
raise 'having a tough time'
|
216
216
|
end
|
217
217
|
end
|
218
|
-
}.to raise_error
|
218
|
+
}.to raise_error 'having a tough time'
|
219
219
|
adapter_context.should have_received(:begin_transaction).once
|
220
220
|
adapter_context.should_not have_received(:commit_transaction)
|
221
221
|
adapter_context.should have_received(:rollback_transaction).once
|
@@ -236,65 +236,65 @@ module MessageDriver
|
|
236
236
|
adapter_context.should_not have_received(:commit_transaction)
|
237
237
|
adapter_context.should_not have_received(:rollback_transaction)
|
238
238
|
end
|
239
|
-
it
|
239
|
+
it 'logs a warning' do
|
240
240
|
allow(logger).to receive(:debug)
|
241
241
|
expect { |blk|
|
242
242
|
subject.with_message_transaction(&blk)
|
243
243
|
}.to yield_control
|
244
|
-
expect(logger).to have_received(:debug).with(
|
244
|
+
expect(logger).to have_received(:debug).with('this adapter does not support transactions')
|
245
245
|
end
|
246
246
|
end
|
247
247
|
end
|
248
248
|
|
249
|
-
describe
|
250
|
-
let(:message) { double(
|
249
|
+
describe '#ack_message' do
|
250
|
+
let(:message) { double('message') }
|
251
251
|
let(:options) { {foo: :bar} }
|
252
252
|
before do
|
253
253
|
allow(message).to receive(:ack)
|
254
254
|
end
|
255
|
-
it
|
255
|
+
it 'calls #ack on the message' do
|
256
256
|
subject.ack_message(message)
|
257
257
|
expect(message).to have_received(:ack).with({})
|
258
258
|
end
|
259
|
-
it
|
259
|
+
it 'calls #ack on the message and passes the supplied options' do
|
260
260
|
subject.ack_message(message, options)
|
261
261
|
expect(message).to have_received(:ack).with(options)
|
262
262
|
end
|
263
263
|
end
|
264
264
|
|
265
|
-
describe
|
266
|
-
let(:message) { double(
|
265
|
+
describe '#nack_message' do
|
266
|
+
let(:message) { double('message') }
|
267
267
|
let(:options) { {foo: :bar} }
|
268
268
|
before do
|
269
269
|
allow(message).to receive(:nack)
|
270
270
|
end
|
271
|
-
it
|
271
|
+
it 'calls #nack on the message' do
|
272
272
|
subject.nack_message(message)
|
273
273
|
expect(message).to have_received(:nack).with({})
|
274
274
|
end
|
275
|
-
it
|
275
|
+
it 'calls #nack on the message and passes the supplied options' do
|
276
276
|
subject.nack_message(message, options)
|
277
277
|
expect(message).to have_received(:nack).with(options)
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
|
-
describe
|
282
|
-
let(:destination) { broker.destination(:my_queue,
|
283
|
-
let(:consumer_double) { lambda do |
|
281
|
+
describe '#subscribe' do
|
282
|
+
let(:destination) { broker.destination(:my_queue, 'my_queue', exclusive: true) }
|
283
|
+
let(:consumer_double) { lambda do |_| end }
|
284
284
|
|
285
285
|
before do
|
286
286
|
adapter_context.stub(:subscribe)
|
287
287
|
broker.consumer(:my_consumer, &consumer_double)
|
288
288
|
end
|
289
289
|
|
290
|
-
it
|
290
|
+
it 'delegates to the adapter_context' do
|
291
291
|
adapter_context.should_receive(:subscribe).with(destination, {}) do |&blk|
|
292
292
|
expect(blk).to be(consumer_double)
|
293
293
|
end
|
294
294
|
subject.subscribe(destination, :my_consumer)
|
295
295
|
end
|
296
296
|
|
297
|
-
it
|
297
|
+
it 'passes the options through' do
|
298
298
|
options = {foo: :bar}
|
299
299
|
adapter_context.should_receive(:subscribe).with(destination, options) do |&blk|
|
300
300
|
expect(blk).to be(consumer_double)
|
@@ -302,7 +302,7 @@ module MessageDriver
|
|
302
302
|
subject.subscribe(destination, :my_consumer, options)
|
303
303
|
end
|
304
304
|
|
305
|
-
it
|
305
|
+
it 'looks up the destination' do
|
306
306
|
adapter_context.should_receive(:subscribe).with(destination, {}) do |&blk|
|
307
307
|
expect(blk).to be(consumer_double)
|
308
308
|
end
|
@@ -311,7 +311,7 @@ module MessageDriver
|
|
311
311
|
|
312
312
|
context "when the destination can't be found" do
|
313
313
|
let(:bad_dest_name) { :not_a_queue }
|
314
|
-
it
|
314
|
+
it 'raises a MessageDriver:NoSuchDestinationError' do
|
315
315
|
expect {
|
316
316
|
subject.subscribe(bad_dest_name, :my_consumer)
|
317
317
|
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
@@ -321,7 +321,7 @@ module MessageDriver
|
|
321
321
|
|
322
322
|
context "when the consumer can't be found" do
|
323
323
|
let(:bad_consumer_name) { :not_a_consumer }
|
324
|
-
it
|
324
|
+
it 'raises a MessageDriver:NoSuchConsumerError' do
|
325
325
|
expect {
|
326
326
|
subject.subscribe(destination, bad_consumer_name)
|
327
327
|
}.to raise_error(MessageDriver::NoSuchConsumerError, /#{bad_consumer_name}/)
|
@@ -330,22 +330,22 @@ module MessageDriver
|
|
330
330
|
end
|
331
331
|
end
|
332
332
|
|
333
|
-
describe
|
334
|
-
let(:destination) { broker.destination(:my_queue,
|
335
|
-
let(:consumer_double) { lambda do |
|
333
|
+
describe '#subscribe_with' do
|
334
|
+
let(:destination) { broker.destination(:my_queue, 'my_queue', exclusive: true) }
|
335
|
+
let(:consumer_double) { lambda do |_| end }
|
336
336
|
|
337
337
|
before do
|
338
338
|
adapter_context.stub(:subscribe)
|
339
339
|
end
|
340
340
|
|
341
|
-
it
|
341
|
+
it 'delegates to the adapter_context' do
|
342
342
|
adapter_context.should_receive(:subscribe).with(destination, {}) do |&blk|
|
343
343
|
expect(blk).to be(consumer_double)
|
344
344
|
end
|
345
345
|
subject.subscribe_with(destination, &consumer_double)
|
346
346
|
end
|
347
347
|
|
348
|
-
it
|
348
|
+
it 'passes the options through' do
|
349
349
|
options = {foo: :bar}
|
350
350
|
adapter_context.should_receive(:subscribe).with(destination, options) do |&blk|
|
351
351
|
expect(blk).to be(consumer_double)
|
@@ -353,7 +353,7 @@ module MessageDriver
|
|
353
353
|
subject.subscribe_with(destination, options, &consumer_double)
|
354
354
|
end
|
355
355
|
|
356
|
-
it
|
356
|
+
it 'looks up the destination' do
|
357
357
|
adapter_context.should_receive(:subscribe).with(destination, {}) do |&blk|
|
358
358
|
expect(blk).to be(consumer_double)
|
359
359
|
end
|
@@ -362,7 +362,7 @@ module MessageDriver
|
|
362
362
|
|
363
363
|
context "when the destination can't be found" do
|
364
364
|
let(:bad_dest_name) { :not_a_queue }
|
365
|
-
it
|
365
|
+
it 'raises a MessageDriver:NoSuchDestinationError' do
|
366
366
|
expect {
|
367
367
|
subject.subscribe_with(bad_dest_name, &consumer_double)
|
368
368
|
}.to raise_error(MessageDriver::NoSuchDestinationError, /#{bad_dest_name}/)
|
@@ -373,17 +373,17 @@ module MessageDriver
|
|
373
373
|
end
|
374
374
|
end
|
375
375
|
|
376
|
-
context
|
376
|
+
context 'when used as an included module' do
|
377
377
|
subject { TestPublisher.new }
|
378
|
-
it_behaves_like
|
378
|
+
it_behaves_like 'a Client'
|
379
379
|
end
|
380
380
|
|
381
|
-
context
|
381
|
+
context 'when the module is used directly' do
|
382
382
|
subject { described_class }
|
383
|
-
it_behaves_like
|
383
|
+
it_behaves_like 'a Client'
|
384
384
|
end
|
385
385
|
|
386
|
-
describe
|
386
|
+
describe '.for_broker' do
|
387
387
|
let(:broker_name) { :my_cool_broker }
|
388
388
|
let(:client) { described_class.for_broker(broker_name) }
|
389
389
|
it "produces a module that extends #{described_class.name}" do
|
@@ -396,25 +396,25 @@ module MessageDriver
|
|
396
396
|
expect(client.broker).to be(broker)
|
397
397
|
end
|
398
398
|
|
399
|
-
context
|
399
|
+
context 'when the resulting module is used as an included module' do
|
400
400
|
subject! do
|
401
401
|
clz = Class.new
|
402
402
|
clz.send :include, client
|
403
403
|
clz.new
|
404
404
|
end
|
405
|
-
it_behaves_like
|
405
|
+
it_behaves_like 'a Client'
|
406
406
|
end
|
407
407
|
|
408
|
-
context
|
409
|
-
it_behaves_like
|
408
|
+
context 'when the resulting module is used directly' do
|
409
|
+
it_behaves_like 'a Client' do
|
410
410
|
subject! { client }
|
411
411
|
end
|
412
412
|
end
|
413
413
|
end
|
414
414
|
|
415
|
-
describe
|
416
|
-
it
|
417
|
-
expected = double(
|
415
|
+
describe '.[]' do
|
416
|
+
it 'grabs the client for the given broker' do
|
417
|
+
expected = double('client')
|
418
418
|
allow(Broker).to receive(:client).with(:test_broker).and_return(expected)
|
419
419
|
expect(described_class[:test_broker]).to be expected
|
420
420
|
end
|