rabbit_feed 0.3.1

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 (145) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +11 -0
  3. data/.rspec +3 -0
  4. data/Brewfile +4 -0
  5. data/DEVELOPING.md +140 -0
  6. data/Gemfile +15 -0
  7. data/Gemfile.lock +121 -0
  8. data/LICENSE.txt +9 -0
  9. data/README.md +304 -0
  10. data/Rakefile +30 -0
  11. data/bin/bundle +3 -0
  12. data/bin/rabbit_feed +11 -0
  13. data/example/non_rails_app/.rspec +1 -0
  14. data/example/non_rails_app/Gemfile +7 -0
  15. data/example/non_rails_app/Gemfile.lock +56 -0
  16. data/example/non_rails_app/Rakefile +5 -0
  17. data/example/non_rails_app/bin/benchmark +63 -0
  18. data/example/non_rails_app/bin/bundle +3 -0
  19. data/example/non_rails_app/config/rabbit_feed.yml +8 -0
  20. data/example/non_rails_app/lib/non_rails_app.rb +32 -0
  21. data/example/non_rails_app/lib/non_rails_app/event_handler.rb +10 -0
  22. data/example/non_rails_app/log/.keep +0 -0
  23. data/example/non_rails_app/spec/lib/non_rails_app/event_handler_spec.rb +14 -0
  24. data/example/non_rails_app/spec/lib/non_rails_app/event_routing_spec.rb +14 -0
  25. data/example/non_rails_app/spec/spec_helper.rb +31 -0
  26. data/example/non_rails_app/tmp/pids/.keep +0 -0
  27. data/example/rails_app/.gitignore +17 -0
  28. data/example/rails_app/.node-version +1 -0
  29. data/example/rails_app/.rspec +1 -0
  30. data/example/rails_app/Gemfile +36 -0
  31. data/example/rails_app/Gemfile.lock +173 -0
  32. data/example/rails_app/README.rdoc +28 -0
  33. data/example/rails_app/Rakefile +6 -0
  34. data/example/rails_app/app/assets/images/.keep +0 -0
  35. data/example/rails_app/app/assets/javascripts/application.js +16 -0
  36. data/example/rails_app/app/assets/javascripts/beavers.js.coffee +3 -0
  37. data/example/rails_app/app/assets/stylesheets/application.css +15 -0
  38. data/example/rails_app/app/assets/stylesheets/beavers.css.scss +3 -0
  39. data/example/rails_app/app/assets/stylesheets/scaffolds.css.scss +69 -0
  40. data/example/rails_app/app/controllers/application_controller.rb +5 -0
  41. data/example/rails_app/app/controllers/beavers_controller.rb +81 -0
  42. data/example/rails_app/app/controllers/concerns/.keep +0 -0
  43. data/example/rails_app/app/helpers/application_helper.rb +2 -0
  44. data/example/rails_app/app/helpers/beavers_helper.rb +2 -0
  45. data/example/rails_app/app/mailers/.keep +0 -0
  46. data/example/rails_app/app/models/.keep +0 -0
  47. data/example/rails_app/app/models/beaver.rb +2 -0
  48. data/example/rails_app/app/models/concerns/.keep +0 -0
  49. data/example/rails_app/app/views/beavers/_form.html.erb +21 -0
  50. data/example/rails_app/app/views/beavers/edit.html.erb +6 -0
  51. data/example/rails_app/app/views/beavers/index.html.erb +25 -0
  52. data/example/rails_app/app/views/beavers/index.json.jbuilder +4 -0
  53. data/example/rails_app/app/views/beavers/new.html.erb +5 -0
  54. data/example/rails_app/app/views/beavers/show.html.erb +9 -0
  55. data/example/rails_app/app/views/beavers/show.json.jbuilder +1 -0
  56. data/example/rails_app/app/views/layouts/application.html.erb +14 -0
  57. data/example/rails_app/bin/bundle +3 -0
  58. data/example/rails_app/bin/rails +4 -0
  59. data/example/rails_app/bin/rake +4 -0
  60. data/example/rails_app/config.ru +4 -0
  61. data/example/rails_app/config/application.rb +25 -0
  62. data/example/rails_app/config/boot.rb +4 -0
  63. data/example/rails_app/config/database.yml +22 -0
  64. data/example/rails_app/config/environment.rb +5 -0
  65. data/example/rails_app/config/environments/development.rb +83 -0
  66. data/example/rails_app/config/environments/test.rb +39 -0
  67. data/example/rails_app/config/initializers/backtrace_silencers.rb +7 -0
  68. data/example/rails_app/config/initializers/cookies_serializer.rb +3 -0
  69. data/example/rails_app/config/initializers/filter_parameter_logging.rb +4 -0
  70. data/example/rails_app/config/initializers/inflections.rb +16 -0
  71. data/example/rails_app/config/initializers/mime_types.rb +4 -0
  72. data/example/rails_app/config/initializers/rabbit_feed.rb +43 -0
  73. data/example/rails_app/config/initializers/session_store.rb +3 -0
  74. data/example/rails_app/config/initializers/wrap_parameters.rb +14 -0
  75. data/example/rails_app/config/locales/en.yml +23 -0
  76. data/example/rails_app/config/rabbit_feed.yml +8 -0
  77. data/example/rails_app/config/routes.rb +58 -0
  78. data/example/rails_app/config/secrets.yml +18 -0
  79. data/example/rails_app/config/unicorn.rb +4 -0
  80. data/example/rails_app/db/migrate/20140424102400_create_beavers.rb +9 -0
  81. data/example/rails_app/db/schema.rb +22 -0
  82. data/example/rails_app/db/seeds.rb +7 -0
  83. data/example/rails_app/lib/assets/.keep +0 -0
  84. data/example/rails_app/lib/event_handler.rb +7 -0
  85. data/example/rails_app/lib/tasks/.keep +0 -0
  86. data/example/rails_app/log/.keep +0 -0
  87. data/example/rails_app/public/404.html +67 -0
  88. data/example/rails_app/public/422.html +67 -0
  89. data/example/rails_app/public/500.html +66 -0
  90. data/example/rails_app/public/favicon.ico +0 -0
  91. data/example/rails_app/public/robots.txt +5 -0
  92. data/example/rails_app/spec/controllers/beavers_controller_spec.rb +32 -0
  93. data/example/rails_app/spec/event_routing_spec.rb +15 -0
  94. data/example/rails_app/spec/spec_helper.rb +51 -0
  95. data/example/rails_app/test/controllers/.keep +0 -0
  96. data/example/rails_app/test/controllers/beavers_controller_test.rb +49 -0
  97. data/example/rails_app/test/fixtures/.keep +0 -0
  98. data/example/rails_app/test/fixtures/beavers.yml +7 -0
  99. data/example/rails_app/test/helpers/.keep +0 -0
  100. data/example/rails_app/test/helpers/beavers_helper_test.rb +4 -0
  101. data/example/rails_app/test/integration/.keep +0 -0
  102. data/example/rails_app/test/mailers/.keep +0 -0
  103. data/example/rails_app/test/models/.keep +0 -0
  104. data/example/rails_app/test/models/beaver_test.rb +7 -0
  105. data/example/rails_app/test/test_helper.rb +13 -0
  106. data/example/rails_app/tmp/pids/.keep +0 -0
  107. data/example/rails_app/vendor/assets/javascripts/.keep +0 -0
  108. data/example/rails_app/vendor/assets/stylesheets/.keep +0 -0
  109. data/lib/dsl.rb +9 -0
  110. data/lib/rabbit_feed.rb +41 -0
  111. data/lib/rabbit_feed/client.rb +181 -0
  112. data/lib/rabbit_feed/configuration.rb +50 -0
  113. data/lib/rabbit_feed/connection_concern.rb +95 -0
  114. data/lib/rabbit_feed/consumer.rb +14 -0
  115. data/lib/rabbit_feed/consumer_connection.rb +108 -0
  116. data/lib/rabbit_feed/event.rb +43 -0
  117. data/lib/rabbit_feed/event_definitions.rb +98 -0
  118. data/lib/rabbit_feed/event_routing.rb +90 -0
  119. data/lib/rabbit_feed/producer.rb +47 -0
  120. data/lib/rabbit_feed/producer_connection.rb +65 -0
  121. data/lib/rabbit_feed/testing_support/rspec_matchers/publish_event.rb +90 -0
  122. data/lib/rabbit_feed/testing_support/testing_helpers.rb +16 -0
  123. data/lib/rabbit_feed/version.rb +3 -0
  124. data/logo.png +0 -0
  125. data/rabbit_feed.gemspec +35 -0
  126. data/run_benchmark +35 -0
  127. data/run_example +62 -0
  128. data/run_recovery_test +26 -0
  129. data/spec/features/connectivity.feature +13 -0
  130. data/spec/features/step_definitions/connectivity_steps.rb +96 -0
  131. data/spec/fixtures/configuration.yml +14 -0
  132. data/spec/lib/rabbit_feed/client_spec.rb +116 -0
  133. data/spec/lib/rabbit_feed/configuration_spec.rb +121 -0
  134. data/spec/lib/rabbit_feed/connection_concern_spec.rb +116 -0
  135. data/spec/lib/rabbit_feed/consumer_connection_spec.rb +85 -0
  136. data/spec/lib/rabbit_feed/event_definitions_spec.rb +139 -0
  137. data/spec/lib/rabbit_feed/event_routing_spec.rb +121 -0
  138. data/spec/lib/rabbit_feed/event_spec.rb +33 -0
  139. data/spec/lib/rabbit_feed/producer_connection_spec.rb +72 -0
  140. data/spec/lib/rabbit_feed/producer_spec.rb +57 -0
  141. data/spec/lib/rabbit_feed/testing_support/rspec_matchers/publish_event_spec.rb +60 -0
  142. data/spec/lib/rabbit_feed/testing_support/testing_helper_spec.rb +34 -0
  143. data/spec/spec_helper.rb +58 -0
  144. data/spec/support/shared_examples_for_connections.rb +40 -0
  145. metadata +305 -0
