hoptoad_notifier 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|