honeybadger 1.11.2 → 1.12.0.beta2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Appraisals +56 -46
- data/CHANGELOG.md +33 -0
- data/Gemfile.lock +1 -1
- data/MIT-LICENSE +2 -1
- data/Rakefile +3 -1
- data/features/standalone.feature +73 -0
- data/features/step_definitions/rack_steps.rb +1 -2
- data/features/step_definitions/standalone_steps.rb +12 -0
- data/features/support/env.rb +2 -0
- data/gemfiles/binding_of_caller.gemfile +8 -0
- data/gemfiles/rails.gemfile +11 -0
- data/gemfiles/standalone.gemfile +7 -0
- data/honeybadger.gemspec +22 -11
- data/lib/honeybadger.rb +15 -9
- data/lib/honeybadger/configuration.rb +9 -4
- data/lib/honeybadger/dependency.rb +65 -0
- data/lib/honeybadger/exception_extensions.rb +35 -0
- data/lib/honeybadger/integrations.rb +4 -0
- data/lib/honeybadger/integrations/delayed_job.rb +20 -0
- data/lib/honeybadger/integrations/delayed_job/plugin.rb +31 -0
- data/lib/honeybadger/integrations/sidekiq.rb +34 -0
- data/lib/honeybadger/notice.rb +48 -11
- data/lib/honeybadger/payload.rb +29 -0
- data/lib/honeybadger/rack.rb +8 -54
- data/lib/honeybadger/rack/error_notifier.rb +60 -0
- data/lib/honeybadger/rack/user_feedback.rb +74 -0
- data/lib/honeybadger/rack/user_informer.rb +28 -0
- data/lib/honeybadger/rails.rb +5 -4
- data/lib/honeybadger/railtie.rb +4 -3
- data/lib/honeybadger/user_feedback.rb +3 -67
- data/lib/honeybadger/user_informer.rb +3 -21
- data/spec/honeybadger/configuration_spec.rb +5 -1
- data/spec/honeybadger/dependency_spec.rb +134 -0
- data/spec/honeybadger/exception_extensions_spec.rb +40 -0
- data/spec/honeybadger/integrations/delayed_job_spec.rb +48 -0
- data/spec/honeybadger/integrations/sidekiq_spec.rb +60 -0
- data/spec/honeybadger/notice_spec.rb +176 -35
- data/spec/honeybadger/payload_spec.rb +27 -0
- data/spec/honeybadger/rails_spec.rb +4 -2
- metadata +24 -13
- data/gemfiles/rack.gemfile.lock +0 -125
- data/gemfiles/rails2.3.gemfile.lock +0 -141
- data/gemfiles/rails3.0.gemfile.lock +0 -193
- data/gemfiles/rails3.1.gemfile.lock +0 -203
- data/gemfiles/rails3.2.gemfile.lock +0 -201
- data/gemfiles/rails4.0.gemfile.lock +0 -197
- data/gemfiles/rails4.1.gemfile.lock +0 -202
- data/gemfiles/rake.gemfile.lock +0 -124
- data/gemfiles/sinatra.gemfile.lock +0 -124
data/lib/honeybadger/rack.rb
CHANGED
@@ -1,58 +1,12 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
#
|
5
|
-
# Synopsis:
|
6
|
-
#
|
7
|
-
# require 'rack'
|
8
|
-
# require 'honeybadger'
|
9
|
-
#
|
10
|
-
# Honeybadger.configure do |config|
|
11
|
-
# config.api_key = 'my_api_key'
|
12
|
-
# end
|
13
|
-
#
|
14
|
-
# app = Rack::Builder.app do
|
15
|
-
# run lambda { |env| raise "Rack down" }
|
16
|
-
# end
|
17
|
-
#
|
18
|
-
# use Honeybadger::Rack
|
19
|
-
# run app
|
20
|
-
#
|
21
|
-
# Use a standard Honeybadger.configure call to configure your api key.
|
22
|
-
class Rack
|
23
|
-
def initialize(app)
|
24
|
-
@app = app
|
25
|
-
Honeybadger.configuration.framework = "Rack: #{::Rack.release}"
|
26
|
-
end
|
1
|
+
require 'honeybadger/rack/error_notifier'
|
2
|
+
require 'honeybadger/rack/user_informer'
|
3
|
+
require 'honeybadger/rack/user_feedback'
|
27
4
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
any? { |ua| ua === env['HTTP_USER_AGENT'] }
|
34
|
-
end
|
35
|
-
|
36
|
-
def notify_honeybadger(exception,env)
|
37
|
-
Honeybadger.notify_or_ignore(exception, :rack_env => env) unless ignored_user_agent?(env)
|
38
|
-
end
|
39
|
-
|
40
|
-
def call(env)
|
41
|
-
begin
|
42
|
-
response = @app.call(env)
|
43
|
-
rescue Exception => raised
|
44
|
-
env['honeybadger.error_id'] = notify_honeybadger(raised, env)
|
45
|
-
raise
|
46
|
-
ensure
|
47
|
-
Honeybadger.context.clear!
|
48
|
-
end
|
49
|
-
|
50
|
-
framework_exception = env['rack.exception'] || env['sinatra.error']
|
51
|
-
if framework_exception
|
52
|
-
env['honeybadger.error_id'] = notify_honeybadger(framework_exception, env)
|
53
|
-
end
|
54
|
-
|
55
|
-
response
|
5
|
+
module Honeybadger
|
6
|
+
module Rack
|
7
|
+
def self.new(*args, &block)
|
8
|
+
warn '[DEPRECATION] Honeybadger::Rack is deprecated in 2.0. Use Honeybadger::Rack::ErrorNotifier.'
|
9
|
+
ErrorNotifier.new(*args, &block)
|
56
10
|
end
|
57
11
|
end
|
58
12
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
module Rack
|
3
|
+
# Middleware for Rack applications. Any errors raised by the upstream
|
4
|
+
# application will be delivered to Honeybadger and re-raised.
|
5
|
+
#
|
6
|
+
# Synopsis:
|
7
|
+
#
|
8
|
+
# require 'rack'
|
9
|
+
# require 'honeybadger'
|
10
|
+
#
|
11
|
+
# Honeybadger.configure do |config|
|
12
|
+
# config.api_key = 'my_api_key'
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# app = Rack::Builder.app do
|
16
|
+
# run lambda { |env| raise "Rack down" }
|
17
|
+
# end
|
18
|
+
#
|
19
|
+
# use Honeybadger::Rack::ErrorNotifier
|
20
|
+
# run app
|
21
|
+
#
|
22
|
+
# Use a standard Honeybadger.configure call to configure your api key.
|
23
|
+
class ErrorNotifier
|
24
|
+
def initialize(app)
|
25
|
+
@app = app
|
26
|
+
Honeybadger.configuration.framework = "Rack: #{::Rack.release}"
|
27
|
+
end
|
28
|
+
|
29
|
+
def ignored_user_agent?(env)
|
30
|
+
true if Honeybadger.
|
31
|
+
configuration.
|
32
|
+
ignore_user_agent.
|
33
|
+
flatten.
|
34
|
+
any? { |ua| ua === env['HTTP_USER_AGENT'] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def notify_honeybadger(exception,env)
|
38
|
+
Honeybadger.notify_or_ignore(exception, :rack_env => env) unless ignored_user_agent?(env)
|
39
|
+
end
|
40
|
+
|
41
|
+
def call(env)
|
42
|
+
begin
|
43
|
+
response = @app.call(env)
|
44
|
+
rescue Exception => raised
|
45
|
+
env['honeybadger.error_id'] = notify_honeybadger(raised, env)
|
46
|
+
raise
|
47
|
+
ensure
|
48
|
+
Honeybadger.context.clear!
|
49
|
+
end
|
50
|
+
|
51
|
+
framework_exception = env['rack.exception'] || env['sinatra.error']
|
52
|
+
if framework_exception
|
53
|
+
env['honeybadger.error_id'] = notify_honeybadger(framework_exception, env)
|
54
|
+
end
|
55
|
+
|
56
|
+
response
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'erb'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'i18n'
|
6
|
+
rescue LoadError
|
7
|
+
module Honeybadger
|
8
|
+
module I18n
|
9
|
+
def self.t(key, options={})
|
10
|
+
options[:default]
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Honeybadger
|
17
|
+
module Rack
|
18
|
+
class UserFeedback
|
19
|
+
def initialize(app)
|
20
|
+
@app = app
|
21
|
+
end
|
22
|
+
|
23
|
+
def call(env)
|
24
|
+
status, headers, body = @app.call(env)
|
25
|
+
if enabled? && env['honeybadger.error_id'] && form = render_form(env['honeybadger.error_id'])
|
26
|
+
new_body = []
|
27
|
+
body.each do |chunk|
|
28
|
+
new_body << chunk.gsub("<!-- HONEYBADGER FEEDBACK -->", form)
|
29
|
+
end
|
30
|
+
body.close if body.respond_to?(:close)
|
31
|
+
headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
|
32
|
+
body = new_body
|
33
|
+
end
|
34
|
+
[status, headers, body]
|
35
|
+
end
|
36
|
+
|
37
|
+
def config
|
38
|
+
Honeybadger.configuration
|
39
|
+
end
|
40
|
+
|
41
|
+
def enabled?
|
42
|
+
config.feedback && config.features['feedback']
|
43
|
+
end
|
44
|
+
|
45
|
+
def action
|
46
|
+
URI.parse("#{config.protocol}://#{config.host}:#{config.port}/v1/feedback/").to_s
|
47
|
+
rescue URI::InvalidURIError
|
48
|
+
nil
|
49
|
+
end
|
50
|
+
|
51
|
+
def render_form(error_id, action = action)
|
52
|
+
return unless action
|
53
|
+
ERB.new(@template ||= File.read(template_file)).result(binding)
|
54
|
+
end
|
55
|
+
|
56
|
+
def custom_template_file
|
57
|
+
@custom_template_file ||= config.project_root &&
|
58
|
+
File.join(config.project_root, 'lib', 'honeybadger', 'templates', 'feedback_form.erb')
|
59
|
+
end
|
60
|
+
|
61
|
+
def custom_template_file?
|
62
|
+
custom_template_file && File.exists?(custom_template_file)
|
63
|
+
end
|
64
|
+
|
65
|
+
def template_file
|
66
|
+
if custom_template_file?
|
67
|
+
custom_template_file
|
68
|
+
else
|
69
|
+
File.expand_path('../../templates/feedback_form.erb', __FILE__)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Honeybadger
|
2
|
+
module Rack
|
3
|
+
class UserInformer
|
4
|
+
def initialize(app)
|
5
|
+
@app = app
|
6
|
+
end
|
7
|
+
|
8
|
+
def replacement(with)
|
9
|
+
Honeybadger.configuration.user_information.gsub(/\{\{\s*error_id\s*\}\}/, with.to_s)
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
status, headers, body = @app.call(env)
|
14
|
+
if env['honeybadger.error_id'] && Honeybadger.configuration.user_information
|
15
|
+
new_body = []
|
16
|
+
replace = replacement(env['honeybadger.error_id'])
|
17
|
+
body.each do |chunk|
|
18
|
+
new_body << chunk.gsub("<!-- HONEYBADGER ERROR -->", replace)
|
19
|
+
end
|
20
|
+
body.close if body.respond_to?(:close)
|
21
|
+
headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
|
22
|
+
body = new_body
|
23
|
+
end
|
24
|
+
[status, headers, body]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/honeybadger/rails.rb
CHANGED
@@ -18,11 +18,11 @@ module Honeybadger
|
|
18
18
|
|
19
19
|
if defined?(::Rails.configuration) && ::Rails.configuration.respond_to?(:middleware)
|
20
20
|
::Rails.configuration.middleware.insert_after 'ActionController::Failsafe',
|
21
|
-
Honeybadger::Rack
|
21
|
+
Honeybadger::Rack::ErrorNotifier
|
22
22
|
::Rails.configuration.middleware.insert_after 'Rack::Lock',
|
23
|
-
Honeybadger::UserInformer
|
24
|
-
::Rails.configuration.middleware.insert_after Honeybadger::UserInformer,
|
25
|
-
Honeybadger::UserFeedback
|
23
|
+
Honeybadger::Rack::UserInformer
|
24
|
+
::Rails.configuration.middleware.insert_after Honeybadger::Rack::UserInformer,
|
25
|
+
Honeybadger::Rack::UserFeedback
|
26
26
|
end
|
27
27
|
|
28
28
|
Honeybadger.configure(true) do |config|
|
@@ -34,6 +34,7 @@ module Honeybadger
|
|
34
34
|
|
35
35
|
if defined?(::Rails.configuration) && ::Rails.configuration.respond_to?(:after_initialize)
|
36
36
|
::Rails.configuration.after_initialize do
|
37
|
+
Honeybadger::Dependency.inject!
|
37
38
|
Honeybadger.ping(Honeybadger.configuration)
|
38
39
|
end
|
39
40
|
end
|
data/lib/honeybadger/railtie.rb
CHANGED
@@ -10,9 +10,9 @@ module Honeybadger
|
|
10
10
|
end
|
11
11
|
|
12
12
|
initializer "honeybadger.use_rack_middleware" do |app|
|
13
|
-
app.config.middleware.insert 0, "Honeybadger::UserInformer"
|
14
|
-
app.config.middleware.insert_after "Honeybadger::UserInformer","Honeybadger::UserFeedback"
|
15
|
-
app.config.middleware.insert_after "Honeybadger::UserFeedback","Honeybadger::Rack"
|
13
|
+
app.config.middleware.insert 0, "Honeybadger::Rack::UserInformer"
|
14
|
+
app.config.middleware.insert_after "Honeybadger::Rack::UserInformer","Honeybadger::Rack::UserFeedback"
|
15
|
+
app.config.middleware.insert_after "Honeybadger::Rack::UserFeedback","Honeybadger::Rack::ErrorNotifier"
|
16
16
|
end
|
17
17
|
|
18
18
|
config.after_initialize do
|
@@ -44,6 +44,7 @@ module Honeybadger
|
|
44
44
|
::ActionDispatch::ShowExceptions.send(:include,Honeybadger::Rails::Middleware::ExceptionsCatcher)
|
45
45
|
end
|
46
46
|
|
47
|
+
Honeybadger::Dependency.inject!
|
47
48
|
Honeybadger.ping(Honeybadger.configuration)
|
48
49
|
end
|
49
50
|
end
|
@@ -1,72 +1,8 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'uri'
|
3
|
-
|
4
|
-
begin
|
5
|
-
require 'i18n'
|
6
|
-
rescue LoadError
|
7
|
-
module Honeybadger
|
8
|
-
module I18n
|
9
|
-
def self.t(key, options={})
|
10
|
-
options[:default]
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
1
|
module Honeybadger
|
17
|
-
class UserFeedback
|
2
|
+
class UserFeedback < Rack::UserFeedback
|
18
3
|
def initialize(app)
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def call(env)
|
23
|
-
status, headers, body = @app.call(env)
|
24
|
-
if enabled? && env['honeybadger.error_id'] && form = render_form(env['honeybadger.error_id'])
|
25
|
-
new_body = []
|
26
|
-
body.each do |chunk|
|
27
|
-
new_body << chunk.gsub("<!-- HONEYBADGER FEEDBACK -->", form)
|
28
|
-
end
|
29
|
-
body.close if body.respond_to?(:close)
|
30
|
-
headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
|
31
|
-
body = new_body
|
32
|
-
end
|
33
|
-
[status, headers, body]
|
34
|
-
end
|
35
|
-
|
36
|
-
def config
|
37
|
-
Honeybadger.configuration
|
38
|
-
end
|
39
|
-
|
40
|
-
def enabled?
|
41
|
-
config.feedback && config.features['feedback']
|
42
|
-
end
|
43
|
-
|
44
|
-
def action
|
45
|
-
URI.parse("#{config.protocol}://#{config.host}:#{config.port}/v1/feedback/").to_s
|
46
|
-
rescue URI::InvalidURIError
|
47
|
-
nil
|
48
|
-
end
|
49
|
-
|
50
|
-
def render_form(error_id, action = action)
|
51
|
-
return unless action
|
52
|
-
ERB.new(@template ||= File.read(template_file)).result(binding)
|
53
|
-
end
|
54
|
-
|
55
|
-
def custom_template_file
|
56
|
-
@custom_template_file ||= config.project_root &&
|
57
|
-
File.join(config.project_root, 'lib', 'honeybadger', 'templates', 'feedback_form.erb')
|
58
|
-
end
|
59
|
-
|
60
|
-
def custom_template_file?
|
61
|
-
custom_template_file && File.exists?(custom_template_file)
|
62
|
-
end
|
63
|
-
|
64
|
-
def template_file
|
65
|
-
if custom_template_file?
|
66
|
-
custom_template_file
|
67
|
-
else
|
68
|
-
File.expand_path('../templates/feedback_form.erb', __FILE__)
|
69
|
-
end
|
4
|
+
warn '[DEPRECATION] Honeybadger::UserFeedback is deprecated in 2.0. Use Honeybadger::Rack::UserFeedback.'
|
5
|
+
super
|
70
6
|
end
|
71
7
|
end
|
72
8
|
end
|
@@ -1,26 +1,8 @@
|
|
1
1
|
module Honeybadger
|
2
|
-
class UserInformer
|
2
|
+
class UserInformer < Rack::UserInformer
|
3
3
|
def initialize(app)
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
def replacement(with)
|
8
|
-
Honeybadger.configuration.user_information.gsub(/\{\{\s*error_id\s*\}\}/, with.to_s)
|
9
|
-
end
|
10
|
-
|
11
|
-
def call(env)
|
12
|
-
status, headers, body = @app.call(env)
|
13
|
-
if env['honeybadger.error_id'] && Honeybadger.configuration.user_information
|
14
|
-
new_body = []
|
15
|
-
replace = replacement(env['honeybadger.error_id'])
|
16
|
-
body.each do |chunk|
|
17
|
-
new_body << chunk.gsub("<!-- HONEYBADGER ERROR -->", replace)
|
18
|
-
end
|
19
|
-
body.close if body.respond_to?(:close)
|
20
|
-
headers['Content-Length'] = new_body.reduce(0) { |a,e| a += e.bytesize }.to_s
|
21
|
-
body = new_body
|
22
|
-
end
|
23
|
-
[status, headers, body]
|
4
|
+
warn '[DEPRECATION] Honeybadger::UserInformer is deprecated in 2.0. Use Honeybadger::Rack::UserInformer.'
|
5
|
+
super
|
24
6
|
end
|
25
7
|
end
|
26
8
|
end
|
@@ -30,11 +30,13 @@ describe Honeybadger::Configuration do
|
|
30
30
|
assert_config_default :source_extract_radius, 2
|
31
31
|
assert_config_default :async, nil
|
32
32
|
assert_config_default :send_request_session, true
|
33
|
+
assert_config_default :send_local_variables, false
|
33
34
|
assert_config_default :debug, false
|
34
35
|
assert_config_default :log_exception_on_send_failure, false
|
35
36
|
assert_config_default :fingerprint, nil
|
36
37
|
assert_config_default :hostname, Socket.gethostname
|
37
38
|
assert_config_default :feedback, true
|
39
|
+
assert_config_default :features, {'notices' => true, 'local_variables' => true}
|
38
40
|
end
|
39
41
|
|
40
42
|
it "configures async as Proc" do
|
@@ -116,6 +118,7 @@ describe Honeybadger::Configuration do
|
|
116
118
|
assert_config_overridable :send_request_session
|
117
119
|
assert_config_overridable :debug
|
118
120
|
assert_config_overridable :hostname
|
121
|
+
assert_config_overridable :features
|
119
122
|
assert_config_overridable :metrics
|
120
123
|
assert_config_overridable :feedback
|
121
124
|
assert_config_overridable :log_exception_on_send_failure
|
@@ -134,7 +137,8 @@ describe Honeybadger::Configuration do
|
|
134
137
|
:notifier_version, :params_filters, :project_root, :port, :protocol,
|
135
138
|
:proxy_host, :proxy_pass, :proxy_port, :proxy_user, :secure,
|
136
139
|
:source_extract_radius, :async, :send_request_session, :debug,
|
137
|
-
:fingerprint, :hostname, :metrics, :feedback,
|
140
|
+
:fingerprint, :hostname, :features, :metrics, :feedback,
|
141
|
+
:log_exception_on_send_failure].each do |option|
|
138
142
|
expect(hash[option]).to eq config[option]
|
139
143
|
end
|
140
144
|
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Honeybadger::Dependency do
|
4
|
+
let(:dependency) { Honeybadger::Dependency.new }
|
5
|
+
subject { dependency }
|
6
|
+
|
7
|
+
before { Honeybadger::Dependency.stub(:instances).and_return([]) }
|
8
|
+
|
9
|
+
describe ".register" do
|
10
|
+
it "returns a new dependency" do
|
11
|
+
instance = double()
|
12
|
+
Honeybadger::Dependency.stub(:new).and_return(instance)
|
13
|
+
expect(Honeybadger::Dependency.register {}).to eq [instance]
|
14
|
+
end
|
15
|
+
|
16
|
+
it "registers a new dependency" do
|
17
|
+
expect { Honeybadger::Dependency.register {} }.to change(described_class, :instances).from([]).to([kind_of(Honeybadger::Dependency)])
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".inject!" do
|
22
|
+
it "injects all satisfied instances" do
|
23
|
+
Honeybadger::Dependency.instances.replace([mock_dependency, mock_dependency])
|
24
|
+
Honeybadger::Dependency.inject!
|
25
|
+
end
|
26
|
+
|
27
|
+
it "skips all unsatisfied instances" do
|
28
|
+
Honeybadger::Dependency.instances.replace([mock_dependency(false), mock_dependency(false)])
|
29
|
+
Honeybadger::Dependency.inject!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "#requirement" do
|
34
|
+
let(:block) { Proc.new {} }
|
35
|
+
|
36
|
+
it "returns and Array of requirements" do
|
37
|
+
expect(subject.requirement(&block)).to eq [block]
|
38
|
+
end
|
39
|
+
|
40
|
+
it "registers a new requirement" do
|
41
|
+
expect { subject.requirement(&block) }.to change(subject, :requirements).from([]).to([block])
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe "#injection" do
|
46
|
+
let(:block) { Proc.new {} }
|
47
|
+
|
48
|
+
it "returns an Array of injections" do
|
49
|
+
expect(subject.injection(&block)).to eq [block]
|
50
|
+
end
|
51
|
+
|
52
|
+
it "registers a new injection" do
|
53
|
+
expect { subject.injection(&block) }.to change(subject, :injections).from([]).to([block])
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe "#ok?" do
|
58
|
+
subject { dependency.ok? }
|
59
|
+
|
60
|
+
context "when not injected yet" do
|
61
|
+
it { should be_true }
|
62
|
+
end
|
63
|
+
|
64
|
+
context "when already injected" do
|
65
|
+
before { dependency.inject! }
|
66
|
+
|
67
|
+
it { should be_false }
|
68
|
+
end
|
69
|
+
|
70
|
+
context "all requirements are met" do
|
71
|
+
before do
|
72
|
+
3.times { dependency.requirement { true } }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "some requirements fail" do
|
77
|
+
before do
|
78
|
+
3.times { dependency.requirement { true } }
|
79
|
+
dependency.requirement { false }
|
80
|
+
end
|
81
|
+
|
82
|
+
it { should be_false }
|
83
|
+
end
|
84
|
+
|
85
|
+
context "some requirements error" do
|
86
|
+
before do
|
87
|
+
dependency.requirement { true }
|
88
|
+
dependency.requirement { fail 'oops!' }
|
89
|
+
end
|
90
|
+
|
91
|
+
it { should be_false }
|
92
|
+
|
93
|
+
it "logs the failure" do
|
94
|
+
Honeybadger.should_receive(:write_verbose_log).with(/oops!/, :error).once
|
95
|
+
dependency.ok?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
describe "#inject!" do
|
101
|
+
it "calls injections" do
|
102
|
+
dependency.injections.replace([mock_injection, mock_injection])
|
103
|
+
dependency.inject!
|
104
|
+
end
|
105
|
+
|
106
|
+
context "some injections fail" do
|
107
|
+
before do
|
108
|
+
failing_injection = Proc.new { fail 'oh noes!' }
|
109
|
+
dependency.injections.replace([mock_injection, failing_injection, mock_injection(false)])
|
110
|
+
end
|
111
|
+
|
112
|
+
it "halts injection silently" do
|
113
|
+
expect { dependency.inject! }.not_to raise_error
|
114
|
+
end
|
115
|
+
|
116
|
+
it "logs the failure" do
|
117
|
+
Honeybadger.should_receive(:write_verbose_log).with(/oh noes!/, :error).once
|
118
|
+
dependency.inject!
|
119
|
+
end
|
120
|
+
|
121
|
+
it "marks the dependency as injected" do
|
122
|
+
expect { dependency.inject!}.to change(dependency, :injected?).from(false).to(true)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def mock_dependency(ok = true)
|
128
|
+
double(:ok? => ok).tap { |d| d.send(ok ? :should_receive : :should_not_receive, :inject!) }
|
129
|
+
end
|
130
|
+
|
131
|
+
def mock_injection(positive = true)
|
132
|
+
double().tap { |d| d.send(positive ? :should_receive : :should_not_receive, :call) }
|
133
|
+
end
|
134
|
+
end
|