errornot_notifier 0.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.
Files changed (41) hide show
  1. data/INSTALL +25 -0
  2. data/MIT-LICENSE +22 -0
  3. data/README.rdoc +289 -0
  4. data/Rakefile +124 -0
  5. data/SUPPORTED_RAILS_VERSIONS +8 -0
  6. data/TESTING.rdoc +8 -0
  7. data/generators/hoptoad/hoptoad_generator.rb +55 -0
  8. data/generators/hoptoad/lib/insert_commands.rb +34 -0
  9. data/generators/hoptoad/lib/rake_commands.rb +24 -0
  10. data/generators/hoptoad/templates/capistrano_hook.rb +6 -0
  11. data/generators/hoptoad/templates/hoptoad_notifier_tasks.rake +5 -0
  12. data/generators/hoptoad/templates/initializer.rb +7 -0
  13. data/lib/hoptoad_notifier/backtrace.rb +99 -0
  14. data/lib/hoptoad_notifier/capistrano.rb +20 -0
  15. data/lib/hoptoad_notifier/configuration.rb +232 -0
  16. data/lib/hoptoad_notifier/notice.rb +287 -0
  17. data/lib/hoptoad_notifier/rack.rb +40 -0
  18. data/lib/hoptoad_notifier/rails/action_controller_catcher.rb +29 -0
  19. data/lib/hoptoad_notifier/rails/controller_methods.rb +59 -0
  20. data/lib/hoptoad_notifier/rails/error_lookup.rb +33 -0
  21. data/lib/hoptoad_notifier/rails.rb +37 -0
  22. data/lib/hoptoad_notifier/sender.rb +85 -0
  23. data/lib/hoptoad_notifier/tasks.rb +97 -0
  24. data/lib/hoptoad_notifier/version.rb +3 -0
  25. data/lib/hoptoad_notifier.rb +146 -0
  26. data/lib/hoptoad_tasks.rb +37 -0
  27. data/lib/templates/rescue.erb +91 -0
  28. data/rails/init.rb +1 -0
  29. data/script/integration_test.rb +38 -0
  30. data/test/backtrace_test.rb +118 -0
  31. data/test/catcher_test.rb +300 -0
  32. data/test/configuration_test.rb +208 -0
  33. data/test/helper.rb +232 -0
  34. data/test/hoptoad_tasks_test.rb +138 -0
  35. data/test/logger_test.rb +85 -0
  36. data/test/notice_test.rb +395 -0
  37. data/test/notifier_test.rb +222 -0
  38. data/test/rack_test.rb +58 -0
  39. data/test/rails_initializer_test.rb +36 -0
  40. data/test/sender_test.rb +123 -0
  41. metadata +164 -0
