errornot_notifier 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -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
@@ -0,0 +1,300 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ActionControllerCatcherTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ def setup
8
+ super
9
+ reset_config
10
+ HoptoadNotifier.sender = CollectingSender.new
11
+ define_constant('RAILS_ROOT', '/path/to/rails/root')
12
+ end
13
+
14
+ def ignore(exception_class)
15
+ HoptoadNotifier.configuration.ignore << exception_class
16
+ end
17
+
18
+ def build_controller_class(&definition)
19
+ returning Class.new(ActionController::Base) do |klass|
20
+ klass.__send__(:include, HoptoadNotifier::Rails::ActionControllerCatcher)
21
+ klass.class_eval(&definition) if definition
22
+ define_constant('HoptoadTestController', klass)
23
+ end
24
+ end
25
+
26
+ def assert_sent_request_info_for(request)
27
+ params = request.parameters.to_hash
28
+ assert_equal params, last_sent_notice_document['error']['request']['params']
29
+ assert_equal params['controller'], last_sent_notice_document['error']['request']['component']
30
+ assert_equal params['action'], last_sent_notice_document['error']['request']['action']
31
+ assert_equal url_from_request(request), last_sent_notice_document['error']['request']['url']
32
+ assert_equal request.env.keys.sort, last_sent_notice_document['error']['request']['cgi-data'].keys.sort
33
+ end
34
+
35
+ def url_from_request(request)
36
+ url = "#{request.protocol}#{request.host}"
37
+
38
+ unless [80, 443].include?(request.port)
39
+ url << ":#{request.port}"
40
+ end
41
+
42
+ url << request.request_uri
43
+ url
44
+ end
45
+
46
+ def sender
47
+ HoptoadNotifier.sender
48
+ end
49
+
50
+ def last_sent_notice_xml
51
+ sender.collected.last
52
+ end
53
+
54
+ def last_sent_notice_document
55
+ assert_not_nil xml = last_sent_notice_xml, "No xml was sent"
56
+ xml
57
+ end
58
+
59
+ def process_action(opts = {}, &action)
60
+ opts[:request] ||= ActionController::TestRequest.new
61
+ opts[:response] ||= ActionController::TestResponse.new
62
+ klass = build_controller_class do
63
+ cattr_accessor :local
64
+ define_method(:index, &action)
65
+ def local_request?
66
+ local
67
+ end
68
+ end
69
+ if opts[:filters]
70
+ klass.filter_parameter_logging *opts[:filters]
71
+ end
72
+ if opts[:user_agent]
73
+ if opts[:request].respond_to?(:user_agent=)
74
+ opts[:request].user_agent = opts[:user_agent]
75
+ else
76
+ opts[:request].env["HTTP_USER_AGENT"] = opts[:user_agent]
77
+ end
78
+ end
79
+ if opts[:port]
80
+ opts[:request].port = opts[:port].to_s
81
+ end
82
+ klass.consider_all_requests_local = opts[:all_local]
83
+ klass.local = opts[:local]
84
+ controller = klass.new
85
+ controller.stubs(:rescue_action_in_public_without_hoptoad)
86
+ opts[:request].query_parameters = opts[:request].query_parameters.merge(opts[:params] || {})
87
+ opts[:request].session = ActionController::TestSession.new(opts[:session] || {})
88
+ controller.process(opts[:request], opts[:response])
89
+ controller
90
+ end
91
+
92
+ def process_action_with_manual_notification(args = {})
93
+ process_action(args) do
94
+ notify_hoptoad(:error_message => 'fail')
95
+ # Rails will raise a template error if we don't render something
96
+ render :nothing => true
97
+ end
98
+ end
99
+
100
+ def process_action_with_automatic_notification(args = {})
101
+ process_action(args) { raise "Hello" }
102
+ end
103
+
104
+ should "deliver notices from exceptions raised in public requests" do
105
+ process_action_with_automatic_notification
106
+ assert_caught_and_sent
107
+ end
108
+
109
+ should "not deliver notices from exceptions in local requests" do
110
+ process_action_with_automatic_notification(:local => true)
111
+ assert_caught_and_not_sent
112
+ end
113
+
114
+ should "not deliver notices from exceptions when all requests are local" do
115
+ process_action_with_automatic_notification(:all_local => true)
116
+ assert_caught_and_not_sent
117
+ end
118
+
119
+ should "not deliver notices from actions that don't raise" do
120
+ controller = process_action { render :text => 'Hello' }
121
+ assert_caught_and_not_sent
122
+ assert_equal 'Hello', controller.response.body
123
+ end
124
+
125
+ should "not deliver ignored exceptions raised by actions" do
126
+ ignore(RuntimeError)
127
+ process_action_with_automatic_notification
128
+ assert_caught_and_not_sent
129
+ end
130
+
131
+ should "deliver ignored exception raised manually" do
132
+ ignore(RuntimeError)
133
+ process_action_with_manual_notification
134
+ assert_caught_and_sent
135
+ end
136
+
137
+ should "deliver manually sent notices in public requests" do
138
+ process_action_with_manual_notification
139
+ assert_caught_and_sent
140
+ end
141
+
142
+ should "not deliver manually sent notices in local requests" do
143
+ process_action_with_manual_notification(:local => true)
144
+ assert_caught_and_not_sent
145
+ end
146
+
147
+ should "not deliver manually sent notices when all requests are local" do
148
+ process_action_with_manual_notification(:all_local => true)
149
+ assert_caught_and_not_sent
150
+ end
151
+
152
+ should "continue with default behavior after delivering an exception" do
153
+ controller = process_action_with_automatic_notification(:public => true)
154
+ # TODO: can we test this without stubbing?
155
+ assert_received(controller, :rescue_action_in_public_without_hoptoad)
156
+ end
157
+
158
+ should "not create actions from Hoptoad methods" do
159
+ controller = build_controller_class.new
160
+ assert_equal [], HoptoadNotifier::Rails::ActionControllerCatcher.instance_methods
161
+ end
162
+
163
+ should "ignore exceptions when user agent is being ignored by regular expression" do
164
+ HoptoadNotifier.configuration.ignore_user_agent_only = [/Ignored/]
165
+ process_action_with_automatic_notification(:user_agent => 'ShouldBeIgnored')
166
+ assert_caught_and_not_sent
167
+ end
168
+
169
+ should "ignore exceptions when user agent is being ignored by string" do
170
+ HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
171
+ process_action_with_automatic_notification(:user_agent => 'IgnoredUserAgent')
172
+ assert_caught_and_not_sent
173
+ end
174
+
175
+ should "not ignore exceptions when user agent is not being ignored" do
176
+ HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent']
177
+ process_action_with_automatic_notification(:user_agent => 'NonIgnoredAgent')
178
+ assert_caught_and_sent
179
+ end
180
+
181
+ should "send session data for manual notifications" do
182
+ data = { 'one' => 'two' }
183
+ process_action_with_manual_notification(:session => data)
184
+ assert_equal data, last_sent_notice_document['error']['session']
185
+ end
186
+
187
+ should "send session data for automatic notification" do
188
+ data = { 'one' => 'two' }
189
+ process_action_with_automatic_notification(:session => data)
190
+ assert_equal data, last_sent_notice_document['error']['session']
191
+ end
192
+
193
+ should "send request data for manual notification" do
194
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
195
+ controller = process_action_with_manual_notification(:params => params)
196
+ assert_sent_request_info_for controller.request
197
+ end
198
+
199
+ should "send request data for manual notification with non-standard port" do
200
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
201
+ controller = process_action_with_manual_notification(:params => params, :port => 81)
202
+ assert_sent_request_info_for controller.request
203
+ end
204
+
205
+ should "send request data for automatic notification" do
206
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
207
+ controller = process_action_with_automatic_notification(:params => params)
208
+ assert_sent_request_info_for controller.request
209
+ end
210
+
211
+ should "send request data for automatic notification with non-standard port" do
212
+ params = { 'controller' => "hoptoad_test", 'action' => "index" }
213
+ controller = process_action_with_automatic_notification(:params => params, :port => 81)
214
+ assert_sent_request_info_for controller.request
215
+ end
216
+
217
+ should "use standard rails logging filters on params and env" do
218
+ filtered_params = { "abc" => "123",
219
+ "def" => "456",
220
+ "ghi" => "[FILTERED]" }
221
+ ENV['ghi'] = 'abc'
222
+ filtered_env = { 'ghi' => '[FILTERED]' }
223
+ filtered_cgi = { 'REQUEST_METHOD' => '[FILTERED]' }
224
+
225
+ process_action_with_automatic_notification(:filters => [:ghi, :request_method],
226
+ :params => { "abc" => "123",
227
+ "def" => "456",
228
+ "ghi" => "789" })
229
+ assert_equal filtered_params, last_sent_notice_document['error']['request']['params']
230
+ assert last_sent_notice_document['error']['request']['cgi-data'].include?('REQUEST_METHOD')
231
+ assert_equal '[FILTERED]', last_sent_notice_document['error']['request']['cgi-data']['REQUEST_METHOD']
232
+ end
233
+
234
+ context "for a local error with development lookup enabled" do
235
+ setup do
236
+ HoptoadNotifier.configuration.development_lookup = true
237
+ HoptoadNotifier.stubs(:build_lookup_hash_for).returns({ :awesome => 2 })
238
+
239
+ @controller = process_action_with_automatic_notification(:local => true)
240
+ @response = @controller.response
241
+ end
242
+
243
+ should "append custom CSS and JS to response body for a local error" do
244
+ assert_match /text\/css/, @response.body
245
+ assert_match /text\/javascript/, @response.body
246
+ end
247
+
248
+ should "contain host, API key and notice JSON" do
249
+ assert_match HoptoadNotifier.configuration.host.to_json, @response.body
250
+ assert_match HoptoadNotifier.configuration.api_key.to_json, @response.body
251
+ assert_match ({ :awesome => 2 }).to_json, @response.body
252
+ end
253
+ end
254
+
255
+ context "for a local error with development lookup disabled" do
256
+ setup do
257
+ HoptoadNotifier.configuration.development_lookup = false
258
+
259
+ @controller = process_action_with_automatic_notification(:local => true)
260
+ @response = @controller.response
261
+ end
262
+
263
+ should "not append custom CSS and JS to response for a local error" do
264
+ assert_no_match /text\/css/, @response.body
265
+ assert_no_match /text\/javascript/, @response.body
266
+ end
267
+ end
268
+
269
+ should "call session.to_hash if available" do
270
+ hash_data = {:key => :value}
271
+
272
+ session = ActionController::TestSession.new
273
+ ActionController::TestSession.stubs(:new).returns(session)
274
+ session.stubs(:to_hash).returns(hash_data)
275
+
276
+ process_action_with_automatic_notification
277
+ assert_received(session, :to_hash)
278
+ assert_received(session, :data) { |expect| expect.never }
279
+ assert_caught_and_sent
280
+ end
281
+
282
+ should "call session.data if session.to_hash is undefined" do
283
+ hash_data = {:key => :value}
284
+
285
+ session = ActionController::TestSession.new
286
+ ActionController::TestSession.stubs(:new).returns(session)
287
+ session.stubs(:data).returns(hash_data)
288
+ if session.respond_to?(:to_hash)
289
+ class << session
290
+ undef to_hash
291
+ end
292
+ end
293
+
294
+ process_action_with_automatic_notification
295
+ assert_received(session, :to_hash) { |expect| expect.never }
296
+ assert_received(session, :data) { |expect| expect.at_least_once }
297
+ assert_caught_and_sent
298
+ end
299
+
300
+ end
@@ -0,0 +1,208 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ConfigurationTest < Test::Unit::TestCase
4
+
5
+ include DefinesConstants
6
+
7
+ should "provide default values" do
8
+ assert_config_default :proxy_host, nil
9
+ assert_config_default :proxy_port, nil
10
+ assert_config_default :proxy_user, nil
11
+ assert_config_default :proxy_pass, nil
12
+ assert_config_default :project_root, nil
13
+ assert_config_default :environment_name, nil
14
+ assert_config_default :logger, nil
15
+ assert_config_default :notifier_version, HoptoadNotifier::VERSION
16
+ assert_config_default :notifier_name, 'Hoptoad Notifier'
17
+ assert_config_default :notifier_url, 'http://hoptoadapp.com'
18
+ assert_config_default :secure, false
19
+ assert_config_default :host, 'hoptoadapp.com'
20
+ assert_config_default :http_open_timeout, 2
21
+ assert_config_default :http_read_timeout, 5
22
+ assert_config_default :ignore_by_filters, []
23
+ assert_config_default :ignore_user_agent, []
24
+ assert_config_default :params_filters,
25
+ HoptoadNotifier::Configuration::DEFAULT_PARAMS_FILTERS
26
+ assert_config_default :backtrace_filters,
27
+ HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS
28
+ assert_config_default :ignore,
29
+ HoptoadNotifier::Configuration::IGNORE_DEFAULT
30
+ assert_config_default :development_lookup, true
31
+ assert_config_default :framework, 'Standalone'
32
+ end
33
+
34
+ should "provide default values for secure connections" do
35
+ config = HoptoadNotifier::Configuration.new
36
+ config.secure = true
37
+ assert_equal 443, config.port
38
+ assert_equal 'https', config.protocol
39
+ end
40
+
41
+ should "provide default values for insecure connections" do
42
+ config = HoptoadNotifier::Configuration.new
43
+ config.secure = false
44
+ assert_equal 80, config.port
45
+ assert_equal 'http', config.protocol
46
+ end
47
+
48
+ should "not cache inferred ports" do
49
+ config = HoptoadNotifier::Configuration.new
50
+ config.secure = false
51
+ config.port
52
+ config.secure = true
53
+ assert_equal 443, config.port
54
+ end
55
+
56
+ should "allow values to be overwritten" do
57
+ assert_config_overridable :proxy_host
58
+ assert_config_overridable :proxy_port
59
+ assert_config_overridable :proxy_user
60
+ assert_config_overridable :proxy_pass
61
+ assert_config_overridable :secure
62
+ assert_config_overridable :host
63
+ assert_config_overridable :port
64
+ assert_config_overridable :http_open_timeout
65
+ assert_config_overridable :http_read_timeout
66
+ assert_config_overridable :project_root
67
+ assert_config_overridable :notifier_version
68
+ assert_config_overridable :notifier_name
69
+ assert_config_overridable :notifier_url
70
+ assert_config_overridable :environment_name
71
+ assert_config_overridable :development_lookup
72
+ assert_config_overridable :logger
73
+ end
74
+
75
+ should "have an api key" do
76
+ assert_config_overridable :api_key
77
+ end
78
+
79
+ should "act like a hash" do
80
+ config = HoptoadNotifier::Configuration.new
81
+ hash = config.to_hash
82
+ [:api_key, :backtrace_filters, :development_environments,
83
+ :environment_name, :host, :http_open_timeout,
84
+ :http_read_timeout, :ignore, :ignore_by_filters, :ignore_user_agent,
85
+ :notifier_name, :notifier_url, :notifier_version, :params_filters,
86
+ :project_root, :port, :protocol, :proxy_host, :proxy_pass, :proxy_port,
87
+ :proxy_user, :secure, :development_lookup].each do |option|
88
+ assert_equal config[option], hash[option], "Wrong value for #{option}"
89
+ end
90
+ end
91
+
92
+ should "be mergable" do
93
+ config = HoptoadNotifier::Configuration.new
94
+ hash = config.to_hash
95
+ assert_equal hash.merge(:key => 'value'), config.merge(:key => 'value')
96
+ end
97
+
98
+ should "allow param filters to be appended" do
99
+ assert_appends_value :params_filters
100
+ end
101
+
102
+ should "warn when attempting to read environment filters" do
103
+ config = HoptoadNotifier::Configuration.new
104
+ config.
105
+ expects(:warn).
106
+ with(regexp_matches(/deprecated/i))
107
+ assert_equal [], config.environment_filters
108
+ end
109
+
110
+ should "allow ignored user agents to be appended" do
111
+ assert_appends_value :ignore_user_agent
112
+ end
113
+
114
+ should "allow backtrace filters to be appended" do
115
+ assert_appends_value(:backtrace_filters) do |config|
116
+ new_filter = lambda {}
117
+ config.filter_backtrace(&new_filter)
118
+ new_filter
119
+ end
120
+ end
121
+
122
+ should "allow ignore by filters to be appended" do
123
+ assert_appends_value(:ignore_by_filters) do |config|
124
+ new_filter = lambda {}
125
+ config.ignore_by_filter(&new_filter)
126
+ new_filter
127
+ end
128
+ end
129
+
130
+ should "allow ignored exceptions to be appended" do
131
+ config = HoptoadNotifier::Configuration.new
132
+ original_filters = config.ignore.dup
133
+ new_filter = 'hello'
134
+ config.ignore << new_filter
135
+ assert_same_elements original_filters + [new_filter], config.ignore
136
+ end
137
+
138
+ should "allow ignored exceptions to be replaced" do
139
+ assert_replaces(:ignore, :ignore_only=)
140
+ end
141
+
142
+ should "allow ignored user agents to be replaced" do
143
+ assert_replaces(:ignore_user_agent, :ignore_user_agent_only=)
144
+ end
145
+
146
+ should "use development and test as development environments by default" do
147
+ config = HoptoadNotifier::Configuration.new
148
+ assert_same_elements %w(development test cucumber), config.development_environments
149
+ end
150
+
151
+ should "be public in a public environment" do
152
+ config = HoptoadNotifier::Configuration.new
153
+ config.development_environments = %w(development)
154
+ config.environment_name = 'production'
155
+ assert config.public?
156
+ end
157
+
158
+ should "not be public in a development environment" do
159
+ config = HoptoadNotifier::Configuration.new
160
+ config.development_environments = %w(staging)
161
+ config.environment_name = 'staging'
162
+ assert !config.public?
163
+ end
164
+
165
+ should "be public without an environment name" do
166
+ config = HoptoadNotifier::Configuration.new
167
+ assert config.public?
168
+ end
169
+
170
+ should "use the assigned logger if set" do
171
+ config = HoptoadNotifier::Configuration.new
172
+ config.logger = "CUSTOM LOGGER"
173
+ assert_equal "CUSTOM LOGGER", config.logger
174
+ end
175
+
176
+ def assert_config_default(option, default_value, config = nil)
177
+ config ||= HoptoadNotifier::Configuration.new
178
+ assert_equal default_value, config.send(option)
179
+ end
180
+
181
+ def assert_config_overridable(option, value = 'a value')
182
+ config = HoptoadNotifier::Configuration.new
183
+ config.send(:"#{option}=", value)
184
+ assert_equal value, config.send(option)
185
+ end
186
+
187
+ def assert_appends_value(option, &block)
188
+ config = HoptoadNotifier::Configuration.new
189
+ original_values = config.send(option).dup
190
+ block ||= lambda do |config|
191
+ new_value = 'hello'
192
+ config.send(option) << new_value
193
+ new_value
194
+ end
195
+ new_value = block.call(config)
196
+ assert_same_elements original_values + [new_value], config.send(option)
197
+ end
198
+
199
+ def assert_replaces(option, setter)
200
+ config = HoptoadNotifier::Configuration.new
201
+ new_value = 'hello'
202
+ config.send(setter, [new_value])
203
+ assert_equal [new_value], config.send(option)
204
+ config.send(setter, new_value)
205
+ assert_equal [new_value], config.send(option)
206
+ end
207
+
208
+ end