dispatch-rider 1.5.3 → 1.6.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/lib/dispatch-rider.rb +1 -0
  4. data/lib/dispatch-rider/configuration.rb +12 -5
  5. data/lib/dispatch-rider/demultiplexer.rb +3 -27
  6. data/lib/dispatch-rider/logging.rb +10 -0
  7. data/lib/dispatch-rider/logging/base_formatter.rb +30 -0
  8. data/lib/dispatch-rider/logging/json_formatter.rb +75 -0
  9. data/lib/dispatch-rider/logging/lifecycle_logger.rb +53 -0
  10. data/lib/dispatch-rider/logging/text_formatter.rb +48 -0
  11. data/lib/dispatch-rider/queue_services/file_system/queue.rb +13 -2
  12. data/lib/dispatch-rider/version.rb +1 -1
  13. data/spec/lib/dispatch-rider/airbrake_error_handler_spec.rb +10 -3
  14. data/spec/lib/dispatch-rider/callbacks/access_spec.rb +16 -18
  15. data/spec/lib/dispatch-rider/callbacks/storage_spec.rb +4 -9
  16. data/spec/lib/dispatch-rider/configuration_spec.rb +3 -3
  17. data/spec/lib/dispatch-rider/default_error_handler_spec.rb +2 -2
  18. data/spec/lib/dispatch-rider/demultiplexer_spec.rb +14 -14
  19. data/spec/lib/dispatch-rider/dispatcher_spec.rb +10 -8
  20. data/spec/lib/dispatch-rider/handlers/base_spec.rb +27 -22
  21. data/spec/lib/dispatch-rider/handlers/inheritance_tracking_spec.rb +6 -6
  22. data/spec/lib/dispatch-rider/logging/json_formatter_spec.rb +72 -0
  23. data/spec/lib/dispatch-rider/logging/lifecycle_logger_spec.rb +73 -0
  24. data/spec/lib/dispatch-rider/logging/text_formatter_spec.rb +61 -0
  25. data/spec/lib/dispatch-rider/message_spec.rb +11 -11
  26. data/spec/lib/dispatch-rider/notification_services/aws_sns_spec.rb +14 -13
  27. data/spec/lib/dispatch-rider/notification_services/base_spec.rb +18 -13
  28. data/spec/lib/dispatch-rider/notification_services/file_system/channel_spec.rb +2 -3
  29. data/spec/lib/dispatch-rider/notification_services/file_system/notifier_spec.rb +1 -3
  30. data/spec/lib/dispatch-rider/notification_services/file_system_spec.rb +3 -4
  31. data/spec/lib/dispatch-rider/publisher/configuration/destination_spec.rb +30 -21
  32. data/spec/lib/dispatch-rider/publisher/configuration/notification_service_spec.rb +22 -16
  33. data/spec/lib/dispatch-rider/publisher/configuration_reader_spec.rb +11 -10
  34. data/spec/lib/dispatch-rider/publisher/configuration_spec.rb +12 -12
  35. data/spec/lib/dispatch-rider/publisher/configuration_support_spec.rb +11 -11
  36. data/spec/lib/dispatch-rider/publisher_spec.rb +22 -15
  37. data/spec/lib/dispatch-rider/queue_services/aws_sqs_spec.rb +44 -36
  38. data/spec/lib/dispatch-rider/queue_services/base_spec.rb +41 -28
  39. data/spec/lib/dispatch-rider/queue_services/file_system_spec.rb +15 -14
  40. data/spec/lib/dispatch-rider/queue_services/received_message_spec.rb +3 -3
  41. data/spec/lib/dispatch-rider/queue_services/simple_spec.rb +9 -9
  42. data/spec/lib/dispatch-rider/registrars/base_spec.rb +5 -5
  43. data/spec/lib/dispatch-rider/registrars/file_system_channel_spec.rb +3 -3
  44. data/spec/lib/dispatch-rider/registrars/handler_spec.rb +1 -1
  45. data/spec/lib/dispatch-rider/registrars/notification_service_spec.rb +1 -1
  46. data/spec/lib/dispatch-rider/registrars/publishing_destination_spec.rb +2 -2
  47. data/spec/lib/dispatch-rider/registrars/queue_service_spec.rb +1 -1
  48. data/spec/lib/dispatch-rider/registrars/sns_channel_spec.rb +5 -5
  49. data/spec/lib/dispatch-rider/runner_spec.rb +1 -1
  50. data/spec/lib/dispatch-rider/subscriber_spec.rb +45 -29
  51. data/spec/lib/dispatch-rider_spec.rb +3 -3
  52. data/spec/spec_helper.rb +3 -1
  53. metadata +13 -2
