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,139 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe EventDefinitions do
5
+ before do
6
+ EventDefinitions do
7
+ define_event('customer_purchases_policy', version: '1.0.0') do
8
+ defined_as do
9
+ 'The definition of a purchase'
10
+ end
11
+ payload_contains do
12
+ field('customer_id', type: 'string', definition: 'The definition of the customer id')
13
+ field('policy_id', type: 'string', definition: 'The definition of the policy id')
14
+ field('price', type: 'string', definition: 'The definition of the price')
15
+ end
16
+ end
17
+ end
18
+ end
19
+ subject { RabbitFeed::Producer.event_definitions['customer_purchases_policy'] }
20
+
21
+ it { should_not be_nil }
22
+ it { should be_valid }
23
+ its(:name) { should eq 'customer_purchases_policy' }
24
+
25
+ describe EventDefinitions::Event do
26
+ let(:name) { 'event_name' }
27
+ let(:version) { '1.0.0' }
28
+ let(:definition) { 'event definition' }
29
+ subject do
30
+ (EventDefinitions::Event.new name, version).tap do |event|
31
+ event.defined_as do
32
+ definition
33
+ end
34
+ event.payload_contains do
35
+ field 'field', { type: 'string', definition: 'field definition' }
36
+ end
37
+ end
38
+ end
39
+
40
+ it { should be_valid }
41
+ its(:fields) { should_not be_empty }
42
+ its(:schema) { should be_a Avro::Schema }
43
+ its(:payload){ should =~ [
44
+ {name: 'application', type: 'string', doc: 'The name of the application that created the event'},
45
+ {name: 'host', type: 'string', doc: 'The hostname of the server on which the event was created'},
46
+ {name: 'environment', type: 'string', doc: 'The environment in which the event was created'},
47
+ {name: 'version', type: 'string', doc: 'The version of the event'},
48
+ {name: 'created_at_utc', type: 'string', doc: 'The UTC time that the event was created'},
49
+ {name: 'field', type: 'string', doc: 'field definition'},
50
+ {name: 'name', type: 'string', doc: 'The name of the event'}
51
+ ]
52
+ }
53
+
54
+ context 'when the name is nil' do
55
+ let(:name) {}
56
+
57
+ it { should_not be_valid }
58
+ end
59
+
60
+ context 'when the version is nil' do
61
+ let(:version) {}
62
+
63
+ it { should_not be_valid }
64
+ end
65
+
66
+ context 'when the version is malformed' do
67
+ let(:version) { '1.a' }
68
+
69
+ it { should_not be_valid }
70
+ end
71
+
72
+ context 'when the definition is nil' do
73
+ let(:definition) {}
74
+
75
+ it { should_not be_valid }
76
+ end
77
+
78
+ context 'when the event is not a valid avro schema' do
79
+ before { subject.fields << (EventDefinitions::Field.new 'junk', 'junk', 'junk') }
80
+
81
+ it { should_not be_valid }
82
+ end
83
+ end
84
+
85
+ describe EventDefinitions::Field do
86
+ let(:name) { 'event_name' }
87
+ let(:type) { 'string' }
88
+ let(:definition) { 'event definition' }
89
+ subject{ EventDefinitions::Field.new name, type, definition }
90
+
91
+ it { should be_valid }
92
+ its(:schema) { should eq({ name: name, type: type, doc: definition }) }
93
+
94
+ context 'when the name is nil' do
95
+ let(:name) {}
96
+
97
+ it 'raises a configuration error' do
98
+ expect{ subject }.to raise_error ConfigurationError
99
+ end
100
+ end
101
+
102
+ context 'when the type is nil' do
103
+ let(:type) {}
104
+
105
+ it 'raises a configuration error' do
106
+ expect{ subject }.to raise_error ConfigurationError
107
+ end
108
+ end
109
+
110
+ context 'when the definition is nil' do
111
+ let(:definition) {}
112
+
113
+ it 'raises a configuration error' do
114
+ expect{ subject }.to raise_error ConfigurationError
115
+ end
116
+ end
117
+ end
118
+
119
+ context 'testing cumulative definitions' do
120
+ before do
121
+ EventDefinitions do
122
+ define_event('plumber_fixes_tap', version: '1.0.0') do
123
+ defined_as do
124
+ 'What a plumber does'
125
+ end
126
+ payload_contains do
127
+ field('plumber_name', type: 'string', definition: 'The name of the plumber')
128
+ end
129
+ end
130
+ end
131
+ end
132
+
133
+ it 'applies event definitions in a cumulative manner' do
134
+ expect(RabbitFeed::Producer.event_definitions['customer_purchases_policy']).to be_present
135
+ expect(RabbitFeed::Producer.event_definitions['plumber_fixes_tap']).to be_present
136
+ end
137
+ end
138
+ end
139
+ end
@@ -0,0 +1,121 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe EventRouting do
5
+ before do
6
+ EventRouting do
7
+ accept_from('dummy_1') do
8
+ event('event_1') do |event|
9
+ event.payload
10
+ end
11
+ event('event_2') do |event|
12
+ event.payload
13
+ end
14
+ end
15
+ accept_from('dummy_2') do
16
+ event('event_3') do |event|
17
+ event.payload
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ it 'should create routing keys for the specified routes' do
24
+
25
+ RabbitFeed::Consumer.event_routing.accepted_routes.should =~ %w{
26
+ test.dummy_1.event_1
27
+ test.dummy_1.event_2
28
+ test.dummy_2.event_3
29
+ }
30
+ end
31
+
32
+ it 'routes the event to the correct action' do
33
+ events = [
34
+ double(:event, application: 'dummy_1', name: 'event_1', payload: 1),
35
+ double(:event, application: 'dummy_1', name: 'event_2', payload: 2),
36
+ double(:event, application: 'dummy_2', name: 'event_3', payload: 3),
37
+ ]
38
+ events.each do |event|
39
+ (RabbitFeed::Consumer.event_routing.handle_event event).should eq event.payload
40
+ end
41
+ end
42
+
43
+ it 'raises a routing error when the event cannot be routed' do
44
+ events = [
45
+ double(:event, application: 'dummy_9', name: 'event_1', payload: 1),
46
+ double(:event, application: 'dummy_1', name: 'event_9', payload: 3),
47
+ ]
48
+ events.each do |event|
49
+ expect{ RabbitFeed::Consumer.event_routing.handle_event event }.to raise_error RoutingError
50
+ end
51
+ end
52
+
53
+ describe EventRouting::Application do
54
+ let(:name) { 'name' }
55
+ subject{ EventRouting::Application.new name }
56
+
57
+ it { should be_valid }
58
+
59
+ context 'when the name is nil' do
60
+ let(:name) {}
61
+
62
+ it 'raises a configuration error' do
63
+ expect{ subject }.to raise_error ConfigurationError
64
+ end
65
+ end
66
+ end
67
+
68
+ describe EventRouting::Event do
69
+ let(:name) { 'name' }
70
+ let(:block) { Proc.new{|event|} }
71
+ subject{ EventRouting::Event.new name, block }
72
+
73
+ it { should be_valid }
74
+
75
+ context 'when the name is nil' do
76
+ let(:name) {}
77
+
78
+ it 'raises a configuration error' do
79
+ expect{ subject }.to raise_error ConfigurationError
80
+ end
81
+ end
82
+
83
+ context 'when no action is provided' do
84
+ let(:block) {}
85
+
86
+ it 'raises a configuration error' do
87
+ expect{ subject }.to raise_error ConfigurationError
88
+ end
89
+ end
90
+
91
+ context 'when the event is not provided to the event action' do
92
+ let(:block) { Proc.new{} }
93
+
94
+ it 'raises a configuration error' do
95
+ expect{ subject }.to raise_error ConfigurationError
96
+ end
97
+ end
98
+ end
99
+
100
+ context 'testing cumulative routing definitions' do
101
+ before do
102
+ EventRouting do
103
+ accept_from('dummy_3') do
104
+ event('event_4') do |event|
105
+ event.payload
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ it 'applies routing definitions in a cumulative manner' do
112
+ RabbitFeed::Consumer.event_routing.accepted_routes.should =~ %w{
113
+ test.dummy_1.event_1
114
+ test.dummy_1.event_2
115
+ test.dummy_2.event_3
116
+ test.dummy_3.event_4
117
+ }
118
+ end
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe Event do
5
+ let(:schema) { double(:schema) }
6
+ let(:payload) { { 'customer_id' => '123' } }
7
+
8
+ subject { described_class.new schema, payload }
9
+
10
+ describe '.new' do
11
+
12
+ it { should be_valid }
13
+ its(:schema) { should eq schema }
14
+ its(:payload) { should eq({ 'customer_id' => '123' }) }
15
+
16
+ context 'when schema is nil' do
17
+ let(:schema) {}
18
+
19
+ it 'should raise an error' do
20
+ expect{ subject }.to raise_error Error
21
+ end
22
+ end
23
+
24
+ context 'when payload is nil' do
25
+ let(:payload) {}
26
+
27
+ it 'should raise an error' do
28
+ expect{ subject }.to raise_error Error
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe ProducerConnection do
5
+ let(:bunny_exchange) { double(:bunny_exchange, on_return: nil, publish: nil) }
6
+ let(:bunny_channel) { double(:bunny_channel, exchange: bunny_exchange, 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
+ end
11
+ subject do
12
+ described_class.new bunny_channel
13
+ end
14
+
15
+ describe '#new' do
16
+ it 'sets up returned message handling' do
17
+ expect(described_class).to receive(:handle_returned_message).with('return_info', 'content')
18
+ expect(bunny_exchange).to receive(:on_return).and_yield('return_info', 'properties', 'content')
19
+ subject
20
+ end
21
+
22
+ it 'assigns the exchange' do
23
+ expect(subject.exchange).to eq bunny_exchange
24
+ end
25
+ end
26
+
27
+ describe '#handle_returned_message' do
28
+
29
+ context 'when Airbrake is defined' do
30
+ before do
31
+ stub_const('Airbrake', double(:airbrake, configuration: airbrake_configuration))
32
+ end
33
+
34
+ context 'and the Airbrake configuration is public' do
35
+ let(:airbrake_configuration) { double(:airbrake_configuration, public?: true) }
36
+
37
+ it 'notifies Airbrake of the return' do
38
+ expect(Airbrake).to receive(:notify_or_ignore).with(an_instance_of ReturnedMessageError)
39
+ described_class.handle_returned_message 1, 2
40
+ end
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '#connection_options' do
46
+
47
+ it 'does not use a threaded connection' do
48
+ expect(described_class.connection_options).to include(threaded: false)
49
+ end
50
+ end
51
+
52
+ describe '#publish' do
53
+ let(:message) { 'the message' }
54
+ let(:options) { {routing_key: 'routing_key'} }
55
+
56
+ it 'publishes the message as mandatory and persistent' do
57
+ expect(bunny_exchange).to receive(:publish).with(message, { persistent: true, mandatory: true, routing_key: 'routing_key' })
58
+ described_class.publish message, options
59
+ end
60
+
61
+ it 'retries on closed connections' do
62
+ expect(described_class).to receive(:retry_on_closed_connection).and_call_original
63
+ described_class.publish message, options
64
+ end
65
+
66
+ it 'retries on exception' do
67
+ expect(described_class).to receive(:retry_on_exception).twice.and_call_original
68
+ described_class.publish message, options
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,57 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ describe Producer do
5
+ describe '.publish' do
6
+ let(:event_name) { 'event_name' }
7
+ before do
8
+ RabbitFeed::Producer.stub!
9
+ EventDefinitions do
10
+ define_event('event_name', version: '1.0.0') do
11
+ defined_as do
12
+ 'The definition of the event'
13
+ end
14
+ payload_contains do
15
+ field('field', type: 'string', definition: 'The definition of the field')
16
+ end
17
+ end
18
+ end
19
+ end
20
+ subject{ RabbitFeed::Producer.publish_event event_name, { 'field' => 'value' } }
21
+
22
+ context 'when event definitions are not set' do
23
+ before{ RabbitFeed::Producer.event_definitions = nil }
24
+
25
+ it 'raises an error' do
26
+ expect{ subject }.to raise_error Error
27
+ end
28
+ end
29
+
30
+ context 'when no event definition is found' do
31
+ let(:event_name) { 'different event name' }
32
+
33
+ it 'raises an error' do
34
+ expect{ subject }.to raise_error Error
35
+ end
36
+ end
37
+
38
+ it 'returns the event' do
39
+ expect(subject).to be_a Event
40
+ end
41
+
42
+ it 'serializes the event and provides message metadata' do
43
+ Timecop.freeze do
44
+ expect(ProducerConnection).to receive(:publish).with(
45
+ an_instance_of(String),
46
+ {
47
+ routing_key: 'test.rabbit_feed.event_name',
48
+ type: 'event_name',
49
+ app_id: 'rabbit_feed',
50
+ timestamp: Time.now.utc.to_i,
51
+ })
52
+ subject
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ module RabbitFeed
4
+ module TestingSupport
5
+ module RSpecMatchers
6
+ describe PublishEvent do
7
+ let(:event_name) { 'test_event' }
8
+ let(:event_payload) { {'field' => 'value'} }
9
+ before do
10
+ EventDefinitions do
11
+ define_event('test_event', version: '1.0.0') do
12
+ defined_as do
13
+ 'The definition of a test event'
14
+ end
15
+ field('field', type: 'string', definition: 'field definition')
16
+ end
17
+ define_event('different name', version: '1.0.0') do
18
+ defined_as do
19
+ 'The definition of a test event with a different name'
20
+ end
21
+ end
22
+ end
23
+ end
24
+
25
+ context 'when the expectation is met' do
26
+
27
+ it 'validates' do
28
+ expect {
29
+ RabbitFeed::Producer.publish_event event_name, event_payload
30
+ }.to publish_event(event_name, event_payload)
31
+ end
32
+
33
+ it 'validates the negation' do
34
+ expect {
35
+ RabbitFeed::Producer.publish_event 'different name', {}
36
+ }.to_not publish_event(event_name, {})
37
+ end
38
+
39
+ it 'traps exceptions' do
40
+ expect {
41
+ raise 'this hurts me more than it hurts you'
42
+ }.to_not publish_event(event_name, {})
43
+ end
44
+ end
45
+
46
+ it 'validates the event name' do
47
+ matcher = described_class.new(event_name, {})
48
+ block = Proc.new { RabbitFeed::Producer.publish_event 'different name', {} }
49
+ (matcher.matches? block).should be_false
50
+ end
51
+
52
+ it 'validates the event payload' do
53
+ matcher = described_class.new(event_name, event_payload)
54
+ block = Proc.new { RabbitFeed::Producer.publish_event event_name, {'field' => 'different value'} }
55
+ (matcher.matches? block).should be_false
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end