message-driver 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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