@@ -0,0 +1,14 @@
1
+ test:
2
+ host: localhost
3
+ port: 5672
4
+ user: guest
5
+ password: guest
6
+ application: rabbit_feed
7
+ exchange: rabbit_feed_exchange
8
+ pool_size: 1
9
+ pool_timeout: 1
10
+ heartbeat: 60
11
+ connect_timeout: 1
12
+ network_recovery_interval: 0.1
13
+ auto_delete_queue: true
14
+ auto_delete_exchange: true
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe Client do
5
+ let(:command) { 'consume' }
6
+ let(:logfile) { 'test.log' }
7
+ let(:pidfile) { './test.pid' }
8
+ let(:config_file) { 'spec/fixtures/configuration.yml' }
9
+ let(:environment) { 'test' }
10
+ let(:require_file){ 'rabbit_feed.rb' }
11
+ let(:arguments) do
12
+ [
13
+ command,
14
+ '--environment',
15
+ environment,
16
+ '--config',
17
+ config_file,
18
+ '--logfile',
19
+ logfile,
20
+ '--pidfile',
21
+ pidfile,
22
+ '--require',
23
+ require_file,
24
+ '--daemon'
25
+ ]
26
+ end
27
+ before do
28
+ RabbitFeed.environment = nil
29
+ RabbitFeed.log = nil
30
+ RabbitFeed.configuration_file_path = nil
31
+ end
32
+ subject{ described_class.new arguments }
33
+
34
+ describe '.new' do
35
+
36
+ it { should be_valid }
37
+
38
+ it 'sets the environment' do
39
+ subject
40
+ expect(RabbitFeed.environment).to eq 'test'
41
+ end
42
+
43
+ it 'sets the logger' do
44
+ subject
45
+ expect(RabbitFeed.log).to be_a Logger
46
+ end
47
+
48
+ it 'sets the configuration' do
49
+ subject
50
+ expect(RabbitFeed.configuration).to be_a Configuration
51
+ end
52
+
53
+ context 'when the command is invalid' do
54
+ let(:command) { 'blah' }
55
+
56
+ it 'should be invalid' do
57
+ expect{subject}.to raise_error Error
58
+ end
59
+ end
60
+
61
+ context 'when the log file path is not present' do
62
+ let(:logfile) { '/blah/blah.log' }
63
+
64
+ it 'should be invalid' do
65
+ expect{subject}.to raise_error Error
66
+ end
67
+ end
68
+
69
+ context 'when the pid file path is not present' do
70
+ let(:pidfile) { '/blah/blah.pid' }
71
+
72
+ it 'should be invalid' do
73
+ expect{subject}.to raise_error Error
74
+ end
75
+ end
76
+
77
+ context 'when the config file is not present' do
78
+ let(:config_file) { '/blah/blah.yml' }
79
+
80
+ it 'should be invalid' do
81
+ expect{subject}.to raise_error Error
82
+ end
83
+ end
84
+
85
+ context 'when the environment is not present' do
86
+ let(:environment) { '' }
87
+ before do
88
+ ENV['RAILS_ENV'] = nil
89
+ ENV['RACK_ENV'] = nil
90
+ end
91
+
92
+ it 'should be invalid' do
93
+ expect{subject}.to raise_error Error
94
+ end
95
+
96
+ context 'when the RAILS_ENV is present' do
97
+ before { ENV['RAILS_ENV'] = 'test' }
98
+ after do
99
+ ENV['RAILS_ENV'] = nil
100
+ ENV['RACK_ENV'] = nil
101
+ end
102
+
103
+ it { should be_valid }
104
+ end
105
+ end
106
+
107
+ context 'when requiring a directory in a non rails app' do
108
+ let(:require_file) { './' }
109
+
110
+ it 'should be invalid' do
111
+ expect{subject}.to raise_error Error
112
+ end
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe Configuration do
5
+
6
+ describe '#queue' do
7
+ let(:options) do
8
+ {
9
+ application: 'rabbit_feed',
10
+ environment: 'test',
11
+ }
12
+ end
13
+ subject { (described_class.new options).queue }
14
+
15
+ it { should eq 'test.rabbit_feed' }
16
+ end
17
+
18
+ describe '.load' do
19
+ let(:file_path) { 'spec/fixtures/configuration.yml' }
20
+ let(:environment) { 'test' }
21
+ subject { described_class.load file_path, environment }
22
+
23
+ context 'with missing configuration' do
24
+ let(:environment) { 'production' }
25
+
26
+ it 'should raise an error' do
27
+ expect{ subject }.to raise_error ConfigurationError
28
+ end
29
+ end
30
+
31
+ context 'with configuration' do
32
+
33
+ its(:host) { should eq 'localhost' }
34
+ its(:port) { should eq 5672 }
35
+ its(:user) { should eq 'guest' }
36
+ its(:password) { should eq 'guest' }
37
+ its(:application) { should eq 'rabbit_feed' }
38
+ its(:environment) { should eq 'test' }
39
+ its(:exchange) { should eq 'rabbit_feed_exchange' }
40
+ its(:pool_size) { should eq 1 }
41
+ its(:pool_timeout) { should eq 1 }
42
+ its(:heartbeat) { should eq 60 }
43
+ its(:connect_timeout) { should eq 1 }
44
+ its(:network_recovery_interval) { should eq 0.1 }
45
+ its(:auto_delete_queue) { should be_true }
46
+ its(:auto_delete_exchange) { should be_true }
47
+ end
48
+
49
+ end
50
+
51
+ describe '.new' do
52
+ let(:options) {{}}
53
+ subject { described_class.new options }
54
+
55
+ context 'with default options' do
56
+ let(:options) do
57
+ {
58
+ application: 'rabbit_feed',
59
+ environment: 'test',
60
+ }
61
+ end
62
+
63
+ its(:host) { should eq 'localhost' }
64
+ its(:port) { should eq 5672 }
65
+ its(:user) { should eq 'guest' }
66
+ its(:password) { should eq 'guest' }
67
+ its(:exchange) { should eq 'amq.topic' }
68
+ its(:pool_size) { should eq 1 }
69
+ its(:pool_timeout) { should eq 5 }
70
+ its(:heartbeat) { should eq 5 }
71
+ its(:connect_timeout) { should eq 10 }
72
+ its(:network_recovery_interval) { should eq 1 }
73
+ its(:auto_delete_queue) { should be_false }
74
+ its(:auto_delete_exchange) { should be_false }
75
+ end
76
+
77
+ context 'with provided options' do
78
+ let(:options) do
79
+ {
80
+ host: 'host_name',
81
+ port: 12345,
82
+ user: 'user_name',
83
+ password: 'password',
84
+ application: 'rabbit_feed',
85
+ environment: 'test',
86
+ exchange: 'exchange_name',
87
+ pool_size: 2,
88
+ pool_timeout: 6,
89
+ heartbeat: 3,
90
+ connect_timeout: 4,
91
+ network_recovery_interval: 2,
92
+ auto_delete_queue: 'true',
93
+ auto_delete_exchange: 'false',
94
+ }
95
+ end
96
+
97
+ its(:host) { should eq 'host_name' }
98
+ its(:port) { should eq 12345 }
99
+ its(:user) { should eq 'user_name' }
100
+ its(:password) { should eq 'password' }
101
+ its(:application) { should eq 'rabbit_feed' }
102
+ its(:environment) { should eq 'test' }
103
+ its(:exchange) { should eq 'exchange_name' }
104
+ its(:pool_size) { should eq 2 }
105
+ its(:pool_timeout) { should eq 6 }
106
+ its(:heartbeat) { should eq 3 }
107
+ its(:connect_timeout) { should eq 4 }
108
+ its(:network_recovery_interval) { should eq 2 }
109
+ its(:auto_delete_queue) { should be_true }
110
+ its(:auto_delete_exchange) { should be_true }
111
+ end
112
+
113
+ context 'with empty options' do
114
+
115
+ it 'should raise an error' do
116
+ expect{ subject }.to raise_error ConfigurationError
117
+ end
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe ConnectionConcern do
5
+ let(:bunny_exchange) { double(:bunny_exchange, on_return: nil) }
6
+ let(:connection_closed) { false }
7
+ let(:bunny_channel) { double(:bunny_channel, exchange: bunny_exchange, id: 1) }
8
+ let(:bunny_connection) { double(:bunny_connection, start: nil, closed?: connection_closed, close: nil, create_channel: bunny_channel) }
9
+ before { allow(Bunny).to receive(:new).and_return(bunny_connection) }
10
+ after do
11
+ subject.instance_variable_set(:@bunny_connection, nil)
12
+ subject.instance_variable_set(:@connection_pool, nil)
13
+ end
14
+ subject { RabbitFeed::ProducerConnection }
15
+
16
+ describe '.with_connection' do
17
+
18
+ it 'retries on exception' do
19
+ expect(subject).to receive(:retry_on_exception).and_call_original
20
+ subject.with_connection{|connection| connection }
21
+ end
22
+
23
+ it 'assigns the connection' do
24
+ subject.with_connection{|connection| connection }
25
+ expect(subject.instance_variable_get(:@bunny_connection)).to eq bunny_connection
26
+ end
27
+
28
+ it 'assigns the connection pool' do
29
+ subject.with_connection{|connection| connection }
30
+ expect(subject.instance_variable_get(:@connection_pool)).to be_a ConnectionPool
31
+ end
32
+
33
+ it 'provides an instance of the class' do
34
+ actual = subject.with_connection{|connection| connection }
35
+ expect(actual).to be_a subject
36
+ end
37
+ end
38
+
39
+ describe '.close' do
40
+
41
+ context 'when the connection is nil' do
42
+
43
+ it 'does not close the connection' do
44
+ expect(bunny_connection).not_to receive(:close)
45
+ subject.close
46
+ end
47
+ end
48
+
49
+ context 'when the connection is not nil' do
50
+ before do
51
+ subject.with_connection{|connection| connection }
52
+ end
53
+
54
+ context 'when the connection is closed' do
55
+ let(:connection_closed) { true }
56
+
57
+ it 'does not close the connection' do
58
+ expect(bunny_connection).not_to receive(:close)
59
+ subject.close
60
+ end
61
+ end
62
+
63
+ context 'when the connection is not closed' do
64
+ let(:connection_closed) { false }
65
+
66
+ it 'closes the connection' do
67
+ expect(bunny_connection).to receive(:close)
68
+ subject.close
69
+ end
70
+
71
+ context 'when closing raises an exception' do
72
+
73
+ it 'does not propogate the exception' do
74
+ allow(bunny_connection).to receive(:close).and_raise 'error'
75
+ expect{ subject.close }.not_to raise_error
76
+ end
77
+ end
78
+ end
79
+
80
+ it 'unsets the connection' do
81
+ subject.close
82
+ expect(subject.instance_variable_get(:@bunny_connection)).to be_nil
83
+ end
84
+
85
+ it 'unsets the connection pool' do
86
+ subject.close
87
+ expect(subject.instance_variable_get(:@connection_pool)).to be_nil
88
+ end
89
+ end
90
+ end
91
+
92
+ describe '.retry_on_exception' do
93
+ it_behaves_like 'an operation that retries on exception', :retry_on_exception, RuntimeError
94
+ it_behaves_like 'an operation that does not retry on exception', :retry_on_exception, Bunny::ConnectionClosedError
95
+ end
96
+
97
+ describe '.retry_on_closed_connection' do
98
+ before do
99
+ subject.with_connection{|connection| connection }
100
+ end
101
+
102
+ it_behaves_like 'an operation that retries on exception', :retry_on_closed_connection, Bunny::ConnectionClosedError
103
+ it_behaves_like 'an operation that does not retry on exception', :retry_on_closed_connection, RuntimeError
104
+
105
+ it 'unsets the connection' do
106
+ expect { subject.retry_on_closed_connection { raise Bunny::ConnectionClosedError.new 'blah' } }.to raise_error
107
+ expect(subject.instance_variable_get(:@bunny_connection)).to be_nil
108
+ end
109
+
110
+ it 'unsets the connection pool' do
111
+ expect { subject.retry_on_closed_connection { raise Bunny::ConnectionClosedError.new 'blah' } }.to raise_error
112
+ expect(subject.instance_variable_get(:@connection_pool)).to be_nil
113
+ end
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,85 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe ConsumerConnection do
5
+ let(:bunny_queue) { double(:bunny_queue, bind: nil, subscribe: nil)}
6
+ let(:bunny_channel) { double(:bunny_channel, prefetch: nil, nack: nil, ack: nil, queue: bunny_queue, id: 1)}
7
+ let(:bunny_connection) { double(:bunny_connection, start: nil, closed?: false, close: nil, create_channel: bunny_channel) }
8
+ before do
9
+ allow(Bunny).to receive(:new).and_return(bunny_connection)
10
+ allow(bunny_queue).to receive(:channel).and_return(bunny_channel)
11
+ end
12
+ subject{ described_class.new bunny_channel }
13
+
14
+ describe '#new' do
15
+ before do
16
+ EventRouting do
17
+ accept_from('rabbit_feed') do
18
+ event('test') {|event|}
19
+ end
20
+ end
21
+ end
22
+
23
+ it 'binds the queue to the exchange' do
24
+ expect(bunny_queue).to receive(:bind).with('rabbit_feed_exchange', { routing_key: 'test.rabbit_feed.test'})
25
+ subject
26
+ end
27
+
28
+ it 'assigns the queue' do
29
+ expect(subject.queue).to eq bunny_queue
30
+ end
31
+
32
+ it 'preserves message order' do
33
+ expect(bunny_channel).to receive(:prefetch).with(1)
34
+ subject
35
+ end
36
+ end
37
+
38
+ describe '#connection_options' do
39
+
40
+ it 'uses a threaded connection' do
41
+ expect(described_class.connection_options).to include(threaded: true)
42
+ end
43
+ end
44
+
45
+ describe '#consume' do
46
+ before do
47
+ allow(bunny_queue).to receive(:subscribe).and_yield(double(:delivery_info, delivery_tag: :tag), 'properties', 'payload')
48
+ allow_any_instance_of(described_class).to receive(:sleep)
49
+ end
50
+
51
+ it 'yields the payload' do
52
+ subject.consume { |payload| payload.should eq 'payload'}
53
+ end
54
+
55
+ it 'acknowledges the message' do
56
+ expect(bunny_channel).to receive(:ack)
57
+ subject.consume { }
58
+ end
59
+
60
+ context 'when an exception is raised' do
61
+
62
+ context 'when Airbrake is defined' do
63
+ before do
64
+ stub_const('Airbrake', double(:airbrake, configuration: airbrake_configuration))
65
+ end
66
+
67
+ context 'and the Airbrake configuration is public' do
68
+ let(:airbrake_configuration) { double(:airbrake_configuration, public?: true) }
69
+
70
+ it 'notifies airbrake' do
71
+ expect(Airbrake).to receive(:notify_or_ignore).with(an_instance_of RuntimeError)
72
+
73
+ expect{ subject.consume { raise 'Consuming time' } }.not_to raise_error
74
+ end
75
+ end
76
+ end
77
+
78
+ it 'negatively acknowledges the message' do
79
+ expect(bunny_channel).to receive(:nack)
80
+ subject.consume { raise 'Consuming time' }
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end