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.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +18 -0
  3. data/.rubocop_todo.yml +160 -0
  4. data/.travis.yml +5 -4
  5. data/CHANGELOG.md +5 -0
  6. data/Gemfile +9 -8
  7. data/Guardfile +14 -7
  8. data/README.md +2 -0
  9. data/Rakefile +16 -10
  10. data/examples/basic_producer_and_consumer/Gemfile +2 -2
  11. data/examples/basic_producer_and_consumer/common.rb +3 -3
  12. data/examples/basic_producer_and_consumer/consumer.rb +5 -5
  13. data/examples/basic_producer_and_consumer/producer.rb +7 -7
  14. data/features/CHANGELOG.md +5 -0
  15. data/features/message_consumers/transactional_ack_consumers.feature +1 -0
  16. data/features/rabbitmq_specific_features/publisher_acknowledgements.feature +51 -0
  17. data/features/step_definitions/error_handling_steps.rb +2 -2
  18. data/features/step_definitions/logging_steps.rb +4 -4
  19. data/features/step_definitions/message_consumers_steps.rb +8 -8
  20. data/features/step_definitions/rabbitmq_specific_steps.rb +10 -0
  21. data/features/step_definitions/steps.rb +15 -15
  22. data/features/support/env.rb +3 -0
  23. data/features/support/firewall_helper.rb +5 -6
  24. data/features/support/message_table_matcher.rb +3 -4
  25. data/features/support/no_error_matcher.rb +3 -3
  26. data/features/support/test_runner.rb +11 -3
  27. data/features/support/transforms.rb +1 -1
  28. data/lib/message-driver.rb +1 -1
  29. data/lib/message_driver.rb +0 -1
  30. data/lib/message_driver/adapters/base.rb +10 -10
  31. data/lib/message_driver/adapters/bunny_adapter.rb +57 -30
  32. data/lib/message_driver/adapters/in_memory_adapter.rb +4 -5
  33. data/lib/message_driver/adapters/stomp_adapter.rb +4 -6
  34. data/lib/message_driver/broker.rb +5 -4
  35. data/lib/message_driver/client.rb +6 -6
  36. data/lib/message_driver/destination.rb +2 -2
  37. data/lib/message_driver/errors.rb +1 -4
  38. data/lib/message_driver/logging.rb +1 -1
  39. data/lib/message_driver/message.rb +2 -2
  40. data/lib/message_driver/subscription.rb +1 -1
  41. data/lib/message_driver/version.rb +1 -1
  42. data/lib/{message_driver/vendor → vendor}/.document +0 -0
  43. data/lib/vendor/nesty.rb +1 -0
  44. data/lib/vendor/nesty/nested_error.rb +28 -0
  45. data/message-driver.gemspec +15 -14
  46. data/spec/integration/bunny/amqp_integration_spec.rb +43 -43
  47. data/spec/integration/bunny/bunny_adapter_spec.rb +117 -101
  48. data/spec/integration/in_memory/in_memory_adapter_spec.rb +35 -35
  49. data/spec/integration/stomp/stomp_adapter_spec.rb +42 -42
  50. data/spec/spec_helper.rb +4 -1
  51. data/spec/support/shared/adapter_examples.rb +7 -7
  52. data/spec/support/shared/client_ack_examples.rb +6 -6
  53. data/spec/support/shared/context_examples.rb +4 -4
  54. data/spec/support/shared/destination_examples.rb +10 -10
  55. data/spec/support/shared/subscription_examples.rb +29 -29
  56. data/spec/support/shared/transaction_examples.rb +10 -10
  57. data/spec/units/message_driver/adapters/base_spec.rb +19 -19
  58. data/spec/units/message_driver/broker_spec.rb +57 -58
  59. data/spec/units/message_driver/client_spec.rb +84 -84
  60. data/spec/units/message_driver/destination_spec.rb +4 -4
  61. data/spec/units/message_driver/message_spec.rb +19 -19
  62. data/spec/units/message_driver/subscription_spec.rb +4 -4
  63. data/test_lib/broker_config.rb +2 -2
  64. metadata +27 -6
  65. data/lib/message_driver/vendor/nesty.rb +0 -1
  66. data/lib/message_driver/vendor/nesty/nested_error.rb +0 -26