@@ -1,11 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe DispatchRider::Callbacks::Storage do
4
-
5
- subject{ described_class.new }
4
+ subject { described_class.new }
6
5
 
7
6
  describe "adding callbacks" do
8
-
9
7
  let!(:log) { [] }
10
8
  let(:actual) { proc { log << :actual } }
11
9
 
@@ -17,7 +15,7 @@ describe DispatchRider::Callbacks::Storage do
17
15
  log << :aafter
18
16
  end
19
17
  subject.for(:initialize).first[actual]
20
- log.should == [:abefore, :actual, :aafter]
18
+ expect(log).to eq [:abefore, :actual, :aafter]
21
19
  end
22
20
  end
23
21
 
@@ -25,7 +23,7 @@ describe DispatchRider::Callbacks::Storage do
25
23
  example do
26
24
  subject.before(:initialize) { log << :before }
27
25
  subject.for(:initialize).first[actual]
28
- log.should == [:before, :actual]
26
+ expect(log).to eq [:before, :actual]
29
27
  end
30
28
  end
31
29
 
@@ -33,11 +31,8 @@ describe DispatchRider::Callbacks::Storage do
33
31
  example do
34
32
  subject.after(:initialize) { log << :after }
35
33
  subject.for(:initialize).first[actual]
36
- log.should == [:actual, :after]
34
+ expect(log).to eq [:actual, :after]
37
35
  end
38
36
  end
39
-
40
37
  end
41
-
42
-
43
38
  end
@@ -2,14 +2,14 @@ require 'spec_helper'
2
2
 
3
3
  describe DispatchRider::Configuration do
4
4
 
5
- subject{ described_class.new }
5
+ subject { described_class.new }
6
6
 
7
7
  describe "defaults" do
8
8
  example do
9
9
  expect(subject.handler_path).to match_regex(/\/app\/handlers/)
10
10
  expect(subject.error_handler).to eq DispatchRider::DefaultErrorHandler
11
11
  expect(subject.queue_kind).to eq :file_system
12
- expect(subject.queue_info).to eq({ path: "tmp/dispatch-rider-queue" })
12
+ expect(subject.queue_info).to eq(path: "tmp/dispatch-rider-queue")
13
13
  expect(subject.subscriber).to eq DispatchRider::Subscriber
14
14
  end
15
15
  end
@@ -47,7 +47,7 @@ describe DispatchRider::Configuration do
47
47
  subject.default_retry_timeout = 60
48
48
  expect(TestHandler.instance_methods).to include(:retry_timeout)
49
49
  #Need to do this so that all the other tests don't have this as default!
50
- DispatchRider::Handlers::Base.send(:remove_method,:retry_timeout)
50
+ DispatchRider::Handlers::Base.send(:remove_method, :retry_timeout)
51
51
  end
52
52
  end
53
53
 
@@ -3,9 +3,9 @@ require "spec_helper"
3
3
  describe DispatchRider::DefaultErrorHandler do
4
4
 
5
5
  describe ".call" do
6
- let(:exception){ Exception.new("Something went terribly wrong") }
6
+ let(:exception) { Exception.new("Something went terribly wrong") }
7
7
  example do