data/test/helper.rb ADDED
@@ -0,0 +1,232 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+
4
+ gem 'jferris-mocha', '>= 0.9.5.0.1241126838'
5
+
6
+ $LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. vendor ginger lib])
7
+ $LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
8
+
9
+ require 'shoulda'
10
+ require 'mocha'
11
+
12
+ require 'ginger'
13
+
14
+ require 'action_controller'
15
+ require 'action_controller/test_process'
16
+ require 'active_record'
17
+ require 'active_record/base'
18
+ require 'active_support'
19
+ require 'nokogiri'
20
+ require 'rack'
21
+
22
+ require "hoptoad_notifier"
23
+
24
+ begin require 'redgreen'; rescue LoadError; end
25
+
26
+ module TestMethods
27
+ def rescue_action e
28
+ raise e
29
+ end
30
+
31
+ def do_raise
32
+ raise "Hoptoad"
33
+ end
34
+
35
+ def do_not_raise
36
+ render :text => "Success"
37
+ end
38
+
39
+ def do_raise_ignored
40
+ raise ActiveRecord::RecordNotFound.new("404")
41
+ end
42
+
43
+ def do_raise_not_ignored
44
+ raise ActiveRecord::StatementInvalid.new("Statement invalid")
45
+ end
46
+
47
+ def manual_notify
48
+ notify_hoptoad(Exception.new)
49
+ render :text => "Success"
50
+ end
51
+
52
+ def manual_notify_ignored
53
+ notify_hoptoad(ActiveRecord::RecordNotFound.new("404"))
54
+ render :text => "Success"
55
+ end
56
+ end
57
+
58
+ class HoptoadController < ActionController::Base
59
+ include TestMethods
60
+ end
61
+
62
+ class Test::Unit::TestCase
63
+ def request(action = nil, method = :get, user_agent = nil, params = {})
64
+ @request = ActionController::TestRequest.new
65
+ @request.action = action ? action.to_s : ""
66
+
67
+ if user_agent
68
+ if @request.respond_to?(:user_agent=)
69
+ @request.user_agent = user_agent
70
+ else
71
+ @request.env["HTTP_USER_AGENT"] = user_agent
72
+ end
73
+ end
74
+ @request.query_parameters = @request.query_parameters.merge(params)
75
+ @response = ActionController::TestResponse.new
76
+ @controller.process(@request, @response)
77
+ end
78
+
79
+ # Borrowed from ActiveSupport 2.3.2
80
+ def assert_difference(expression, difference = 1, message = nil, &block)
81
+ b = block.send(:binding)
82
+ exps = Array.wrap(expression)
83
+ before = exps.map { |e| eval(e, b) }
84
+
85
+ yield
86
+
87
+ exps.each_with_index do |e, i|
88
+ error = "#{e.inspect} didn't change by #{difference}"
89
+ error = "#{message}.\n#{error}" if message
90
+ assert_equal(before[i] + difference, eval(e, b), error)
91
+ end
92
+ end
93
+
94
+ def assert_no_difference(expression, message = nil, &block)
95
+ assert_difference expression, 0, message, &block
96
+ end
97
+
98
+ def stub_sender
99
+ stub('sender', :send_to_hoptoad => nil)
100
+ end
101
+
102
+ def stub_sender!
103
+ HoptoadNotifier.sender = stub_sender
104
+ end
105
+
106
+ def stub_notice
107
+ stub('notice', :to_xml => 'some yaml', :ignore? => false)
108
+ end
109
+
110
+ def stub_notice!
111
+ returning stub_notice do |notice|
112
+ HoptoadNotifier::Notice.stubs(:new => notice)
113
+ end
114
+ end
115
+
116
+ def create_dummy
117
+ HoptoadNotifier::DummySender.new
118
+ end
119
+
120
+ def reset_config
121
+ HoptoadNotifier.configuration = nil
122
+ HoptoadNotifier.configure do |config|
123
+ config.api_key = 'abc123'
124
+ end
125
+ end
126
+
127
+ def clear_backtrace_filters
128
+ HoptoadNotifier.configuration.backtrace_filters.clear
129
+ end
130
+
131
+ def build_exception
132
+ raise
133
+ rescue => caught_exception
134
+ caught_exception
135
+ end
136
+
137
+ def build_notice_data(exception = nil)
138
+ exception ||= build_exception
139
+ {
140
+ :api_key => 'abc123',
141
+ :error_class => exception.class.name,
142
+ :error_message => "#{exception.class.name}: #{exception.message}",
143
+ :backtrace => exception.backtrace,
144
+ :environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' },
145
+ :request => {
146
+ :params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' },
147
+ :rails_root => '/path/to/application',
148
+ :url => "http://test.host/users/1"
149
+ },
150
+ :session => {
151
+ :key => '123abc',
152
+ :data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } }
153
+ }
154
+ }
155
+ end
156
+
157
+ def assert_caught_and_sent
158
+ assert !HoptoadNotifier.sender.collected.empty?
159
+ end
160
+
161
+ def assert_caught_and_not_sent
162
+ assert HoptoadNotifier.sender.collected.empty?
163
+ end
164
+
165
+ def assert_array_starts_with(expected, actual)
166
+ assert_respond_to actual, :to_ary
167
+ array = actual.to_ary.reverse
168
+ expected.reverse.each_with_index do |value, i|
169
+ assert_equal value, array[i]
170
+ end
171
+ end
172
+
173
+ end
174
+
175
+ module DefinesConstants
176
+ def setup
177
+ @defined_constants = []
178
+ end
179
+
180
+ def teardown
181
+ @defined_constants.each do |constant|
182
+ Object.__send__(:remove_const, constant)
183
+ end
184
+ end
185
+
186
+ def define_constant(name, value)
187
+ Object.const_set(name, value)
188
+ @defined_constants << name
189
+ end
190
+ end
191
+
192
+ # Also stolen from AS 2.3.2
193
+ class Array
194
+ # Wraps the object in an Array unless it's an Array. Converts the
195
+ # object to an Array using #to_ary if it implements that.
196
+ def self.wrap(object)
197
+ case object
198
+ when nil
199
+ []
200
+ when self
201
+ object
202
+ else
203
+ if object.respond_to?(:to_ary)
204
+ object.to_ary
205
+ else
206
+ [object]
207
+ end
208
+ end
209
+ end
210
+
211
+ end
212
+
213
+ class CollectingSender
214
+ attr_reader :collected
215
+
216
+ def initialize
217
+ @collected = []
218
+ end
219
+
220
+ def send_to_hoptoad(data)
221
+ @collected << data
222
+ end
223
+ end
224
+
225
+ class FakeLogger
226
+ def info(*args); end
227
+ def debug(*args); end
228
+ def warn(*args); end
229
+ def error(*args); end
230
+ def fatal(*args); end
231
+ end
232
+
@@ -0,0 +1,138 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+ require 'rubygems'
3
+
4
+ require File.dirname(__FILE__) + '/../lib/hoptoad_tasks'
5
+ require 'fakeweb'
6
+
7
+ FakeWeb.allow_net_connect = false
8
+
9
+ class HoptoadTasksTest < Test::Unit::TestCase
10
+ def successful_response(body = "")
11
+ response = Net::HTTPSuccess.new('1.2', '200', 'OK')
12
+ response.stubs(:body).returns(body)
13
+ return response
14
+ end
15
+
16
+ def unsuccessful_response(body = "")
17
+ response = Net::HTTPClientError.new('1.2', '200', 'OK')
18
+ response.stubs(:body).returns(body)
19
+ return response
20
+ end
21
+
22
+ context "being quiet" do
23
+ setup { HoptoadTasks.stubs(:puts) }
24
+
25
+ context "in a configured project" do
26
+ setup { HoptoadNotifier.configure { |config| config.api_key = "1234123412341234" } }
27
+
28
+ context "on deploy({})" do
29
+ setup { @output = HoptoadTasks.deploy({}) }
30
+
31
+ before_should "complain about missing rails env" do
32
+ HoptoadTasks.expects(:puts).with(regexp_matches(/rails environment/i))
33
+ end
34
+
35
+ should "return false" do
36
+ assert !@output
37
+ end
38
+ end
39
+
40
+ context "given valid options" do
41
+ setup { @options = {:rails_env => "staging"} }
42
+
43
+ context "on deploy(options)" do
44
+ setup { @output = HoptoadTasks.deploy(@options) }
45
+
46
+ before_should "post to http://hoptoadapp.com/deploys.txt" do
47
+ URI.stubs(:parse).with('http://hoptoadapp.com/deploys.txt').returns(:uri)
48
+ Net::HTTP.expects(:post_form).with(:uri, kind_of(Hash)).returns(successful_response)
49
+ end
50
+
51
+ before_should "use the project api key" do
52
+ Net::HTTP.expects(:post_form).
53
+ with(kind_of(URI), has_entries('api_key' => "1234123412341234")).
54
+ returns(successful_response)
55
+ end
56
+
57
+ before_should "use send the rails_env param" do
58
+ Net::HTTP.expects(:post_form).
59
+ with(kind_of(URI), has_entries("deploy[rails_env]" => "staging")).
60
+ returns(successful_response)
61
+ end
62
+
63
+ [:local_username, :scm_repository, :scm_revision].each do |key|
64
+ before_should "use send the #{key} param if it's passed in." do
65
+ @options[key] = "value"
66
+ Net::HTTP.expects(:post_form).
67
+ with(kind_of(URI), has_entries("deploy[#{key}]" => "value")).
68
+ returns(successful_response)
69
+ end
70
+ end
71
+
72
+ before_should "use the :api_key param if it's passed in." do
73
+ @options[:api_key] = "value"
74
+ Net::HTTP.expects(:post_form).
75
+ with(kind_of(URI), has_entries("api_key" => "value")).
76
+ returns(successful_response)
77
+ end
78
+
79
+ before_should "puts the response body on success" do
80
+ HoptoadTasks.expects(:puts).with("body")
81
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(successful_response('body'))
82
+ end
83
+
84
+ before_should "puts the response body on failure" do
85
+ HoptoadTasks.expects(:puts).with("body")
86
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(unsuccessful_response('body'))
87
+ end
88
+
89
+ should "return false on failure", :before => lambda {
90
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(unsuccessful_response('body'))
91
+ } do
92
+ assert !@output
93
+ end
94
+
95
+ should "return true on success", :before => lambda {
96
+ Net::HTTP.expects(:post_form).with(any_parameters).returns(successful_response('body'))
97
+ } do
98
+ assert @output
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ context "in a configured project with custom host" do
105
+ setup do
106
+ HoptoadNotifier.configure do |config|
107
+ config.api_key = "1234123412341234"
108
+ config.host = "custom.host"
109
+ end
110
+ end
111
+
112
+ context "on deploy(:rails_env => 'staging')" do
113
+ setup { @output = HoptoadTasks.deploy(:rails_env => "staging") }
114
+
115
+ before_should "post to the custom host" do
116
+ URI.stubs(:parse).with('http://custom.host/deploys.txt').returns(:uri)
117
+ Net::HTTP.expects(:post_form).with(:uri, kind_of(Hash)).returns(successful_response)
118
+ end
119
+ end
120
+ end
121
+
122
+ context "when not configured" do
123
+ setup { HoptoadNotifier.configure { |config| config.api_key = "" } }
124
+
125
+ context "on deploy(:rails_env => 'staging')" do
126
+ setup { @output = HoptoadTasks.deploy(:rails_env => "staging") }
127
+
128
+ before_should "complain about missing api key" do
129
+ HoptoadTasks.expects(:puts).with(regexp_matches(/api key/i))
130
+ end
131
+
132
+ should "return false" do
133
+ assert !@output
134
+ end
135
+ end
136
+ end
137
+ end
138
+ end
@@ -0,0 +1,85 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class LoggerTest < Test::Unit::TestCase
4
+ def stub_http(response, body = nil)
5
+ response.stubs(:body => body) if body
6
+ @http = stub(:post => response,
7
+ :read_timeout= => nil,
8
+ :open_timeout= => nil,
9
+ :use_ssl= => nil)
10
+ Net::HTTP.stubs(:new).returns(@http)
11
+ end
12
+
13
+ def send_notice
14
+ HoptoadNotifier.sender.send_to_hoptoad('data')
15
+ end
16
+
17
+ def stub_verbose_log
18
+ HoptoadNotifier.stubs(:write_verbose_log)
19
+ end
20
+
21
+ def assert_logged(expected)
22
+ assert_received(HoptoadNotifier, :write_verbose_log) do |expect|
23
+ expect.with {|actual| actual =~ expected }
24
+ end
25
+ end
26
+
27
+ def assert_not_logged(expected)
28
+ assert_received(HoptoadNotifier, :write_verbose_log) do |expect|
29
+ expect.with {|actual| actual =~ expected }.never
30
+ end
31
+ end
32
+
33
+ def configure
34
+ HoptoadNotifier.configure { |config| }
35
+ end
36
+
37
+ should "report that notifier is ready when configured" do
38
+ stub_verbose_log
39
+ configure
40
+ assert_logged /Notifier (.*) ready/
41
+ end
42
+
43
+ should "not report that notifier is ready when internally configured" do
44
+ stub_verbose_log
45
+ HoptoadNotifier.configure(true) { |config| }
46
+ assert_not_logged /.*/
47
+ end
48
+
49
+ should "print environment info a successful notification without a body" do
50
+ reset_config
51
+ stub_verbose_log
52
+ stub_http(Net::HTTPSuccess)
53
+ send_notice
54
+ assert_logged /Environment Info:/
55
+ assert_not_logged /Response from Hoptoad:/
56
+ end
57
+
58
+ should "print environment info on a failed notification without a body" do
59
+ reset_config
60
+ stub_verbose_log
61
+ stub_http(Net::HTTPError)
62
+ send_notice
63
+ assert_logged /Environment Info:/
64
+ assert_not_logged /Response from Hoptoad:/
65
+ end
66
+
67
+ should "print environment info and response on a success with a body" do
68
+ reset_config
69
+ stub_verbose_log
70
+ stub_http(Net::HTTPSuccess, 'test')
71
+ send_notice
72
+ assert_logged /Environment Info:/
73
+ assert_logged /Response from Hoptoad:/
74
+ end
75
+
76
+ should "print environment info and response on a failure with a body" do
77
+ reset_config
78
+ stub_verbose_log
79
+ stub_http(Net::HTTPError, 'test')
80
+ send_notice
81
+ assert_logged /Environment Info:/
82
+ assert_logged /Response from Hoptoad:/
83
+ end
84
+
85
+ end