@@ -7,22 +7,22 @@ module MessageDriver::Adapters
7
7
 
8
8
  let(:valid_connection_attrs) { BrokerConfig.config }
9
9
 
10
- describe "#initialize" do
10
+ describe '#initialize' do
11
11
  let(:connection_attrs) { valid_connection_attrs }
12
- let(:broker) { double("broker") }
12
+ let(:broker) { double('broker') }
13
13
 
14
- context "differing stomp versions" do
15
- shared_examples "raises a stomp error" do
16
- it "raises an error" do
17
- stub_const("Stomp::Version::STRING", version)
14
+ context 'differing stomp versions' do
15
+ shared_examples 'raises a stomp error' do
16
+ it 'raises an error' do
17
+ stub_const('Stomp::Version::STRING', version)
18
18
  expect {
19
19
  described_class.new(broker, connection_attrs)
20
- }.to raise_error MessageDriver::Error, "stomp 1.3.1 or a later version of the 1.3.x series is required for the stomp adapter"
20
+ }.to raise_error MessageDriver::Error, 'stomp 1.3.1 or a later version of the 1.3.x series is required for the stomp adapter'
21
21
  end
22
22
  end
23
23
  shared_examples "doesn't raise a stomp error" do
24
24
  it "doesn't raise an an error" do
25
- stub_const("Stomp::Version::STRING", version)
25
+ stub_const('Stomp::Version::STRING', version)
26
26
  adapter = nil