8
- expect{
8
+ expect {
9
9
  described_class.call("Error", exception)
10
10
  }.to raise_exception exception
11
11
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe DispatchRider::Demultiplexer, :nodb => true do
3
+ describe DispatchRider::Demultiplexer, nodb: true do
4
4
  class TestHandler < DispatchRider::Handlers::Base
5
5
  def process(options)
6
6
  raise "OMG!!!" if options["raise_exception"]
@@ -17,7 +17,7 @@ describe DispatchRider::Demultiplexer, :nodb => true do
17
17
  DispatchRider::QueueServices::Simple.new
18
18
  end
19
19
 
20
- let(:message){ DispatchRider::Message.new(:subject => "test_handler", :body => {}) }
20
+ let(:message) { DispatchRider::Message.new(subject: "test_handler", body: {}) }
21
21
 
22
22
  let(:demultiplexer_thread) do
23
23
  demultiplexer
@@ -28,17 +28,17 @@ describe DispatchRider::Demultiplexer, :nodb => true do
28
28
  thread
29
29
  end
30
30
 
31
- let(:error_handler){ ->(message, exception){ raise exception }}
31
+ let(:error_handler) { ->(_message, exception) { raise exception } }
32
32
 
33
33
  subject(:demultiplexer) { DispatchRider::Demultiplexer.new(queue, dispatcher, error_handler) }
34
34
 
35
35
  describe "#initialize" do
36
36
  it "should assign the queue" do
37
- demultiplexer.queue.should be_empty
37
+ expect(demultiplexer.queue).to be_empty
38
38
  end
39
39
 
40
40
  it "should assign the dispatcher" do
41
- demultiplexer.dispatcher.fetch(:test_handler).should eq(TestHandler)
41
+ expect(demultiplexer.dispatcher.fetch(:test_handler)).to eq(TestHandler)
42
42
  end
43
43
  end
44
44
 
@@ -55,7 +55,7 @@ describe DispatchRider::Demultiplexer, :nodb => true do
55
55
  end
56
56
 
57
57
  it "should be sending the message to the dispatcher" do
58
- demultiplexer.should_receive(:dispatch_message).with(message).at_least(:once)
58
+ expect(demultiplexer).to receive(:dispatch_message).with(message).at_least(:once)
59
59
  demultiplexer_thread.run
60
60
  sleep 0.01 # give it a chance to process the job async before killing the demux
61
61
  end
@@ -63,7 +63,7 @@ describe DispatchRider::Demultiplexer, :nodb => true do
63
63
  # THIS ALSO TESTS THAT THE JOB IS NOT RUN MULTIPLE TIMES
64
64
  # IF THIS FAILS, BE CAREFUL NOT TO INTRODUCE BUGS
65
65
  it "should call the correct handler" do
66
- TestHandler.any_instance.should_receive(:process).with(message.body).at_least(1).times
66
+ expect_any_instance_of(TestHandler).to receive(:process).with(message.body).at_least(1).times
67
67
  demultiplexer_thread.run
68
68
  sleep 0.01 # give it a chance to process the job async before killing the demux
69
69
  end
@@ -71,7 +71,7 @@ describe DispatchRider::Demultiplexer, :nodb => true do
71
71
 
72
72
  context "when the queue is empty" do
73
73
  it "should not be sending any message to the dispatcher" do
74
- demultiplexer.should_receive(:dispatch_message).exactly(0).times
74
+ expect(demultiplexer).to receive(:dispatch_message).exactly(0).times
75
75
  demultiplexer_thread.run
76
76
  end
77
77
  end
@@ -83,8 +83,8 @@ describe DispatchRider::Demultiplexer, :nodb => true do
83
83
  end
84
84
 
85
85
  it "should call the error handler" do
86
- error_handler.should_receive(:call).at_least(:once).and_return(true)
87
- queue.should_not_receive(:delete)
86
+ expect(error_handler).to receive(:call).at_least(:once).and_return(true)
87
+ expect(queue).not_to receive(:delete)
88
88
  demultiplexer_thread.run
89
89
  sleep 0.01 # give it a chance to process the job async before killing the demux
90
90
  end
@@ -92,11 +92,11 @@ describe DispatchRider::Demultiplexer, :nodb => true do
92
92
 
93
93
  context "when the queue crashes" do
94
94
  before do
95
- queue.stub(:pop){ raise "OMG!!!"}
95
+ allow(queue).to receive(:pop) { raise "OMG!!!" }
96
96
  end
97
97
 
98
98
  it "should call the error handler" do
99
- error_handler.should_receive(:call).once
99
+ expect(error_handler).to receive(:call).once
100
100
  demultiplexer_thread.run
101
101
 
102
102
  sleep 0.01 # give it a chance to process the job async before killing the demux
@@ -107,10 +107,10 @@ describe DispatchRider::Demultiplexer, :nodb => true do
107
107
  describe ".stop" do
108
108
  it "should stop the demultiplexer" do
109
109
  demultiplexer_thread.run
110
- demultiplexer_thread.should be_alive # looper should be looping
110
+ expect(demultiplexer_thread).to be_alive # looper should be looping
111
111
  demultiplexer_thread[:demultiplexer].stop
112
112
  demultiplexer_thread.join
113
- demultiplexer_thread.should_not be_alive # looper should close the loop
113
+ expect(demultiplexer_thread).not_to be_alive # looper should close the loop
114
114
  end
115
115
  end
116
116
 
@@ -8,21 +8,21 @@ describe DispatchRider::Dispatcher, :nodb => true do
8
8
  end
9
9
 
10
10
  class HandlerThatReturnsFalse < DispatchRider::Handlers::Base
11
- def process(params)
11
+ def process(_params)
12
12
  false
13
13
  end
14
14
  end
15
15
 
16
16
  describe "#dispatch" do
17
- let(:message){ DispatchRider::Message.new(:subject => "handle_something", :body => { :do_throw_something => true }) }
17
+ let(:message) { DispatchRider::Message.new(subject: "handle_something", body: { do_throw_something: true }) }
18
18
 
19
19
  describe "callbacks" do
20
20
  let(:dummy) { double(:dummy) }
21
21
  let(:storage) { DispatchRider::Callbacks::Storage.new }
22
- let(:message){ DispatchRider::Message.new(:subject => "handle_something", :body => { :do_throw_something => true }) }
22
+ let(:message) { DispatchRider::Message.new(subject: "handle_something", body: { do_throw_something: true }) }
23
23
 
24
24
  before do
25
- DispatchRider.config.stub(:callbacks) { storage }
25
+ allow(DispatchRider.config).to receive(:callbacks) { storage }
26
26
  storage.around(:dispatch_message) do |block, message|
27
27
  begin
28
28
  dummy.before
@@ -35,9 +35,9 @@ describe DispatchRider::Dispatcher, :nodb => true do
35
35
  subject.register('handle_something')
36
36
  end
37
37
  example do
38
- dummy.should_receive(:before).once
39
- dummy.should_receive(:after).once
40
- dummy.should_receive(:log).with(message).once
38
+ expect(dummy).to receive(:before).once
39
+ expect(dummy).to receive(:after).once
40
+ expect(dummy).to receive(:log).with(message).once
41
41
  catch(:something) do
42
42
  subject.dispatch(message)
43
43
  end
@@ -55,7 +55,9 @@ describe DispatchRider::Dispatcher, :nodb => true do
55
55
  end
56
56
 
57
57
  context "when the handler returns false" do
58
- let(:message){ DispatchRider::Message.new(:subject => "handler_that_returns_false", :body => { :do_throw_something => true }) }
58
+ let(:message) do
59
+ DispatchRider::Message.new(subject: "handler_that_returns_false", body: { do_throw_something: true })
60
+ end
59
61
 
60
62
  before :each do
61
63
  subject.register('handler_that_returns_false')
@@ -5,32 +5,38 @@ describe DispatchRider::Handlers::Base do
5
5
  end
6
6
 
7
7
  class ProcessImplemented < DispatchRider::Handlers::Base
8
- def process(options)
8
+ def process(_options)
9
9
  "good job"
10
10
  end
11
11
  end
12
-
12
+
13
13
  class ProcessWithImmediateRetry < DispatchRider::Handlers::Base
14
- def process(options)
14
+ def process(_options)
15
15
  raise "I have failed!"
16
16
  end
17
-
18
- def retry_timeout; :immediate; end
17
+
18
+ def retry_timeout
19
+ :immediate
20
+ end
19
21
  end
20
-
22
+
21
23
  class ProcessWithTenSecondRetry < DispatchRider::Handlers::Base
22
- def process(options)
24
+ def process(_options)
23
25
  raise "I have failed!"
24
26
  end
25
-
26
- def retry_timeout; 10*60; end
27
+
28
+ def retry_timeout
29
+ 10 * 60
30
+ end
27
31
  end
28
32
 
29
33
  describe "#do_process" do
30
- let(:message){ double(:message, subject: 'some_message', body: { 'guid' => DispatchRider::Debug::PUBLISHER_MESSAGE_GUID }) }
34
+ let(:message) do
35
+ double(:message, subject: 'some_message', body: { 'guid' => DispatchRider::Debug::PUBLISHER_MESSAGE_GUID })
36
+ end
31
37
 
32
38
  context "when class doesn't implement process" do
33
- let(:handler){ NoProcessImplemented.new }
39
+ let(:handler) { NoProcessImplemented.new }
34
40
 
35
41
  example do
36
42
  expect {
@@ -40,7 +46,7 @@ describe DispatchRider::Handlers::Base do
40
46
  end
41
47
 
42
48
  context "when the class does implement process" do
43
- let(:handler){ ProcessImplemented.new }
49
+ let(:handler) { ProcessImplemented.new }
44
50
 
45
51
  example do
46
52
  expect {
@@ -49,33 +55,32 @@ describe DispatchRider::Handlers::Base do
49
55
  end
50
56
 
51
57
  example do
52
- handler.do_process(message).should == "good job"
58
+ expect(handler.do_process(message)).to eq("good job")
53
59
  end
54
60
  end
55
-
61
+
56
62
  context "when the class wants to immediately retry" do
57
63
  let(:handler) { ProcessWithImmediateRetry.new }
58
-
64
+
59
65
  example do
60
- message.should_receive(:return_to_queue)
61
-
66
+ expect(message).to receive(:return_to_queue)
67
+
62
68
  expect {
63
69
  handler.do_process(message)
64
70
  }.to raise_exception "I have failed!"
65
71
  end
66
72
  end
67
-
73
+
68
74
  context "when the class wants to retry in 10 seconds" do
69
75
  let(:handler) { ProcessWithTenSecondRetry.new }
70
-
76
+
71
77
  example do
72
- message.should_receive(:extend_timeout).with(10*60)
73
-
78
+ expect(message).to receive(:extend_timeout).with(10 * 60)
79
+
74
80
  expect {
75
81
  handler.do_process(message)
76
82
  }.to raise_exception "I have failed!"
77
83
  end
78
84
  end
79
85
  end
80
-
81
86
  end
@@ -1,27 +1,27 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe DispatchRider::Handlers::InheritanceTracking do
4
-
5
4
  class InheritanceDummyClass
6
5
  extend DispatchRider::Handlers::InheritanceTracking
7
6
  end
8
7
 
9
8
  describe ".subclasses" do
10
9
  context "when a class inherits from the dummy class" do
11
- class Blah < InheritanceDummyClass; end
10
+ class Blah < InheritanceDummyClass
11
+ end
12
12
 
13
13
  example do
14
- InheritanceDummyClass.subclasses.should include(Blah)
14
+ expect(InheritanceDummyClass.subclasses).to include(Blah)
15
15
  end
16
16
 
17
17
  context "and another class inherits from the dummy class" do
18
- class Foo < InheritanceDummyClass; end
18
+ class Foo < InheritanceDummyClass
19
+ end
19
20
 
20
21
  example do
21
- InheritanceDummyClass.subclasses.should include(Blah, Foo)
22
+ expect(InheritanceDummyClass.subclasses).to include(Blah, Foo)
22
23
  end
23
24
  end
24
25
  end
25
26
  end
26
-
27
27
  end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+
3
+ describe DispatchRider::Logging::JsonFormatter do
4
+ let(:fs_message) { DispatchRider::Message.new(subject: 'test', body: { 'key' => 'value', 'guid' => 123 }) }
5
+ let(:item) { double :item }
6
+ let(:queue) { double :queue }
7
+ let(:message) { DispatchRider::QueueServices::FileSystem::FsReceivedMessage.new(fs_message, item, queue) }
8
+ let(:exception) { StandardError.new }
9
+ let(:reason) { "Stop reason" }
10
+
11
+ let(:result_object) do
12
+ {
13
+ "subject" => "test",
14
+ "guid" => "123",
15
+ "body" => {
16
+ "key" => "value"
17
+ },
18
+ }
19
+ end
20
+ let(:result_exception) do
21
+ {
22
+ "expection" => {
23
+ "class" => "StandardError",
24
+ "message" => "StandardError"
25
+ }
26
+ }
27
+ end
28
+
29
+ context "format_error_handler_fail" do
30
+ let(:formatted_message) { result_object.merge("phase" => "failed").merge(result_exception) }
31
+ let(:result_message) { JSON.parse subject.format_error_handler_fail(message, exception) }
32
+
33
+ example { expect(result_message).to eq(formatted_message) }
34
+ end
35
+
36
+ context "format_got_stop" do
37
+ let(:formatted_message) { result_object.merge("phase" => "stop", "reason" => reason) }
38
+ let(:result_message) { JSON.parse subject.format_got_stop(message, reason) }
39
+
40
+ example { expect(result_message).to eq(formatted_message) }
41
+ end
42
+
43
+ context "format_handling" do
44
+ context "start" do
45
+ let(:formatted_message) { result_object.merge("phase" => "start") }
46
+ let(:result_message) { JSON.parse subject.format_handling(:start, message) }
47
+
48
+ example { expect(result_message).to eq(formatted_message) }
49
+ end
50
+
51
+ context "success" do
52
+ let(:formatted_message) { result_object.merge("phase" => "success") }
53
+ let(:result_message) { JSON.parse subject.format_handling(:success, message) }
54
+
55
+ example { expect(result_message).to eq(formatted_message) }
56
+ end
57
+
58
+ context "complete" do
59
+ let(:formatted_message) { result_object.merge("phase" => "complete", "duration" => "2.00") }
60
+ let(:result_message) { JSON.parse subject.format_handling(:complete, message, duration: 2.0) }
61
+
62
+ example { expect(result_message).to eq(formatted_message) }
63
+ end
64
+
65
+ context "fail" do
66
+ let(:formatted_message) { result_object.merge("phase" => "fail").merge(result_exception) }
67
+ let(:result_message) { JSON.parse subject.format_handling(:fail, message, exception: exception) }
68
+
69
+ example { expect(formatted_message).to eq(formatted_message) }
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe DispatchRider::Logging::LifecycleLogger do
4
+ subject { DispatchRider::Logging::LifecycleLogger }
5
+
6
+ let(:message) { DispatchRider::Message.new(subject: 'test', body: 'test_handler') }
7
+ let(:string_to_log) { "string to log" }
8
+ let(:exception) { StandardError.new }
9
+ let(:reason) { "Stop reason" }
10
+
11
+ let(:formatter) { DispatchRider.config.log_formatter }
12
+ let(:logger) { DispatchRider.config.logger }
13
+
14
+ before do
15
+ allow(formatter).to receive(:format_got_stop).and_return(string_to_log)
16
+ allow(formatter).to receive(:format_error_handler_fail).and_return(string_to_log)
17
+ allow(formatter).to receive(:format_handling).and_return(string_to_log)
18
+ end
19
+
20
+ context "log_error_handler_fail" do
21
+ after { subject.log_error_handler_fail message, exception }
22
+
23
+ it "calls logger with error" do
24
+ expect(logger).to receive(:error).with(string_to_log)
25
+ end
26
+ end
27
+
28
+ context "log_got_stop" do
29
+ after { subject.log_got_stop reason, message }
30
+
31
+ it "calls logger with info" do
32
+ expect(logger).to receive(:info).with(string_to_log)
33
+ end
34
+ end
35
+
36
+ context "wrap_handling" do
37
+ context "block runs successfully" do
38
+ let(:block) { Proc.new { true } }
39
+ after { subject.wrap_handling(message, &block) }
40
+
41
+ it "logs start" do
42
+ expect(subject).to receive(:log_start).with(message)
43
+ end
44
+
45
+ it "logs success" do
46
+ expect(subject).to receive(:log_success).with(message)
47
+ end
48
+
49
+ it "logs complete" do
50
+ expect(subject).to receive(:log_complete).with(message, an_instance_of(Float))
51
+ end
52
+ end
53
+
54
+ context "block fails" do
55
+ let(:block) { Proc.new { raise exception } }
56
+ after do
57
+ expect { subject.wrap_handling(message, &block) }.to raise_error(exception)
58
+ end
59
+
60
+ it "logs start" do
61
+ expect(subject).to receive(:log_start).with(message)
62
+ end
63
+
64
+ it "logs fail" do
65
+ expect(subject).to receive(:log_fail).with(message, exception)
66
+ end
67
+
68
+ it "logs complete" do
69
+ expect(subject).to receive(:log_complete).with(message, an_instance_of(Float))
70
+ end
71
+ end
72
+ end
73
+ end