Commit 4bafab9d837bced1c384fe1c8d3653b3b6768e81
1 parent
61ec5114
Exists in
master
and in
1 other branch
API level protection against users deactivating too many choice to have a valid prompt
Showing
49 changed files
with
13 additions
and
3832 deletions
Show diff stats
app/controllers/choices_controller.rb
@@ -25,7 +25,7 @@ class ChoicesController < InheritedResources::Base | @@ -25,7 +25,7 @@ class ChoicesController < InheritedResources::Base | ||
25 | end | 25 | end |
26 | end | 26 | end |
27 | index! do |format| | 27 | index! do |format| |
28 | - format.xml { render :xml => @choices.to_xml(:only => [ :data, :score, :id ])} | 28 | + format.xml { render :xml => @choices.to_xml(:only => [ :data, :score, :id, :active ])} |
29 | end | 29 | end |
30 | 30 | ||
31 | end | 31 | end |
@@ -97,17 +97,20 @@ class ChoicesController < InheritedResources::Base | @@ -97,17 +97,20 @@ class ChoicesController < InheritedResources::Base | ||
97 | 97 | ||
98 | def deactivate_from_abroad | 98 | def deactivate_from_abroad |
99 | authenticate | 99 | authenticate |
100 | - expire_page :action => :index | ||
101 | @question = current_user.questions.find(params[:question_id]) | 100 | @question = current_user.questions.find(params[:question_id]) |
102 | @choice = @question.choices.find(params[:id]) | 101 | @choice = @question.choices.find(params[:id]) |
103 | 102 | ||
104 | respond_to do |format| | 103 | respond_to do |format| |
105 | - if @choice.deactivate! | 104 | + if @question.choices.active.size < 3 |
105 | + logger.info "will not deactivate choice because that would lead to fewer than two active choices for the question, #{@question.name}" | ||
106 | + format.xml { render(:xml => false) and return} | ||
107 | + format.json { render :json => false } | ||
108 | + elsif @choice.deactivate! | ||
106 | logger.info "successfully deactivated choice #{@choice.inspect}" | 109 | logger.info "successfully deactivated choice #{@choice.inspect}" |
107 | format.xml { render :xml => true } | 110 | format.xml { render :xml => true } |
108 | format.json { render :json => true } | 111 | format.json { render :json => true } |
109 | else | 112 | else |
110 | - logger.info "failed to deactivate choice #{@choice.inspect}" | 113 | + logger.info "failed to deactivate choice #{@choice.inspect}" |
111 | format.xml { render :xml => @choice.to_xml(:methods => [:data, :votes_count, :wins_plus_losses])} | 114 | format.xml { render :xml => @choice.to_xml(:methods => [:data, :votes_count, :wins_plus_losses])} |
112 | format.json { render :json => @choice.to_json(:methods => [:data])} | 115 | format.json { render :json => @choice.to_json(:methods => [:data])} |
113 | end | 116 | end |
@@ -116,7 +119,6 @@ class ChoicesController < InheritedResources::Base | @@ -116,7 +119,6 @@ class ChoicesController < InheritedResources::Base | ||
116 | 119 | ||
117 | def activate | 120 | def activate |
118 | authenticate | 121 | authenticate |
119 | - expire_page :action => :index | ||
120 | @question = current_user.questions.find(params[:question_id]) | 122 | @question = current_user.questions.find(params[:question_id]) |
121 | @choice = @question.choices.find(params[:id]) | 123 | @choice = @question.choices.find(params[:id]) |
122 | respond_to do |format| | 124 | respond_to do |format| |
@@ -133,7 +135,6 @@ class ChoicesController < InheritedResources::Base | @@ -133,7 +135,6 @@ class ChoicesController < InheritedResources::Base | ||
133 | 135 | ||
134 | def suspend | 136 | def suspend |
135 | authenticate | 137 | authenticate |
136 | - expire_page :action => :index | ||
137 | @question = current_user.questions.find(params[:question_id]) | 138 | @question = current_user.questions.find(params[:question_id]) |
138 | @choice = @question.choices.find(params[:id]) | 139 | @choice = @question.choices.find(params[:id]) |
139 | respond_to do |format| | 140 | respond_to do |format| |
config/environment.rb
@@ -14,6 +14,7 @@ Rails::Initializer.run do |config| | @@ -14,6 +14,7 @@ Rails::Initializer.run do |config| | ||
14 | #config.action_mailer.delivery_method = :smtp | 14 | #config.action_mailer.delivery_method = :smtp |
15 | config.action_mailer.delivery_method = :sendmail | 15 | config.action_mailer.delivery_method = :sendmail |
16 | 16 | ||
17 | + config.gem 'hoptoad_notifier' | ||
17 | config.gem "ambethia-smtp-tls", | 18 | config.gem "ambethia-smtp-tls", |
18 | :lib => "smtp-tls", | 19 | :lib => "smtp-tls", |
19 | :version => "1.1.2", | 20 | :version => "1.1.2", |
vendor/plugins/hoptoad_notifier/.yardopts
vendor/plugins/hoptoad_notifier/INSTALL
@@ -1,25 +0,0 @@ | @@ -1,25 +0,0 @@ | ||
1 | -=== Configuration | ||
2 | - | ||
3 | -You should have something like this in config/initializers/hoptoad.rb. | ||
4 | - | ||
5 | - HoptoadNotifier.configure do |config| | ||
6 | - config.api_key = '1234567890abcdef' | ||
7 | - end | ||
8 | - | ||
9 | -(Please note that this configuration should be in a global configuration, and | ||
10 | -is *not* environment-specific. Hoptoad is smart enough to know what errors are | ||
11 | -caused by what environments, so your staging errors don't get mixed in with | ||
12 | -your production errors.) | ||
13 | - | ||
14 | -You can test that Hoptoad is working in your production environment by using | ||
15 | -this rake task (from RAILS_ROOT): | ||
16 | - | ||
17 | - rake hoptoad:test | ||
18 | - | ||
19 | -If everything is configured properly, that task will send a notice to Hoptoad | ||
20 | -which will be visible immediately. | ||
21 | - | ||
22 | -NOTE FOR RAILS 1.2.* USERS: | ||
23 | - | ||
24 | -You will need to copy the hoptoad_notifier_tasks.rake file into your | ||
25 | -RAILS_ROOT/lib/tasks directory in order for the rake hoptoad:test task to work. |
vendor/plugins/hoptoad_notifier/MIT-LICENSE
@@ -1,22 +0,0 @@ | @@ -1,22 +0,0 @@ | ||
1 | -Copyright (c) 2007, Tammer Saleh, Thoughtbot, Inc. | ||
2 | - | ||
3 | -Permission is hereby granted, free of charge, to any person | ||
4 | -obtaining a copy of this software and associated documentation | ||
5 | -files (the "Software"), to deal in the Software without | ||
6 | -restriction, including without limitation the rights to use, | ||
7 | -copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
8 | -copies of the Software, and to permit persons to whom the | ||
9 | -Software is furnished to do so, subject to the following | ||
10 | -conditions: | ||
11 | - | ||
12 | -The above copyright notice and this permission notice shall be | ||
13 | -included in all copies or substantial portions of the Software. | ||
14 | - | ||
15 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
16 | -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | ||
17 | -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
18 | -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | ||
19 | -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | ||
20 | -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
21 | -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
22 | -OTHER DEALINGS IN THE SOFTWARE. |
vendor/plugins/hoptoad_notifier/README.rdoc
@@ -1,227 +0,0 @@ | @@ -1,227 +0,0 @@ | ||
1 | -= HoptoadNotifier | ||
2 | - | ||
3 | -This is the notifier plugin for integrating apps with Hoptoad. | ||
4 | - | ||
5 | -When an uncaught exception occurs, HoptoadNotifier will POST the relevant data | ||
6 | -to the Hoptoad server specified in your environment. | ||
7 | - | ||
8 | -== Help | ||
9 | - | ||
10 | -* {IRC}[irc://irc.freenode.net/thoughtbot] | ||
11 | -* {mailing list}[http://groups.google.com/group/hoptoad-notifier-dev] | ||
12 | - | ||
13 | -== Installation | ||
14 | - | ||
15 | -=== Remove exception_notifier | ||
16 | - | ||
17 | -in your ApplicationController, REMOVE this line: | ||
18 | - | ||
19 | - include ExceptionNotifiable | ||
20 | - | ||
21 | -In your config/environment* files, remove all references to ExceptionNotifier | ||
22 | - | ||
23 | -Remove the vendor/plugins/exception_notifier directory. | ||
24 | - | ||
25 | -=== Install hoptoad_notifier | ||
26 | - | ||
27 | -from your project's RAILS_ROOT, run: | ||
28 | - | ||
29 | - script/plugin install -f git://github.com/thoughtbot/hoptoad_notifier.git | ||
30 | - | ||
31 | -=== Configuration | ||
32 | - | ||
33 | -You should have something like this in config/initializers/hoptoad.rb. | ||
34 | - | ||
35 | - HoptoadNotifier.configure do |config| | ||
36 | - config.api_key = '1234567890abcdef' | ||
37 | - end | ||
38 | - | ||
39 | -(Please note that this configuration should be in a global configuration, and | ||
40 | -is *not* environment-specific. Hoptoad is smart enough to know what errors are | ||
41 | -caused by what environments, so your staging errors don't get mixed in with | ||
42 | -your production errors.) | ||
43 | - | ||
44 | -After adding to your config/initializers like this you must restart your | ||
45 | -server. This will not affect the rake task but it bears stating. | ||
46 | - | ||
47 | -That should be it! Now all exceptions will be logged to Hoptoad where they can | ||
48 | -be aggregated, filtered, sorted, analyzed, massaged, and searched. In previous | ||
49 | -releases you had to include HoptoadNotifier::Catcher into your | ||
50 | -ApplicationController, but the plugin takes care of that now. | ||
51 | - | ||
52 | -You can test that Hoptoad is working in your production environment by using | ||
53 | -this rake task (from RAILS_ROOT): | ||
54 | - | ||
55 | - rake hoptoad:test | ||
56 | - | ||
57 | -If everything is configured properly, that task will send a notice to Hoptoad | ||
58 | -which will be visible immediately. | ||
59 | - | ||
60 | -=== NOTE FOR RAILS 1.2.* USERS: | ||
61 | - | ||
62 | -You will need to copy the hoptoad_notifier_tasks.rake file into your | ||
63 | -RAILS_ROOT/lib/tasks directory in order for the rake hoptoad:test task to work. | ||
64 | - | ||
65 | -== Usage | ||
66 | - | ||
67 | -for the most part, Hoptoad works for itself. Once you've included the notifier | ||
68 | -in your ApplicationController (which is now done automatically by the plugin), | ||
69 | -all errors will be rescued by the #rescue_action_in_public provided by the plugin. | ||
70 | - | ||
71 | -If you want to log arbitrary things which you've rescued yourself from a | ||
72 | -controller, you can do something like this: | ||
73 | - | ||
74 | - ... | ||
75 | - rescue => ex | ||
76 | - notify_hoptoad(ex) | ||
77 | - flash[:failure] = 'Encryptions could not be rerouted, try again.' | ||
78 | - end | ||
79 | - ... | ||
80 | - | ||
81 | -The #notify_hoptoad call will send the notice over to Hoptoad for later analysis. While in your controllers you use the notify_hoptoad method, anywhere else in your code, use HoptoadNotifier.notify. | ||
82 | - | ||
83 | -To perform custom error processing after Hoptoad has been notified, define the instance method #rescue_action_in_public_without_hoptoad(exception) in your controller. | ||
84 | - | ||
85 | -== Tracking deployments in Hoptoad | ||
86 | - | ||
87 | -Paying Hoptoad plans support the ability to track deployments of your application in Hoptoad. | ||
88 | -By notifying Hoptoad of your application deployments, all errors are resolved when a deploy occurs, | ||
89 | -so that you'll be notified again about any errors that reoccur after a deployment. | ||
90 | - | ||
91 | -Additionally, it's possible to review the errors in Hoptoad that occurred before and after a deploy. | ||
92 | - | ||
93 | -When Hoptoad is installed as a plugin this functionality is loaded automatically (if you have Capistrano version 2.0.0 or greater). | ||
94 | - | ||
95 | -When Hoptoad is installed as a gem, you need to add | ||
96 | - | ||
97 | - require 'hoptoad_notifier/recipes/hoptoad' | ||
98 | - | ||
99 | -to your deploy.rb | ||
100 | - | ||
101 | -== Going beyond exceptions | ||
102 | - | ||
103 | -You can also pass a hash to notify_hoptoad method and store whatever you want, not just an exception. And you can also use it anywhere, not just in controllers: | ||
104 | - | ||
105 | - begin | ||
106 | - params = { | ||
107 | - # params that you pass to a method that can throw an exception | ||
108 | - } | ||
109 | - my_unpredicable_method(params) | ||
110 | - rescue => e | ||
111 | - HoptoadNotifier.notify( | ||
112 | - :error_class => "Special Error", | ||
113 | - :error_message => "Special Error: #{e.message}", | ||
114 | - :parameters => params | ||
115 | - ) | ||
116 | - end | ||
117 | - | ||
118 | -While in your controllers you use the notify_hoptoad method, anywhere else in your code, use HoptoadNotifier.notify. Hoptoad will get all the information about the error itself. As for a hash, these are the keys you should pass: | ||
119 | - | ||
120 | -* :error_class – Use this to group similar errors together. When Hoptoad catches an exception it sends the class name of that exception object. | ||
121 | -* :error_message – This is the title of the error you see in the errors list. For exceptions it is "#{exception.class.name}: #{exception.message}" | ||
122 | -* :parameters – While there are several ways to send additional data to Hoptoad, passing a Hash as :parameters as in the example above is the most common use case. When Hoptoad catches an exception in a controller, the actual HTTP client request parameters are sent using this key. | ||
123 | - | ||
124 | -Hoptoad merges the hash you pass with these default options: | ||
125 | - | ||
126 | - { | ||
127 | - :api_key => HoptoadNotifier.api_key, | ||
128 | - :error_message => 'Notification', | ||
129 | - :backtrace => caller, | ||
130 | - :parameters => {}, | ||
131 | - :session => {} | ||
132 | - } | ||
133 | - | ||
134 | -You can override any of those parameters. | ||
135 | - | ||
136 | -== Filtering | ||
137 | - | ||
138 | -You can specify a whitelist of errors, that Hoptoad will not report on. Use | ||
139 | -this feature when you are so apathetic to certain errors that you don't want | ||
140 | -them even logged. | ||
141 | - | ||
142 | -This filter will only be applied to automatic notifications, not manual | ||
143 | -notifications (when #notify is called directly). | ||
144 | - | ||
145 | -Hoptoad ignores the following exceptions by default: | ||
146 | - | ||
147 | - ActiveRecord::RecordNotFound | ||
148 | - ActionController::RoutingError | ||
149 | - ActionController::InvalidAuthenticityToken | ||
150 | - ActionController::UnknownAction | ||
151 | - CGI::Session::CookieStore::TamperedWithCookie | ||
152 | - | ||
153 | -To ignore errors in addition to those, specify their names in your Hoptoad | ||
154 | -configuration block. | ||
155 | - | ||
156 | - HoptoadNotifier.configure do |config| | ||
157 | - config.api_key = '1234567890abcdef' | ||
158 | - config.ignore << ActiveRecord::IgnoreThisError | ||
159 | - end | ||
160 | - | ||
161 | -To ignore *only* certain errors (and override the defaults), use the | ||
162 | -#ignore_only attribute. | ||
163 | - | ||
164 | - HoptoadNotifier.configure do |config| | ||
165 | - config.api_key = '1234567890abcdef' | ||
166 | - config.ignore_only = [ActiveRecord::IgnoreThisError] | ||
167 | - end | ||
168 | - | ||
169 | -To ignore certain user agents, add in the #ignore_user_agent attribute as a | ||
170 | -string or regexp: | ||
171 | - | ||
172 | - HoptoadNotifier.configure do |config| | ||
173 | - config.api_key = '1234567890abcdef' | ||
174 | - config.ignore_user_agent << /Ignored/ | ||
175 | - config.ignore_user_agent << 'IgnoredUserAgent' | ||
176 | - end | ||
177 | - | ||
178 | -To ignore exceptions based on other conditions, use #ignore_by_filter: | ||
179 | - | ||
180 | - HoptoadNotifier.configure do |config| | ||
181 | - config.api_key = '1234567890abcdef' | ||
182 | - config.ignore_by_filter do |exception_data| | ||
183 | - true if exception_data[:error_class] == "RuntimeError" | ||
184 | - end | ||
185 | - end | ||
186 | - | ||
187 | -To replace sensitive information sent to the Hoptoad service with [FILTERED] use #params_filters: | ||
188 | - | ||
189 | - HoptoadNotifier.configure do |config| | ||
190 | - config.api_key = '1234567890abcdef' | ||
191 | - config.params_filters << "credit_card_number" | ||
192 | - end | ||
193 | - | ||
194 | -Note that, when rescuing exceptions within an ActionController method, | ||
195 | -hoptoad_notifier will reuse filters specified by #filter_params_logging. | ||
196 | - | ||
197 | -== Testing | ||
198 | - | ||
199 | -When you run your tests, you might notice that the Hoptoad service is recording | ||
200 | -notices generated using #notify when you don't expect it to. You can | ||
201 | -use code like this in your test_helper.rb to redefine that method so those | ||
202 | -errors are not reported while running tests. | ||
203 | - | ||
204 | - module HoptoadNotifier::Catcher | ||
205 | - def notify(thing) | ||
206 | - # do nothing. | ||
207 | - end | ||
208 | - end | ||
209 | - | ||
210 | -== Supported rails versions | ||
211 | - | ||
212 | -the notifier currently supports the following versions of Rails: | ||
213 | - | ||
214 | -* 1.2.6 | ||
215 | -* 2.0.2 | ||
216 | -* 2.1.0 | ||
217 | -* 2.1.2 | ||
218 | -* 2.2.2 | ||
219 | -* 2.3.2 | ||
220 | -* 2.3.3 | ||
221 | -* 2.3.4 | ||
222 | - | ||
223 | -Please open up a support ticket on Tender ( http://help.hoptoadapp.com ) if you're using a version of Rails that is not listed above and the notifier is not working properly. | ||
224 | - | ||
225 | -== Thanks | ||
226 | - | ||
227 | -Thanks to Eugene Bolshakov for the excellent write-up on GOING BEYOND EXCEPTIONS, which we have included above. |
vendor/plugins/hoptoad_notifier/Rakefile
@@ -1,29 +0,0 @@ | @@ -1,29 +0,0 @@ | ||
1 | -require 'rake' | ||
2 | -require 'rake/testtask' | ||
3 | -require 'rake/rdoctask' | ||
4 | - | ||
5 | -desc 'Default: run unit tests.' | ||
6 | -task :default => :test | ||
7 | - | ||
8 | -desc 'Test the hoptoad_notifier plugin.' | ||
9 | -Rake::TestTask.new(:test) do |t| | ||
10 | - t.libs << 'lib' | ||
11 | - t.pattern = 'test/**/*_test.rb' | ||
12 | - t.verbose = true | ||
13 | -end | ||
14 | - | ||
15 | -desc 'Run ginger tests' | ||
16 | -task :ginger do | ||
17 | - $LOAD_PATH << File.join(*%w[vendor ginger lib]) | ||
18 | - ARGV.clear | ||
19 | - ARGV << 'test' | ||
20 | - load File.join(*%w[vendor ginger bin ginger]) | ||
21 | -end | ||
22 | - | ||
23 | -begin | ||
24 | - require 'yard' | ||
25 | - YARD::Rake::YardocTask.new do |t| | ||
26 | - t.files = ['lib/**/*.rb', 'TESTING.rdoc'] | ||
27 | - end | ||
28 | -rescue LoadError | ||
29 | -end |
vendor/plugins/hoptoad_notifier/TESTING.rdoc
@@ -1,8 +0,0 @@ | @@ -1,8 +0,0 @@ | ||
1 | -= For Maintainers: | ||
2 | - | ||
3 | -When developing the Hoptoad Notifier, be sure to use the integration test | ||
4 | -against an existing project on staging before pushing to master. | ||
5 | - | ||
6 | -+./script/integration_test.rb <test project's api key> <staging server hostname>+ | ||
7 | - | ||
8 | -+./script/integration_test.rb <test project's api key> <staging server hostname> secure+ |
vendor/plugins/hoptoad_notifier/ginger_scenarios.rb
@@ -1,31 +0,0 @@ | @@ -1,31 +0,0 @@ | ||
1 | -require 'ginger' | ||
2 | - | ||
3 | -def create_scenario(version) | ||
4 | - scenario = Ginger::Scenario.new | ||
5 | - scenario[/^active_?support$/] = version | ||
6 | - scenario[/^active_?record$/] = version | ||
7 | - scenario[/^action_?pack$/] = version | ||
8 | - scenario[/^action_?controller$/] = version | ||
9 | - scenario | ||
10 | -end | ||
11 | - | ||
12 | -Ginger.configure do |config| | ||
13 | - config.aliases["active_record"] = "activerecord" | ||
14 | - config.aliases["active_support"] = "activesupport" | ||
15 | - config.aliases["action_controller"] = "actionpack" | ||
16 | - | ||
17 | - rails_1_2_6 = Ginger::Scenario.new | ||
18 | - rails_1_2_6[/^active_?support$/] = "1.4.4" | ||
19 | - rails_1_2_6[/^active_?record$/] = "1.15.6" | ||
20 | - rails_1_2_6[/^action_?pack$/] = "1.13.6" | ||
21 | - rails_1_2_6[/^action_?controller$/] = "1.13.6" | ||
22 | - | ||
23 | - config.scenarios << rails_1_2_6 | ||
24 | - config.scenarios << create_scenario("2.0.2") | ||
25 | - config.scenarios << create_scenario("2.1.2") | ||
26 | - config.scenarios << create_scenario("2.2.2") | ||
27 | - config.scenarios << create_scenario("2.3.2") | ||
28 | - # Rails 2.3.3 has broken params filtering | ||
29 | - # config.scenarios << create_scenario("2.3.3") | ||
30 | - config.scenarios << create_scenario("2.3.4") | ||
31 | -end |
vendor/plugins/hoptoad_notifier/init.rb
@@ -1 +0,0 @@ | @@ -1 +0,0 @@ | ||
1 | -require File.join(File.dirname(__FILE__), 'rails', 'init') |
vendor/plugins/hoptoad_notifier/install.rb
@@ -1 +0,0 @@ | @@ -1 +0,0 @@ | ||
1 | -puts IO.read(File.join(File.dirname(__FILE__), 'INSTALL')) |
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier.rb
@@ -1,150 +0,0 @@ | @@ -1,150 +0,0 @@ | ||
1 | -require 'net/http' | ||
2 | -require 'net/https' | ||
3 | -require 'rubygems' | ||
4 | -require 'active_support' | ||
5 | -require 'hoptoad_notifier/configuration' | ||
6 | -require 'hoptoad_notifier/notice' | ||
7 | -require 'hoptoad_notifier/sender' | ||
8 | -require 'hoptoad_notifier/catcher' | ||
9 | -require 'hoptoad_notifier/backtrace' | ||
10 | - | ||
11 | -# Plugin for applications to automatically post errors to the Hoptoad of their choice. | ||
12 | -module HoptoadNotifier | ||
13 | - | ||
14 | - VERSION = "2.0.18" | ||
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 | - if defined?(Rails.logger) | ||
62 | - Rails.logger | ||
63 | - elsif defined?(RAILS_DEFAULT_LOGGER) | ||
64 | - RAILS_DEFAULT_LOGGER | ||
65 | - end | ||
66 | - end | ||
67 | - | ||
68 | - # Call this method to modify defaults in your initializers. | ||
69 | - # | ||
70 | - # @example | ||
71 | - # HoptoadNotifier.configure do |config| | ||
72 | - # config.api_key = '1234567890abcdef' | ||
73 | - # config.secure = false | ||
74 | - # end | ||
75 | - def configure(silent = false) | ||
76 | - self.configuration ||= Configuration.new | ||
77 | - yield(configuration) | ||
78 | - self.sender = Sender.new(configuration) | ||
79 | - report_ready unless silent | ||
80 | - end | ||
81 | - | ||
82 | - # Sends an exception manually using this method, even when you are not in a controller. | ||
83 | - # | ||
84 | - # @param [Exception] exception The exception you want to notify Hoptoad about. | ||
85 | - # @param [Hash] opts Data that will be sent to Hoptoad. | ||
86 | - # | ||
87 | - # @option opts [String] :api_key The API key for this project. The API key is a unique identifier that Hoptoad uses for identification. | ||
88 | - # @option opts [String] :error_message The error returned by the exception (or the message you want to log). | ||
89 | - # @option opts [String] :backtrace A backtrace, usually obtained with +caller+. | ||
90 | - # @option opts [String] :request The controller's request object. | ||
91 | - # @option opts [String] :session The contents of the user's session. | ||
92 | - # @option opts [String] :environment ENV merged with the contents of the request's environment. | ||
93 | - def notify(exception, opts = {}) | ||
94 | - send_notice(build_notice_for(exception, opts)) | ||
95 | - end | ||
96 | - | ||
97 | - # Sends the notice unless it is one of the default ignored exceptions | ||
98 | - # @see HoptoadNotifier.notify | ||
99 | - def notify_or_ignore(exception, opts = {}) | ||
100 | - notice = build_notice_for(exception, opts) | ||
101 | - send_notice(notice) unless notice.ignore? | ||
102 | - end | ||
103 | - | ||
104 | - def build_lookup_hash_for(exception, options = {}) | ||
105 | - notice = build_notice_for(exception, options) | ||
106 | - | ||
107 | - result = {} | ||
108 | - result[:action] = notice.action rescue nil | ||
109 | - result[:component] = notice.component rescue nil | ||
110 | - result[:error_class] = notice.error_class if notice.error_class | ||
111 | - result[:environment_name] = 'production' | ||
112 | - | ||
113 | - unless notice.backtrace.lines.empty? | ||
114 | - result[:file] = notice.backtrace.lines.first.file | ||
115 | - result[:line_number] = notice.backtrace.lines.first.number | ||
116 | - end | ||
117 | - | ||
118 | - result | ||
119 | - end | ||
120 | - | ||
121 | - private | ||
122 | - | ||
123 | - def send_notice(notice) | ||
124 | - if configuration.public? | ||
125 | - sender.send_to_hoptoad(notice.to_xml) | ||
126 | - end | ||
127 | - end | ||
128 | - | ||
129 | - def build_notice_for(exception, opts = {}) | ||
130 | - exception = unwrap_exception(exception) | ||
131 | - if exception.respond_to?(:to_hash) | ||
132 | - opts = opts.merge(exception) | ||
133 | - else | ||
134 | - opts = opts.merge(:exception => exception) | ||
135 | - end | ||
136 | - Notice.new(configuration.merge(opts)) | ||
137 | - end | ||
138 | - | ||
139 | - def unwrap_exception(exception) | ||
140 | - if exception.respond_to?(:original_exception) | ||
141 | - exception.original_exception | ||
142 | - elsif exception.respond_to?(:continued_exception) | ||
143 | - exception.continued_exception | ||
144 | - else | ||
145 | - exception | ||
146 | - end | ||
147 | - end | ||
148 | - end | ||
149 | -end | ||
150 | - |
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/backtrace.rb
@@ -1,99 +0,0 @@ | @@ -1,99 +0,0 @@ | ||
1 | -module HoptoadNotifier | ||
2 | - # Front end to parsing the backtrace for each notice | ||
3 | - class Backtrace | ||
4 | - | ||
5 | - # Handles backtrace parsing line by line | ||
6 | - class Line | ||
7 | - | ||
8 | - INPUT_FORMAT = %r{^([^:]+):(\d+)(?::in `([^']+)')?$}.freeze | ||
9 | - | ||
10 | - # The file portion of the line (such as app/models/user.rb) | ||
11 | - attr_reader :file | ||
12 | - | ||
13 | - # The line number portion of the line | ||
14 | - attr_reader :number | ||
15 | - | ||
16 | - # The method of the line (such as index) | ||
17 | - attr_reader :method | ||
18 | - | ||
19 | - # Parses a single line of a given backtrace | ||
20 | - # @param [String] unparsed_line The raw line from +caller+ or some backtrace | ||
21 | - # @return [Line] The parsed backtrace line | ||
22 | - def self.parse(unparsed_line) | ||
23 | - _, file, number, method = unparsed_line.match(INPUT_FORMAT).to_a | ||
24 | - new(file, number, method) | ||
25 | - end | ||
26 | - | ||
27 | - def initialize(file, number, method) | ||
28 | - self.file = file | ||
29 | - self.number = number | ||
30 | - self.method = method | ||
31 | - end | ||
32 | - | ||
33 | - # Reconstructs the line in a readable fashion | ||
34 | - def to_s | ||
35 | - "#{file}:#{number}:in `#{method}'" | ||
36 | - end | ||
37 | - | ||
38 | - def ==(other) | ||
39 | - to_s == other.to_s | ||
40 | - end | ||
41 | - | ||
42 | - def inspect | ||
43 | - "<Line:#{to_s}>" | ||
44 | - end | ||
45 | - | ||
46 | - private | ||
47 | - | ||
48 | - attr_writer :file, :number, :method | ||
49 | - end | ||
50 | - | ||
51 | - # holder for an Array of Backtrace::Line instances | ||
52 | - attr_reader :lines | ||
53 | - | ||
54 | - def self.parse(ruby_backtrace, opts = {}) | ||
55 | - ruby_lines = split_multiline_backtrace(ruby_backtrace) | ||
56 | - | ||
57 | - filters = opts[:filters] || [] | ||
58 | - filtered_lines = ruby_lines.to_a.map do |line| | ||
59 | - filters.inject(line) do |line, proc| | ||
60 | - proc.call(line) | ||
61 | - end | ||
62 | - end.compact | ||
63 | - | ||
64 | - lines = filtered_lines.collect do |unparsed_line| | ||
65 | - Line.parse(unparsed_line) | ||
66 | - end | ||
67 | - | ||
68 | - instance = new(lines) | ||
69 | - end | ||
70 | - | ||
71 | - def initialize(lines) | ||
72 | - self.lines = lines | ||
73 | - end | ||
74 | - | ||
75 | - def inspect | ||
76 | - "<Backtrace: " + lines.collect { |line| line.inspect }.join(", ") + ">" | ||
77 | - end | ||
78 | - | ||
79 | - def ==(other) | ||
80 | - if other.respond_to?(:lines) | ||
81 | - lines == other.lines | ||
82 | - else | ||
83 | - false | ||
84 | - end | ||
85 | - end | ||
86 | - | ||
87 | - private | ||
88 | - | ||
89 | - attr_writer :lines | ||
90 | - | ||
91 | - def self.split_multiline_backtrace(backtrace) | ||
92 | - if backtrace.to_a.size == 1 | ||
93 | - backtrace.to_a.first.split(/\n\s*/) | ||
94 | - else | ||
95 | - backtrace | ||
96 | - end | ||
97 | - end | ||
98 | - end | ||
99 | -end |
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/catcher.rb
@@ -1,95 +0,0 @@ | @@ -1,95 +0,0 @@ | ||
1 | -module HoptoadNotifier | ||
2 | - # Include this module in Controllers in which you want to be notified of errors. | ||
3 | - module Catcher | ||
4 | - | ||
5 | - # Sets up an alias chain to catch exceptions when Rails does | ||
6 | - def self.included(base) #:nodoc: | ||
7 | - if base.instance_methods.map(&:to_s).include? 'rescue_action_in_public' and !base.instance_methods.map(&:to_s).include? 'rescue_action_in_public_without_hoptoad' | ||
8 | - base.send(:alias_method, :rescue_action_in_public_without_hoptoad, :rescue_action_in_public) | ||
9 | - base.send(:alias_method, :rescue_action_in_public, :rescue_action_in_public_with_hoptoad) | ||
10 | - base.send(:alias_method, :rescue_action_locally_without_hoptoad, :rescue_action_locally) | ||
11 | - base.send(:alias_method, :rescue_action_locally, :rescue_action_locally_with_hoptoad) | ||
12 | - end | ||
13 | - end | ||
14 | - | ||
15 | - private | ||
16 | - | ||
17 | - # Overrides the rescue_action method in ActionController::Base, but does not inhibit | ||
18 | - # any custom processing that is defined with Rails 2's exception helpers. | ||
19 | - def rescue_action_in_public_with_hoptoad(exception) | ||
20 | - unless hoptoad_ignore_user_agent? | ||
21 | - HoptoadNotifier.notify_or_ignore(exception, hoptoad_request_data) | ||
22 | - end | ||
23 | - rescue_action_in_public_without_hoptoad(exception) | ||
24 | - end | ||
25 | - | ||
26 | - def rescue_action_locally_with_hoptoad(exception) | ||
27 | - result = rescue_action_locally_without_hoptoad(exception) | ||
28 | - | ||
29 | - if HoptoadNotifier.configuration.development_lookup | ||
30 | - path = File.join(File.dirname(__FILE__), '..', 'templates', 'rescue.erb') | ||
31 | - notice = HoptoadNotifier.build_lookup_hash_for(exception, hoptoad_request_data) | ||
32 | - | ||
33 | - result << @template.render( | ||
34 | - :file => path, | ||
35 | - :use_full_path => false, | ||
36 | - :locals => { :host => HoptoadNotifier.configuration.host, | ||
37 | - :api_key => HoptoadNotifier.configuration.api_key, | ||
38 | - :notice => notice }) | ||
39 | - end | ||
40 | - | ||
41 | - result | ||
42 | - end | ||
43 | - | ||
44 | - # This method should be used for sending manual notifications while you are still | ||
45 | - # inside the controller. Otherwise it works like HoptoadNotifier.notify. | ||
46 | - def notify_hoptoad(hash_or_exception) | ||
47 | - unless consider_all_requests_local || local_request? | ||
48 | - HoptoadNotifier.notify(hash_or_exception, hoptoad_request_data) | ||
49 | - end | ||
50 | - end | ||
51 | - | ||
52 | - def hoptoad_ignore_user_agent? #:nodoc: | ||
53 | - # Rails 1.2.6 doesn't have request.user_agent, so check for it here | ||
54 | - user_agent = request.respond_to?(:user_agent) ? request.user_agent : request.env["HTTP_USER_AGENT"] | ||
55 | - HoptoadNotifier.configuration.ignore_user_agent.flatten.any? { |ua| ua === user_agent } | ||
56 | - end | ||
57 | - | ||
58 | - def hoptoad_request_data | ||
59 | - { :parameters => hoptoad_filter_if_filtering(params.to_hash), | ||
60 | - :session_data => hoptoad_session_data, | ||
61 | - :controller => params[:controller], | ||
62 | - :action => params[:action], | ||
63 | - :url => hoptoad_request_url, | ||
64 | - :cgi_data => hoptoad_filter_if_filtering(request.env), | ||
65 | - :environment_vars => hoptoad_filter_if_filtering(ENV) } | ||
66 | - end | ||
67 | - | ||
68 | - def hoptoad_filter_if_filtering(hash) | ||
69 | - if respond_to?(:filter_parameters) | ||
70 | - filter_parameters(hash) rescue hash | ||
71 | - else | ||
72 | - hash | ||
73 | - end | ||
74 | - end | ||
75 | - | ||
76 | - def hoptoad_session_data | ||
77 | - if session.respond_to?(:to_hash) | ||
78 | - session.to_hash | ||
79 | - else | ||
80 | - session.data | ||
81 | - end | ||
82 | - end | ||
83 | - | ||
84 | - def hoptoad_request_url | ||
85 | - url = "#{request.protocol}#{request.host}" | ||
86 | - | ||
87 | - unless [80, 443].include?(request.port) | ||
88 | - url << ":#{request.port}" | ||
89 | - end | ||
90 | - | ||
91 | - url << request.request_uri | ||
92 | - url | ||
93 | - end | ||
94 | - end | ||
95 | -end |
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/configuration.rb
@@ -1,229 +0,0 @@ | @@ -1,229 +0,0 @@ | ||
1 | -module HoptoadNotifier | ||
2 | - # Used to set up and modify settings for the notifier. | ||
3 | - class Configuration | ||
4 | - | ||
5 | - OPTIONS = [:api_key, :backtrace_filters, :development_environments, | ||
6 | - :development_lookup, :environment_name, :host, | ||
7 | - :http_open_timeout, :http_read_timeout, :ignore, :ignore_by_filters, | ||
8 | - :ignore_user_agent, :notifier_name, :notifier_url, :notifier_version, | ||
9 | - :params_filters, :project_root, :port, :protocol, :proxy_host, | ||
10 | - :proxy_pass, :proxy_port, :proxy_user, :secure].freeze | ||
11 | - | ||
12 | - # The API key for your project, found on the project edit form. | ||
13 | - attr_accessor :api_key | ||
14 | - | ||
15 | - # The host to connect to (defaults to hoptoadapp.com). | ||
16 | - attr_accessor :host | ||
17 | - | ||
18 | - # The port on which your Hoptoad server runs (defaults to 443 for secure | ||
19 | - # connections, 80 for insecure connections). | ||
20 | - attr_accessor :port | ||
21 | - | ||
22 | - # +true+ for https connections, +false+ for http connections. | ||
23 | - attr_accessor :secure | ||
24 | - | ||
25 | - # The HTTP open timeout in seconds (defaults to 2). | ||
26 | - attr_accessor :http_open_timeout | ||
27 | - | ||
28 | - # The HTTP read timeout in seconds (defaults to 5). | ||
29 | - attr_accessor :http_read_timeout | ||
30 | - | ||
31 | - # The hostname of your proxy server (if using a proxy) | ||
32 | - attr_accessor :proxy_host | ||
33 | - | ||
34 | - # The port of your proxy server (if using a proxy) | ||
35 | - attr_accessor :proxy_port | ||
36 | - | ||
37 | - # The username to use when logging into your proxy server (if using a proxy) | ||
38 | - attr_accessor :proxy_user | ||
39 | - | ||
40 | - # The password to use when logging into your proxy server (if using a proxy) | ||
41 | - attr_accessor :proxy_pass | ||
42 | - | ||
43 | - # A list of parameters that should be filtered out of what is sent to Hoptoad. | ||
44 | - # By default, all "password" attributes will have their contents replaced. | ||
45 | - attr_reader :params_filters | ||
46 | - | ||
47 | - # A list of filters for cleaning and pruning the backtrace. See #filter_backtrace. | ||
48 | - attr_reader :backtrace_filters | ||
49 | - | ||
50 | - # A list of filters for ignoring exceptions. See #ignore_by_filter. | ||
51 | - attr_reader :ignore_by_filters | ||
52 | - | ||
53 | - # A list of exception classes to ignore. The array can be appended to. | ||
54 | - attr_reader :ignore | ||
55 | - | ||
56 | - # A list of user agents that are being ignored. The array can be appended to. | ||
57 | - attr_reader :ignore_user_agent | ||
58 | - | ||
59 | - # A list of environments in which notifications should not be sent. | ||
60 | - attr_accessor :development_environments | ||
61 | - | ||
62 | - # +true+ if you want to check for production errors matching development errors, +false+ otherwise. | ||
63 | - attr_accessor :development_lookup | ||
64 | - | ||
65 | - # The name of the environment the application is running in | ||
66 | - attr_accessor :environment_name | ||
67 | - | ||
68 | - # The path to the project in which the error occurred, such as the RAILS_ROOT | ||
69 | - attr_accessor :project_root | ||
70 | - | ||
71 | - # The name of the notifier library being used to send notifications (such as "Hoptoad Notifier") | ||
72 | - attr_accessor :notifier_name | ||
73 | - | ||
74 | - # The version of the notifier library being used to send notifications (such as "1.0.2") | ||
75 | - attr_accessor :notifier_version | ||
76 | - | ||
77 | - # The url of the notifier library being used to send notifications | ||
78 | - attr_accessor :notifier_url | ||
79 | - | ||
80 | - DEFAULT_PARAMS_FILTERS = %w(password password_confirmation).freeze | ||
81 | - | ||
82 | - DEFAULT_BACKTRACE_FILTERS = [ | ||
83 | - lambda { |line| | ||
84 | - if defined?(HoptoadNotifier.configuration.project_root) | ||
85 | - line.gsub(/#{HoptoadNotifier.configuration.project_root}/, "[PROJECT_ROOT]") | ||
86 | - else | ||
87 | - line | ||
88 | - end | ||
89 | - }, | ||
90 | - lambda { |line| line.gsub(/^\.\//, "") }, | ||
91 | - lambda { |line| | ||
92 | - if defined?(Gem) | ||
93 | - Gem.path.inject(line) do |line, path| | ||
94 | - line.gsub(/#{path}/, "[GEM_ROOT]") | ||
95 | - end | ||
96 | - end | ||
97 | - }, | ||
98 | - lambda { |line| line if line !~ %r{lib/hoptoad_notifier} } | ||
99 | - ].freeze | ||
100 | - | ||
101 | - IGNORE_DEFAULT = ['ActiveRecord::RecordNotFound', | ||
102 | - 'ActionController::RoutingError', | ||
103 | - 'ActionController::InvalidAuthenticityToken', | ||
104 | - 'CGI::Session::CookieStore::TamperedWithCookie', | ||
105 | - 'ActionController::UnknownAction'] | ||
106 | - | ||
107 | - # Some of these don't exist for Rails 1.2.*, so we have to consider that. | ||
108 | - IGNORE_DEFAULT.map!{|e| eval(e) rescue nil }.compact! | ||
109 | - IGNORE_DEFAULT.freeze | ||
110 | - | ||
111 | - alias_method :secure?, :secure | ||
112 | - | ||
113 | - def initialize | ||
114 | - @secure = false | ||
115 | - @host = 'hoptoadapp.com' | ||
116 | - @http_open_timeout = 2 | ||
117 | - @http_read_timeout = 5 | ||
118 | - @params_filters = DEFAULT_PARAMS_FILTERS.dup | ||
119 | - @backtrace_filters = DEFAULT_BACKTRACE_FILTERS.dup | ||
120 | - @ignore_by_filters = [] | ||
121 | - @ignore = IGNORE_DEFAULT.dup | ||
122 | - @ignore_user_agent = [] | ||
123 | - @development_environments = %w(development test cucumber) | ||
124 | - @development_lookup = true | ||
125 | - @notifier_name = 'Hoptoad Notifier' | ||
126 | - @notifier_version = VERSION | ||
127 | - @notifier_url = 'http://hoptoadapp.com' | ||
128 | - end | ||
129 | - | ||
130 | - # Takes a block and adds it to the list of backtrace filters. When the filters | ||
131 | - # run, the block will be handed each line of the backtrace and can modify | ||
132 | - # it as necessary. | ||
133 | - # | ||
134 | - # @example | ||
135 | - # config.filter_bracktrace do |line| | ||
136 | - # line.gsub(/^#{Rails.root}/, "[RAILS_ROOT]") | ||
137 | - # end | ||
138 | - # | ||
139 | - # @param [Proc] block The new backtrace filter. | ||
140 | - # @yieldparam [String] line A line in the backtrace. | ||
141 | - def filter_backtrace(&block) | ||
142 | - self.backtrace_filters << block | ||
143 | - end | ||
144 | - | ||
145 | - # Takes a block and adds it to the list of ignore filters. | ||
146 | - # When the filters run, the block will be handed the exception. | ||
147 | - # @example | ||
148 | - # config.ignore_by_filter do |exception_data| | ||
149 | - # true if exception_data[:error_class] == "RuntimeError" | ||
150 | - # end | ||
151 | - # | ||
152 | - # @param [Proc] block The new ignore filter | ||
153 | - # @yieldparam [Hash] data The exception data given to +HoptoadNotifier.notify+ | ||
154 | - # @yieldreturn [Boolean] If the block returns true the exception will be ignored, otherwise it will be processed by hoptoad. | ||
155 | - def ignore_by_filter(&block) | ||
156 | - self.ignore_by_filters << block | ||
157 | - end | ||
158 | - | ||
159 | - # Overrides the list of default ignored errors. | ||
160 | - # | ||
161 | - # @param [Array<Exception>] names A list of exceptions to ignore. | ||
162 | - def ignore_only=(names) | ||
163 | - @ignore = [names].flatten | ||
164 | - end | ||
165 | - | ||
166 | - # Overrides the list of default ignored user agents | ||
167 | - # | ||
168 | - # @param [Array<String>] A list of user agents to ignore | ||
169 | - def ignore_user_agent_only=(names) | ||
170 | - @ignore_user_agent = [names].flatten | ||
171 | - end | ||
172 | - | ||
173 | - # Allows config options to be read like a hash | ||
174 | - # | ||
175 | - # @param [Symbol] option Key for a given attribute | ||
176 | - def [](option) | ||
177 | - send(option) | ||
178 | - end | ||
179 | - | ||
180 | - # Returns a hash of all configurable options | ||
181 | - def to_hash | ||
182 | - OPTIONS.inject({}) do |hash, option| | ||
183 | - hash.merge(option.to_sym => send(option)) | ||
184 | - end | ||
185 | - end | ||
186 | - | ||
187 | - # Returns a hash of all configurable options merged with +hash+ | ||
188 | - # | ||
189 | - # @param [Hash] hash A set of configuration options that will take precedence over the defaults | ||
190 | - def merge(hash) | ||
191 | - to_hash.merge(hash) | ||
192 | - end | ||
193 | - | ||
194 | - # Determines if the notifier will send notices. | ||
195 | - # @return [Boolean] Returns +false+ if in a development environment, +true+ otherwise. | ||
196 | - def public? | ||
197 | - !development_environments.include?(environment_name) | ||
198 | - end | ||
199 | - | ||
200 | - def port | ||
201 | - @port || default_port | ||
202 | - end | ||
203 | - | ||
204 | - def protocol | ||
205 | - if secure? | ||
206 | - 'https' | ||
207 | - else | ||
208 | - 'http' | ||
209 | - end | ||
210 | - end | ||
211 | - | ||
212 | - def environment_filters | ||
213 | - warn 'config.environment_filters has been deprecated and has no effect.' | ||
214 | - [] | ||
215 | - end | ||
216 | - | ||
217 | - private | ||
218 | - | ||
219 | - def default_port | ||
220 | - if secure? | ||
221 | - 443 | ||
222 | - else | ||
223 | - 80 | ||
224 | - end | ||
225 | - end | ||
226 | - | ||
227 | - end | ||
228 | - | ||
229 | -end |
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/notice.rb
@@ -1,295 +0,0 @@ | @@ -1,295 +0,0 @@ | ||
1 | -module HoptoadNotifier | ||
2 | - class Notice | ||
3 | - | ||
4 | - # The exception that caused this notice, if any | ||
5 | - attr_reader :exception | ||
6 | - | ||
7 | - # The API key for the project to which this notice should be sent | ||
8 | - attr_reader :api_key | ||
9 | - | ||
10 | - # The backtrace from the given exception or hash. | ||
11 | - attr_reader :backtrace | ||
12 | - | ||
13 | - # The name of the class of error (such as RuntimeError) | ||
14 | - attr_reader :error_class | ||
15 | - | ||
16 | - # The name of the server environment (such as "production") | ||
17 | - attr_reader :environment_name | ||
18 | - | ||
19 | - # CGI variables such as HTTP_METHOD | ||
20 | - attr_reader :cgi_data | ||
21 | - | ||
22 | - # The message from the exception, or a general description of the error | ||
23 | - attr_reader :error_message | ||
24 | - | ||
25 | - # See Configuration#backtrace_filters | ||
26 | - attr_reader :backtrace_filters | ||
27 | - | ||
28 | - # See Configuration#params_filters | ||
29 | - attr_reader :params_filters | ||
30 | - | ||
31 | - # A hash of parameters from the query string or post body. | ||
32 | - attr_reader :parameters | ||
33 | - alias_method :params, :parameters | ||
34 | - | ||
35 | - # The component (if any) which was used in this request (usually the controller) | ||
36 | - attr_reader :component | ||
37 | - alias_method :controller, :component | ||
38 | - | ||
39 | - # The action (if any) that was called in this request | ||
40 | - attr_reader :action | ||
41 | - | ||
42 | - # A hash of session data from the request | ||
43 | - attr_reader :session_data | ||
44 | - | ||
45 | - # The path to the project that caused the error (usually RAILS_ROOT) | ||
46 | - attr_reader :project_root | ||
47 | - | ||
48 | - # The URL at which the error occurred (if any) | ||
49 | - attr_reader :url | ||
50 | - | ||
51 | - # See Configuration#ignore | ||
52 | - attr_reader :ignore | ||
53 | - | ||
54 | - # See Configuration#ignore_by_filters | ||
55 | - attr_reader :ignore_by_filters | ||
56 | - | ||
57 | - # The name of the notifier library sending this notice, such as "Hoptoad Notifier" | ||
58 | - attr_reader :notifier_name | ||
59 | - | ||
60 | - # The version number of the notifier library sending this notice, such as "2.1.3" | ||
61 | - attr_reader :notifier_version | ||
62 | - | ||
63 | - # A URL for more information about the notifier library sending this notice | ||
64 | - attr_reader :notifier_url | ||
65 | - | ||
66 | - def initialize(args) | ||
67 | - self.args = args | ||
68 | - self.exception = args[:exception] | ||
69 | - self.api_key = args[:api_key] | ||
70 | - self.project_root = args[:project_root] | ||
71 | - self.url = args[:url] | ||
72 | - | ||
73 | - self.notifier_name = args[:notifier_name] | ||
74 | - self.notifier_version = args[:notifier_version] | ||
75 | - self.notifier_url = args[:notifier_url] | ||
76 | - | ||
77 | - self.ignore = args[:ignore] || [] | ||
78 | - self.ignore_by_filters = args[:ignore_by_filters] || [] | ||
79 | - self.backtrace_filters = args[:backtrace_filters] || [] | ||
80 | - self.params_filters = args[:params_filters] || [] | ||
81 | - self.parameters = args[:parameters] || {} | ||
82 | - self.component = args[:component] || args[:controller] | ||
83 | - self.action = args[:action] | ||
84 | - | ||
85 | - self.environment_name = args[:environment_name] | ||
86 | - self.cgi_data = args[:cgi_data] | ||
87 | - self.backtrace = Backtrace.parse(exception_attribute(:backtrace, caller)) | ||
88 | - self.error_class = exception_attribute(:error_class) {|exception| exception.class.name } | ||
89 | - self.error_message = exception_attribute(:error_message, 'Notification') do |exception| | ||
90 | - "#{exception.class.name}: #{exception.message}" | ||
91 | - end | ||
92 | - | ||
93 | - find_session_data | ||
94 | - clean_params | ||
95 | - end | ||
96 | - | ||
97 | - # Converts the given notice to XML | ||
98 | - def to_xml | ||
99 | - builder = Builder::XmlMarkup.new | ||
100 | - builder.instruct! | ||
101 | - xml = builder.notice(:version => HoptoadNotifier::API_VERSION) do |notice| | ||
102 | - notice.tag!("api-key", api_key) | ||
103 | - notice.notifier do |notifier| | ||
104 | - notifier.name(notifier_name) | ||
105 | - notifier.version(notifier_version) | ||
106 | - notifier.url(notifier_url) | ||
107 | - end | ||
108 | - notice.error do |error| | ||
109 | - error.tag!('class', error_class) | ||
110 | - error.message(error_message) | ||
111 | - error.backtrace do |backtrace| | ||
112 | - self.backtrace.lines.each do |line| | ||
113 | - backtrace.line(:number => line.number, | ||
114 | - :file => line.file, | ||
115 | - :method => line.method) | ||
116 | - end | ||
117 | - end | ||
118 | - end | ||
119 | - if url || | ||
120 | - controller || | ||
121 | - action || | ||
122 | - !parameters.blank? || | ||
123 | - !cgi_data.blank? || | ||
124 | - !session_data.blank? | ||
125 | - notice.request do |request| | ||
126 | - request.url(url) | ||
127 | - request.component(controller) | ||
128 | - request.action(action) | ||
129 | - unless parameters.blank? | ||
130 | - request.params do |params| | ||
131 | - xml_vars_for(params, parameters) | ||
132 | - end | ||
133 | - end | ||
134 | - unless session_data.blank? | ||
135 | - request.session do |session| | ||
136 | - xml_vars_for(session, session_data) | ||
137 | - end | ||
138 | - end | ||
139 | - unless cgi_data.blank? | ||
140 | - request.tag!("cgi-data") do |cgi_datum| | ||
141 | - xml_vars_for(cgi_datum, cgi_data) | ||
142 | - end | ||
143 | - end | ||
144 | - end | ||
145 | - end | ||
146 | - notice.tag!("server-environment") do |env| | ||
147 | - env.tag!("project-root", project_root) | ||
148 | - env.tag!("environment-name", environment_name) | ||
149 | - end | ||
150 | - end | ||
151 | - xml.to_s | ||
152 | - end | ||
153 | - | ||
154 | - # Determines if this notice should be ignored | ||
155 | - def ignore? | ||
156 | - ignored_class_names.include?(error_class) || | ||
157 | - ignore_by_filters.any? {|filter| filter.call(self) } | ||
158 | - end | ||
159 | - | ||
160 | - # Allows properties to be accessed using a hash-like syntax | ||
161 | - # | ||
162 | - # @example | ||
163 | - # notice[:error_message] | ||
164 | - # @param [String] method The given key for an attribute | ||
165 | - # @return The attribute value, or self if given +:request+ | ||
166 | - def [](method) | ||
167 | - case method | ||
168 | - when :request | ||
169 | - self | ||
170 | - else | ||
171 | - send(method) | ||
172 | - end | ||
173 | - end | ||
174 | - | ||
175 | - private | ||
176 | - | ||
177 | - attr_writer :exception, :api_key, :backtrace, :error_class, :error_message, | ||
178 | - :backtrace_filters, :parameters, :params_filters, | ||
179 | - :environment_filters, :session_data, :project_root, :url, :ignore, | ||
180 | - :ignore_by_filters, :notifier_name, :notifier_url, :notifier_version, | ||
181 | - :component, :action, :cgi_data, :environment_name | ||
182 | - | ||
183 | - # Arguments given in the initializer | ||
184 | - attr_accessor :args | ||
185 | - | ||
186 | - # Gets a property named +attribute+ of an exception, either from an actual | ||
187 | - # exception or a hash. | ||
188 | - # | ||
189 | - # If an exception is available, #from_exception will be used. Otherwise, | ||
190 | - # a key named +attribute+ will be used from the #args. | ||
191 | - # | ||
192 | - # If no exception or hash key is available, +default+ will be used. | ||
193 | - def exception_attribute(attribute, default = nil, &block) | ||
194 | - (exception && from_exception(attribute, &block)) || args[attribute] || default | ||
195 | - end | ||
196 | - | ||
197 | - # Gets a property named +attribute+ from an exception. | ||
198 | - # | ||
199 | - # If a block is given, it will be used when getting the property from an | ||
200 | - # exception. The block should accept and exception and return the value for | ||
201 | - # the property. | ||
202 | - # | ||
203 | - # If no block is given, a method with the same name as +attribute+ will be | ||
204 | - # invoked for the value. | ||
205 | - def from_exception(attribute) | ||
206 | - if block_given? | ||
207 | - yield(exception) | ||
208 | - else | ||
209 | - exception.send(attribute) | ||
210 | - end | ||
211 | - end | ||
212 | - | ||
213 | - # Removes non-serializable data from the given attribute. | ||
214 | - # See #clean_unserializable_data | ||
215 | - def clean_unserializable_data_from(attribute) | ||
216 | - self.send(:"#{attribute}=", clean_unserializable_data(send(attribute))) | ||
217 | - end | ||
218 | - | ||
219 | - # Removes non-serializable data. Allowed data types are strings, arrays, | ||
220 | - # and hashes. All other types are converted to strings. | ||
221 | - # TODO: move this onto Hash | ||
222 | - def clean_unserializable_data(data) | ||
223 | - if data.respond_to?(:to_hash) | ||
224 | - data.to_hash.inject({}) do |result, (key, value)| | ||
225 | - result.merge(key => clean_unserializable_data(value)) | ||
226 | - end | ||
227 | - elsif data.respond_to?(:to_ary) | ||
228 | - data.collect do |value| | ||
229 | - clean_unserializable_data(value) | ||
230 | - end | ||
231 | - else | ||
232 | - data.to_s | ||
233 | - end | ||
234 | - end | ||
235 | - | ||
236 | - # Replaces the contents of params that match params_filters. | ||
237 | - # TODO: extract this to a different class | ||
238 | - def clean_params | ||
239 | - clean_unserializable_data_from(:parameters) | ||
240 | - filter(parameters) | ||
241 | - if cgi_data | ||
242 | - clean_unserializable_data_from(:cgi_data) | ||
243 | - filter(cgi_data) | ||
244 | - end | ||
245 | - if session_data | ||
246 | - clean_unserializable_data_from(:session_data) | ||
247 | - end | ||
248 | - end | ||
249 | - | ||
250 | - def filter(hash) | ||
251 | - if params_filters | ||
252 | - hash.each do |key, value| | ||
253 | - if filter_key?(key) | ||
254 | - hash[key] = "[FILTERED]" | ||
255 | - elsif value.respond_to?(:to_hash) | ||
256 | - filter(hash[key]) | ||
257 | - end | ||
258 | - end | ||
259 | - end | ||
260 | - end | ||
261 | - | ||
262 | - def filter_key?(key) | ||
263 | - params_filters.any? do |filter| | ||
264 | - key.to_s.include?(filter) | ||
265 | - end | ||
266 | - end | ||
267 | - | ||
268 | - def find_session_data | ||
269 | - self.session_data = args[:session_data] || args[:session] || {} | ||
270 | - self.session_data = session_data[:data] if session_data[:data] | ||
271 | - end | ||
272 | - | ||
273 | - # Converts the mixed class instances and class names into just names | ||
274 | - # TODO: move this into Configuration or another class | ||
275 | - def ignored_class_names | ||
276 | - ignore.collect do |string_or_class| | ||
277 | - if string_or_class.respond_to?(:name) | ||
278 | - string_or_class.name | ||
279 | - else | ||
280 | - string_or_class | ||
281 | - end | ||
282 | - end | ||
283 | - end | ||
284 | - | ||
285 | - def xml_vars_for(builder, hash) | ||
286 | - hash.each do |key, value| | ||
287 | - if value.respond_to?(:to_hash) | ||
288 | - builder.var(:key => key){|b| xml_vars_for(b, value.to_hash) } | ||
289 | - else | ||
290 | - builder.var(value.to_s, :key => key) | ||
291 | - end | ||
292 | - end | ||
293 | - end | ||
294 | - end | ||
295 | -end |
vendor/plugins/hoptoad_notifier/lib/hoptoad_notifier/sender.rb
@@ -1,63 +0,0 @@ | @@ -1,63 +0,0 @@ | ||
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}" } | ||
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 |
vendor/plugins/hoptoad_notifier/lib/hoptoad_tasks.rb
@@ -1,37 +0,0 @@ | @@ -1,37 +0,0 @@ | ||
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 | - |
vendor/plugins/hoptoad_notifier/lib/templates/rescue.erb
@@ -1,91 +0,0 @@ | @@ -1,91 +0,0 @@ | ||
1 | -<script type="text/javascript"> | ||
2 | -var Hoptoad = { | ||
3 | - host : <%= host.to_json %>, | ||
4 | - api_key : <%= api_key.to_json %>, | ||
5 | - notice : <%= notice.to_json %>, | ||
6 | - message : 'This error exists in production!', | ||
7 | - | ||
8 | - initialize: function() { | ||
9 | - if (this.initialized) { | ||
10 | - return; | ||
11 | - } else { | ||
12 | - this.initialized = true; | ||
13 | - } | ||
14 | - | ||
15 | - var data = []; | ||
16 | - | ||
17 | - for (var key in this.notice) { | ||
18 | - data[data.length] = 'notice[' + key + ']=' + this.notice[key]; | ||
19 | - } | ||
20 | - | ||
21 | - data[data.length] = 'notice[api_key]=' + this.api_key; | ||
22 | - data[data.length] = 'callback=Hoptoad.onSuccess'; | ||
23 | - data[data.length] = '_=' + (new Date()).getTime(); | ||
24 | - | ||
25 | - var head = document.getElementsByTagName('head')[0]; | ||
26 | - var done = false; | ||
27 | - | ||
28 | - var | ||
29 | - script = document.createElement('script'); | ||
30 | - script.src = 'http://' + this.host + '/notices_api/v1/notices/exist?' + | ||
31 | - data.join('&'); | ||
32 | - script.type = 'text/javascript'; | ||
33 | - script.onload = script.onreadystatechange = function(){ | ||
34 | - if (!done && (!this.readyState || | ||
35 | - this.readyState == 'loaded' || this.readyState == 'complete')) { | ||
36 | - | ||
37 | - done = true; | ||
38 | - | ||
39 | - // Handle memory leak in IE. (via jQuery) | ||
40 | - script.onload = script.onreadystatechange = null; | ||
41 | - head.removeChild(script); | ||
42 | - } | ||
43 | - }; | ||
44 | - | ||
45 | - head.appendChild(script); | ||
46 | - }, | ||
47 | - | ||
48 | - onSuccess: function(error) { | ||
49 | - var body = document.getElementsByTagName('body')[0]; | ||
50 | - var text = document.createTextNode(this.message); | ||
51 | - var element = document.createElement('a'); | ||
52 | - | ||
53 | - element.id = 'hoptoad'; | ||
54 | - element.href = 'http://' + error.subdomain + '.' + this.host + | ||
55 | - '/projects/' + error.project_id + '/errors/' + error.id; | ||
56 | - element.appendChild(text); | ||
57 | - | ||
58 | - body.insertBefore(element, body.firstChild); | ||
59 | - | ||
60 | - var h1 = document.getElementsByTagName('h1')[0]; | ||
61 | - var pre = document.getElementsByTagName('pre')[0]; | ||
62 | - var wrapper = document.createElement('div'); | ||
63 | - | ||
64 | - wrapper.id = 'wrapper'; | ||
65 | - wrapper.appendChild(h1); | ||
66 | - wrapper.appendChild(pre); | ||
67 | - | ||
68 | - body.insertBefore(wrapper, body.children[1]); | ||
69 | - } | ||
70 | -}; | ||
71 | - | ||
72 | -window.onload = function() { | ||
73 | - Hoptoad.initialize.apply(Hoptoad); | ||
74 | -}; | ||
75 | -</script> | ||
76 | - | ||
77 | -<style type="text/css"> | ||
78 | -#hoptoad { | ||
79 | - background: #FFF url(http://hoptoadapp.com/images/fell-off-the-toad.gif) no-repeat top right; | ||
80 | - color: #F00; | ||
81 | - padding: 45px 101px 45px 12px; | ||
82 | - font-size: 14px; | ||
83 | - font-weight: bold; | ||
84 | - display: block; | ||
85 | - float: right; | ||
86 | -} | ||
87 | - | ||
88 | -#wrapper { | ||
89 | - padding-right: 360px; | ||
90 | -} | ||
91 | -</style> |
vendor/plugins/hoptoad_notifier/rails/init.rb
@@ -1,8 +0,0 @@ | @@ -1,8 +0,0 @@ | ||
1 | -if defined?(ActionController::Base) && !ActionController::Base.include?(HoptoadNotifier::Catcher) | ||
2 | - ActionController::Base.send(:include, HoptoadNotifier::Catcher) | ||
3 | -end | ||
4 | - | ||
5 | -HoptoadNotifier.configure(true) do |config| | ||
6 | - config.environment_name = RAILS_ENV | ||
7 | - config.project_root = RAILS_ROOT | ||
8 | -end |
vendor/plugins/hoptoad_notifier/recipes/hoptoad.rb
@@ -1,24 +0,0 @@ | @@ -1,24 +0,0 @@ | ||
1 | -# When Hoptoad is installed as a plugin this is loaded automatically. | ||
2 | -# | ||
3 | -# When Hoptoad installed as a gem, you need to add | ||
4 | -# require 'hoptoad_notifier/recipes/hoptoad' | ||
5 | -# to your deploy.rb | ||
6 | -# | ||
7 | -# Defines deploy:notify_hoptoad which will send information about the deploy to Hoptoad. | ||
8 | -# | ||
9 | -after "deploy", "deploy:notify_hoptoad" | ||
10 | -after "deploy:migrations", "deploy:notify_hoptoad" | ||
11 | - | ||
12 | -namespace :deploy do | ||
13 | - desc "Notify Hoptoad of the deployment" | ||
14 | - task :notify_hoptoad, :except => { :no_release => true } do | ||
15 | - rails_env = fetch(:hoptoad_env, fetch(:rails_env, "production")) | ||
16 | - local_user = ENV['USER'] || ENV['USERNAME'] | ||
17 | - executable = RUBY_PLATFORM.downcase.include?('mswin') ? 'rake.bat' : 'rake' | ||
18 | - notify_command = "#{executable} hoptoad:deploy TO=#{rails_env} REVISION=#{current_revision} REPO=#{repository} USER=#{local_user}" | ||
19 | - notify_command << " API_KEY=#{ENV['API_KEY']}" if ENV['API_KEY'] | ||
20 | - puts "Notifying Hoptoad of Deploy (#{notify_command})" | ||
21 | - `#{notify_command}` | ||
22 | - puts "Hoptoad Notification Complete." | ||
23 | - end | ||
24 | -end |
vendor/plugins/hoptoad_notifier/script/integration_test.rb
@@ -1,38 +0,0 @@ | @@ -1,38 +0,0 @@ | ||
1 | -#!/usr/bin/env ruby | ||
2 | - | ||
3 | -require 'logger' | ||
4 | -require 'fileutils' | ||
5 | - | ||
6 | -RAILS_ENV = "production" | ||
7 | -RAILS_ROOT = FileUtils.pwd | ||
8 | -RAILS_DEFAULT_LOGGER = Logger.new(STDOUT) | ||
9 | - | ||
10 | -$: << File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')) | ||
11 | -require 'hoptoad_notifier' | ||
12 | -require 'rails/init' | ||
13 | - | ||
14 | -fail "Please supply an API Key as the first argument" if ARGV.empty? | ||
15 | - | ||
16 | -host = ARGV[1] | ||
17 | -host ||= "hoptoadapp.com" | ||
18 | - | ||
19 | -secure = (ARGV[2] == "secure") | ||
20 | - | ||
21 | -exception = begin | ||
22 | - raise "Testing hoptoad notifier with secure = #{secure}. If you can see this, it works." | ||
23 | - rescue => foo | ||
24 | - foo | ||
25 | - end | ||
26 | - | ||
27 | -HoptoadNotifier.configure do |config| | ||
28 | - config.secure = secure | ||
29 | - config.host = host | ||
30 | - config.api_key = ARGV.first | ||
31 | -end | ||
32 | -puts "Configuration:" | ||
33 | -HoptoadNotifier.configuration.to_hash.each do |key, value| | ||
34 | - puts sprintf("%25s: %s", key.to_s, value.inspect.slice(0, 55)) | ||
35 | -end | ||
36 | -puts "Sending #{secure ? "" : "in"}secure notification to project with key #{ARGV.first}" | ||
37 | -HoptoadNotifier.notify(exception) | ||
38 | - |
vendor/plugins/hoptoad_notifier/tasks/hoptoad_notifier_tasks.rake
@@ -1,89 +0,0 @@ | @@ -1,89 +0,0 @@ | ||
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 plugin 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 | - |
vendor/plugins/hoptoad_notifier/test/backtrace_test.rb
@@ -1,94 +0,0 @@ | @@ -1,94 +0,0 @@ | ||
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 | - should "remove notifier trace" do | ||
67 | - inside_notifier = ['lib/hoptoad_notifier.rb:13:in `voodoo`'] | ||
68 | - outside_notifier = ['users_controller:8:in `index`'] | ||
69 | - | ||
70 | - without_inside = HoptoadNotifier::Backtrace.parse(outside_notifier) | ||
71 | - with_inside = HoptoadNotifier::Backtrace.parse(inside_notifier + outside_notifier, | ||
72 | - :filters => default_filters) | ||
73 | - | ||
74 | - assert_equal without_inside, with_inside | ||
75 | - end | ||
76 | - | ||
77 | - should "run filters on the backtrace" do | ||
78 | - filters = [lambda { |line| line.sub('foo', 'bar') }] | ||
79 | - input = HoptoadNotifier::Backtrace.parse(["foo:13:in `one'", "baz:14:in `two'"], | ||
80 | - :filters => filters) | ||
81 | - expected = HoptoadNotifier::Backtrace.parse(["bar:13:in `one'", "baz:14:in `two'"]) | ||
82 | - assert_equal expected, input | ||
83 | - end | ||
84 | - | ||
85 | - def build_backtrace_array | ||
86 | - ["app/models/user.rb:13:in `magic'", | ||
87 | - "app/controllers/users_controller.rb:8:in `index'"] | ||
88 | - end | ||
89 | - | ||
90 | - def default_filters | ||
91 | - HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS | ||
92 | - end | ||
93 | - | ||
94 | -end |
vendor/plugins/hoptoad_notifier/test/catcher_test.rb
@@ -1,314 +0,0 @@ | @@ -1,314 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/helper' | ||
2 | - | ||
3 | -class CatcherTest < 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::Catcher) | ||
21 | - klass.class_eval(&definition) if definition | ||
22 | - define_constant('HoptoadTestController', klass) | ||
23 | - end | ||
24 | - end | ||
25 | - | ||
26 | - def assert_sent_hash(hash, xpath) | ||
27 | - hash.each do |key, value| | ||
28 | - element_xpath = "#{xpath}/var[@key = '#{key}']" | ||
29 | - if value.respond_to?(:to_hash) | ||
30 | - assert_sent_hash value.to_hash, element_xpath | ||
31 | - else | ||
32 | - assert_sent_element value.to_s, element_xpath | ||
33 | - end | ||
34 | - end | ||
35 | - end | ||
36 | - | ||
37 | - def assert_sent_element(value, xpath) | ||
38 | - assert_valid_node last_sent_notice_document, xpath, value | ||
39 | - end | ||
40 | - | ||
41 | - def assert_sent_request_info_for(request) | ||
42 | - params = request.parameters.to_hash | ||
43 | - assert_sent_hash params, '/notice/request/params' | ||
44 | - assert_sent_element params['controller'], '/notice/request/component' | ||
45 | - assert_sent_element params['action'], '/notice/request/action' | ||
46 | - assert_sent_element url_from_request(request), '/notice/request/url' | ||
47 | - assert_sent_hash request.env, '/notice/request/cgi-data' | ||
48 | - end | ||
49 | - | ||
50 | - def url_from_request(request) | ||
51 | - url = "#{request.protocol}#{request.host}" | ||
52 | - | ||
53 | - unless [80, 443].include?(request.port) | ||
54 | - url << ":#{request.port}" | ||
55 | - end | ||
56 | - | ||
57 | - url << request.request_uri | ||
58 | - url | ||
59 | - end | ||
60 | - | ||
61 | - def sender | ||
62 | - HoptoadNotifier.sender | ||
63 | - end | ||
64 | - | ||
65 | - def last_sent_notice_xml | ||
66 | - sender.collected.last | ||
67 | - end | ||
68 | - | ||
69 | - def last_sent_notice_document | ||
70 | - assert_not_nil xml = last_sent_notice_xml, "No xml was sent" | ||
71 | - Nokogiri::XML.parse(xml) | ||
72 | - end | ||
73 | - | ||
74 | - def process_action(opts = {}, &action) | ||
75 | - opts[:request] ||= ActionController::TestRequest.new | ||
76 | - opts[:response] ||= ActionController::TestResponse.new | ||
77 | - klass = build_controller_class do | ||
78 | - cattr_accessor :local | ||
79 | - define_method(:index, &action) | ||
80 | - def local_request? | ||
81 | - local | ||
82 | - end | ||
83 | - end | ||
84 | - if opts[:filters] | ||
85 | - klass.filter_parameter_logging *opts[:filters] | ||
86 | - end | ||
87 | - if opts[:user_agent] | ||
88 | - if opts[:request].respond_to?(:user_agent=) | ||
89 | - opts[:request].user_agent = opts[:user_agent] | ||
90 | - else | ||
91 | - opts[:request].env["HTTP_USER_AGENT"] = opts[:user_agent] | ||
92 | - end | ||
93 | - end | ||
94 | - if opts[:port] | ||
95 | - opts[:request].port = opts[:port] | ||
96 | - end | ||
97 | - klass.consider_all_requests_local = opts[:all_local] | ||
98 | - klass.local = opts[:local] | ||
99 | - controller = klass.new | ||
100 | - controller.stubs(:rescue_action_in_public_without_hoptoad) | ||
101 | - opts[:request].query_parameters = opts[:request].query_parameters.merge(opts[:params] || {}) | ||
102 | - opts[:request].session = ActionController::TestSession.new(opts[:session] || {}) | ||
103 | - controller.process(opts[:request], opts[:response]) | ||
104 | - controller | ||
105 | - end | ||
106 | - | ||
107 | - def process_action_with_manual_notification(args = {}) | ||
108 | - process_action(args) do | ||
109 | - notify_hoptoad(:error_message => 'fail') | ||
110 | - # Rails will raise a template error if we don't render something | ||
111 | - render :nothing => true | ||
112 | - end | ||
113 | - end | ||
114 | - | ||
115 | - def process_action_with_automatic_notification(args = {}) | ||
116 | - process_action(args) { raise "Hello" } | ||
117 | - end | ||
118 | - | ||
119 | - should "deliver notices from exceptions raised in public requests" do | ||
120 | - process_action_with_automatic_notification | ||
121 | - assert_caught_and_sent | ||
122 | - end | ||
123 | - | ||
124 | - should "not deliver notices from exceptions in local requests" do | ||
125 | - process_action_with_automatic_notification(:local => true) | ||
126 | - assert_caught_and_not_sent | ||
127 | - end | ||
128 | - | ||
129 | - should "not deliver notices from exceptions when all requests are local" do | ||
130 | - process_action_with_automatic_notification(:all_local => true) | ||
131 | - assert_caught_and_not_sent | ||
132 | - end | ||
133 | - | ||
134 | - should "not deliver notices from actions that don't raise" do | ||
135 | - controller = process_action { render :text => 'Hello' } | ||
136 | - assert_caught_and_not_sent | ||
137 | - assert_equal 'Hello', controller.response.body | ||
138 | - end | ||
139 | - | ||
140 | - should "not deliver ignored exceptions raised by actions" do | ||
141 | - ignore(RuntimeError) | ||
142 | - process_action_with_automatic_notification | ||
143 | - assert_caught_and_not_sent | ||
144 | - end | ||
145 | - | ||
146 | - should "deliver ignored exception raised manually" do | ||
147 | - ignore(RuntimeError) | ||
148 | - process_action_with_manual_notification | ||
149 | - assert_caught_and_sent | ||
150 | - end | ||
151 | - | ||
152 | - should "deliver manually sent notices in public requests" do | ||
153 | - process_action_with_manual_notification | ||
154 | - assert_caught_and_sent | ||
155 | - end | ||
156 | - | ||
157 | - should "not deliver manually sent notices in local requests" do | ||
158 | - process_action_with_manual_notification(:local => true) | ||
159 | - assert_caught_and_not_sent | ||
160 | - end | ||
161 | - | ||
162 | - should "not deliver manually sent notices when all requests are local" do | ||
163 | - process_action_with_manual_notification(:all_local => true) | ||
164 | - assert_caught_and_not_sent | ||
165 | - end | ||
166 | - | ||
167 | - should "continue with default behavior after delivering an exception" do | ||
168 | - controller = process_action_with_automatic_notification(:public => true) | ||
169 | - # TODO: can we test this without stubbing? | ||
170 | - assert_received(controller, :rescue_action_in_public_without_hoptoad) | ||
171 | - end | ||
172 | - | ||
173 | - should "not create actions from Hoptoad methods" do | ||
174 | - controller = build_controller_class.new | ||
175 | - assert_equal [], HoptoadNotifier::Catcher.instance_methods | ||
176 | - end | ||
177 | - | ||
178 | - should "ignore exceptions when user agent is being ignored by regular expression" do | ||
179 | - HoptoadNotifier.configuration.ignore_user_agent_only = [/Ignored/] | ||
180 | - process_action_with_automatic_notification(:user_agent => 'ShouldBeIgnored') | ||
181 | - assert_caught_and_not_sent | ||
182 | - end | ||
183 | - | ||
184 | - should "ignore exceptions when user agent is being ignored by string" do | ||
185 | - HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent'] | ||
186 | - process_action_with_automatic_notification(:user_agent => 'IgnoredUserAgent') | ||
187 | - assert_caught_and_not_sent | ||
188 | - end | ||
189 | - | ||
190 | - should "not ignore exceptions when user agent is not being ignored" do | ||
191 | - HoptoadNotifier.configuration.ignore_user_agent_only = ['IgnoredUserAgent'] | ||
192 | - process_action_with_automatic_notification(:user_agent => 'NonIgnoredAgent') | ||
193 | - assert_caught_and_sent | ||
194 | - end | ||
195 | - | ||
196 | - should "send session data for manual notifications" do | ||
197 | - data = { 'one' => 'two' } | ||
198 | - process_action_with_manual_notification(:session => data) | ||
199 | - assert_sent_hash data, "/notice/request/session" | ||
200 | - end | ||
201 | - | ||
202 | - should "send session data for automatic notification" do | ||
203 | - data = { 'one' => 'two' } | ||
204 | - process_action_with_automatic_notification(:session => data) | ||
205 | - assert_sent_hash data, "/notice/request/session" | ||
206 | - end | ||
207 | - | ||
208 | - should "send request data for manual notification" do | ||
209 | - params = { 'controller' => "hoptoad_test", 'action' => "index" } | ||
210 | - controller = process_action_with_manual_notification(:params => params) | ||
211 | - assert_sent_request_info_for controller.request | ||
212 | - end | ||
213 | - | ||
214 | - should "send request data for manual notification with non-standard port" do | ||
215 | - params = { 'controller' => "hoptoad_test", 'action' => "index" } | ||
216 | - controller = process_action_with_manual_notification(:params => params, :port => 81) | ||
217 | - assert_sent_request_info_for controller.request | ||
218 | - end | ||
219 | - | ||
220 | - should "send request data for automatic notification" do | ||
221 | - params = { 'controller' => "hoptoad_test", 'action' => "index" } | ||
222 | - controller = process_action_with_automatic_notification(:params => params) | ||
223 | - assert_sent_request_info_for controller.request | ||
224 | - end | ||
225 | - | ||
226 | - should "send request data for automatic notification with non-standard port" do | ||
227 | - params = { 'controller' => "hoptoad_test", 'action' => "index" } | ||
228 | - controller = process_action_with_automatic_notification(:params => params, :port => 81) | ||
229 | - assert_sent_request_info_for controller.request | ||
230 | - end | ||
231 | - | ||
232 | - should "use standard rails logging filters on params and env" do | ||
233 | - filtered_params = { "abc" => "123", | ||
234 | - "def" => "456", | ||
235 | - "ghi" => "[FILTERED]" } | ||
236 | - ENV['ghi'] = 'abc' | ||
237 | - filtered_env = { 'ghi' => '[FILTERED]' } | ||
238 | - filtered_cgi = { 'REQUEST_METHOD' => '[FILTERED]' } | ||
239 | - | ||
240 | - process_action_with_automatic_notification(:filters => [:ghi, :request_method], | ||
241 | - :params => { "abc" => "123", | ||
242 | - "def" => "456", | ||
243 | - "ghi" => "789" }) | ||
244 | - assert_sent_hash filtered_params, '/notice/request/params' | ||
245 | - assert_sent_hash filtered_cgi, '/notice/request/cgi-data' | ||
246 | - end | ||
247 | - | ||
248 | - context "for a local error with development lookup enabled" do | ||
249 | - setup do | ||
250 | - HoptoadNotifier.configuration.development_lookup = true | ||
251 | - HoptoadNotifier.stubs(:build_lookup_hash_for).returns({ :awesome => 2 }) | ||
252 | - | ||
253 | - @controller = process_action_with_automatic_notification(:local => true) | ||
254 | - @response = @controller.response | ||
255 | - end | ||
256 | - | ||
257 | - should "append custom CSS and JS to response body for a local error" do | ||
258 | - assert_match /text\/css/, @response.body | ||
259 | - assert_match /text\/javascript/, @response.body | ||
260 | - end | ||
261 | - | ||
262 | - should "contain host, API key and notice JSON" do | ||
263 | - assert_match HoptoadNotifier.configuration.host.to_json, @response.body | ||
264 | - assert_match HoptoadNotifier.configuration.api_key.to_json, @response.body | ||
265 | - assert_match ({ :awesome => 2 }).to_json, @response.body | ||
266 | - end | ||
267 | - end | ||
268 | - | ||
269 | - context "for a local error with development lookup disabled" do | ||
270 | - setup do | ||
271 | - HoptoadNotifier.configuration.development_lookup = false | ||
272 | - | ||
273 | - @controller = process_action_with_automatic_notification(:local => true) | ||
274 | - @response = @controller.response | ||
275 | - end | ||
276 | - | ||
277 | - should "not append custom CSS and JS to response for a local error" do | ||
278 | - assert_no_match /text\/css/, @response.body | ||
279 | - assert_no_match /text\/javascript/, @response.body | ||
280 | - end | ||
281 | - end | ||
282 | - | ||
283 | - should "call session.to_hash if available" do | ||
284 | - hash_data = {:key => :value} | ||
285 | - | ||
286 | - session = ActionController::TestSession.new | ||
287 | - ActionController::TestSession.stubs(:new).returns(session) | ||
288 | - session.stubs(:to_hash).returns(hash_data) | ||
289 | - | ||
290 | - process_action_with_automatic_notification | ||
291 | - assert_received(session, :to_hash) | ||
292 | - assert_received(session, :data) { |expect| expect.never } | ||
293 | - assert_caught_and_sent | ||
294 | - end | ||
295 | - | ||
296 | - should "call session.data if session.to_hash is undefined" do | ||
297 | - hash_data = {:key => :value} | ||
298 | - | ||
299 | - session = ActionController::TestSession.new | ||
300 | - ActionController::TestSession.stubs(:new).returns(session) | ||
301 | - session.stubs(:data).returns(hash_data) | ||
302 | - if session.respond_to?(:to_hash) | ||
303 | - class << session | ||
304 | - undef to_hash | ||
305 | - end | ||
306 | - end | ||
307 | - | ||
308 | - process_action_with_automatic_notification | ||
309 | - assert_received(session, :to_hash) { |expect| expect.never } | ||
310 | - assert_received(session, :data) { |expect| expect.at_least_once } | ||
311 | - assert_caught_and_sent | ||
312 | - end | ||
313 | - | ||
314 | -end |
vendor/plugins/hoptoad_notifier/test/configuration_test.rb
@@ -1,199 +0,0 @@ | @@ -1,199 +0,0 @@ | ||
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 :notifier_version, HoptoadNotifier::VERSION | ||
15 | - assert_config_default :notifier_name, 'Hoptoad Notifier' | ||
16 | - assert_config_default :notifier_url, 'http://hoptoadapp.com' | ||
17 | - assert_config_default :secure, false | ||
18 | - assert_config_default :host, 'hoptoadapp.com' | ||
19 | - assert_config_default :http_open_timeout, 2 | ||
20 | - assert_config_default :http_read_timeout, 5 | ||
21 | - assert_config_default :ignore_by_filters, [] | ||
22 | - assert_config_default :ignore_user_agent, [] | ||
23 | - assert_config_default :params_filters, | ||
24 | - HoptoadNotifier::Configuration::DEFAULT_PARAMS_FILTERS | ||
25 | - assert_config_default :backtrace_filters, | ||
26 | - HoptoadNotifier::Configuration::DEFAULT_BACKTRACE_FILTERS | ||
27 | - assert_config_default :ignore, | ||
28 | - HoptoadNotifier::Configuration::IGNORE_DEFAULT | ||
29 | - assert_config_default :development_lookup, true | ||
30 | - end | ||
31 | - | ||
32 | - should "provide default values for secure connections" do | ||
33 | - config = HoptoadNotifier::Configuration.new | ||
34 | - config.secure = true | ||
35 | - assert_equal 443, config.port | ||
36 | - assert_equal 'https', config.protocol | ||
37 | - end | ||
38 | - | ||
39 | - should "provide default values for insecure connections" do | ||
40 | - config = HoptoadNotifier::Configuration.new | ||
41 | - config.secure = false | ||
42 | - assert_equal 80, config.port | ||
43 | - assert_equal 'http', config.protocol | ||
44 | - end | ||
45 | - | ||
46 | - should "not cache inferred ports" do | ||
47 | - config = HoptoadNotifier::Configuration.new | ||
48 | - config.secure = false | ||
49 | - config.port | ||
50 | - config.secure = true | ||
51 | - assert_equal 443, config.port | ||
52 | - end | ||
53 | - | ||
54 | - should "allow values to be overwritten" do | ||
55 | - assert_config_overridable :proxy_host | ||
56 | - assert_config_overridable :proxy_port | ||
57 | - assert_config_overridable :proxy_user | ||
58 | - assert_config_overridable :proxy_pass | ||
59 | - assert_config_overridable :secure | ||
60 | - assert_config_overridable :host | ||
61 | - assert_config_overridable :port | ||
62 | - assert_config_overridable :http_open_timeout | ||
63 | - assert_config_overridable :http_read_timeout | ||
64 | - assert_config_overridable :project_root | ||
65 | - assert_config_overridable :notifier_version | ||
66 | - assert_config_overridable :notifier_name | ||
67 | - assert_config_overridable :notifier_url | ||
68 | - assert_config_overridable :environment_name | ||
69 | - assert_config_overridable :development_lookup | ||
70 | - end | ||
71 | - | ||
72 | - should "have an api key" do | ||
73 | - assert_config_overridable :api_key | ||
74 | - end | ||
75 | - | ||
76 | - should "act like a hash" do | ||
77 | - config = HoptoadNotifier::Configuration.new | ||
78 | - hash = config.to_hash | ||
79 | - [:api_key, :backtrace_filters, :development_environments, | ||
80 | - :environment_name, :host, :http_open_timeout, | ||
81 | - :http_read_timeout, :ignore, :ignore_by_filters, :ignore_user_agent, | ||
82 | - :notifier_name, :notifier_url, :notifier_version, :params_filters, | ||
83 | - :project_root, :port, :protocol, :proxy_host, :proxy_pass, :proxy_port, | ||
84 | - :proxy_user, :secure, :development_lookup].each do |option| | ||
85 | - assert_equal config[option], hash[option], "Wrong value for #{option}" | ||
86 | - end | ||
87 | - end | ||
88 | - | ||
89 | - should "be mergable" do | ||
90 | - config = HoptoadNotifier::Configuration.new | ||
91 | - hash = config.to_hash | ||
92 | - assert_equal hash.merge(:key => 'value'), config.merge(:key => 'value') | ||
93 | - end | ||
94 | - | ||
95 | - should "allow param filters to be appended" do | ||
96 | - assert_appends_value :params_filters | ||
97 | - end | ||
98 | - | ||
99 | - should "warn when attempting to read environment filters" do | ||
100 | - config = HoptoadNotifier::Configuration.new | ||
101 | - config. | ||
102 | - expects(:warn). | ||
103 | - with(regexp_matches(/deprecated/i)) | ||
104 | - assert_equal [], config.environment_filters | ||
105 | - end | ||
106 | - | ||
107 | - should "allow ignored user agents to be appended" do | ||
108 | - assert_appends_value :ignore_user_agent | ||
109 | - end | ||
110 | - | ||
111 | - should "allow backtrace filters to be appended" do | ||
112 | - assert_appends_value(:backtrace_filters) do |config| | ||
113 | - new_filter = lambda {} | ||
114 | - config.filter_backtrace(&new_filter) | ||
115 | - new_filter | ||
116 | - end | ||
117 | - end | ||
118 | - | ||
119 | - should "allow ignore by filters to be appended" do | ||
120 | - assert_appends_value(:ignore_by_filters) do |config| | ||
121 | - new_filter = lambda {} | ||
122 | - config.ignore_by_filter(&new_filter) | ||
123 | - new_filter | ||
124 | - end | ||
125 | - end | ||
126 | - | ||
127 | - should "allow ignored exceptions to be appended" do | ||
128 | - config = HoptoadNotifier::Configuration.new | ||
129 | - original_filters = config.ignore.dup | ||
130 | - new_filter = 'hello' | ||
131 | - config.ignore << new_filter | ||
132 | - assert_same_elements original_filters + [new_filter], config.ignore | ||
133 | - end | ||
134 | - | ||
135 | - should "allow ignored exceptions to be replaced" do | ||
136 | - assert_replaces(:ignore, :ignore_only=) | ||
137 | - end | ||
138 | - | ||
139 | - should "allow ignored user agents to be replaced" do | ||
140 | - assert_replaces(:ignore_user_agent, :ignore_user_agent_only=) | ||
141 | - end | ||
142 | - | ||
143 | - should "use development and test as development environments by default" do | ||
144 | - config = HoptoadNotifier::Configuration.new | ||
145 | - assert_same_elements %w(development test cucumber), config.development_environments | ||
146 | - end | ||
147 | - | ||
148 | - should "be public in a public environment" do | ||
149 | - config = HoptoadNotifier::Configuration.new | ||
150 | - config.development_environments = %w(development) | ||
151 | - config.environment_name = 'production' | ||
152 | - assert config.public? | ||
153 | - end | ||
154 | - | ||
155 | - should "not be public in a development environment" do | ||
156 | - config = HoptoadNotifier::Configuration.new | ||
157 | - config.development_environments = %w(staging) | ||
158 | - config.environment_name = 'staging' | ||
159 | - assert !config.public? | ||
160 | - end | ||
161 | - | ||
162 | - should "be public without an environment name" do | ||
163 | - config = HoptoadNotifier::Configuration.new | ||
164 | - assert config.public? | ||
165 | - end | ||
166 | - | ||
167 | - def assert_config_default(option, default_value, config = nil) | ||
168 | - config ||= HoptoadNotifier::Configuration.new | ||
169 | - assert_equal default_value, config.send(option) | ||
170 | - end | ||
171 | - | ||
172 | - def assert_config_overridable(option, value = 'a value') | ||
173 | - config = HoptoadNotifier::Configuration.new | ||
174 | - config.send(:"#{option}=", value) | ||
175 | - assert_equal value, config.send(option) | ||
176 | - end | ||
177 | - | ||
178 | - def assert_appends_value(option, &block) | ||
179 | - config = HoptoadNotifier::Configuration.new | ||
180 | - original_values = config.send(option).dup | ||
181 | - block ||= lambda do |config| | ||
182 | - new_value = 'hello' | ||
183 | - config.send(option) << new_value | ||
184 | - new_value | ||
185 | - end | ||
186 | - new_value = block.call(config) | ||
187 | - assert_same_elements original_values + [new_value], config.send(option) | ||
188 | - end | ||
189 | - | ||
190 | - def assert_replaces(option, setter) | ||
191 | - config = HoptoadNotifier::Configuration.new | ||
192 | - new_value = 'hello' | ||
193 | - config.send(setter, [new_value]) | ||
194 | - assert_equal [new_value], config.send(option) | ||
195 | - config.send(setter, new_value) | ||
196 | - assert_equal [new_value], config.send(option) | ||
197 | - end | ||
198 | - | ||
199 | -end |
vendor/plugins/hoptoad_notifier/test/helper.rb
@@ -1,238 +0,0 @@ | @@ -1,238 +0,0 @@ | ||
1 | -require 'test/unit' | ||
2 | -require 'rubygems' | ||
3 | - | ||
4 | -gem 'jferris-mocha', '0.9.5.0.1241126838' | ||
5 | - | ||
6 | -require 'shoulda' | ||
7 | -require 'mocha' | ||
8 | - | ||
9 | -$LOAD_PATH << File.join(File.dirname(__FILE__), *%w[.. vendor ginger lib]) | ||
10 | -require 'ginger' | ||
11 | - | ||
12 | -require 'action_controller' | ||
13 | -require 'action_controller/test_process' | ||
14 | -require 'active_record' | ||
15 | -require 'active_record/base' | ||
16 | -require 'active_support' | ||
17 | -require 'nokogiri' | ||
18 | - | ||
19 | -require File.join(File.dirname(__FILE__), "..", "lib", "hoptoad_notifier") | ||
20 | - | ||
21 | -begin require 'redgreen'; rescue LoadError; end | ||
22 | - | ||
23 | -module TestMethods | ||
24 | - def rescue_action e | ||
25 | - raise e | ||
26 | - end | ||
27 | - | ||
28 | - def do_raise | ||
29 | - raise "Hoptoad" | ||
30 | - end | ||
31 | - | ||
32 | - def do_not_raise | ||
33 | - render :text => "Success" | ||
34 | - end | ||
35 | - | ||
36 | - def do_raise_ignored | ||
37 | - raise ActiveRecord::RecordNotFound.new("404") | ||
38 | - end | ||
39 | - | ||
40 | - def do_raise_not_ignored | ||
41 | - raise ActiveRecord::StatementInvalid.new("Statement invalid") | ||
42 | - end | ||
43 | - | ||
44 | - def manual_notify | ||
45 | - notify_hoptoad(Exception.new) | ||
46 | - render :text => "Success" | ||
47 | - end | ||
48 | - | ||
49 | - def manual_notify_ignored | ||
50 | - notify_hoptoad(ActiveRecord::RecordNotFound.new("404")) | ||
51 | - render :text => "Success" | ||
52 | - end | ||
53 | -end | ||
54 | - | ||
55 | -class HoptoadController < ActionController::Base | ||
56 | - include TestMethods | ||
57 | -end | ||
58 | - | ||
59 | -class Test::Unit::TestCase | ||
60 | - def request(action = nil, method = :get, user_agent = nil, params = {}) | ||
61 | - @request = ActionController::TestRequest.new | ||
62 | - @request.action = action ? action.to_s : "" | ||
63 | - | ||
64 | - if user_agent | ||
65 | - if @request.respond_to?(:user_agent=) | ||
66 | - @request.user_agent = user_agent | ||
67 | - else | ||
68 | - @request.env["HTTP_USER_AGENT"] = user_agent | ||
69 | - end | ||
70 | - end | ||
71 | - @request.query_parameters = @request.query_parameters.merge(params) | ||
72 | - @response = ActionController::TestResponse.new | ||
73 | - @controller.process(@request, @response) | ||
74 | - end | ||
75 | - | ||
76 | - # Borrowed from ActiveSupport 2.3.2 | ||
77 | - def assert_difference(expression, difference = 1, message = nil, &block) | ||
78 | - b = block.send(:binding) | ||
79 | - exps = Array.wrap(expression) | ||
80 | - before = exps.map { |e| eval(e, b) } | ||
81 | - | ||
82 | - yield | ||
83 | - | ||
84 | - exps.each_with_index do |e, i| | ||
85 | - error = "#{e.inspect} didn't change by #{difference}" | ||
86 | - error = "#{message}.\n#{error}" if message | ||
87 | - assert_equal(before[i] + difference, eval(e, b), error) | ||
88 | - end | ||
89 | - end | ||
90 | - | ||
91 | - def assert_no_difference(expression, message = nil, &block) | ||
92 | - assert_difference expression, 0, message, &block | ||
93 | - end | ||
94 | - | ||
95 | - def stub_sender | ||
96 | - stub('sender', :send_to_hoptoad => nil) | ||
97 | - end | ||
98 | - | ||
99 | - def stub_sender! | ||
100 | - HoptoadNotifier.sender = stub_sender | ||
101 | - end | ||
102 | - | ||
103 | - def stub_notice | ||
104 | - stub('notice', :to_xml => 'some yaml', :ignore? => false) | ||
105 | - end | ||
106 | - | ||
107 | - def stub_notice! | ||
108 | - returning stub_notice do |notice| | ||
109 | - HoptoadNotifier::Notice.stubs(:new => notice) | ||
110 | - end | ||
111 | - end | ||
112 | - | ||
113 | - def create_dummy | ||
114 | - HoptoadNotifier::DummySender.new | ||
115 | - end | ||
116 | - | ||
117 | - def reset_config | ||
118 | - HoptoadNotifier.configuration = nil | ||
119 | - HoptoadNotifier.configure do |config| | ||
120 | - config.api_key = 'abc123' | ||
121 | - end | ||
122 | - end | ||
123 | - | ||
124 | - def clear_backtrace_filters | ||
125 | - HoptoadNotifier.configuration.backtrace_filters.clear | ||
126 | - end | ||
127 | - | ||
128 | - def build_exception | ||
129 | - raise | ||
130 | - rescue => caught_exception | ||
131 | - caught_exception | ||
132 | - end | ||
133 | - | ||
134 | - def build_notice_data(exception = nil) | ||
135 | - exception ||= build_exception | ||
136 | - { | ||
137 | - :api_key => 'abc123', | ||
138 | - :error_class => exception.class.name, | ||
139 | - :error_message => "#{exception.class.name}: #{exception.message}", | ||
140 | - :backtrace => exception.backtrace, | ||
141 | - :environment => { 'PATH' => '/bin', 'REQUEST_URI' => '/users/1' }, | ||
142 | - :request => { | ||
143 | - :params => { 'controller' => 'users', 'action' => 'show', 'id' => '1' }, | ||
144 | - :rails_root => '/path/to/application', | ||
145 | - :url => "http://test.host/users/1" | ||
146 | - }, | ||
147 | - :session => { | ||
148 | - :key => '123abc', | ||
149 | - :data => { 'user_id' => '5', 'flash' => { 'notice' => 'Logged in successfully' } } | ||
150 | - } | ||
151 | - } | ||
152 | - end | ||
153 | - | ||
154 | - def assert_caught_and_sent | ||
155 | - assert !HoptoadNotifier.sender.collected.empty? | ||
156 | - end | ||
157 | - | ||
158 | - def assert_caught_and_not_sent | ||
159 | - assert HoptoadNotifier.sender.collected.empty? | ||
160 | - end | ||
161 | - | ||
162 | - def assert_array_starts_with(expected, actual) | ||
163 | - assert_respond_to actual, :to_ary | ||
164 | - array = actual.to_ary.reverse | ||
165 | - expected.reverse.each_with_index do |value, i| | ||
166 | - assert_equal value, array[i] | ||
167 | - end | ||
168 | - end | ||
169 | - | ||
170 | - def assert_valid_node(document, xpath, content) | ||
171 | - nodes = document.xpath(xpath) | ||
172 | - assert nodes.any?{|node| node.content == content }, | ||
173 | - "Expected xpath #{xpath} to have content #{content}, " + | ||
174 | - "but found #{nodes.map { |n| n.content }} in #{nodes.size} matching nodes." + | ||
175 | - "Document:\n#{document.to_s}" | ||
176 | - end | ||
177 | -end | ||
178 | - | ||
179 | -module DefinesConstants | ||
180 | - def setup | ||
181 | - @defined_constants = [] | ||
182 | - end | ||
183 | - | ||
184 | - def teardown | ||
185 | - @defined_constants.each do |constant| | ||
186 | - Object.__send__(:remove_const, constant) | ||
187 | - end | ||
188 | - end | ||
189 | - | ||
190 | - def define_constant(name, value) | ||
191 | - Object.const_set(name, value) | ||
192 | - @defined_constants << name | ||
193 | - end | ||
194 | -end | ||
195 | - | ||
196 | -# Also stolen from AS 2.3.2 | ||
197 | -class Array | ||
198 | - # Wraps the object in an Array unless it's an Array. Converts the | ||
199 | - # object to an Array using #to_ary if it implements that. | ||
200 | - def self.wrap(object) | ||
201 | - case object | ||
202 | - when nil | ||
203 | - [] | ||
204 | - when self | ||
205 | - object | ||
206 | - else | ||
207 | - if object.respond_to?(:to_ary) | ||
208 | - object.to_ary | ||
209 | - else | ||
210 | - [object] | ||
211 | - end | ||
212 | - end | ||
213 | - end | ||
214 | - | ||
215 | -end | ||
216 | - | ||
217 | -class CollectingSender | ||
218 | - attr_reader :collected | ||
219 | - | ||
220 | - def initialize | ||
221 | - @collected = [] | ||
222 | - end | ||
223 | - | ||
224 | - def send_to_hoptoad(data) | ||
225 | - @collected << data | ||
226 | - end | ||
227 | -end | ||
228 | - | ||
229 | -class FakeLogger | ||
230 | - def info(*args); end | ||
231 | - def debug(*args); end | ||
232 | - def warn(*args); end | ||
233 | - def error(*args); end | ||
234 | - def fatal(*args); end | ||
235 | -end | ||
236 | - | ||
237 | -RAILS_DEFAULT_LOGGER = FakeLogger.new | ||
238 | - |
vendor/plugins/hoptoad_notifier/test/hoptoad_2_0.xsd
@@ -1,76 +0,0 @@ | @@ -1,76 +0,0 @@ | ||
1 | -<?xml version="1.0"?> | ||
2 | -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> | ||
3 | - | ||
4 | - <xs:element name="notice"> | ||
5 | - <xs:complexType> | ||
6 | - <xs:all> | ||
7 | - <xs:element name="api-key" type="xs:string"/> | ||
8 | - <xs:element name="notifier" type="notifier"/> | ||
9 | - <xs:element name="error" type="error"/> | ||
10 | - <xs:element name="request" type="request" minOccurs="0"/> | ||
11 | - <xs:element name="server-environment" type="serverEnvironment"/> | ||
12 | - </xs:all> | ||
13 | - <xs:attribute name="version" type="xs:string" use="required"/> | ||
14 | - </xs:complexType> | ||
15 | - </xs:element> | ||
16 | - | ||
17 | - <xs:complexType name="notifier"> | ||
18 | - <xs:all> | ||
19 | - <xs:element name="name" type="xs:string"/> | ||
20 | - <xs:element name="version" type="xs:string"/> | ||
21 | - <xs:element name="url" type="xs:string"/> | ||
22 | - </xs:all> | ||
23 | - </xs:complexType> | ||
24 | - | ||
25 | - <xs:complexType name="error"> | ||
26 | - <xs:all> | ||
27 | - <xs:element name="class" type="xs:string"/> | ||
28 | - <xs:element name="message" type="xs:string" minOccurs="0"/> | ||
29 | - <xs:element name="backtrace" type="backtrace"/> | ||
30 | - </xs:all> | ||
31 | - </xs:complexType> | ||
32 | - | ||
33 | - <xs:complexType name="backtrace"> | ||
34 | - <xs:sequence> | ||
35 | - <xs:element name="line" maxOccurs="unbounded"> | ||
36 | - <xs:complexType> | ||
37 | - <xs:attribute name="file" type="xs:string" use="required"/> | ||
38 | - <xs:attribute name="number" type="xs:string" use="required"/> | ||
39 | - <xs:attribute name="method" type="xs:string" use="optional"/> | ||
40 | - </xs:complexType> | ||
41 | - </xs:element> | ||
42 | - </xs:sequence> | ||
43 | - </xs:complexType> | ||
44 | - | ||
45 | - <xs:complexType name="request"> | ||
46 | - <xs:all> | ||
47 | - <xs:element name="url" type="xs:string"/> | ||
48 | - <xs:element name="component" type="xs:string"/> | ||
49 | - <xs:element name="action" type="xs:string" minOccurs="0"/> | ||
50 | - <xs:element name="params" type="varList" minOccurs="0"/> | ||
51 | - <xs:element name="session" type="varList" minOccurs="0"/> | ||
52 | - <xs:element name="cgi-data" type="varList" minOccurs="0"/> | ||
53 | - </xs:all> | ||
54 | - </xs:complexType> | ||
55 | - | ||
56 | - <xs:complexType name="varList"> | ||
57 | - <xs:sequence> | ||
58 | - <xs:element name="var" type="var" maxOccurs="unbounded"/> | ||
59 | - </xs:sequence> | ||
60 | - </xs:complexType> | ||
61 | - | ||
62 | - <xs:complexType name="var" mixed="true"> | ||
63 | - <xs:sequence> | ||
64 | - <xs:element name="var" type="var" minOccurs="0" maxOccurs="unbounded"/> | ||
65 | - </xs:sequence> | ||
66 | - <xs:attribute name="key" type="xs:string" use="required"/> | ||
67 | - </xs:complexType> | ||
68 | - | ||
69 | - <xs:complexType name="serverEnvironment"> | ||
70 | - <xs:sequence> | ||
71 | - <xs:element name="project-root" type="xs:string" minOccurs="0"/> | ||
72 | - <xs:element name="environment-name" type="xs:string"/> | ||
73 | - </xs:sequence> | ||
74 | - </xs:complexType> | ||
75 | - | ||
76 | -</xs:schema> |
vendor/plugins/hoptoad_notifier/test/hoptoad_tasks_test.rb
@@ -1,138 +0,0 @@ | @@ -1,138 +0,0 @@ | ||
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 |
vendor/plugins/hoptoad_notifier/test/logger_test.rb
@@ -1,85 +0,0 @@ | @@ -1,85 +0,0 @@ | ||
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 |
vendor/plugins/hoptoad_notifier/test/notice_test.rb
@@ -1,363 +0,0 @@ | @@ -1,363 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/helper' | ||
2 | - | ||
3 | -class NoticeTest < Test::Unit::TestCase | ||
4 | - | ||
5 | - include DefinesConstants | ||
6 | - | ||
7 | - def configure | ||
8 | - returning HoptoadNotifier::Configuration.new do |config| | ||
9 | - config.api_key = 'abc123def456' | ||
10 | - end | ||
11 | - end | ||
12 | - | ||
13 | - def build_notice(args = {}) | ||
14 | - configuration = args.delete(:configuration) || configure | ||
15 | - HoptoadNotifier::Notice.new(configuration.merge(args)) | ||
16 | - end | ||
17 | - | ||
18 | - def stub_request(attrs = {}) | ||
19 | - stub('request', { :parameters => { 'one' => 'two' }, | ||
20 | - :protocol => 'http', | ||
21 | - :host => 'some.host', | ||
22 | - :request_uri => '/some/uri', | ||
23 | - :session => { :to_hash => { 'a' => 'b' } }, | ||
24 | - :env => { 'three' => 'four' } }.update(attrs)) | ||
25 | - end | ||
26 | - | ||
27 | - should "set the api key" do | ||
28 | - api_key = 'key' | ||
29 | - notice = build_notice(:api_key => api_key) | ||
30 | - assert_equal api_key, notice.api_key | ||
31 | - end | ||
32 | - | ||
33 | - should "accept a project root" do | ||
34 | - project_root = '/path/to/project' | ||
35 | - notice = build_notice(:project_root => project_root) | ||
36 | - assert_equal project_root, notice.project_root | ||
37 | - end | ||
38 | - | ||
39 | - should "accept a component" do | ||
40 | - assert_equal 'users_controller', build_notice(:component => 'users_controller').controller | ||
41 | - end | ||
42 | - | ||
43 | - should "alias the component as controller" do | ||
44 | - assert_equal 'users_controller', build_notice(:controller => 'users_controller').component | ||
45 | - assert_equal 'users_controller', build_notice(:component => 'users_controller').controller | ||
46 | - end | ||
47 | - | ||
48 | - should "accept a action" do | ||
49 | - assert_equal 'index', build_notice(:action => 'index').action | ||
50 | - end | ||
51 | - | ||
52 | - should "accept a url" do | ||
53 | - url = 'http://some.host/uri' | ||
54 | - notice = build_notice(:url => url) | ||
55 | - assert_equal url, notice.url | ||
56 | - end | ||
57 | - | ||
58 | - should "accept a backtrace from an exception or hash" do | ||
59 | - array = ["user.rb:34:in `crazy'"] | ||
60 | - exception = build_exception | ||
61 | - exception.set_backtrace array | ||
62 | - backtrace = HoptoadNotifier::Backtrace.parse(array) | ||
63 | - notice_from_exception = build_notice(:exception => exception) | ||
64 | - | ||
65 | - | ||
66 | - assert_equal notice_from_exception.backtrace, | ||
67 | - backtrace, | ||
68 | - "backtrace was not correctly set from an exception" | ||
69 | - | ||
70 | - notice_from_hash = build_notice(:backtrace => array) | ||
71 | - assert_equal notice_from_hash.backtrace, | ||
72 | - backtrace, | ||
73 | - "backtrace was not correctly set from a hash" | ||
74 | - end | ||
75 | - | ||
76 | - should "set the error class from an exception or hash" do | ||
77 | - assert_accepts_exception_attribute :error_class do |exception| | ||
78 | - exception.class.name | ||
79 | - end | ||
80 | - end | ||
81 | - | ||
82 | - should "set the error message from an exception or hash" do | ||
83 | - assert_accepts_exception_attribute :error_message do |exception| | ||
84 | - "#{exception.class.name}: #{exception.message}" | ||
85 | - end | ||
86 | - end | ||
87 | - | ||
88 | - should "accept parameters from a request or hash" do | ||
89 | - parameters = { 'one' => 'two' } | ||
90 | - notice_from_hash = build_notice(:parameters => parameters) | ||
91 | - assert_equal notice_from_hash.parameters, parameters | ||
92 | - end | ||
93 | - | ||
94 | - should "accept session data from a session[:data] hash" do | ||
95 | - data = { 'one' => 'two' } | ||
96 | - notice = build_notice(:session => { :data => data }) | ||
97 | - assert_equal data, notice.session_data | ||
98 | - end | ||
99 | - | ||
100 | - should "accept session data from a session_data hash" do | ||
101 | - data = { 'one' => 'two' } | ||
102 | - notice = build_notice(:session_data => data) | ||
103 | - assert_equal data, notice.session_data | ||
104 | - end | ||
105 | - | ||
106 | - should "accept an environment name" do | ||
107 | - assert_equal 'development', build_notice(:environment_name => 'development').environment_name | ||
108 | - end | ||
109 | - | ||
110 | - should "accept CGI data from a hash" do | ||
111 | - data = { 'string' => 'value' } | ||
112 | - notice = build_notice(:cgi_data => data) | ||
113 | - assert_equal data, notice.cgi_data, "should take CGI data from a hash" | ||
114 | - end | ||
115 | - | ||
116 | - should "accept notifier information" do | ||
117 | - params = { :notifier_name => 'a name for a notifier', | ||
118 | - :notifier_version => '1.0.5', | ||
119 | - :notifier_url => 'http://notifiers.r.us/download' } | ||
120 | - notice = build_notice(params) | ||
121 | - assert_equal params[:notifier_name], notice.notifier_name | ||
122 | - assert_equal params[:notifier_version], notice.notifier_version | ||
123 | - assert_equal params[:notifier_url], notice.notifier_url | ||
124 | - end | ||
125 | - | ||
126 | - should "set sensible defaults without an exception" do | ||
127 | - backtrace = HoptoadNotifier::Backtrace.parse(caller) | ||
128 | - notice = build_notice | ||
129 | - | ||
130 | - assert_equal 'Notification', notice.error_message | ||
131 | - assert_array_starts_with backtrace.lines, notice.backtrace.lines | ||
132 | - assert_equal({}, notice.parameters) | ||
133 | - assert_equal({}, notice.session_data) | ||
134 | - end | ||
135 | - | ||
136 | - should "use the caller as the backtrace for an exception without a backtrace" do | ||
137 | - backtrace = HoptoadNotifier::Backtrace.parse(caller) | ||
138 | - notice = build_notice(:exception => StandardError.new('error'), :backtrace => nil) | ||
139 | - | ||
140 | - assert_array_starts_with backtrace.lines, notice.backtrace.lines | ||
141 | - end | ||
142 | - | ||
143 | - should "convert unserializable objects to strings" do | ||
144 | - assert_serializes_hash(:parameters) | ||
145 | - assert_serializes_hash(:cgi_data) | ||
146 | - assert_serializes_hash(:session_data) | ||
147 | - end | ||
148 | - | ||
149 | - should "filter parameters" do | ||
150 | - assert_filters_hash(:parameters) | ||
151 | - end | ||
152 | - | ||
153 | - should "filter cgi data" do | ||
154 | - assert_filters_hash(:cgi_data) | ||
155 | - end | ||
156 | - | ||
157 | - context "a Notice turned into XML" do | ||
158 | - setup do | ||
159 | - HoptoadNotifier.configure do |config| | ||
160 | - config.api_key = "1234567890" | ||
161 | - end | ||
162 | - | ||
163 | - @exception = build_exception | ||
164 | - | ||
165 | - @notice = build_notice({ | ||
166 | - :notifier_name => 'a name', | ||
167 | - :notifier_version => '1.2.3', | ||
168 | - :notifier_url => 'http://some.url/path', | ||
169 | - :exception => @exception, | ||
170 | - :controller => "controller", | ||
171 | - :action => "action", | ||
172 | - :url => "http://url.com", | ||
173 | - :parameters => { "paramskey" => "paramsvalue", | ||
174 | - "nestparentkey" => { "nestkey" => "nestvalue" } }, | ||
175 | - :session_data => { "sessionkey" => "sessionvalue" }, | ||
176 | - :cgi_data => { "cgikey" => "cgivalue" }, | ||
177 | - :project_root => "RAILS_ROOT", | ||
178 | - :environment_name => "RAILS_ENV" | ||
179 | - }) | ||
180 | - | ||
181 | - @xml = @notice.to_xml | ||
182 | - | ||
183 | - @document = Nokogiri::XML::Document.parse(@xml) | ||
184 | - end | ||
185 | - | ||
186 | - should "validate against the XML schema" do | ||
187 | - assert_valid_notice_document @document | ||
188 | - end | ||
189 | - | ||
190 | - should "serialize a Notice to XML when sent #to_xml" do | ||
191 | - assert_valid_node(@document, "//api-key", @notice.api_key) | ||
192 | - | ||
193 | - assert_valid_node(@document, "//notifier/name", @notice.notifier_name) | ||
194 | - assert_valid_node(@document, "//notifier/version", @notice.notifier_version) | ||
195 | - assert_valid_node(@document, "//notifier/url", @notice.notifier_url) | ||
196 | - | ||
197 | - assert_valid_node(@document, "//error/class", @notice.error_class) | ||
198 | - assert_valid_node(@document, "//error/message", @notice.error_message) | ||
199 | - | ||
200 | - assert_valid_node(@document, "//error/backtrace/line/@number", @notice.backtrace.lines.first.number) | ||
201 | - assert_valid_node(@document, "//error/backtrace/line/@file", @notice.backtrace.lines.first.file) | ||
202 | - assert_valid_node(@document, "//error/backtrace/line/@method", @notice.backtrace.lines.first.method) | ||
203 | - | ||
204 | - assert_valid_node(@document, "//request/url", @notice.url) | ||
205 | - assert_valid_node(@document, "//request/component", @notice.controller) | ||
206 | - assert_valid_node(@document, "//request/action", @notice.action) | ||
207 | - | ||
208 | - assert_valid_node(@document, "//request/params/var/@key", "paramskey") | ||
209 | - assert_valid_node(@document, "//request/params/var", "paramsvalue") | ||
210 | - assert_valid_node(@document, "//request/params/var/@key", "nestparentkey") | ||
211 | - assert_valid_node(@document, "//request/params/var/var/@key", "nestkey") | ||
212 | - assert_valid_node(@document, "//request/params/var/var", "nestvalue") | ||
213 | - assert_valid_node(@document, "//request/session/var/@key", "sessionkey") | ||
214 | - assert_valid_node(@document, "//request/session/var", "sessionvalue") | ||
215 | - assert_valid_node(@document, "//request/cgi-data/var/@key", "cgikey") | ||
216 | - assert_valid_node(@document, "//request/cgi-data/var", "cgivalue") | ||
217 | - | ||
218 | - assert_valid_node(@document, "//server-environment/project-root", "RAILS_ROOT") | ||
219 | - assert_valid_node(@document, "//server-environment/environment-name", "RAILS_ENV") | ||
220 | - end | ||
221 | - end | ||
222 | - | ||
223 | - should "not send empty request data" do | ||
224 | - notice = build_notice | ||
225 | - assert_nil notice.url | ||
226 | - assert_nil notice.controller | ||
227 | - assert_nil notice.action | ||
228 | - | ||
229 | - xml = notice.to_xml | ||
230 | - document = Nokogiri::XML.parse(xml) | ||
231 | - assert_nil document.at('//request/url') | ||
232 | - assert_nil document.at('//request/component') | ||
233 | - assert_nil document.at('//request/action') | ||
234 | - | ||
235 | - assert_valid_notice_document document | ||
236 | - end | ||
237 | - | ||
238 | - %w(url controller action).each do |var| | ||
239 | - should "send a request if #{var} is present" do | ||
240 | - notice = build_notice(var.to_sym => 'value') | ||
241 | - xml = notice.to_xml | ||
242 | - document = Nokogiri::XML.parse(xml) | ||
243 | - assert_not_nil document.at('//request') | ||
244 | - end | ||
245 | - end | ||
246 | - | ||
247 | - %w(parameters cgi_data session_data).each do |var| | ||
248 | - should "send a request if #{var} is present" do | ||
249 | - notice = build_notice(var.to_sym => { 'key' => 'value' }) | ||
250 | - xml = notice.to_xml | ||
251 | - document = Nokogiri::XML.parse(xml) | ||
252 | - assert_not_nil document.at('//request') | ||
253 | - end | ||
254 | - end | ||
255 | - | ||
256 | - should "not ignore an exception not matching ignore filters" do | ||
257 | - notice = build_notice(:error_class => 'ArgumentError', | ||
258 | - :ignore => ['Argument'], | ||
259 | - :ignore_by_filters => [lambda { |notice| false }]) | ||
260 | - assert !notice.ignore? | ||
261 | - end | ||
262 | - | ||
263 | - should "ignore an exception with a matching error class" do | ||
264 | - notice = build_notice(:error_class => 'ArgumentError', | ||
265 | - :ignore => [ArgumentError]) | ||
266 | - assert notice.ignore? | ||
267 | - end | ||
268 | - | ||
269 | - should "ignore an exception with a matching error class name" do | ||
270 | - notice = build_notice(:error_class => 'ArgumentError', | ||
271 | - :ignore => ['ArgumentError']) | ||
272 | - assert notice.ignore? | ||
273 | - end | ||
274 | - | ||
275 | - should "ignore an exception with a matching filter" do | ||
276 | - filter = lambda {|notice| notice.error_class == 'ArgumentError' } | ||
277 | - notice = build_notice(:error_class => 'ArgumentError', | ||
278 | - :ignore_by_filters => [filter]) | ||
279 | - assert notice.ignore? | ||
280 | - end | ||
281 | - | ||
282 | - should "not raise without an ignore list" do | ||
283 | - notice = build_notice(:ignore => nil, :ignore_by_filters => nil) | ||
284 | - assert_nothing_raised do | ||
285 | - notice.ignore? | ||
286 | - end | ||
287 | - end | ||
288 | - | ||
289 | - should "act like a hash" do | ||
290 | - notice = build_notice(:error_message => 'some message') | ||
291 | - assert_equal notice.error_message, notice[:error_message] | ||
292 | - end | ||
293 | - | ||
294 | - should "return params on notice[:request][:params]" do | ||
295 | - params = { 'one' => 'two' } | ||
296 | - notice = build_notice(:parameters => params) | ||
297 | - assert_equal params, notice[:request][:params] | ||
298 | - end | ||
299 | - | ||
300 | - should "ensure #to_hash is called on objects that support it" do | ||
301 | - assert_nothing_raised do | ||
302 | - build_notice(:session => { :object => stub(:to_hash => {}) }) | ||
303 | - end | ||
304 | - end | ||
305 | - | ||
306 | - def assert_accepts_exception_attribute(attribute, args = {}, &block) | ||
307 | - exception = build_exception | ||
308 | - block ||= lambda { exception.send(attribute) } | ||
309 | - value = block.call(exception) | ||
310 | - | ||
311 | - notice_from_exception = build_notice(args.merge(:exception => exception)) | ||
312 | - | ||
313 | - assert_equal notice_from_exception.send(attribute), | ||
314 | - value, | ||
315 | - "#{attribute} was not correctly set from an exception" | ||
316 | - | ||
317 | - notice_from_hash = build_notice(args.merge(attribute => value)) | ||
318 | - assert_equal notice_from_hash.send(attribute), | ||
319 | - value, | ||
320 | - "#{attribute} was not correctly set from a hash" | ||
321 | - end | ||
322 | - | ||
323 | - def assert_serializes_hash(attribute) | ||
324 | - [File.open(__FILE__), Proc.new { puts "boo!" }, Module.new].each do |object| | ||
325 | - hash = { | ||
326 | - :strange_object => object, | ||
327 | - :sub_hash => { | ||
328 | - :sub_object => object | ||
329 | - }, | ||
330 | - :array => [object] | ||
331 | - } | ||
332 | - notice = build_notice(attribute => hash) | ||
333 | - hash = notice.send(attribute) | ||
334 | - assert_equal object.to_s, hash[:strange_object], "objects should be serialized" | ||
335 | - assert_kind_of Hash, hash[:sub_hash], "subhashes should be kept" | ||
336 | - assert_equal object.to_s, hash[:sub_hash][:sub_object], "subhash members should be serialized" | ||
337 | - assert_kind_of Array, hash[:array], "arrays should be kept" | ||
338 | - assert_equal object.to_s, hash[:array].first, "array members should be serialized" | ||
339 | - end | ||
340 | - end | ||
341 | - | ||
342 | - def assert_valid_notice_document(document) | ||
343 | - xsd_path = File.join(File.dirname(__FILE__), "hoptoad_2_0.xsd") | ||
344 | - schema = Nokogiri::XML::Schema.new(IO.read(xsd_path)) | ||
345 | - errors = schema.validate(document) | ||
346 | - assert errors.empty?, errors.collect{|e| e.message }.join | ||
347 | - end | ||
348 | - | ||
349 | - def assert_filters_hash(attribute) | ||
350 | - filters = %w(abc def) | ||
351 | - original = { 'abc' => "123", 'def' => "456", 'ghi' => "789", 'nested' => { 'abc' => '100' } } | ||
352 | - filtered = { 'abc' => "[FILTERED]", | ||
353 | - 'def' => "[FILTERED]", | ||
354 | - 'ghi' => "789", | ||
355 | - 'nested' => { 'abc' => '[FILTERED]' } } | ||
356 | - | ||
357 | - notice = build_notice(:params_filters => filters, attribute => original) | ||
358 | - | ||
359 | - assert_equal(filtered, | ||
360 | - notice.send(attribute)) | ||
361 | - end | ||
362 | - | ||
363 | -end |
vendor/plugins/hoptoad_notifier/test/notifier_test.rb
@@ -1,222 +0,0 @@ | @@ -1,222 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/helper' | ||
2 | - | ||
3 | -class NotifierTest < Test::Unit::TestCase | ||
4 | - | ||
5 | - class OriginalException < Exception | ||
6 | - end | ||
7 | - | ||
8 | - class ContinuedException < Exception | ||
9 | - end | ||
10 | - | ||
11 | - include DefinesConstants | ||
12 | - | ||
13 | - def setup | ||
14 | - super | ||
15 | - reset_config | ||
16 | - end | ||
17 | - | ||
18 | - def assert_sent(notice, notice_args) | ||
19 | - assert_received(HoptoadNotifier::Notice, :new) {|expect| expect.with(has_entries(notice_args)) } | ||
20 | - assert_received(notice, :to_xml) | ||
21 | - assert_received(HoptoadNotifier.sender, :send_to_hoptoad) {|expect| expect.with(notice.to_xml) } | ||
22 | - end | ||
23 | - | ||
24 | - def set_public_env | ||
25 | - HoptoadNotifier.configure { |config| config.environment_name = 'production' } | ||
26 | - end | ||
27 | - | ||
28 | - def set_development_env | ||
29 | - HoptoadNotifier.configure { |config| config.environment_name = 'development' } | ||
30 | - end | ||
31 | - | ||
32 | - should "yield and save a configuration when configuring" do | ||
33 | - yielded_configuration = nil | ||
34 | - HoptoadNotifier.configure do |config| | ||
35 | - yielded_configuration = config | ||
36 | - end | ||
37 | - | ||
38 | - assert_kind_of HoptoadNotifier::Configuration, yielded_configuration | ||
39 | - assert_equal yielded_configuration, HoptoadNotifier.configuration | ||
40 | - end | ||
41 | - | ||
42 | - should "not remove existing config options when configuring twice" do | ||
43 | - first_config = nil | ||
44 | - HoptoadNotifier.configure do |config| | ||
45 | - first_config = config | ||
46 | - end | ||
47 | - HoptoadNotifier.configure do |config| | ||
48 | - assert_equal first_config, config | ||
49 | - end | ||
50 | - end | ||
51 | - | ||
52 | - should "configure the sender" do | ||
53 | - sender = stub_sender | ||
54 | - HoptoadNotifier::Sender.stubs(:new => sender) | ||
55 | - configuration = nil | ||
56 | - | ||
57 | - HoptoadNotifier.configure { |yielded_config| configuration = yielded_config } | ||
58 | - | ||
59 | - assert_received(HoptoadNotifier::Sender, :new) { |expect| expect.with(configuration) } | ||
60 | - assert_equal sender, HoptoadNotifier.sender | ||
61 | - end | ||
62 | - | ||
63 | - should "create and send a notice for an exception" do | ||
64 | - set_public_env | ||
65 | - exception = build_exception | ||
66 | - stub_sender! | ||
67 | - notice = stub_notice! | ||
68 | - | ||
69 | - HoptoadNotifier.notify(exception) | ||
70 | - | ||
71 | - assert_sent notice, :exception => exception | ||
72 | - end | ||
73 | - | ||
74 | - should "create and send a notice for a hash" do | ||
75 | - set_public_env | ||
76 | - notice = stub_notice! | ||
77 | - notice_args = { :error_message => 'uh oh' } | ||
78 | - stub_sender! | ||
79 | - | ||
80 | - HoptoadNotifier.notify(notice_args) | ||
81 | - | ||
82 | - assert_sent(notice, notice_args) | ||
83 | - end | ||
84 | - | ||
85 | - should "create and sent a notice for an exception and hash" do | ||
86 | - set_public_env | ||
87 | - exception = build_exception | ||
88 | - notice = stub_notice! | ||
89 | - notice_args = { :error_message => 'uh oh' } | ||
90 | - stub_sender! | ||
91 | - | ||
92 | - HoptoadNotifier.notify(exception, notice_args) | ||
93 | - | ||
94 | - assert_sent(notice, notice_args.merge(:exception => exception)) | ||
95 | - end | ||
96 | - | ||
97 | - should "not create a notice in a development environment" do | ||
98 | - set_development_env | ||
99 | - sender = stub_sender! | ||
100 | - | ||
101 | - HoptoadNotifier.notify(build_exception) | ||
102 | - HoptoadNotifier.notify_or_ignore(build_exception) | ||
103 | - | ||
104 | - assert_received(sender, :send_to_hoptoad) {|expect| expect.never } | ||
105 | - end | ||
106 | - | ||
107 | - should "not deliver an ignored exception when notifying implicitly" do | ||
108 | - set_public_env | ||
109 | - exception = build_exception | ||
110 | - sender = stub_sender! | ||
111 | - notice = stub_notice! | ||
112 | - notice.stubs(:ignore? => true) | ||
113 | - | ||
114 | - HoptoadNotifier.notify_or_ignore(exception) | ||
115 | - | ||
116 | - assert_received(sender, :send_to_hoptoad) {|expect| expect.never } | ||
117 | - end | ||
118 | - | ||
119 | - should "deliver an ignored exception when notifying manually" do | ||
120 | - set_public_env | ||
121 | - exception = build_exception | ||
122 | - sender = stub_sender! | ||
123 | - notice = stub_notice! | ||
124 | - notice.stubs(:ignore? => true) | ||
125 | - | ||
126 | - HoptoadNotifier.notify(exception) | ||
127 | - | ||
128 | - assert_sent(notice, :exception => exception) | ||
129 | - end | ||
130 | - | ||
131 | - should "pass config to created notices" do | ||
132 | - exception = build_exception | ||
133 | - config_opts = { 'one' => 'two', 'three' => 'four' } | ||
134 | - notice = stub_notice! | ||
135 | - stub_sender! | ||
136 | - HoptoadNotifier.configuration = stub('config', :merge => config_opts, :public? => true) | ||
137 | - | ||
138 | - HoptoadNotifier.notify(exception) | ||
139 | - | ||
140 | - assert_received(HoptoadNotifier::Notice, :new) do |expect| | ||
141 | - expect.with(has_entries(config_opts)) | ||
142 | - end | ||
143 | - end | ||
144 | - | ||
145 | - context "building notice JSON for an exception" do | ||
146 | - setup do | ||
147 | - @params = { :controller => "users", :action => "create" } | ||
148 | - @exception = build_exception | ||
149 | - @hash = HoptoadNotifier.build_lookup_hash_for(@exception, @params) | ||
150 | - end | ||
151 | - | ||
152 | - should "set action" do | ||
153 | - assert_equal @params[:action], @hash[:action] | ||
154 | - end | ||
155 | - | ||
156 | - should "set controller" do | ||
157 | - assert_equal @params[:controller], @hash[:component] | ||
158 | - end | ||
159 | - | ||
160 | - should "set line number" do | ||
161 | - assert @hash[:line_number] =~ /\d+/ | ||
162 | - end | ||
163 | - | ||
164 | - should "set file" do | ||
165 | - assert_match /\/test\/helper\.rb$/, @hash[:file] | ||
166 | - end | ||
167 | - | ||
168 | - should "set rails_env to production" do | ||
169 | - assert_equal 'production', @hash[:environment_name] | ||
170 | - end | ||
171 | - | ||
172 | - should "set error class" do | ||
173 | - assert_equal 'RuntimeError', @hash[:error_class] | ||
174 | - end | ||
175 | - | ||
176 | - should "not set file or line number with no backtrace" do | ||
177 | - @exception.stubs(:backtrace).returns([]) | ||
178 | - | ||
179 | - @hash = HoptoadNotifier.build_lookup_hash_for(@exception) | ||
180 | - | ||
181 | - assert_nil @hash[:line_number] | ||
182 | - assert_nil @hash[:file] | ||
183 | - end | ||
184 | - | ||
185 | - should "not set action or controller when not provided" do | ||
186 | - @hash = HoptoadNotifier.build_lookup_hash_for(@exception) | ||
187 | - | ||
188 | - assert_nil @hash[:action] | ||
189 | - assert_nil @hash[:controller] | ||
190 | - end | ||
191 | - | ||
192 | - context "when an exception that provides #original_exception is raised" do | ||
193 | - setup do | ||
194 | - @exception.stubs(:original_exception).returns(begin | ||
195 | - raise NotifierTest::OriginalException.new | ||
196 | - rescue Exception => e | ||
197 | - e | ||
198 | - end) | ||
199 | - end | ||
200 | - | ||
201 | - should "unwrap exceptions that provide #original_exception" do | ||
202 | - @hash = HoptoadNotifier.build_lookup_hash_for(@exception) | ||
203 | - assert_equal "NotifierTest::OriginalException", @hash[:error_class] | ||
204 | - end | ||
205 | - end | ||
206 | - | ||
207 | - context "when an exception that provides #continued_exception is raised" do | ||
208 | - setup do | ||
209 | - @exception.stubs(:continued_exception).returns(begin | ||
210 | - raise NotifierTest::ContinuedException.new | ||
211 | - rescue Exception => e | ||
212 | - e | ||
213 | - end) | ||
214 | - end | ||
215 | - | ||
216 | - should "unwrap exceptions that provide #continued_exception" do | ||
217 | - @hash = HoptoadNotifier.build_lookup_hash_for(@exception) | ||
218 | - assert_equal "NotifierTest::ContinuedException", @hash[:error_class] | ||
219 | - end | ||
220 | - end | ||
221 | - end | ||
222 | -end |
vendor/plugins/hoptoad_notifier/test/sender_test.rb
@@ -1,123 +0,0 @@ | @@ -1,123 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/helper' | ||
2 | - | ||
3 | -class SenderTest < Test::Unit::TestCase | ||
4 | - | ||
5 | - def setup | ||
6 | - reset_config | ||
7 | - end | ||
8 | - | ||
9 | - def build_sender(opts = {}) | ||
10 | - config = HoptoadNotifier::Configuration.new | ||
11 | - opts.each {|opt, value| config.send(:"#{opt}=", value) } | ||
12 | - HoptoadNotifier::Sender.new(config) | ||
13 | - end | ||
14 | - | ||
15 | - def send_exception(args = {}) | ||
16 | - notice = args.delete(:notice) || build_notice_data | ||
17 | - sender = args.delete(:sender) || build_sender(args) | ||
18 | - sender.send_to_hoptoad(notice) | ||
19 | - sender | ||
20 | - end | ||
21 | - | ||
22 | - def stub_http | ||
23 | - response = stub(:body => 'body') | ||
24 | - http = stub(:post => response, | ||
25 | - :read_timeout= => nil, | ||
26 | - :open_timeout= => nil, | ||
27 | - :use_ssl= => nil) | ||
28 | - Net::HTTP.stubs(:new => http) | ||
29 | - http | ||
30 | - end | ||
31 | - | ||
32 | - should "post to Hoptoad when using an HTTP proxy" do | ||
33 | - response = stub(:body => 'body') | ||
34 | - http = stub(:post => response, | ||
35 | - :read_timeout= => nil, | ||
36 | - :open_timeout= => nil, | ||
37 | - :use_ssl= => nil) | ||
38 | - proxy = stub(:new => http) | ||
39 | - Net::HTTP.stubs(:Proxy => proxy) | ||
40 | - | ||
41 | - url = "http://hoptoadapp.com:80#{HoptoadNotifier::Sender::NOTICES_URI}" | ||
42 | - uri = URI.parse(url) | ||
43 | - | ||
44 | - proxy_host = 'some.host' | ||
45 | - proxy_port = 88 | ||
46 | - proxy_user = 'login' | ||
47 | - proxy_pass = 'passwd' | ||
48 | - | ||
49 | - send_exception(:proxy_host => proxy_host, | ||
50 | - :proxy_port => proxy_port, | ||
51 | - :proxy_user => proxy_user, | ||
52 | - :proxy_pass => proxy_pass) | ||
53 | - assert_received(http, :post) do |expect| | ||
54 | - expect.with(uri.path, anything, HoptoadNotifier::HEADERS) | ||
55 | - end | ||
56 | - assert_received(Net::HTTP, :Proxy) do |expect| | ||
57 | - expect.with(proxy_host, proxy_port, proxy_user, proxy_pass) | ||
58 | - end | ||
59 | - end | ||
60 | - | ||
61 | - should "post to the right url for non-ssl" do | ||
62 | - http = stub_http | ||
63 | - url = "http://hoptoadapp.com:80#{HoptoadNotifier::Sender::NOTICES_URI}" | ||
64 | - uri = URI.parse(url) | ||
65 | - send_exception(:secure => false) | ||
66 | - assert_received(http, :post) {|expect| expect.with(uri.path, anything, HoptoadNotifier::HEADERS) } | ||
67 | - end | ||
68 | - | ||
69 | - should "post to the right path for ssl" do | ||
70 | - http = stub_http | ||
71 | - send_exception(:secure => true) | ||
72 | - assert_received(http, :post) {|expect| expect.with(HoptoadNotifier::Sender::NOTICES_URI, anything, HoptoadNotifier::HEADERS) } | ||
73 | - end | ||
74 | - | ||
75 | - should "default the open timeout to 2 seconds" do | ||
76 | - http = stub_http | ||
77 | - send_exception | ||
78 | - assert_received(http, :open_timeout=) {|expect| expect.with(2) } | ||
79 | - end | ||
80 | - | ||
81 | - should "default the read timeout to 5 seconds" do | ||
82 | - http = stub_http | ||
83 | - send_exception | ||
84 | - assert_received(http, :read_timeout=) {|expect| expect.with(5) } | ||
85 | - end | ||
86 | - | ||
87 | - should "allow override of the open timeout" do | ||
88 | - http = stub_http | ||
89 | - send_exception(:http_open_timeout => 4) | ||
90 | - assert_received(http, :open_timeout=) {|expect| expect.with(4) } | ||
91 | - end | ||
92 | - | ||
93 | - should "allow override of the read timeout" do | ||
94 | - http = stub_http | ||
95 | - send_exception(:http_read_timeout => 10) | ||
96 | - assert_received(http, :read_timeout=) {|expect| expect.with(10) } | ||
97 | - end | ||
98 | - | ||
99 | - should "connect to the right port for ssl" do | ||
100 | - stub_http | ||
101 | - send_exception(:secure => true) | ||
102 | - assert_received(Net::HTTP, :new) {|expect| expect.with("hoptoadapp.com", 443) } | ||
103 | - end | ||
104 | - | ||
105 | - should "connect to the right port for non-ssl" do | ||
106 | - stub_http | ||
107 | - send_exception(:secure => false) | ||
108 | - assert_received(Net::HTTP, :new) {|expect| expect.with("hoptoadapp.com", 80) } | ||
109 | - end | ||
110 | - | ||
111 | - should "use ssl if secure" do | ||
112 | - stub_http | ||
113 | - send_exception(:secure => true, :host => 'example.org') | ||
114 | - assert_received(Net::HTTP, :new) {|expect| expect.with('example.org', 443) } | ||
115 | - end | ||
116 | - | ||
117 | - should "not use ssl if not secure" do | ||
118 | - stub_http | ||
119 | - send_exception(:secure => false, :host => 'example.org') | ||
120 | - assert_received(Net::HTTP, :new) {|expect| expect.with('example.org', 80) } | ||
121 | - end | ||
122 | - | ||
123 | -end |
vendor/plugins/hoptoad_notifier/vendor/ginger/.gitignore
vendor/plugins/hoptoad_notifier/vendor/ginger/LICENCE
@@ -1,20 +0,0 @@ | @@ -1,20 +0,0 @@ | ||
1 | -Copyright (c) 2008 Pat Allan | ||
2 | - | ||
3 | -Permission is hereby granted, free of charge, to any person obtaining | ||
4 | -a copy of this software and associated documentation files (the | ||
5 | -"Software"), to deal in the Software without restriction, including | ||
6 | -without limitation the rights to use, copy, modify, merge, publish, | ||
7 | -distribute, sublicense, and/or sell copies of the Software, and to | ||
8 | -permit persons to whom the Software is furnished to do so, subject to | ||
9 | -the following conditions: | ||
10 | - | ||
11 | -The above copyright notice and this permission notice shall be | ||
12 | -included in all copies or substantial portions of the Software. | ||
13 | - | ||
14 | -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
15 | -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
16 | -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
17 | -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
18 | -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
19 | -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
20 | -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
vendor/plugins/hoptoad_notifier/vendor/ginger/README.textile
@@ -1,50 +0,0 @@ | @@ -1,50 +0,0 @@ | ||
1 | -Ginger is a small gem that allows you to test your projects using multiple versions of gem libraries. The idea is from "Ian White's garlic":http://github.com/ianwhite/garlic/tree - hence the related name of this - but my approach is a bit different, since I don't test my plugins from within a rails application. Maybe they can be merged at some point - I just hacked this up quickly to fit my needs. | ||
2 | - | ||
3 | -To get it all working, you need to do four things. The first is, of course, to install this gem. | ||
4 | - | ||
5 | -<pre><code>sudo gem install freelancing-god-ginger --source=http://gems.github.com</code></pre> | ||
6 | - | ||
7 | -Next, add the following line of code to your @spec_helper.rb@ file (or equivalent): | ||
8 | - | ||
9 | -<pre><code>require 'ginger'</code></pre> | ||
10 | - | ||
11 | -You'll want to put it as high up as possible - in particular, before any @require@ calls to libraries you want to cover multiple versions of. | ||
12 | - | ||
13 | -Step number three is creating the sets of scenarios in a file called @ginger_scenarios.rb@, which should go in the root, spec or test directory of your project. Here's an example, showing off the syntax possibilities. | ||
14 | - | ||
15 | -<pre><code>require 'ginger' | ||
16 | - | ||
17 | -Ginger.configure do |config| | ||
18 | - config.aliases["active_record"] = "activerecord" | ||
19 | - | ||
20 | - ar_1_2_6 = Ginger::Scenario.new | ||
21 | - ar_1_2_6[/^active_?record$/] = "1.15.6" | ||
22 | - | ||
23 | - ar_2_0_2 = Ginger::Scenario.new | ||
24 | - ar_2_0_2[/^active_?record$/] = "2.0.2" | ||
25 | - | ||
26 | - ar_2_1_1 = Ginger::Scenario.new | ||
27 | - ar_2_1_1[/^active_?record$/] = "2.1.1" | ||
28 | - | ||
29 | - config.scenarios << ar_1_2_6 << ar_2_0_2 << ar_2_1_1 | ||
30 | -end</code></pre> | ||
31 | - | ||
32 | -Above, I've added three different scenarios, for three different versions of ActiveRecord. I also added an alias, as people sometimes use the underscore, and sometimes don't. The gem's name has no underscore though, so the _value_ of the alias matches the gem name (whereas the key would be alternative usage). | ||
33 | - | ||
34 | -You can have multiple gems set in each scenario - and you don't have to use regular expressions, you can just use straight strings. | ||
35 | - | ||
36 | -<pre><code>sphinx_scenario = Ginger::Scenario.new | ||
37 | -sphinx_scenario["riddle"] = "0.9.8" | ||
38 | -sphinx_scenario["thinking_sphinx"] = "0.9.8"</code></pre> | ||
39 | - | ||
40 | -Don't forget to add them to @config@'s scenarios collection, else they're not saved anywhere. | ||
41 | - | ||
42 | -And finally, you'll want to run the tests or specs for each scenario. This is done using the @ginger@ CLI tool, which parrots whatever parameters you give it onto @rake@. So just do something like: | ||
43 | - | ||
44 | -<pre><code>ginger spec | ||
45 | -ginger test | ||
46 | -ginger spec:unit</code></pre> | ||
47 | - | ||
48 | -h2. Contributors | ||
49 | - | ||
50 | -* "Adam Meehan":http://duckpunching.com/ |
vendor/plugins/hoptoad_notifier/vendor/ginger/Rakefile
@@ -1,57 +0,0 @@ | @@ -1,57 +0,0 @@ | ||
1 | -require 'rubygems' | ||
2 | -require 'spec' | ||
3 | -require 'rake/rdoctask' | ||
4 | -require 'spec/rake/spectask' | ||
5 | -require 'rake/gempackagetask' | ||
6 | - | ||
7 | -$LOAD_PATH.unshift File.dirname(__FILE__) + '/lib' | ||
8 | - | ||
9 | -require 'ginger' | ||
10 | - | ||
11 | -spec = Gem::Specification.new do |s| | ||
12 | - s.name = "ginger" | ||
13 | - s.version = Ginger::Version::String | ||
14 | - s.summary = "Run specs/tests multiple times through different gem versions." | ||
15 | - s.description = "Run specs/tests multiple times through different gem versions." | ||
16 | - s.author = "Pat Allan" | ||
17 | - s.email = "pat@freelancing-gods.com" | ||
18 | - s.homepage = "http://github.com/freelancing_god/ginger/tree" | ||
19 | - s.has_rdoc = true | ||
20 | - s.rdoc_options << "--title" << "Ginger" << | ||
21 | - "--line-numbers" | ||
22 | - s.rubyforge_project = "ginger" | ||
23 | - s.test_files = FileList["spec/**/*_spec.rb"] | ||
24 | - s.files = FileList[ | ||
25 | - "lib/**/*.rb", | ||
26 | - "LICENCE", | ||
27 | - "README.textile" | ||
28 | - ] | ||
29 | - s.executables = ["ginger"] | ||
30 | -end | ||
31 | - | ||
32 | -Rake::GemPackageTask.new(spec) do |p| | ||
33 | - p.gem_spec = spec | ||
34 | - p.need_tar = true | ||
35 | - p.need_zip = true | ||
36 | -end | ||
37 | - | ||
38 | -desc "Generate ginger.gemspec file" | ||
39 | -task :gemspec do | ||
40 | - File.open('ginger.gemspec', 'w') { |f| | ||
41 | - f.write spec.to_ruby | ||
42 | - } | ||
43 | -end | ||
44 | - | ||
45 | -desc "Run the specs under spec" | ||
46 | -Spec::Rake::SpecTask.new do |t| | ||
47 | - t.spec_files = FileList['spec/**/*_spec.rb'] | ||
48 | - t.spec_opts << "-c" | ||
49 | -end | ||
50 | - | ||
51 | -desc "Generate RCov reports" | ||
52 | -Spec::Rake::SpecTask.new(:rcov) do |t| | ||
53 | - t.libs << 'lib' | ||
54 | - t.spec_files = FileList['spec/**/*_spec.rb'] | ||
55 | - t.rcov = true | ||
56 | - t.rcov_opts = ['--exclude', 'spec', '--exclude', 'gems'] | ||
57 | -end | ||
58 | \ No newline at end of file | 0 | \ No newline at end of file |
vendor/plugins/hoptoad_notifier/vendor/ginger/bin/ginger
@@ -1,42 +0,0 @@ | @@ -1,42 +0,0 @@ | ||
1 | -#!/usr/bin/env ruby | ||
2 | - | ||
3 | -require 'rubygems' | ||
4 | -require 'ginger' | ||
5 | -require 'rake' | ||
6 | - | ||
7 | -if ARGV.length == 0 | ||
8 | - puts <<-USAGE | ||
9 | -ginger #{Ginger::Version::String} | ||
10 | -Use ginger to run specs for each scenario defined. Scenarios must be set out in | ||
11 | -a file called ginger_scenarios.rb wherever this tool is run. Once they're | ||
12 | -defined, then you can run this tool and provide the rake task that would | ||
13 | -normally be called. | ||
14 | - | ||
15 | -Examples: | ||
16 | - ginger spec | ||
17 | - ginger test | ||
18 | - ginger spec:models | ||
19 | -USAGE | ||
20 | - exit 0 | ||
21 | -end | ||
22 | - | ||
23 | -file_path = File.join Dir.pwd, ".ginger" | ||
24 | - | ||
25 | -File.delete(file_path) if File.exists?(file_path) | ||
26 | - | ||
27 | -scenarios = Ginger::Configuration.instance.scenarios | ||
28 | -puts "No Ginger Scenarios defined" if scenarios.empty? | ||
29 | - | ||
30 | -scenarios.each_with_index do |scenario, index| | ||
31 | - puts <<-SCENARIO | ||
32 | - | ||
33 | -------------------- | ||
34 | -Ginger Scenario #{index+1} | ||
35 | -------------------- | ||
36 | - SCENARIO | ||
37 | - | ||
38 | - File.open('.ginger', 'w') { |f| f.write index.to_s } | ||
39 | - system("rake #{ARGV.join(" ")}") | ||
40 | -end | ||
41 | - | ||
42 | -File.delete(file_path) if File.exists?(file_path) |
vendor/plugins/hoptoad_notifier/vendor/ginger/ginger.gemspec
@@ -1,33 +0,0 @@ | @@ -1,33 +0,0 @@ | ||
1 | -# -*- encoding: utf-8 -*- | ||
2 | - | ||
3 | -Gem::Specification.new do |s| | ||
4 | - s.name = %q{ginger} | ||
5 | - s.version = "1.0.0" | ||
6 | - | ||
7 | - s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version= | ||
8 | - s.authors = ["Pat Allan"] | ||
9 | - s.date = %q{2008-10-11} | ||
10 | - s.default_executable = %q{ginger} | ||
11 | - s.description = %q{Run specs/tests multiple times through different gem versions.} | ||
12 | - s.email = %q{pat@freelancing-gods.com} | ||
13 | - s.executables = ["ginger"] | ||
14 | - s.files = ["lib/ginger/configuration.rb", "lib/ginger/kernel.rb", "lib/ginger/scenario.rb", "lib/ginger.rb", "LICENCE", "README.textile", "spec/ginger/configuration_spec.rb", "spec/ginger/kernel_spec.rb", "spec/ginger/scenario_spec.rb", "spec/ginger_spec.rb", "bin/ginger"] | ||
15 | - s.has_rdoc = true | ||
16 | - s.homepage = %q{http://github.com/freelancing_god/ginger/tree} | ||
17 | - s.rdoc_options = ["--title", "Ginger", "--line-numbers"] | ||
18 | - s.require_paths = ["lib"] | ||
19 | - s.rubyforge_project = %q{ginger} | ||
20 | - s.rubygems_version = %q{1.3.0} | ||
21 | - s.summary = %q{Run specs/tests multiple times through different gem versions.} | ||
22 | - s.test_files = ["spec/ginger/configuration_spec.rb", "spec/ginger/kernel_spec.rb", "spec/ginger/scenario_spec.rb", "spec/ginger_spec.rb"] | ||
23 | - | ||
24 | - if s.respond_to? :specification_version then | ||
25 | - current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION | ||
26 | - s.specification_version = 2 | ||
27 | - | ||
28 | - if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then | ||
29 | - else | ||
30 | - end | ||
31 | - else | ||
32 | - end | ||
33 | -end |
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger.rb
@@ -1,21 +0,0 @@ | @@ -1,21 +0,0 @@ | ||
1 | -require 'ginger/configuration' | ||
2 | -require 'ginger/scenario' | ||
3 | -require 'ginger/kernel' | ||
4 | - | ||
5 | -module Ginger | ||
6 | - module Version | ||
7 | - Major = 1 | ||
8 | - Minor = 0 | ||
9 | - Tiny = 0 | ||
10 | - | ||
11 | - String = [Major, Minor, Tiny].join('.') | ||
12 | - end | ||
13 | - | ||
14 | - def self.configure(&block) | ||
15 | - yield Ginger::Configuration.instance | ||
16 | - end | ||
17 | -end | ||
18 | - | ||
19 | -Kernel.send(:include, Ginger::Kernel) | ||
20 | - | ||
21 | -Ginger::Configuration.detect_scenario_file | ||
22 | \ No newline at end of file | 0 | \ No newline at end of file |
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger/configuration.rb
@@ -1,20 +0,0 @@ | @@ -1,20 +0,0 @@ | ||
1 | -require 'singleton' | ||
2 | - | ||
3 | -module Ginger | ||
4 | - class Configuration | ||
5 | - include Singleton | ||
6 | - | ||
7 | - attr_accessor :scenarios, :aliases | ||
8 | - | ||
9 | - def initialize | ||
10 | - @scenarios = [] | ||
11 | - @aliases = {} | ||
12 | - end | ||
13 | - | ||
14 | - def self.detect_scenario_file | ||
15 | - ['.','spec','test'].each do |path| | ||
16 | - require "#{path}/ginger_scenarios" and break if File.exists?("#{path}/ginger_scenarios.rb") | ||
17 | - end | ||
18 | - end | ||
19 | - end | ||
20 | -end |
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger/kernel.rb
@@ -1,56 +0,0 @@ | @@ -1,56 +0,0 @@ | ||
1 | -module Ginger | ||
2 | - module Kernel | ||
3 | - def self.included(base) | ||
4 | - base.class_eval do | ||
5 | - def require_with_ginger(req) | ||
6 | - unless scenario = ginger_scenario | ||
7 | - require_without_ginger(req) | ||
8 | - return | ||
9 | - end | ||
10 | - | ||
11 | - if scenario.version(req) | ||
12 | - gem ginger_gem_name(req) | ||
13 | - end | ||
14 | - | ||
15 | - require_without_ginger(req) | ||
16 | - end | ||
17 | - | ||
18 | - alias_method :require_without_ginger, :require | ||
19 | - alias_method :require, :require_with_ginger | ||
20 | - | ||
21 | - def gem_with_ginger(gem_name, *version_requirements) | ||
22 | - unless scenario = ginger_scenario | ||
23 | - gem_without_ginger(gem_name, *version_requirements) | ||
24 | - return | ||
25 | - end | ||
26 | - | ||
27 | - if version_requirements.length == 0 && | ||
28 | - version = scenario.version(gem_name) | ||
29 | - version_requirements << "= #{version}" | ||
30 | - end | ||
31 | - | ||
32 | - gem_without_ginger(gem_name, *version_requirements) | ||
33 | - end | ||
34 | - | ||
35 | - alias_method :gem_without_ginger, :gem | ||
36 | - alias_method :gem, :gem_with_ginger | ||
37 | - | ||
38 | - private | ||
39 | - | ||
40 | - def ginger_scenario | ||
41 | - return nil unless File.exists?(".ginger") | ||
42 | - | ||
43 | - scenario = nil | ||
44 | - File.open('.ginger') { |f| scenario = f.read } | ||
45 | - return nil unless scenario | ||
46 | - | ||
47 | - Ginger::Configuration.instance.scenarios[scenario.to_i] | ||
48 | - end | ||
49 | - | ||
50 | - def ginger_gem_name(gem_name) | ||
51 | - Ginger::Configuration.instance.aliases[gem_name] || gem_name | ||
52 | - end | ||
53 | - end | ||
54 | - end | ||
55 | - end | ||
56 | -end | ||
57 | \ No newline at end of file | 0 | \ No newline at end of file |
vendor/plugins/hoptoad_notifier/vendor/ginger/lib/ginger/scenario.rb
@@ -1,24 +0,0 @@ | @@ -1,24 +0,0 @@ | ||
1 | -module Ginger | ||
2 | - class Scenario < Hash | ||
3 | - def add(gem, version) | ||
4 | - self[gem] = version | ||
5 | - end | ||
6 | - | ||
7 | - def version(gem) | ||
8 | - self.keys.each do |key| | ||
9 | - case key | ||
10 | - when String | ||
11 | - return self[key] if gem == key | ||
12 | - when Regexp | ||
13 | - return self[key] if gem =~ key | ||
14 | - end | ||
15 | - end | ||
16 | - | ||
17 | - return nil | ||
18 | - end | ||
19 | - | ||
20 | - def gems | ||
21 | - self.keys | ||
22 | - end | ||
23 | - end | ||
24 | -end | ||
25 | \ No newline at end of file | 0 | \ No newline at end of file |
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger/configuration_spec.rb
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger/kernel_spec.rb
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger/scenario_spec.rb
@@ -1,50 +0,0 @@ | @@ -1,50 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/../spec_helper' | ||
2 | - | ||
3 | -describe Ginger::Scenario do | ||
4 | - it "should allow for multiple gem/version pairs" do | ||
5 | - scenario = Ginger::Scenario.new | ||
6 | - scenario.add "thinking_sphinx", "1.0" | ||
7 | - scenario.add "riddle", "0.9.8" | ||
8 | - | ||
9 | - scenario.gems.should include("thinking_sphinx") | ||
10 | - scenario.gems.should include("riddle") | ||
11 | - end | ||
12 | - | ||
13 | - it "should be able to be used as a hash" do | ||
14 | - scenario = Ginger::Scenario.new | ||
15 | - scenario["thinking_sphinx"] = "1.0" | ||
16 | - scenario["riddle"] = "0.9.8" | ||
17 | - | ||
18 | - scenario.gems.should include("thinking_sphinx") | ||
19 | - scenario.gems.should include("riddle") | ||
20 | - end | ||
21 | - | ||
22 | - it "should allow gem names to be regular expressions" do | ||
23 | - scenario = Ginger::Scenario.new | ||
24 | - scenario.add /^active_?record$/, "2.1.0" | ||
25 | - | ||
26 | - scenario.gems.first.should be_kind_of(Regexp) | ||
27 | - end | ||
28 | - | ||
29 | - it "should return the appropriate version for a given gem" do | ||
30 | - scenario = Ginger::Scenario.new | ||
31 | - scenario.add "riddle", "0.9.8" | ||
32 | - | ||
33 | - scenario.version("riddle").should == "0.9.8" | ||
34 | - end | ||
35 | - | ||
36 | - it "should use regular expressions to figure out matching version" do | ||
37 | - scenario = Ginger::Scenario.new | ||
38 | - scenario[/^active_?record$/] = "2.1.0" | ||
39 | - | ||
40 | - scenario.version("activerecord").should == "2.1.0" | ||
41 | - scenario.version("active_record").should == "2.1.0" | ||
42 | - end | ||
43 | - | ||
44 | - it "should return nil if no matching gem" do | ||
45 | - scenario = Ginger::Scenario.new | ||
46 | - scenario.add "riddle", "0.9.8" | ||
47 | - | ||
48 | - scenario.version("thinking_sphinx").should be_nil | ||
49 | - end | ||
50 | -end |
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/ginger_spec.rb
@@ -1,14 +0,0 @@ | @@ -1,14 +0,0 @@ | ||
1 | -require File.dirname(__FILE__) + '/spec_helper' | ||
2 | - | ||
3 | -describe "Ginger" do | ||
4 | - it "should add scenarios to the Configuration instance" do | ||
5 | - Ginger.configure do |config| | ||
6 | - scenario = Ginger::Scenario.new | ||
7 | - scenario["riddle"] = "0.9.8" | ||
8 | - | ||
9 | - config.scenarios << scenario | ||
10 | - end | ||
11 | - | ||
12 | - Ginger::Configuration.instance.scenarios.length.should == 1 | ||
13 | - end | ||
14 | -end |
vendor/plugins/hoptoad_notifier/vendor/ginger/spec/spec_helper.rb