27
27
  expect {
28
28
  adapter = described_class.new(broker, connection_attrs)
@@ -32,7 +32,7 @@ module MessageDriver::Adapters
32
32
  %w(1.1.0 1.2.9 1.3.0 1.4.0).each do |v|
33
33
  context "stomp version #{v}" do
34
34
  let(:version) { v }
35
- include_examples "raises a stomp error"
35
+ include_examples 'raises a stomp error'
36
36
  end
37
37
  end
38
38
  %w(1.3.1 1.3.5).each do |v|
@@ -43,35 +43,35 @@ module MessageDriver::Adapters
43
43
  end
44
44
  end
45
45
 
46
- describe "the resulting config" do
47
- let(:connection_attrs) { {hosts: [{host: "my_host"}]} }
46
+ describe 'the resulting config' do
47
+ let(:connection_attrs) { {hosts: [{host: 'my_host'}]} }
48
48
  subject(:config) { described_class.new(broker, connection_attrs).config }
49
49
 
50
- its([:connect_headers]) { should eq(:"accept-version" => "1.1,1.2") }
50
+ its([:connect_headers]) { should eq(:"accept-version" => '1.1,1.2') }
51
51
  its([:hosts]) { should eq(connection_attrs[:hosts]) }
52
52
 
53
- context "when vhost is specified" do
54
- let(:connection_attrs) { {hosts: [{host: "my_host"}], vhost: "my_vhost"} }
53
+ context 'when vhost is specified' do
54
+ let(:connection_attrs) { {hosts: [{host: 'my_host'}], vhost: 'my_vhost'} }
55
55
 
56
56
  it { should_not have_key(:vhost) }
57
- its([:connect_headers]) { should eq(:"accept-version" => "1.1,1.2", :"host" => "my_vhost") }
57
+ its([:connect_headers]) { should eq(:"accept-version" => '1.1,1.2', :"host" => 'my_vhost') }
58
58
  end
59
59
 
60
- context "when there are things in the connect_headers" do
61
- let(:connection_attrs) { {hosts: [{host: "my_host"}], connect_headers: {"foo" => "bar"}} }
60
+ context 'when there are things in the connect_headers' do
61
+ let(:connection_attrs) { {hosts: [{host: 'my_host'}], connect_headers: {'foo' => 'bar'}} }
62
62
 
63
- its([:connect_headers]) { should eq(:"accept-version" => "1.1,1.2", "foo" => "bar") }
63
+ its([:connect_headers]) { should eq(:"accept-version" => '1.1,1.2', 'foo' => 'bar') }
64
64
 
65
- context "and accept-version is one of the parameters" do
66
- let(:connection_attrs) { {hosts: [{host: "my_host"}], connect_headers: {"foo" => "bar", :"accept-version" => "foo!"}} }
65
+ context 'and accept-version is one of the parameters' do
66
+ let(:connection_attrs) { {hosts: [{host: 'my_host'}], connect_headers: {'foo' => 'bar', :"accept-version" => 'foo!'}} }
67
67
 
68
- its([:connect_headers]) { should eq(:"accept-version" => "1.1,1.2", "foo" => "bar") }
68
+ its([:connect_headers]) { should eq(:"accept-version" => '1.1,1.2', 'foo' => 'bar') }
69
69
  end
70
70
  end
71
71
  end
72
72
  end
73
73
 
74
- shared_context "a connected stomp adapter" do
74
+ shared_context 'a connected stomp adapter' do
75
75
  let(:broker) { MessageDriver::Broker.configure(valid_connection_attrs) }
76
76
  subject(:adapter) { broker.adapter }
77
77
 
@@ -80,54 +80,54 @@ module MessageDriver::Adapters
80
80
  end
81
81
  end
82
82
 
83
- it_behaves_like "an adapter" do
84
- include_context "a connected stomp adapter"
83
+ it_behaves_like 'an adapter' do
84
+ include_context 'a connected stomp adapter'
85
85
  end
86
86
 
87
- describe "#new_context" do
88
- include_context "a connected stomp adapter"
87
+ describe '#new_context' do
88
+ include_context 'a connected stomp adapter'
89
89
 
90
- it "returns a StompAdapter::StompContext" do
90
+ it 'returns a StompAdapter::StompContext' do
91
91
  expect(adapter.new_context).to be_a StompAdapter::StompContext
92
92
  end
93
93
  end
94
94
 
95
95
  describe StompAdapter::StompContext do
96
- include_context "a connected stomp adapter"
96
+ include_context 'a connected stomp adapter'
97
97
  subject(:adapter_context) { adapter.new_context }
98
98
 
99
- it_behaves_like "an adapter context"
100
- it_behaves_like "transactions are not supported"
101
- it_behaves_like "client acks are not supported"
102
- it_behaves_like "subscriptions are not supported"
99
+ it_behaves_like 'an adapter context'
100
+ it_behaves_like 'transactions are not supported'
101
+ it_behaves_like 'client acks are not supported'
102
+ it_behaves_like 'subscriptions are not supported'
103
103
 
104
- describe "#create_destination" do
104
+ describe '#create_destination' do
105
105
 
106
- context "the resulting destination" do
107
- let(:dest_name) { "/queue/stomp_destination_spec" }
106
+ context 'the resulting destination' do
107
+ let(:dest_name) { '/queue/stomp_destination_spec' }
108
108
  subject(:destination) { adapter_context.create_destination(dest_name) }
109
109
 
110
110
  it { should be_a StompAdapter::Destination }
111
111
 
112
- it_behaves_like "a destination"
112
+ it_behaves_like 'a destination'
113
113
  include_examples "doesn't support #message_count"
114
114
 
115
- describe "pop_message" do
116
- context "when there is a message on the queue" do
117
- let(:body) { "Testing stomp pop_message" }
115
+ describe 'pop_message' do
116
+ context 'when there is a message on the queue' do
117
+ let(:body) { 'Testing stomp pop_message' }
118
118
  before do
119
119
  destination.publish(body)
120
120
  end
121
121
 
122
- it "returns the message" do
122
+ it 'returns the message' do
123
123
  msg = destination.pop_message
124
124
  expect(msg).to be_a MessageDriver::Adapters::StompAdapter::Message
125
125
  expect(msg.body).to eq(body)
126
126
  end
127
127
  end
128
128
 
129
- context "when the queue is empty" do
130
- it "returns nil" do
129
+ context 'when the queue is empty' do
130
+ it 'returns nil' do
131
131
  msg = destination.pop_message
132
132
  expect(msg).to be_nil
133
133
  end
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,11 @@
1
+ require 'coveralls'
2
+ Coveralls.wear!
3
+
1
4
  require 'message_driver'
2
5
 
3
6
  require File.join(File.dirname(__FILE__), '..', 'test_lib', 'broker_config')
4
7
 
5
- Dir["./spec/support/**/*.rb"].sort.each {|f| require f}
8
+ Dir['./spec/support/**/*.rb'].sort.each {|f| require f}
6
9
 
7
10
  RSpec.configure do |c|
8
11
  c.treat_symbols_as_metadata_keys_with_true_values = true
@@ -1,12 +1,12 @@
1
- shared_examples "an adapter" do
2
- describe "#new_context" do
3
- it "returns a MessageDriver::Adapters::ContextBase" do
1
+ shared_examples 'an adapter' do
2
+ describe '#new_context' do
3
+ it 'returns a MessageDriver::Adapters::ContextBase' do
4
4
  expect(subject.new_context).to be_a MessageDriver::Adapters::ContextBase
5
5
  end
6
6
  end
7
7
 
8
- describe "#stop" do
9
- it "invalidates all the adapter contexts" do
8
+ describe '#stop' do
9
+ it 'invalidates all the adapter contexts' do
10
10
  ctx1 = subject.new_context
11
11
  ctx2 = subject.new_context
12
12
  subject.stop
@@ -15,8 +15,8 @@ shared_examples "an adapter" do
15
15
  end
16
16
  end
17
17
 
18
- describe "#broker" do
19
- it "returns the broker associated with the adapter" do
18
+ describe '#broker' do
19
+ it 'returns the broker associated with the adapter' do
20
20
  expect(subject.broker).to be(broker)
21
21
  end
22
22
  end
@@ -1,6 +1,6 @@
1
- shared_examples "client acks are supported" do
2
- describe "#supports_client_acks" do
3
- it "returns true" do
1
+ shared_examples 'client acks are supported' do
2
+ describe '#supports_client_acks' do
3
+ it 'returns true' do
4
4
  expect(subject.supports_client_acks?).to eq(true)
5
5
  end
6
6
  end
@@ -9,9 +9,9 @@ shared_examples "client acks are supported" do
9
9
  it { should respond_to :nack_message }
10
10
  end
11
11
 
12
- shared_examples "client acks are not supported" do
13
- describe "#supports_client_acks" do
14
- it "returns false" do
12
+ shared_examples 'client acks are not supported' do
13
+ describe '#supports_client_acks' do
14
+ it 'returns false' do
15
15
  expect(subject.supports_client_acks?).to eq(false)
16
16
  end
17
17
  end
@@ -1,14 +1,14 @@
1
- shared_examples "an adapter context" do
1
+ shared_examples 'an adapter context' do
2
2
  it { should be_a MessageDriver::Adapters::ContextBase }
3
3
 
4
4
  its(:adapter) { should be adapter }
5
5
 
6
- it "is initially valid" do
6
+ it 'is initially valid' do
7
7
  should be_valid
8
8
  end
9
9
 
10
- describe "#invalidate" do
11
- it "causes the context to become invalid" do
10
+ describe '#invalidate' do
11
+ it 'causes the context to become invalid' do
12
12
  subject.invalidate
13
13
  expect(subject).to_not be_valid
14
14
  end
@@ -1,16 +1,16 @@
1
- shared_examples "a destination" do
1
+ shared_examples 'a destination' do
2
2
  its(:adapter) { should be adapter }
3
3
 
4
- describe "#pop_message" do
5
- let(:body) { "The message body" }
6
- let(:headers) { { "foo" => "bar", "bar" => "baz"} }
4
+ describe '#pop_message' do
5
+ let(:body) { 'The message body' }
6
+ let(:headers) { { 'foo' => 'bar', 'bar' => 'baz'} }
7
7
  let(:properties) { {persistent: true, client_ack: true} }
8
8
 
9
9
  before do
10
10
  destination.publish(body, headers, properties)
11
11
  end
12
12
 
13
- context "the result" do
13
+ context 'the result' do
14
14
  subject(:message) { destination.pop_message }
15
15
 
16
16
  it { should be_a MessageDriver::Message::Base }
@@ -22,8 +22,8 @@ shared_examples "a destination" do
22
22
  end
23
23
 
24
24
  shared_examples "doesn't support #message_count" do
25
- describe "#message_count" do
26
- it "raises an error" do
25
+ describe '#message_count' do
26
+ it 'raises an error' do
27
27
  expect {
28
28
  destination.message_count
29
29
  }.to raise_error "#message_count is not supported by #{destination.class}"
@@ -31,11 +31,11 @@ shared_examples "doesn't support #message_count" do
31
31
  end
32
32
  end
33
33
 
34
- shared_examples "supports #message_count" do
34
+ shared_examples 'supports #message_count' do
35
35
  it "reports it's message_count" do
36
36
  expect {
37
- destination.publish("msg1")
38
- destination.publish("msg2")
37
+ destination.publish('msg1')
38
+ destination.publish('msg2')
39
39
  pause_if_needed
40
40
  }.to change{destination.message_count}.by(2)
41
41
  end
@@ -1,14 +1,14 @@
1
- shared_examples "subscriptions are not supported" do
2
- describe "#supports_subscriptions?" do
3
- it "returns false" do
1
+ shared_examples 'subscriptions are not supported' do
2
+ describe '#supports_subscriptions?' do
3
+ it 'returns false' do
4
4
  expect(subject.supports_subscriptions?).to eq(false)
5
5
  end
6
6
  end
7
7
 
8
- describe "#subscribe" do
9
- it "raises an error" do
10
- destination = double("destination")
11
- consumer = lambda do |m| end
8
+ describe '#subscribe' do
9
+ it 'raises an error' do
10
+ destination = double('destination')
11
+ consumer = lambda do |_| end
12
12
  expect {
13
13
  subject.subscribe(destination, &consumer)
14
14
  }.to raise_error "#subscribe is not supported by #{subject.adapter.class}"
@@ -16,17 +16,17 @@ shared_examples "subscriptions are not supported" do
16
16
  end
17
17
  end
18
18
 
19
- shared_examples "subscriptions are supported" do |subscription_type|
20
- describe "#supports_subscriptions?" do
21
- it "returns true" do
19
+ shared_examples 'subscriptions are supported' do |subscription_type|
20
+ describe '#supports_subscriptions?' do
21
+ it 'returns true' do
22
22
  expect(subject.supports_subscriptions?).to eq(true)
23
23
  end
24
24
  end
25
25
 
26
- let(:destination) { adapter_context.create_destination("subscriptions_example_queue") }
26
+ let(:destination) { adapter_context.create_destination('subscriptions_example_queue') }
27
27
 
28
- let(:message1) { "message 1" }
29
- let(:message2) { "message 2" }
28
+ let(:message1) { 'message 1' }
29
+ let(:message2) { 'message 2' }
30
30
  let(:messages) { [] }
31
31
  let(:consumer) do
32
32
  lambda do |msg|
@@ -34,7 +34,7 @@ shared_examples "subscriptions are supported" do |subscription_type|
34
34
  end
35
35
  end
36
36
 
37
- describe "#subscribe" do
37
+ describe '#subscribe' do
38
38
  before do
39
39
  if destination.respond_to? :purge
40
40
  destination.purge
@@ -46,11 +46,11 @@ shared_examples "subscriptions are supported" do |subscription_type|
46
46
  subscription.unsubscribe
47
47
  end
48
48
 
49
- it "returns a MessageDriver::Subscription::Base" do
49
+ it 'returns a MessageDriver::Subscription::Base' do
50
50
  expect(subscription).to be_a MessageDriver::Subscription::Base
51
51
  end
52
52
 
53
- context "the subscription" do
53
+ context 'the subscription' do
54
54
  subject { subscription }
55
55
 
56
56
  it { should be_a MessageDriver::Subscription::Base }
@@ -59,23 +59,23 @@ shared_examples "subscriptions are supported" do |subscription_type|
59
59
  its(:destination) { should be destination }
60
60
  its(:consumer) { should be consumer }
61
61
 
62
- describe "#unsubscribe" do
62
+ describe '#unsubscribe' do
63
63
  it "makes it so messages don't go to the consumer any more" do
64
64
  subscription.unsubscribe
65
65
  expect {
66
- destination.publish("should not be consumed")
66
+ destination.publish('should not be consumed')
67
67
  }.to_not change{messages.size}
68
68
  end
69
69
  end
70
70
  end
71
71
 
72
- context "when there are already messages in the destination" do
72
+ context 'when there are already messages in the destination' do
73
73
  before do
74
74
  destination.publish(message1)
75
75
  destination.publish(message2)
76
76
  end
77
77
 
78
- it "plays the messages into the consumer" do
78
+ it 'plays the messages into the consumer' do
79
79
  expect {
80
80
  subscription
81
81
  pause_if_needed
@@ -85,7 +85,7 @@ shared_examples "subscriptions are supported" do |subscription_type|
85
85
  expect(bodies).to include(message2)
86
86
  end
87
87
 
88
- it "removes the messages from the queue" do
88
+ it 'removes the messages from the queue' do
89
89
  pause_if_needed
90
90
  expect {
91
91
  subscription
@@ -94,12 +94,12 @@ shared_examples "subscriptions are supported" do |subscription_type|
94
94
  end
95
95
  end
96
96
 
97
- context "when a message is published to the destination" do
97
+ context 'when a message is published to the destination' do
98
98
  before do
99
99
  subscription
100
100
  end
101
101
 
102
- it "consumers the message into the consumer instead of putting them on the queue" do
102
+ it 'consumers the message into the consumer instead of putting them on the queue' do
103
103
  expect {
104
104
  expect {
105
105
  subject.publish(destination, message1)
@@ -110,10 +110,10 @@ shared_examples "subscriptions are supported" do |subscription_type|
110
110
  end
111
111
  end
112
112
 
113
- context "when the consumer raises an error" do
114
- let(:error) { RuntimeError.new("oh nos!") }
113
+ context 'when the consumer raises an error' do
114
+ let(:error) { RuntimeError.new('oh nos!') }
115
115
  let(:consumer) do
116
- lambda do |msg|
116
+ lambda do |_|
117
117
  raise error
118
118
  end
119
119
  end
@@ -123,7 +123,7 @@ shared_examples "subscriptions are supported" do |subscription_type|
123
123
  destination.publish(message2)
124
124
  end
125
125
 
126
- it "keeps processing the messages" do
126
+ it 'keeps processing the messages' do
127
127
  pause_if_needed
128
128
  expect {
129
129
  subscription
@@ -131,11 +131,11 @@ shared_examples "subscriptions are supported" do |subscription_type|
131
131
  }.to change{destination.message_count}.from(2).to(0)
132
132
  end
133
133
 
134
- context "an error_handler is provided" do
134
+ context 'an error_handler is provided' do
135
135
  let(:error_handler) { double(:error_handler, call: nil) }
136
136
  let(:subscription) { adapter_context.subscribe(destination, error_handler: error_handler, &consumer) }
137
137
 
138
- it "passes the errors and the messages to the error handler" do
138
+ it 'passes the errors and the messages to the error handler' do
139
139
  subscription
140
140
  pause_if_needed
141
141
  expect(error_handler).to have_received(:call).with(error, kind_of(MessageDriver::Message::Base)).at_least(2).times