diff --git a/lib/application_checker.rb b/lib/application_checker.rb
index c0e5e8b..21dce00 100644
--- a/lib/application_checker.rb
+++ b/lib/application_checker.rb
@@ -5,22 +5,22 @@ module Rails
class ApplicationChecker
def initialize
@issues = []
-
+
raise NotInRailsAppError unless in_rails_app?
end
-
+
def in_rails_app?
File.exist?("config/environment.rb")
end
-
+
# Run all the check methods
def run
# Ruby 1.8 returns method names as strings whereas 1.9 uses symbols
the_methods = (self.public_methods - Object.methods) - [:run, :initialize, "run", "initialize"]
-
+
the_methods.each {|m| send m }
end
-
+
# Check for deprecated ActiveRecord calls
def check_ar_methods
files = []
@@ -28,10 +28,10 @@ module Rails
lines = grep_for(v, "app/")
files += extract_filenames(lines) || []
end
-
+
unless files.empty?
alert(
- "Soon-to-be-deprecated ActiveRecord calls",
+ "Soon-to-be-deprecated ActiveRecord calls",
"Methods such as find(:all), find(:first), finds with conditions, and the :joins option will soon be deprecated.",
"http://m.onkey.org/2010/1/22/active-record-query-interface",
files
@@ -40,33 +40,33 @@ module Rails
lines = grep_for("named_scope", "app/models/")
files = extract_filenames(lines)
-
+
if files
alert(
- "named_scope is now just scope",
+ "named_scope is now just scope",
"The named_scope method has been renamed to just scope.",
"http://github.com/rails/rails/commit/d60bb0a9e4be2ac0a9de9a69041a4ddc2e0cc914",
files
)
end
end
-
+
# Check for deprecated router syntax
def check_routes
lines = ["map\\.", "ActionController::Routing::Routes", "\\.resources"].map do |v|
grep_for(v, "config/routes.rb").empty? ? nil : true
end.compact
-
+
unless lines.empty?
alert(
- "Old router API",
+ "Old router API",
"The router API has totally changed.",
"http://yehudakatz.com/2009/12/26/the-rails-3-router-rack-it-up/",
"config/routes.rb"
)
end
end
-
+
# Check for deprecated test_help require
def check_test_help
files = []
@@ -77,121 +77,121 @@ module Rails
lines = grep_for("\"test_help\"", "test/")
files += extract_filenames(lines) || []
-
+
files.uniq!
-
+
unless files.empty?
alert(
- "Deprecated test_help path",
+ "Deprecated test_help path",
"You now must require 'rails/test_help' not just 'test_help'.",
"http://weblog.rubyonrails.org/2009/9/1/gem-packaging-best-practices",
files
)
end
end
-
+
# Check for old (pre-application.rb) environment.rb file
def check_environment
unless File.exist?("config/application.rb")
alert(
- "New file needed: config/application.rb",
+ "New file needed: config/application.rb",
"You need to add a config/application.rb.",
"http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade",
"config/application.rb"
)
end
-
+
lines = grep_for("config.", "config/environment.rb")
-
+
unless lines.empty?
alert(
- "Old environment.rb",
+ "Old environment.rb",
"environment.rb doesn't do what it used to; you'll need to move some of that into application.rb.",
"http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade",
"config/environment.rb"
)
end
end
-
+
# Check for deprecated constants
def check_deprecated_constants
files = []
["RAILS_ENV", "RAILS_ROOT", "RAILS_DEFAULT_LOGGER"].each do |v|
lines = grep_for(v, "app/")
files += extract_filenames(lines) || []
-
+
lines = grep_for(v, "lib/")
files += extract_filenames(lines) || []
end
-
+
unless files.empty?
alert(
- "Deprecated constant(s)",
+ "Deprecated constant(s)",
"Constants like RAILS_ENV, RAILS_ROOT, and RAILS_DEFAULT_LOGGER are now deprecated.",
"http://litanyagainstfear.com/blog/2010/02/03/the-rails-module/",
files.uniq
)
end
end
-
+
# Check for old-style config.gem calls
def check_gems
lines = grep_for("config.gem ", "config/*.rb")
files = extract_filenames(lines)
-
+
if files
alert(
- "Old gem bundling (config.gems)",
+ "Old gem bundling (config.gems)",
"The old way of bundling is gone now. You need a Gemfile for bundler.",
"http://omgbloglol.com/post/353978923/the-path-to-rails-3-approaching-the-upgrade",
files
)
end
end
-
+
# Checks for old mailer syntax in both mailer classes and those
# classes utilizing the mailers
def check_mailers
lines = grep_for("deliver_", "app/models/ #{base_path}app/controllers/ #{base_path}app/observers/")
files = extract_filenames(lines)
-
+
if files
alert(
- "Deprecated ActionMailer API",
+ "Deprecated ActionMailer API",
"You're using the old ActionMailer API to send e-mails in a controller, model, or observer.",
"http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3",
files
)
end
-
+
files = []
["recipients ", "attachment ", "subject ", "from "].each do |v|
lines = grep_for(v, "app/models/")
files += extract_filenames(lines) || []
end
-
+
unless files.empty?
alert(
- "Old ActionMailer class API",
+ "Old ActionMailer class API",
"You're using the old API in a mailer class.",
"http://lindsaar.net/2010/1/26/new-actionmailer-api-in-rails-3",
files
)
end
end
-
+
# Checks for old-style generators
def check_generators
generators = Dir.glob(base_path + "vendor/plugins/**/generators/**/")
-
+
unless generators.empty?
files = generators.map do |g|
grep_for("def manifest", g).empty? ? g : nil
end.compact
-
+
if !files.empty?
alert(
- "Old Rails generator API",
+ "Old Rails generator API",
"A plugin in the app is using the old generator API (a new one may be available at http://github.com/trydionel/rails3-generators).",
"http://blog.plataformatec.com.br/2010/01/discovering-rails-3-generators/",
files
@@ -199,43 +199,43 @@ module Rails
end
end
end
-
+
# Checks a list of known broken plugins and gems
def check_plugins
# This list is off the wiki; will need to be updated often, esp. since RSpec is working on it
bad_plugins = ["rspec", "rspec-rails", "hoptoad", "authlogic", "nifty-generators",
"restful_authentication", "searchlogic", "cucumber", "cucumber-rails", "devise",
"inherited_resources"]
-
- bad_plugins = bad_plugins.map do |p|
+
+ bad_plugins = bad_plugins.map do |p|
p if File.exist?("#{base_path}vendor/plugins/#{p}") || !Dir.glob("#{base_path}vendor/gems/#{p}-*").empty?
end.compact
unless bad_plugins.empty?
alert(
- "Known broken plugins",
+ "Known broken plugins",
"At least one plugin in your app is broken (according to the wiki). Most of project maintainers are rapidly working towards compatability, but do be aware you may encounter issues.",
"http://wiki.rubyonrails.org/rails/version3/plugins_and_gems",
bad_plugins
)
end
end
-
+
# Checks for old-style ERb helpers
def check_old_helpers
lines = grep_for("<% .* do.*%>", "app/views/**/*")
files = extract_filenames(lines)
-
+
if files
alert(
- "Deprecated ERb helper calls",
+ "Deprecated ERb helper calls",
"Block helpers that use concat (e.g., form_for) should use <%= instead of <%. The current form will continue to work for now, but you will get deprecation warnings since this form will go away in the future.",
"http://weblog.rubyonrails.org/",
files
)
end
end
-
+
# Checks for old-style AJAX helpers
def check_old_ajax_helpers
files = []
@@ -244,17 +244,17 @@ module Rails
inner_files = extract_filenames(lines)
files += inner_files unless inner_files.nil?
end
-
- if files
+
+ unless files.empty?
alert(
- "Deprecated AJAX helper calls",
+ "Deprecated AJAX helper calls",
"AJAX javascript helpers have been switched to be unobtrusive and use :remote => true instead of having a seperate function to handle remote requests.",
"http://www.themodestrubyist.com/2010/02/24/rails-3-ujs-and-csrf-meta-tags/",
files
)
end
end
-
+
# Checks for old cookie secret settings
def check_old_cookie_secret
lines = grep_for("ActionController::Base.cookie_verifier_secret = ", "config/**/*")
@@ -262,7 +262,7 @@ module Rails
if files
alert(
- "Deprecated cookie secret setting",
+ "Deprecated cookie secret setting",
"Previously, cookie secret was set directly on ActionController::Base; it's now config.secret_token.",
"http://lindsaar.net/2010/4/7/rails_3_session_secret_and_session_store",
files
@@ -276,29 +276,29 @@ module Rails
if files
alert(
- "Deprecated session secret setting",
+ "Deprecated session secret setting",
"Previously, session secret was set directly on ActionController::Base; it's now config.secret_token.",
"http://lindsaar.net/2010/4/7/rails_3_session_secret_and_session_store",
files
)
end
end
-
+
# Checks for old session settings
def check_old_session_setting
lines = grep_for("ActionController::Base.session_store", "config/**/*")
files = extract_filenames(lines)
-
+
if files
alert(
- "Old session store setting",
+ "Old session store setting",
"Previously, session store was set directly on ActionController::Base; it's now config.session_store :whatever.",
"http://lindsaar.net/2010/4/7/rails_3_session_secret_and_session_store",
files
)
end
end
-
+
private
# Find a string in a set of files; calls +find_with_grep+ and +find_with_rak+
# depending on platform.
@@ -313,18 +313,18 @@ module Rails
else
find_with_rak(text, base_path + where, double_quote)
end
-
+
# ignore comments
lines.gsub! /^\s*#.+$/m, ""
-
+
lines
end
-
+
# Sets a base path for finding files; mostly for testing
def base_path
Dir.pwd + "/"
end
-
+
# Use the grep utility to find a string in a set of files
def find_with_grep(text, where, double_quote)
value = ""
@@ -334,14 +334,14 @@ module Rails
else
"grep -r --exclude=\*.svn\* '#{text}' #{where}"
end
-
+
Open3.popen3(command) do |stdin, stdout, stderr|
value = stdout.read
end
-
+
value
end
-
+
# Use the rak gem to grep the files (not yet implemented)
def find_with_rak(text, where, double_quote)
value = ""
@@ -349,10 +349,10 @@ module Rails
Open3.popen3("rak --nogroup -l '#{Regexp.escape(text)}' #{where}") do |stdin, stdout, stderr|
value = stdout.read
end
-
+
value
end
-
+
# Extract the filenames from the grep output
def extract_filenames(output)
if @probably_has_grep
@@ -361,25 +361,25 @@ module Rails
extract_filenames_from_rak(output)
end
end
-
+
def extract_filenames_from_grep(output)
return nil if output.empty?
-
- fnames = output.split("\n").map do |fn|
+
+ fnames = output.split("\n").map do |fn|
if m = fn.match(/^(.+?):/)
m[1]
end
end.compact
-
+
fnames.uniq
end
-
+
def extract_filenames_from_rak(output)
return nil if output.empty?
-
+
output.split("\n").uniq
end
-
+
# Terminal colors, borrowed from Thor
CLEAR = "\e[0m"
BOLD = "\e[1m"
@@ -387,7 +387,7 @@ module Rails
YELLOW = "\e[33m"
CYAN = "\e[36m"
WHITE = "\e[37m"
-
+
# Show an upgrade alert to the user
def alert(title, text, more_info_url, culprits)
if Config::CONFIG['host_os'].downcase =~ /mswin|windows|mingw/
@@ -396,7 +396,7 @@ module Rails
color_alert(title, text, more_info_url, culprits)
end
end
-
+
# Show an upgrade alert to the user. If we're on Windows, we can't
# use terminal colors, hence this method.
def basic_alert(title, text, more_info_url, culprits)
@@ -410,7 +410,7 @@ module Rails
end
puts
end
-
+
# Show a colorful alert to the user
def color_alert(title, text, more_info_url, culprits)
puts "#{RED}#{BOLD}#{title}#{CLEAR}"
diff --git a/test/application_checker_test.rb b/test/application_checker_test.rb
index 085a0f2..40031d5 100644
--- a/test/application_checker_test.rb
+++ b/test/application_checker_test.rb
@@ -16,19 +16,19 @@ module Rails
module Upgrading
class ApplicationChecker
attr_reader :alerts
-
+
def base_path
BASE_ROOT + "/"
end
-
+
def in_rails_app?
true
end
-
+
def initialize
@alerts = {}
end
-
+
def alert(title, text, more_info_url, culprits)
@alerts[title] = [text, more_info_url, culprits]
end
@@ -40,125 +40,125 @@ class ApplicationCheckerTest < ActiveSupport::TestCase
def setup
@checker = Rails::Upgrading::ApplicationChecker.new
@old_dir = Dir.pwd
-
+
Dir.chdir(BASE_ROOT)
end
-
+
def test_check_ar_methods_in_controller
make_file("app/controllers", "post_controller.rb", "Post.find(:all)")
@checker.check_ar_methods
assert @checker.alerts.has_key?("Soon-to-be-deprecated ActiveRecord calls")
end
-
+
def test_check_ar_methods_in_models
make_file("app/models", "post.rb", "Post.find(:all)")
@checker.check_ar_methods
assert @checker.alerts.has_key?("Soon-to-be-deprecated ActiveRecord calls")
end
-
+
def test_named_scope_left_over
make_file("app/models", "post.rb", "named_scope :failure")
@checker.check_ar_methods
assert @checker.alerts.has_key?("named_scope is now just scope")
end
-
+
def test_check_routes
make_file("config/", "routes.rb", " map.connect 'fail'")
@checker.check_routes
assert @checker.alerts.has_key?("Old router API")
end
-
+
def test_check_for_old_test_help
make_file("test/", "test_helper.rb", " require 'test_help'")
@checker.check_test_help
assert @checker.alerts.has_key?("Deprecated test_help path")
end
-
+
def test_check_for_old_test_help_with_double_quotes
make_file("test/", "test_helper.rb", " require \"test_help\"")
@checker.check_test_help
assert @checker.alerts.has_key?("Deprecated test_help path")
end
-
+
def test_check_for_old_test_help_doesnt_see_test_helper
make_file("test/", "test_helper.rb", " require 'test_helper'")
@checker.check_test_help
assert !@checker.alerts.has_key?("Deprecated test_help path")
end
-
+
def test_check_lack_of_app_dot_rb
@checker.check_environment
assert @checker.alerts.has_key?("New file needed: config/application.rb")
end
-
+
def test_check_environment_syntax
make_file("config/", "environment.rb", "config.frameworks = []")
@checker.check_environment
-
- assert @checker.alerts.has_key?("Old environment.rb")
+
+ assert @checker.alerts.has_key?("Old environment.rb")
end
-
+
def test_check_gems
make_file("config/", "environment.rb", "config.gem 'rails'")
@checker.check_gems
-
+
assert @checker.alerts.has_key?("Old gem bundling (config.gems)")
end
-
+
def test_check_mailer_syntax
make_file("app/models/", "notifications.rb", "def signup\nrecipients @users\n end")
@checker.check_mailers
assert @checker.alerts.has_key?("Old ActionMailer class API")
end
-
+
def test_check_mailer_api
make_file("app/controllers/", "thing_controller.rb", "def signup\n Notifications.deliver_signup\n end")
@checker.check_mailers
-
+
assert @checker.alerts.has_key?("Deprecated ActionMailer API")
end
-
+
def test_check_generators
make_file("vendor/plugins/thing/generators/thing/", "thing_generator.rb", "def manifest\n m.whatever\n end")
@checker.check_generators
-
- assert @checker.alerts.has_key?("Old Rails generator API")
+
+ assert @checker.alerts.has_key?("Old Rails generator API")
end
-
+
def test_check_plugins
make_file("vendor/plugins/rspec-rails/", "whatever.rb", "def rspec; end")
@checker.check_plugins
-
+
assert @checker.alerts.has_key?("Known broken plugins")
end
-
+
def test_ignoring_comments
make_file("config/", "routes.rb", "# map.connect 'fail'")
@checker.check_routes
assert !@checker.alerts.has_key?("Old router API")
end
-
+
def test_check_deprecated_constants_in_app_code
make_file("app/controllers/", "thing_controller.rb", "class ThingController; THING = RAILS_ENV; end;")
@checker.check_deprecated_constants
-
+
assert @checker.alerts.has_key?("Deprecated constant(s)")
end
-
+
def test_check_deprecated_constants_in_lib
make_file("lib/", "extra_thing.rb", "class ExtraThing; THING = RAILS_ENV; end;")
@checker.check_deprecated_constants
-
+
assert @checker.alerts.has_key?("Deprecated constant(s)")
end
@@ -175,34 +175,47 @@ class ApplicationCheckerTest < ActiveSupport::TestCase
assert @checker.alerts.has_key?("Deprecated session secret setting")
end
-
+
def test_check_deprecated_session_settings
make_file("config/initializers/", "more_settings.rb", "ActionController::Base.session_store = :cookie\nthings.awesome(:whatever)")
@checker.check_old_session_setting
-
+
assert @checker.alerts.has_key?("Old session store setting")
end
-
+
def test_check_helpers
make_file("app/views/users/", "test.html.erb", "blah blah blah<% form_for(:thing) do |f| %> <%= f.whatever %> <% end %>")
@checker.check_old_helpers
-
+
assert @checker.alerts.has_key?("Deprecated ERb helper calls")
end
-
+
+ def test_check_old_ajax_helpers
+ make_file("app/views/sections", "section.js", "<%= link_to_remote 'section-', :update => 'sections', :url => {:action => :destroy, :controller => 'sections', :id => @section.id } %>")
+ @checker.check_old_ajax_helpers
+
+ assert @checker.alerts.has_key?("Deprecated AJAX helper calls")
+ end
+
+ def test_check_old_ajax_helpers_empty
+ @checker.check_old_ajax_helpers
+
+ assert ! @checker.alerts.has_key?("Deprecated AJAX helper calls")
+ end
+
def teardown
clear_files
-
+
Dir.chdir(@old_dir)
end
-
+
def make_file(where, name=nil, contents=nil)
FileUtils.mkdir_p "#{BASE_ROOT}/#{where}"
File.open("#{BASE_ROOT}/#{where}/#{name}", "w+") do |f|
f.write(contents)
end if name
end
-
+
def clear_files
FileUtils.rm_rf(Dir.glob("#{BASE_ROOT}/*"))
end