hoptoad_notifier 2.1.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.
- data/INSTALL +25 -0
- data/MIT-LICENSE +22 -0
- data/README.rdoc +221 -0
- data/Rakefile +117 -0
- data/SUPPORTED_RAILS_VERSIONS +8 -0
- data/TESTING.rdoc +8 -0
- data/generators/hoptoad/hoptoad_generator.rb +42 -0
- data/generators/hoptoad/lib/insert_commands.rb +34 -0
- data/generators/hoptoad/lib/rake_commands.rb +24 -0
- data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +5 -0
- data/generators/hoptoad/templates/initializer.rb +6 -0
- data/lib/hoptoad_notifier/backtrace.rb +99 -0
- data/lib/hoptoad_notifier/capistrano.rb +20 -0
- data/lib/hoptoad_notifier/catcher.rb +95 -0
- data/lib/hoptoad_notifier/configuration.rb +228 -0
- data/lib/hoptoad_notifier/notice.rb +295 -0
- data/lib/hoptoad_notifier/rails.rb +11 -0
- data/lib/hoptoad_notifier/rails_initializer.rb +16 -0
- data/lib/hoptoad_notifier/sender.rb +63 -0
- data/lib/hoptoad_notifier/tasks.rb +91 -0
- data/lib/hoptoad_notifier/version.rb +3 -0
- data/lib/hoptoad_notifier.rb +146 -0
- data/lib/hoptoad_tasks.rb +37 -0
- data/rails/init.rb +1 -0
- data/tasks/hoptoad_notifier_tasks.rake +89 -0
- data/test/backtrace_test.rb +118 -0
- data/test/catcher_test.rb +314 -0
- data/test/configuration_test.rb +207 -0
- data/test/helper.rb +237 -0
- data/test/hoptoad_tasks_test.rb +138 -0
- data/test/logger_test.rb +85 -0
- data/test/notice_test.rb +402 -0
- data/test/notifier_test.rb +222 -0
- data/test/rails_initializer_test.rb +35 -0
- data/test/sender_test.rb +123 -0
- metadata +99 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
module HoptoadNotifier
|
2
|
+
# Sends out the notice to Hoptoad
|
3
|
+
class Sender
|
4
|
+
|
5
|
+
NOTICES_URI = '/notifier_api/v2/notices/'.freeze
|
6
|
+
|
7
|
+
def initialize(options = {})
|
8
|
+
[:proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
|
9
|
+
:host, :port, :secure, :http_open_timeout, :http_read_timeout].each do |option|
|
10
|
+
instance_variable_set("@#{option}", options[option])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# Sends the notice data off to Hoptoad for processing.
|
15
|
+
#
|
16
|
+
# @param [String] data The XML notice to be sent off
|
17
|
+
def send_to_hoptoad(data)
|
18
|
+
logger.debug { "Sending request to #{url.to_s}:\n#{data}" } if logger
|
19
|
+
|
20
|
+
http =
|
21
|
+
Net::HTTP::Proxy(proxy_host, proxy_port, proxy_user, proxy_pass).
|
22
|
+
new(url.host, url.port)
|
23
|
+
|
24
|
+
http.read_timeout = http_read_timeout
|
25
|
+
http.open_timeout = http_open_timeout
|
26
|
+
http.use_ssl = secure
|
27
|
+
|
28
|
+
response = begin
|
29
|
+
http.post(url.path, data, HEADERS)
|
30
|
+
rescue TimeoutError => e
|
31
|
+
log :error, "Timeout while contacting the Hoptoad server."
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
|
35
|
+
case response
|
36
|
+
when Net::HTTPSuccess then
|
37
|
+
log :info, "Success: #{response.class}", response
|
38
|
+
else
|
39
|
+
log :error, "Failure: #{response.class}", response
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
attr_reader :proxy_host, :proxy_port, :proxy_user, :proxy_pass, :protocol,
|
46
|
+
:host, :port, :secure, :http_open_timeout, :http_read_timeout
|
47
|
+
|
48
|
+
def url
|
49
|
+
URI.parse("#{protocol}://#{host}:#{port}").merge(NOTICES_URI)
|
50
|
+
end
|
51
|
+
|
52
|
+
def log(level, message, response = nil)
|
53
|
+
logger.send level, LOG_PREFIX + message if logger
|
54
|
+
HoptoadNotifier.report_environment_info
|
55
|
+
HoptoadNotifier.report_response_body(response.body) if response && response.respond_to?(:body)
|
56
|
+
end
|
57
|
+
|
58
|
+
def logger
|
59
|
+
HoptoadNotifier.logger
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'hoptoad_notifier'
|
2
|
+
|
3
|
+
namespace :hoptoad do
|
4
|
+
desc "Notify Hoptoad of a new deploy."
|
5
|
+
task :deploy => :environment do
|
6
|
+
require 'hoptoad_tasks'
|
7
|
+
HoptoadTasks.deploy(:rails_env => ENV['TO'],
|
8
|
+
:scm_revision => ENV['REVISION'],
|
9
|
+
:scm_repository => ENV['REPO'],
|
10
|
+
:local_username => ENV['USER'],
|
11
|
+
:api_key => ENV['API_KEY'])
|
12
|
+
end
|
13
|
+
|
14
|
+
task :log_stdout do
|
15
|
+
require 'logger'
|
16
|
+
RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
|
17
|
+
end
|
18
|
+
|
19
|
+
desc "Verify your gem installation by sending a test exception to the hoptoad service"
|
20
|
+
task :test => ['hoptoad:log_stdout', :environment] do
|
21
|
+
RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
|
22
|
+
|
23
|
+
require 'action_controller/test_process'
|
24
|
+
require 'app/controllers/application' if File.exists?('app/controllers/application.rb')
|
25
|
+
|
26
|
+
request = ActionController::TestRequest.new
|
27
|
+
response = ActionController::TestResponse.new
|
28
|
+
|
29
|
+
class HoptoadTestingException < RuntimeError; end
|
30
|
+
|
31
|
+
unless HoptoadNotifier.configuration.api_key
|
32
|
+
puts "Hoptoad needs an API key configured! Check the README to see how to add it."
|
33
|
+
exit
|
34
|
+
end
|
35
|
+
|
36
|
+
HoptoadNotifier.configuration.development_environments = []
|
37
|
+
|
38
|
+
in_controller = ApplicationController.included_modules.include? HoptoadNotifier::Catcher
|
39
|
+
in_base = ActionController::Base.included_modules.include? HoptoadNotifier::Catcher
|
40
|
+
if !in_controller || !in_base
|
41
|
+
puts "HoptoadNotifier::Catcher must be included inside your ApplicationController class."
|
42
|
+
exit
|
43
|
+
end
|
44
|
+
|
45
|
+
puts "Configuration:"
|
46
|
+
HoptoadNotifier.configuration.to_hash.each do |key, value|
|
47
|
+
puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
|
48
|
+
end
|
49
|
+
|
50
|
+
puts 'Setting up the Controller.'
|
51
|
+
class ApplicationController
|
52
|
+
# This is to bypass any filters that may prevent access to the action.
|
53
|
+
prepend_before_filter :test_hoptoad
|
54
|
+
def test_hoptoad
|
55
|
+
puts "Raising '#{exception_class.name}' to simulate application failure."
|
56
|
+
raise exception_class.new, 'Testing hoptoad via "rake hoptoad:test". If you can see this, it works.'
|
57
|
+
end
|
58
|
+
|
59
|
+
def rescue_action exception
|
60
|
+
rescue_action_in_public exception
|
61
|
+
end
|
62
|
+
|
63
|
+
# Ensure we actually have an action to go to.
|
64
|
+
def verify; end
|
65
|
+
|
66
|
+
def consider_all_requests_local
|
67
|
+
false
|
68
|
+
end
|
69
|
+
|
70
|
+
def local_request?
|
71
|
+
false
|
72
|
+
end
|
73
|
+
|
74
|
+
def exception_class
|
75
|
+
exception_name = ENV['EXCEPTION'] || "HoptoadTestingException"
|
76
|
+
Object.const_get(exception_name)
|
77
|
+
rescue
|
78
|
+
Object.const_set(exception_name, Class.new(Exception))
|
79
|
+
end
|
80
|
+
|
81
|
+
def logger
|
82
|
+
nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
puts 'Processing request.'
|
87
|
+
class HoptoadVerificationController < ApplicationController; end
|
88
|
+
HoptoadVerificationController.new.process(request, response)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
@@ -0,0 +1,146 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'net/https'
|
3
|
+
require 'rubygems'
|
4
|
+
require 'active_support'
|
5
|
+
require 'hoptoad_notifier/version'
|
6
|
+
require 'hoptoad_notifier/configuration'
|
7
|
+
require 'hoptoad_notifier/notice'
|
8
|
+
require 'hoptoad_notifier/sender'
|
9
|
+
require 'hoptoad_notifier/catcher'
|
10
|
+
require 'hoptoad_notifier/backtrace'
|
11
|
+
|
12
|
+
# Gem for applications to automatically post errors to the Hoptoad of their choice.
|
13
|
+
module HoptoadNotifier
|
14
|
+
|
15
|
+
API_VERSION = "2.0"
|
16
|
+
LOG_PREFIX = "** [Hoptoad] "
|
17
|
+
|
18
|
+
HEADERS = {
|
19
|
+
'Content-type' => 'text/xml',
|
20
|
+
'Accept' => 'text/xml, application/xml'
|
21
|
+
}
|
22
|
+
|
23
|
+
class << self
|
24
|
+
# The sender object is responsible for delivering formatted data to the Hoptoad server.
|
25
|
+
# Must respond to #send_to_hoptoad. See HoptoadNotifier::Sender.
|
26
|
+
attr_accessor :sender
|
27
|
+
|
28
|
+
# A Hoptoad configuration object. Must act like a hash and return sensible
|
29
|
+
# values for all Hoptoad configuration options. See HoptoadNotifier::Configuration.
|
30
|
+
attr_accessor :configuration
|
31
|
+
|
32
|
+
# Tell the log that the Notifier is good to go
|
33
|
+
def report_ready
|
34
|
+
write_verbose_log("Notifier #{VERSION} ready to catch errors")
|
35
|
+
end
|
36
|
+
|
37
|
+
# Prints out the environment info to the log for debugging help
|
38
|
+
def report_environment_info
|
39
|
+
write_verbose_log("Environment Info: #{environment_info}")
|
40
|
+
end
|
41
|
+
|
42
|
+
# Prints out the response body from Hoptoad for debugging help
|
43
|
+
def report_response_body(response)
|
44
|
+
write_verbose_log("Response from Hoptoad: \n#{response}")
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns the Ruby version, Rails version, and current Rails environment
|
48
|
+
def environment_info
|
49
|
+
info = "[Ruby: #{RUBY_VERSION}]"
|
50
|
+
info << " [Rails: #{::Rails::VERSION::STRING}]" if defined?(Rails)
|
51
|
+
info << " [Env: #{configuration.environment_name}]"
|
52
|
+
end
|
53
|
+
|
54
|
+
# Writes out the given message to the #logger
|
55
|
+
def write_verbose_log(message)
|
56
|
+
logger.info LOG_PREFIX + message if logger
|
57
|
+
end
|
58
|
+
|
59
|
+
# Look for the Rails logger currently defined
|
60
|
+
def logger
|
61
|
+
self.configuration.logger
|
62
|
+
end
|
63
|
+
|
64
|
+
# Call this method to modify defaults in your initializers.
|
65
|
+
#
|
66
|
+
# @example
|
67
|
+
# HoptoadNotifier.configure do |config|
|
68
|
+
# config.api_key = '1234567890abcdef'
|
69
|
+
# config.secure = false
|
70
|
+
# end
|
71
|
+
def configure(silent = false)
|
72
|
+
self.configuration ||= Configuration.new
|
73
|
+
yield(configuration)
|
74
|
+
self.sender = Sender.new(configuration)
|
75
|
+
report_ready unless silent
|
76
|
+
end
|
77
|
+
|
78
|
+
# Sends an exception manually using this method, even when you are not in a controller.
|
79
|
+
#
|
80
|
+
# @param [Exception] exception The exception you want to notify Hoptoad about.
|
81
|
+
# @param [Hash] opts Data that will be sent to Hoptoad.
|
82
|
+
#
|
83
|
+
# @option opts [String] :api_key The API key for this project. The API key is a unique identifier that Hoptoad uses for identification.
|
84
|
+
# @option opts [String] :error_message The error returned by the exception (or the message you want to log).
|
85
|
+
# @option opts [String] :backtrace A backtrace, usually obtained with +caller+.
|
86
|
+
# @option opts [String] :request The controller's request object.
|
87
|
+
# @option opts [String] :session The contents of the user's session.
|
88
|
+
# @option opts [String] :environment ENV merged with the contents of the request's environment.
|
89
|
+
def notify(exception, opts = {})
|
90
|
+
send_notice(build_notice_for(exception, opts))
|
91
|
+
end
|
92
|
+
|
93
|
+
# Sends the notice unless it is one of the default ignored exceptions
|
94
|
+
# @see HoptoadNotifier.notify
|
95
|
+
def notify_or_ignore(exception, opts = {})
|
96
|
+
notice = build_notice_for(exception, opts)
|
97
|
+
send_notice(notice) unless notice.ignore?
|
98
|
+
end
|
99
|
+
|
100
|
+
def build_lookup_hash_for(exception, options = {})
|
101
|
+
notice = build_notice_for(exception, options)
|
102
|
+
|
103
|
+
result = {}
|
104
|
+
result[:action] = notice.action rescue nil
|
105
|
+
result[:component] = notice.component rescue nil
|
106
|
+
result[:error_class] = notice.error_class if notice.error_class
|
107
|
+
result[:environment_name] = 'production'
|
108
|
+
|
109
|
+
unless notice.backtrace.lines.empty?
|
110
|
+
result[:file] = notice.backtrace.lines.first.file
|
111
|
+
result[:line_number] = notice.backtrace.lines.first.number
|
112
|
+
end
|
113
|
+
|
114
|
+
result
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
def send_notice(notice)
|
120
|
+
if configuration.public?
|
121
|
+
sender.send_to_hoptoad(notice.to_xml)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def build_notice_for(exception, opts = {})
|
126
|
+
exception = unwrap_exception(exception)
|
127
|
+
if exception.respond_to?(:to_hash)
|
128
|
+
opts = opts.merge(exception)
|
129
|
+
else
|
130
|
+
opts = opts.merge(:exception => exception)
|
131
|
+
end
|
132
|
+
Notice.new(configuration.merge(opts))
|
133
|
+
end
|
134
|
+
|
135
|
+
def unwrap_exception(exception)
|
136
|
+
if exception.respond_to?(:original_exception)
|
137
|
+
exception.original_exception
|
138
|
+
elsif exception.respond_to?(:continued_exception)
|
139
|
+
exception.continued_exception
|
140
|
+
else
|
141
|
+
exception
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'uri'
|
3
|
+
require 'active_support'
|
4
|
+
|
5
|
+
# Capistrano tasks for notifying Hoptoad of deploys
|
6
|
+
module HoptoadTasks
|
7
|
+
|
8
|
+
# Alerts Hoptoad of a deploy.
|
9
|
+
#
|
10
|
+
# @param [Hash] opts Data about the deploy that is set to Hoptoad
|
11
|
+
#
|
12
|
+
# @option opts [String] :rails_env Environment of the deploy (production, staging)
|
13
|
+
# @option opts [String] :scm_revision The given revision/sha that is being deployed
|
14
|
+
# @option opts [String] :scm_repository Address of your repository to help with code lookups
|
15
|
+
# @option opts [String] :local_username Who is deploying
|
16
|
+
def self.deploy(opts = {})
|
17
|
+
if HoptoadNotifier.configuration.api_key.blank?
|
18
|
+
puts "I don't seem to be configured with an API key. Please check your configuration."
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
|
22
|
+
if opts[:rails_env].blank?
|
23
|
+
puts "I don't know to which Rails environment you are deploying (use the TO=production option)."
|
24
|
+
return false
|
25
|
+
end
|
26
|
+
|
27
|
+
params = {'api_key' => opts.delete(:api_key) ||
|
28
|
+
HoptoadNotifier.configuration.api_key}
|
29
|
+
opts.each {|k,v| params["deploy[#{k}]"] = v }
|
30
|
+
|
31
|
+
url = URI.parse("http://#{HoptoadNotifier.configuration.host || 'hoptoadapp.com'}/deploys.txt")
|
32
|
+
response = Net::HTTP.post_form(url, params)
|
33
|
+
puts response.body
|
34
|
+
return Net::HTTPSuccess === response
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
data/rails/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'hoptoad_notifier/rails'
|
@@ -0,0 +1,89 @@
|
|
1
|
+
namespace :hoptoad do
|
2
|
+
desc "Notify Hoptoad of a new deploy."
|
3
|
+
task :deploy => :environment do
|
4
|
+
require 'hoptoad_tasks'
|
5
|
+
HoptoadTasks.deploy(:rails_env => ENV['TO'],
|
6
|
+
:scm_revision => ENV['REVISION'],
|
7
|
+
:scm_repository => ENV['REPO'],
|
8
|
+
:local_username => ENV['USER'],
|
9
|
+
:api_key => ENV['API_KEY'])
|
10
|
+
end
|
11
|
+
|
12
|
+
task :log_stdout do
|
13
|
+
require 'logger'
|
14
|
+
RAILS_DEFAULT_LOGGER = Logger.new(STDOUT)
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Verify your gem installation by sending a test exception to the hoptoad service"
|
18
|
+
task :test => ['hoptoad:log_stdout', :environment] do
|
19
|
+
RAILS_DEFAULT_LOGGER.level = Logger::DEBUG
|
20
|
+
|
21
|
+
require 'action_controller/test_process'
|
22
|
+
require 'app/controllers/application' if File.exists?('app/controllers/application.rb')
|
23
|
+
|
24
|
+
request = ActionController::TestRequest.new
|
25
|
+
response = ActionController::TestResponse.new
|
26
|
+
|
27
|
+
class HoptoadTestingException < RuntimeError; end
|
28
|
+
|
29
|
+
unless HoptoadNotifier.configuration.api_key
|
30
|
+
puts "Hoptoad needs an API key configured! Check the README to see how to add it."
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
|
34
|
+
HoptoadNotifier.configuration.development_environments = []
|
35
|
+
|
36
|
+
in_controller = ApplicationController.included_modules.include? HoptoadNotifier::Catcher
|
37
|
+
in_base = ActionController::Base.included_modules.include? HoptoadNotifier::Catcher
|
38
|
+
if !in_controller || !in_base
|
39
|
+
puts "HoptoadNotifier::Catcher must be included inside your ApplicationController class."
|
40
|
+
exit
|
41
|
+
end
|
42
|
+
|
43
|
+
puts "Configuration:"
|
44
|
+
HoptoadNotifier.configuration.to_hash.each do |key, value|
|
45
|
+
puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55))
|
46
|
+
end
|
47
|
+
|
48
|
+
puts 'Setting up the Controller.'
|
49
|
+
class ApplicationController
|
50
|
+
# This is to bypass any filters that may prevent access to the action.
|
51
|
+
prepend_before_filter :test_hoptoad
|
52
|
+
def test_hoptoad
|
53
|
+
puts "Raising '#{exception_class.name}' to simulate application failure."
|
54
|
+
raise exception_class.new, 'Testing hoptoad via "rake hoptoad:test". If you can see this, it works.'
|
55
|
+
end
|
56
|
+
|
57
|
+
def rescue_action exception
|
58
|
+
rescue_action_in_public exception
|
59
|
+
end
|
60
|
+
|
61
|
+
# Ensure we actually have an action to go to.
|
62
|
+
def verify; end
|
63
|
+
|
64
|
+
def consider_all_requests_local
|
65
|
+
false
|
66
|
+
end
|
67
|
+
|
68
|
+
def local_request?
|
69
|
+
false
|
70
|
+
end
|
71
|
+
|
72
|
+
def exception_class
|
73
|
+
exception_name = ENV['EXCEPTION'] || "HoptoadTestingException"
|
74
|
+
Object.const_get(exception_name)
|
75
|
+
rescue
|
76
|
+
Object.const_set(exception_name, Class.new(Exception))
|
77
|
+
end
|
78
|
+
|
79
|
+
def logger
|
80
|
+
nil
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
puts 'Processing request.'
|
85
|
+
class HoptoadVerificationController < ApplicationController; end
|
86
|
+
HoptoadVerificationController.new.process(request, response)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/helper'
|
2
|
+
|
3
|
+
class BacktraceTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
should "parse a backtrace into lines" do
|
6
|
+
array = [
|
7
|
+
"app/models/user.rb:13:in `magic'",
|
8
|
+
"app/controllers/users_controller.rb:8:in `index'"
|
9
|
+
]
|
10
|
+
|
11
|
+
backtrace = HoptoadNotifier::Backtrace.parse(array)
|
12
|
+
|
13
|
+
line = backtrace.lines.first
|
14
|
+
assert_equal '13', line.number
|
15
|
+
assert_equal 'app/models/user.rb', line.file
|
16
|
+
assert_equal 'magic', line.method
|
17
|
+
|
18
|
+
line = backtrace.lines.last
|
19
|
+
assert_equal '8', line.number
|
20
|
+
assert_equal 'app/controllers/users_controller.rb', line.file
|
21
|
+
assert_equal 'index', line.method
|
22
|
+
end
|
23
|
+
|
24
|
+
should "be equal with equal lines" do
|
25
|
+
one = build_backtrace_array
|
26
|
+
two = one.dup
|
27
|
+
assert_equal one, two
|
28
|
+
|
29
|
+
assert_equal HoptoadNotifier::Backtrace.parse(one), HoptoadNotifier::Backtrace.parse(two)
|
30
|
+
end
|
31
|
+
|
32
|
+
should "parse massive one-line exceptions into multiple lines" do
|
33
|
+
original_backtrace = HoptoadNotifier::Backtrace.
|
34
|
+
parse(["one:1:in `one'\n two:2:in `two'\n three:3:in `three`"])
|
35
|
+
expected_backtrace = HoptoadNotifier::Backtrace.
|
36
|
+
parse(["one:1:in `one'", "two:2:in `two'", "three:3:in `three`"])
|
37
|
+
|
38
|
+
assert_equal expected_backtrace, original_backtrace
|
39
|
+
end
|
40
|
+
|
41
|
+
context "with a project root" do
|
42
|
+
setup do
|
43
|
+
@project_root = '/some/path'
|
44
|
+
HoptoadNotifier.configure {|config| config.project_root = @project_root }
|
45
|
+
end
|
46
|
+
|
47
|
+
teardown do
|
48
|
+
reset_config
|
49
|
+
end
|
50
|
+
|
51
|
+
should "filter out the project root" do
|
52
|
+
backtrace_with_root = HoptoadNotifier::Backtrace.parse(
|
53
|
+
["#{@project_root}/app/models/user.rb:7:in `latest'",
|
54
|
+
"#{@project_root}/app/controllers/users_controller.rb:13:in `index'",
|
55
|
+
"/lib/something.rb:41:in `open'"],
|
56
|
+
:filters => default_filters)
|
57
|
+
backtrace_without_root = HoptoadNotifier::Backtrace.parse(
|
58
|
+
["[PROJECT_ROOT]/app/models/user.rb:7:in `latest'",
|
59
|
+
"[PROJECT_ROOT]/app/controllers/users_controller.rb:13:in `index'",
|
60
|
+
"/lib/something.rb:41:in `open'"])
|
61
|
+
|
62
|
+
assert_equal backtrace_without_root, backtrace_with_root
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with a blank project root" do
|
67
|
+
setup do
|
68
|
+
HoptoadNotifier.configure {|config| config.project_root = '' }
|
69
|
+
end
|
70
|
+
|
71
|
+
teardown do
|
72
|
+
reset_config
|
73
|
+
end
|
74
|
+
|
75
|
+
should "not filter line numbers with respect to any project root" do
|
76
|
+
backtrace = ["/app/models/user.rb:7:in `latest'",
|
77
|
+
"/app/controllers/users_controller.rb:13:in `index'",
|
78
|
+
"/lib/something.rb:41:in `open'"]
|
79
|
+
|
80
|
+
backtrace_with_root =
|
81
|
+
HoptoadNotifier::Backtrace.parse(backtrace, :filters => default_filters)
|
82
|
+
|
83
|
+
backtrace_without_root =
|
84
|
+
HoptoadNotifier::Backtrace.parse(backtrace)
|
85
|
+
|
86
|
+
assert_equal backtrace_without_root, backtrace_with_root
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
should "remove notifier trace" do
|
91
|
+
inside_notifier = ['lib/hoptoad_notifier.rb:13:in `voodoo`']
|
92
|
+
outside_notifier = ['users_controller:8:in `index`']
|
93
|
+
|
94
|
+
without_inside = HoptoadNotifier::Backtrace.parse(outside_notifier)
|
95
|
+
with_inside = HoptoadNotifier::Backtrace.parse(inside_notifier + outside_notifier,
|
96
|
+
:filters => default_filters)
|
97
|
+
|
98
|
+
assert_equal without_inside, with_inside
|
99
|
+
end
|
100
|
+
|
101
|
+
should "run filters on the backtrace" do
|
102
|
+
filters = [lambda { |line| line.sub('foo', 'bar') }]
|
103
|
+
input = HoptoadNotifier::Backtrace.parse(["foo:13:in `one'", "baz:14:in `two'"],
|
104
|
+
:filters => filters)
|
105
|
+
expected = HoptoadNotifier::Backtrace.parse(["bar:13:in `one'", "baz:14:in `two'"])
|
106
|
+
assert_equal expected, input
|
107
|
+
end
|
108
|
+
|
109
|
+
def build_backtrace_array
|
110
|
+
["app/models/user.rb:13:in `magic'",
|
111
|
+
"app/controllers/users_controller.rb:8:in `index'"]
|
112
|
+
end
|
113
|
+
|
114
|
+
def default_filters
|
115
|
+
HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|