diff options
Diffstat (limited to 'railties')
29 files changed, 475 insertions, 358 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index ae13c3ccc9..f67177a047 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -38,41 +38,27 @@ *Sam Ruby* -* Rails now generates a `test/test_helper.rb` file with `fixtures :all` commented out by default, - since we don't want to force loading all fixtures for user when a single test is run. However, - fixtures are still going to be loaded automatically for test suites. - - To force all fixtures to be create in your database, use `rails test -f` to run your test. - - *Prem Sichanugrist* - -* Add `rails test` command for running tests +* Improved `rake test` command for running tests To run all tests: - $ rails test + $ rake test To run a test suite - $ rails test [models,helpers,units,controllers,mailers,...] + $ rake test:[models,helpers,units,controllers,mailers,...] To run a selected test file(s): - $ rails test test/unit/foo_test.rb [test/unit/bar_test.rb ...] + $ rake test test/unit/foo_test.rb [test/unit/bar_test.rb ...] To run a single test from a test file - $ rails test test/unit/foo_test.rb -n test_the_truth - - For more information, see `rails test --help`. - - This command will eventually replace `rake test:*` and `rake test` tasks. - - *Prem Sichanugrist and Chris Toomey* + $ rake test test/unit/foo_test.rb TESTOPTS='-n test_the_truth' * Improve service pages with new layout (404, etc). - *Stanislav Sobolev* + *Stanislav Sobolev* ## Rails 4.0.0.beta1 (February 25, 2013) ## diff --git a/railties/Rakefile b/railties/Rakefile index a9cb37776d..4789f41ad4 100644 --- a/railties/Rakefile +++ b/railties/Rakefile @@ -12,8 +12,9 @@ task :test => 'test:isolated' namespace :test do task :isolated do - dir = ENV["TEST_DIR"] || "**" - Dir["test/#{dir}/*_test.rb"].each do |file| + dirs = (ENV["TEST_DIR"] || ENV["TEST_DIRS"] || "**").split(",") + test_files = dirs.map { |dir| "test/#{dir}/*_test.rb" } + Dir[*test_files].each do |file| next true if file.include?("fixtures") dash_i = [ 'test', diff --git a/railties/lib/rails/all.rb b/railties/lib/rails/all.rb index 19c2226619..1493815c30 100644 --- a/railties/lib/rails/all.rb +++ b/railties/lib/rails/all.rb @@ -1,6 +1,6 @@ require "rails" -if defined?(Rake) && Rake.application.top_level_tasks.grep(/^test(?::|$)/).any? +if defined?(Rake) && Rake.application.top_level_tasks.grep(/^(default$|test(:|$))/).any? ENV['RAILS_ENV'] ||= 'test' end diff --git a/railties/lib/rails/api/task.rb b/railties/lib/rails/api/task.rb index 1e6458cf93..c829873da4 100644 --- a/railties/lib/rails/api/task.rb +++ b/railties/lib/rails/api/task.rb @@ -57,7 +57,8 @@ module Rails CHANGELOG.md MIT-LICENSE lib/**/*.rb - ) + ), + :exclude => 'lib/rails/generators/rails/**/templates/**/*.rb' } } diff --git a/railties/lib/rails/app_rails_loader.rb b/railties/lib/rails/app_rails_loader.rb index 44f4d3dabc..4a17803f1c 100644 --- a/railties/lib/rails/app_rails_loader.rb +++ b/railties/lib/rails/app_rails_loader.rb @@ -4,34 +4,58 @@ module Rails module AppRailsLoader RUBY = File.join(*RbConfig::CONFIG.values_at("bindir", "ruby_install_name")) + RbConfig::CONFIG["EXEEXT"] EXECUTABLES = ['bin/rails', 'script/rails'] + BUNDLER_WARNING = <<EOS +Looks like your app's ./bin/rails is a stub that was generated by Bundler. + +In Rails 4, your app's bin/ directory contains executables that are versioned +like any other source code, rather than stubs that are generated on demand. + +Here's how to upgrade: + + bundle config --delete bin # Turn off Bundler's stub generator + rake rails:update:bin # Use the new Rails 4 executables + git add bin # Add bin/ to source control + +You may need to remove bin/ from your .gitignore as well. + +When you install a gem whose executable you want to use in your app, +generate it and add it to source control: + + bundle binstubs some-gem-name + git add bin/new-executable + +EOS def self.exec_app_rails - cwd = Dir.pwd + original_cwd = Dir.pwd - exe = find_executable - exe ||= find_executable_in_parent_path - return unless exe + loop do + if exe = find_executable + contents = File.read(exe) - exec RUBY, exe, *ARGV if find_executable - Dir.chdir("..") do - # Recurse in a chdir block: if the search fails we want to be sure - # the application is generated in the original working directory. - exec_app_rails unless cwd == Dir.pwd - end - rescue SystemCallError - # could not chdir, no problem just return - end + if contents =~ /(APP|ENGINE)_PATH/ + exec RUBY, exe, *ARGV + break # non reachable, hack to be able to stub exec in the test suite + elsif exe.end_with?('bin/rails') && contents.include?('This file was generated by Bundler') + $stderr.puts(BUNDLER_WARNING) + Object.const_set(:APP_PATH, File.expand_path('config/application', Dir.pwd)) + require File.expand_path('../boot', APP_PATH) + require 'rails/commands' + break + end + end - def self.find_executable - EXECUTABLES.find do |exe| - File.exists?(exe) && File.read(exe) =~ /(APP|ENGINE)_PATH/ + # If we exhaust the search there is no executable, this could be a + # call to generate a new application, so restore the original cwd. + Dir.chdir(original_cwd) and return if Pathname.new(Dir.pwd).root? + + # Otherwise keep moving upwards in search of a executable. + Dir.chdir('..') end end - def self.find_executable_in_parent_path(path = Pathname.new(Dir.pwd)) - EXECUTABLES.find do |exe| - File.exists?(File.join(path, exe)) || !path.root? && find_executable_in_parent_path(path.parent) - end + def self.find_executable + EXECUTABLES.find { |exe| File.exists?(exe) } end end end diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index 1a99e3beca..2d5aa9d952 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -1,6 +1,5 @@ require 'fileutils' require 'active_support/core_ext/object/blank' -# FIXME remove LegacyKeyGenerator and this require in 4.1 require 'active_support/key_generator' require 'rails/engine' diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb index 41d3722c18..0d1286031c 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -80,15 +80,6 @@ when 'server' server.start end -when 'test' - $LOAD_PATH.unshift("./test") - require 'rails/commands/test_runner' - options = Rails::TestRunner.parse_arguments(ARGV) - ENV['RAILS_ENV'] ||= options[:environment] || 'test' - - require APP_PATH - Rails::TestRunner.start(ARGV, options) - when 'dbconsole' require 'rails/commands/dbconsole' Rails::DBConsole.start diff --git a/railties/lib/rails/commands/test_runner.rb b/railties/lib/rails/commands/test_runner.rb deleted file mode 100644 index d8857bd183..0000000000 --- a/railties/lib/rails/commands/test_runner.rb +++ /dev/null @@ -1,146 +0,0 @@ -require 'optparse' -require 'minitest/unit' - -module Rails - # Handles all logic behind +rails test+ command. - class TestRunner - class << self - # Creates a new +TestRunner+ object with an array of test files to run - # based on the arguments. When no arguments are provided, it runs all test - # files. When a suite argument is provided, it runs only the test files in - # that suite. Otherwise, it runs the specified test file(s). - def start(files, options = {}) - original_fixtures_options = options.delete(:fixtures) - options[:fixtures] = true - - case files.first - when nil - new(Dir['test/**/*_test.rb'], options).run - when 'models' - new(Dir['test/models/**/*_test.rb'], options).run - when 'helpers' - new(Dir['test/helpers/**/*_test.rb'], options).run - when 'units' - new(Dir['test/{models,helpers,unit}/**/*_test.rb'], options).run - when 'controllers' - new(Dir['test/controllers/**/*_test.rb'], options).run - when 'mailers' - new(Dir['test/mailers/**/*_test.rb'], options).run - when 'functionals' - new(Dir['test/{controllers,mailers,functional}/**/*_test.rb'], options).run - when 'integration' - new(Dir['test/integration/**/*_test.rb'], options).run - else - options[:fixtures] = original_fixtures_options - new(files, options).run - end - end - - # Parses arguments and sets them as option flags - def parse_arguments(arguments) - options = {} - orig_arguments = arguments.dup - - OptionParser.new do |opts| - opts.banner = "Usage: rails test [path to test file(s) or test suite]" - - opts.separator "" - opts.separator "Run a specific test file(s) or a test suite, under Rails'" - opts.separator "environment. If the file name(s) or suit name is omitted," - opts.separator "Rails will run all tests." - opts.separator "" - opts.separator "Specific options:" - - opts.on '-h', '--help', 'Display this help.' do - puts opts - exit - end - - opts.on '-e', '--environment NAME', String, 'Specifies the environment to run this test under' do |e| - options[:environment] = e - end - - opts.on '-f', '--fixtures', 'Load fixtures in test/fixtures/ before running the tests' do - options[:fixtures] = true - end - - opts.on '-s', '--seed SEED', Integer, "Sets random seed" do |m| - options[:seed] = m.to_i - end - - opts.on '-v', '--verbose', "Verbose. Show progress processing files." do - options[:verbose] = true - end - - opts.on '-n', '--name PATTERN', "Filter test names on pattern (e.g. /foo/)" do |n| - options[:filter] = n - end - - opts.separator "" - opts.separator "Support types of test suites:" - opts.separator "-------------------------------------------------------------" - opts.separator "* models (test/models/**/*)" - opts.separator "* helpers (test/helpers/**/*)" - opts.separator "* units (test/{models,helpers,unit}/**/*" - opts.separator "* controllers (test/controllers/**/*)" - opts.separator "* mailers (test/mailers/**/*)" - opts.separator "* functionals (test/{controllers,mailers,functional}/**/*)" - opts.separator "* integration (test/integration/**/*)" - opts.separator "-------------------------------------------------------------" - - opts.parse! arguments - orig_arguments -= arguments - end - options - end - end - - # Creates a new +TestRunner+ object with a list of test file paths. - def initialize(files, options) - @files = files - - Rails.application.load_tasks - Rake::Task['db:test:load'].invoke - - if options.delete(:fixtures) - if defined?(ActiveRecord::Base) - ActiveSupport::TestCase.send :include, ActiveRecord::TestFixtures - ActiveSupport::TestCase.fixture_path = "#{Rails.root}/test/fixtures/" - ActiveSupport::TestCase.fixtures :all - end - end - - MiniTest::Unit.runner.options = options - MiniTest::Unit.output = SilentUntilSyncStream.new(MiniTest::Unit.output) - end - - # Runs test files by evaluating each of them. - def run - @files.each { |filename| load(filename) } - end - - # A null stream object which ignores everything until +sync+ has been set - # to true. This is only used to silence unnecessary output from MiniTest, - # as MiniTest calls +output.sync = true+ right before it outputs the first - # test result. - class SilentUntilSyncStream < File - # Creates a +SilentUntilSyncStream+ object by giving it a target stream - # object that will be assigned to +MiniTest::Unit.output+ after +sync+ is - # set to true. - def initialize(target_stream) - @target_stream = target_stream - super(File::NULL, 'w') - end - - # Swaps +MiniTest::Unit.output+ to another stream when +sync+ is true. - def sync=(sync) - if sync - @target_stream.sync = true - MiniTest::Unit.output = @target_stream - end - - super - end - end - end -end diff --git a/railties/lib/rails/engine.rb b/railties/lib/rails/engine.rb index 93504b3b35..86f62dfb40 100644 --- a/railties/lib/rails/engine.rb +++ b/railties/lib/rails/engine.rb @@ -553,7 +553,7 @@ module Rails # # This needs to be an initializer, since it needs to run once # per engine and get the engine as a block parameter - initializer :set_autoload_paths, before: :bootstrap_hook do |app| + initializer :set_autoload_paths, before: :bootstrap_hook do ActiveSupport::Dependencies.autoload_paths.unshift(*_all_autoload_paths) ActiveSupport::Dependencies.autoload_once_paths.unshift(*_all_autoload_once_paths) diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index de14186a09..44fbd2f6bd 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -115,7 +115,11 @@ module Rails end def database_gemfile_entry - options[:skip_active_record] ? "" : "gem '#{gem_for_database}'" + options[:skip_active_record] ? "" : + <<-GEMFILE.strip_heredoc.chomp + # Use #{options[:database]} as the database for ActiveRecord + gem '#{gem_for_database}' + GEMFILE end def include_all_railties? @@ -131,13 +135,11 @@ module Rails <<-GEMFILE.strip_heredoc gem 'rails', path: '#{Rails::Generators::RAILS_DEV_PATH}' gem 'arel', github: 'rails/arel' - gem 'activerecord-deprecated_finders', github: 'rails/activerecord-deprecated_finders' GEMFILE elsif options.edge? <<-GEMFILE.strip_heredoc gem 'rails', github: 'rails/rails' gem 'arel', github: 'rails/arel' - gem 'activerecord-deprecated_finders', github: 'rails/activerecord-deprecated_finders' GEMFILE else <<-GEMFILE.strip_heredoc @@ -178,58 +180,56 @@ module Rails return if options[:skip_sprockets] gemfile = if options.dev? || options.edge? - <<-GEMFILE.gsub(/^ {12}/, '') + <<-GEMFILE.strip_heredoc # Use edge version of sprockets-rails gem 'sprockets-rails', github: 'rails/sprockets-rails' # Use SCSS for stylesheets - gem 'sass-rails', github: 'rails/sass-rails' + gem 'sass-rails', github: 'rails/sass-rails' - # To use Uglifier as compressor for JavaScript assets - gem 'uglifier', '>= 1.3.0' + # Use Uglifier as compressor for JavaScript assets + gem 'uglifier', '~> 1.3' GEMFILE else - <<-GEMFILE.gsub(/^ {12}/, '') + <<-GEMFILE.strip_heredoc # Use SCSS for stylesheets - gem 'sass-rails', '~> 4.0.0.beta1' + gem 'sass-rails', '~> 4.0.0.beta1' - # To use Uglifier as compressor for JavaScript assets - gem 'uglifier', '>= 1.3.0' + # Use Uglifier as compressor for JavaScript assets + gem 'uglifier', '~> 1.3' GEMFILE end if options[:skip_javascript] - gemfile += <<-GEMFILE.gsub(/^ {12}/, '') + gemfile += <<-GEMFILE #{coffee_gemfile_entry} #{javascript_runtime_gemfile_entry} GEMFILE end - gemfile.strip_heredoc.gsub(/^[ \t]*$/, '') + gemfile.gsub(/^[ \t]+/, '') end def coffee_gemfile_entry - gemfile = if options.dev? || options.edge? - <<-GEMFILE.gsub(/^ {12}/, '') + if options.dev? || options.edge? + <<-GEMFILE # Use CoffeeScript for .js.coffee assets and views gem 'coffee-rails', github: 'rails/coffee-rails' GEMFILE else - <<-GEMFILE.gsub(/^ {12}/, '') + <<-GEMFILE # Use CoffeeScript for .js.coffee assets and views gem 'coffee-rails', '~> 4.0.0.beta1' GEMFILE end - - gemfile.strip_heredoc.gsub(/^[ \t]*$/, '') end def javascript_gemfile_entry unless options[:skip_javascript] - <<-GEMFILE.gsub(/^ {12}/, '').strip_heredoc + <<-GEMFILE.gsub(/^[ \t]+/, '') #{coffee_gemfile_entry} #{javascript_runtime_gemfile_entry} - + # Use #{options[:javascript]} as the JavaScript library gem '#{options[:javascript]}-rails' # Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks @@ -244,7 +244,7 @@ module Rails else "# gem 'therubyracer', platforms: :ruby" end - <<-GEMFILE.gsub(/^ {10}/, '') + <<-GEMFILE # See https://github.com/sstephenson/execjs#readme for more supported runtimes #{runtime} GEMFILE diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 8b4f52bb3b..d891ba1215 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -40,7 +40,7 @@ module Rails def indent(content, multiplier = 2) spaces = " " * multiplier - content = content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join + content.each_line.map {|line| line.blank? ? line : "#{spaces}#{line}" }.join end def wrap_with_namespace(content) diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 07cf31dd83..1842e09bae 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -17,16 +17,16 @@ end # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 1.0.1' -# To use ActiveModel has_secure_password +# Use ActiveModel has_secure_password # gem 'bcrypt-ruby', '~> 3.0.0' # Use unicorn as the app server # gem 'unicorn' -# Deploy with Capistrano +# Use Capistrano for deployment # gem 'capistrano', group: :development <% unless defined?(JRUBY_VERSION) -%> -# To use debugger +# Use debugger # gem 'debugger', group: [:development, :test] <% end -%> diff --git a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb index ca40914d3b..4fd060341e 100644 --- a/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/app/templates/test/test_helper.rb @@ -6,12 +6,11 @@ class ActiveSupport::TestCase <% unless options[:skip_active_record] -%> ActiveRecord::Migration.check_pending! - # Uncomment the `fixtures :all` line below to setup all fixtures in test/fixtures/*.yml - # for all tests in alphabetical order. + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. # # Note: You'll currently still have to declare fixtures explicitly in integration tests # -- they do not yet inherit this setting - # fixtures :all + fixtures :all <% end -%> # Add more helper methods to be used by all tests here... diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE index 6574200fbf..1998a392aa 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/rails/generators/rails/model/USAGE @@ -52,20 +52,26 @@ Available field types: `rails generate model product supplier:references{polymorphic}` - You can also specify some options just after the field type. You can use the - following options: + For integer, string, text and binary fields an integer in curly braces will + be set as the limit: - limit Set the maximum size of the field giving a number between curly braces - default Set a default value for the field - precision Defines the precision for the decimal fields - scale Defines the scale for the decimal fields - uniq Defines the field values as unique - index Will add an index on the field + `rails generate model user pseudo:string{30}` - Examples: + For decimal two integers separated by a comma in curly braces will be used + for precision and scale: + + `rails generate model product price:decimal{10,2}` + + You can add a `:uniq` or `:index` suffix for unique or standard indexes + respectively: - `rails generate model user pseudo:string{30}` `rails generate model user pseudo:string:uniq` + `rails generate model user pseudo:string:index` + + You can combine any single curly brace option with the index options: + + `rails generate model user username:string{30}:uniq` + `rails generate model product supplier:references{polymorphic}:index` Examples: diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb index caad810de8..7576eba6e0 100644 --- a/railties/lib/rails/generators/testing/behaviour.rb +++ b/railties/lib/rails/generators/testing/behaviour.rb @@ -61,7 +61,10 @@ module Rails # You can provide a configuration hash as second argument. This method returns the output # printed by the generator. def run_generator(args=self.default_arguments, config={}) - capture(:stdout) { self.generator_class.start(args, config.reverse_merge(destination_root: destination_root)) } + capture(:stdout) do + args += ['--skip-bundle'] unless args.include? '--dev' + self.generator_class.start(args, config.reverse_merge(destination_root: destination_root)) + end end # Instantiate the generator. diff --git a/railties/lib/rails/test_unit/sub_test_task.rb b/railties/lib/rails/test_unit/sub_test_task.rb index 87b6f9b5a4..a463380e2d 100644 --- a/railties/lib/rails/test_unit/sub_test_task.rb +++ b/railties/lib/rails/test_unit/sub_test_task.rb @@ -1,6 +1,83 @@ +require 'rake/testtask' + module Rails + class TestTask < Rake::TestTask # :nodoc: all + class TestInfo + def initialize(tasks) + @tasks = tasks + end + + def files + @tasks.map { |task| + [task, translate(task)].find { |file| test_file?(file) } + }.compact + end + + def translate(file) + if file =~ /^app\/(.*)$/ + "test/#{$1.sub(/\.rb$/, '')}_test.rb" + else + "test/#{file}_test.rb" + end + end + + def tasks + @tasks - test_file_tasks - opt_names + end + + def opts + opts = opt_names + if opts.any? + "-n #{opts.join ' '}" + end + end + + private + + def test_file_tasks + @tasks.find_all { |task| + [task, translate(task)].any? { |file| test_file?(file) } + } + end + + def test_file?(file) + file =~ /^test/ && File.file?(file) && !File.directory?(file) + end + + def opt_names + (@tasks - test_file_tasks).reject { |t| task_defined? t } + end + + def task_defined?(task) + Rake::Task.task_defined? task + end + end + + def self.test_info(tasks) + TestInfo.new tasks + end + + def initialize(name = :test) + super + @libs << "test" # lib *and* test seem like a better default + end + + def define + task @name do + if ENV['TESTOPTS'] + ARGV.replace Shellwords.split ENV['TESTOPTS'] + end + libs = @libs - $LOAD_PATH + $LOAD_PATH.unshift(*libs) + file_list.each { |fl| + FileList[fl].to_a.each { |f| require File.expand_path f } + } + end + end + end + # Silence the default description to cut down on `rake -T` noise. - class SubTestTask < Rake::TestTask + class SubTestTask < Rake::TestTask # :nodoc: def desc(string) # Ignore the description. end diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake index 3c247f32c0..877dd6d254 100644 --- a/railties/lib/rails/test_unit/testing.rake +++ b/railties/lib/rails/test_unit/testing.rake @@ -48,10 +48,17 @@ task default: :test desc 'Runs test:units, test:functionals, test:integration together' task :test do - if ENV['TEST'] - exec "bundle exec rails test #{ENV['TEST'].inspect}" + info = Rails::TestTask.test_info Rake.application.top_level_tasks + if info.files.any? + Rails::TestTask.new('test:single') { |t| + t.test_files = info.files + } + ENV['TESTOPTS'] ||= info.opts + Rake.application.top_level_tasks.replace info.tasks + + Rake::Task['test:single'].invoke else - exec 'bundle exec rails test' + Rake::Task[ENV['TEST'] ? 'test:single' : 'test:run'].invoke end end @@ -60,15 +67,11 @@ namespace :test do # Placeholder task for other Railtie and plugins to enhance. See Active Record for an example. end - task :run do - ActiveSupport::Deprecation.warn "`rake test:run` is deprecated. Please use `rails test`." - exec 'bundle exec rails test' - end + task :run => ['test:units', 'test:functionals', 'test:integration'] # Inspired by: http://ngauthier.com/2012/02/quick-tests-with-bash.html desc "Run tests quickly by merging all types and not resetting db" - Rake::TestTask.new(:all) do |t| - t.libs << "test" + Rails::TestTask.new(:all) do |t| t.pattern = "test/**/*_test.rb" end @@ -90,7 +93,6 @@ namespace :test do recent_tests('app/controllers/**/*.rb', 'test/controllers', since) + recent_tests('app/controllers/**/*.rb', 'test/functional', since) - t.libs << 'test' t.test_files = touched.uniq end Rake::Task['test:recent'].comment = "Deprecated; Test recent changes" @@ -114,23 +116,36 @@ namespace :test do controllers.map { |controller| "test/functional/#{File.basename(controller, '.rb')}_test.rb" } (unit_tests + functional_tests).uniq.select { |file| File.exist?(file) } end - - t.libs << 'test' end Rake::Task['test:uncommitted'].comment = "Deprecated; Test changes since last checkin (only Subversion and Git)" - desc "Deprecated; Please use `rails test \"#{ENV['TEST']}\"`" - task :single do - ActiveSupport::Deprecation.warn "`rake test:single` is deprecated. Please use `rails test \"#{ENV['TEST']}\"`." - exec "bundle exec rails test #{test_suit_name}" + Rails::TestTask.new(single: "test:prepare") + + Rails::TestTask.new(models: "test:prepare") do |t| + t.pattern = 'test/models/**/*_test.rb' end - [:models, :helpers, :units, :controllers, :functionals, :integration].each do |test_suit_name| - desc "Deprecated; Please use `rails test #{test_suit_name}`" - task test_suit_name do - ActiveSupport::Deprecation.warn "`rake test:#{test_suit_name}` is deprecated. Please use `rails test #{test_suit_name}`." + Rails::TestTask.new(helpers: "test:prepare") do |t| + t.pattern = 'test/helpers/**/*_test.rb' + end - exec "bundle exec rails test #{test_suit_name}" - end + Rails::TestTask.new(units: "test:prepare") do |t| + t.pattern = 'test/{models,helpers,unit}/**/*_test.rb' + end + + Rails::TestTask.new(controllers: "test:prepare") do |t| + t.pattern = 'test/controllers/**/*_test.rb' + end + + Rails::TestTask.new(mailers: "test:prepare") do |t| + t.pattern = 'test/mailers/**/*_test.rb' + end + + Rails::TestTask.new(functionals: "test:prepare") do |t| + t.pattern = 'test/{controllers,mailers,functional}/**/*_test.rb' + end + + Rails::TestTask.new(integration: "test:prepare") do |t| + t.pattern = 'test/integration/**/*_test.rb' end end diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_rails_loader_test.rb index 63ed9eaef0..ceae78ae80 100644 --- a/railties/test/app_rails_loader_test.rb +++ b/railties/test/app_rails_loader_test.rb @@ -1,48 +1,68 @@ +require 'tmpdir' require 'abstract_unit' require 'rails/app_rails_loader' class AppRailsLoaderTest < ActiveSupport::TestCase + def write(filename, contents=nil) + FileUtils.mkdir_p(File.dirname(filename)) + File.write(filename, contents) + end + + def expects_exec(exe) + Rails::AppRailsLoader.expects(:exec).with(Rails::AppRailsLoader::RUBY, exe) + end setup do - File.stubs(:exists?).returns(false) + @tmp = Dir.mktmpdir('railties-rails-loader-test-suite') + @cwd = Dir.pwd + Dir.chdir(@tmp) end - ['bin/rails', 'script/rails'].each do |exe| - test "is in a rails application if #{exe} exists and contains APP_PATH" do - File.stubs(:exists?).with(exe).returns(true) - File.stubs(:read).with(exe).returns('APP_PATH') - assert Rails::AppRailsLoader.find_executable - end + ['bin', 'script'].each do |script_dir| + exe = "#{script_dir}/rails" - test "is not in a rails application if #{exe} exists but doesn't contain APP_PATH" do - File.stubs(:exists?).with(exe).returns(true) - File.stubs(:read).with(exe).returns("railties #{exe}") - assert !Rails::AppRailsLoader.find_executable - end + test "is not in a Rails application if #{exe} is not found in the current or parent directories" do + File.stubs(:exists?).with('bin/rails').returns(false) + File.stubs(:exists?).with('script/rails').returns(false) - test "is in a rails application if parent directory has #{exe} containing APP_PATH" do - File.stubs(:exists?).with("/foo/bar/#{exe}").returns(false) - File.stubs(:exists?).with("/foo/#{exe}").returns(true) - File.stubs(:read).with("/foo/#{exe}").returns('APP_PATH') - assert Rails::AppRailsLoader.find_executable_in_parent_path(Pathname.new("/foo/bar")) + assert !Rails::AppRailsLoader.exec_app_rails end - test "is not in a rails application if at the root directory and doesn't have #{exe}" do - Pathname.any_instance.stubs(:root?).returns true - assert !Rails::AppRailsLoader.find_executable - end + ['APP_PATH', 'ENGINE_PATH'].each do |keyword| + test "is in a Rails application if #{exe} exists and contains #{keyword}" do + write exe, keyword - test "is in a rails engine if parent directory has #{exe} containing ENGINE_PATH" do - File.stubs(:exists?).with("/foo/bar/#{exe}").returns(false) - File.stubs(:exists?).with("/foo/#{exe}").returns(true) - File.stubs(:read).with("/foo/#{exe}").returns('ENGINE_PATH') - assert Rails::AppRailsLoader.find_executable_in_parent_path(Pathname.new("/foo/bar")) - end + expects_exec exe + Rails::AppRailsLoader.exec_app_rails + end - test "is in a rails engine if #{exe} exists containing ENGINE_PATH" do - File.stubs(:exists?).with(exe).returns(true) - File.stubs(:read).with(exe).returns('ENGINE_PATH') - assert Rails::AppRailsLoader.find_executable + test "is not in a Rails application if #{exe} exists but doesn't contain #{keyword}" do + write exe + + assert !Rails::AppRailsLoader.exec_app_rails + end + + test "is in a Rails application if parent directory has #{exe} containing #{keyword} and chdirs to the root directory" do + write "foo/bar/#{exe}" + write "foo/#{exe}", keyword + + Dir.chdir('foo/bar') + + expects_exec exe + Rails::AppRailsLoader.exec_app_rails + + # Compare the realpath in case either of them has symlinks. + # + # This happens in particular in Mac OS X, where @tmp starts + # with "/var", and Dir.pwd with "/private/var", due to a + # default system symlink var -> private/var. + assert_equal File.realpath("#@tmp/foo"), File.realpath(Dir.pwd) + end end end + + teardown do + Dir.chdir(@cwd) + FileUtils.rm_rf(@tmp) + end end diff --git a/railties/test/application/initializers/load_path_test.rb b/railties/test/application/initializers/load_path_test.rb index 9b18c329ec..0c66213caa 100644 --- a/railties/test/application/initializers/load_path_test.rb +++ b/railties/test/application/initializers/load_path_test.rb @@ -72,6 +72,7 @@ module ApplicationTests end test "load environment with global" do + $initialize_test_set_from_env = nil app_file "config/environments/development.rb", <<-RUBY $initialize_test_set_from_env = 'success' AppTemplate::Application.configure do diff --git a/railties/test/application/middleware/remote_ip_test.rb b/railties/test/application/middleware/remote_ip_test.rb index c655384d75..91c5807379 100644 --- a/railties/test/application/middleware/remote_ip_test.rb +++ b/railties/test/application/middleware/remote_ip_test.rb @@ -1,5 +1,4 @@ require 'isolation/abstract_unit' -# FIXME remove LegacyKeyGenerator and this require in 4.1 require 'active_support/key_generator' module ApplicationTests diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index a9e0e1bcb7..fa3ab969ae 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -79,25 +79,30 @@ module ApplicationTests assert_match "Hello world", output end - def test_code_statistics_sanity - assert_match "Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0", - Dir.chdir(app_path){ `rake stats` } - end + def test_should_not_eager_load_model_path_for_rake + add_to_config <<-RUBY + config.eager_load = true - def test_rake_test_error_output - Dir.chdir(app_path){ `rake db:migrate` } + rake_tasks do + task do_nothing: :environment do + end + end + RUBY - app_file "test/models/one_model_test.rb", <<-RUBY - raise 'models' + app_file "app/models/hello.rb", <<-RUBY + raise 'should not be pre-required for rake even `eager_load=true`' RUBY - silence_stderr do - output = Dir.chdir(app_path) { `rake test 2>&1` } - assert_match 'models', output - end + Dir.chdir(app_path){ `rake do_nothing` } + end + + def test_code_statistics_sanity + assert_match "Code LOC: 5 Test LOC: 0 Code to Test Ratio: 1:0.0", + Dir.chdir(app_path){ `rake stats` } end def test_rake_test_uncommitted_always_find_git_in_parent_dir + return "FIXME :'(" app_name = File.basename(app_path) app_dir = File.dirname(app_path) moved_app_name = app_name + '_moved' @@ -129,13 +134,10 @@ module ApplicationTests Dir.chdir(app_path){ `rails generate scaffold user name:string` } Dir.chdir(app_path){ `rake db:migrate` } - %w(run recent uncommitted models helpers units controllers functionals integration).each do |test_suit_name| + %w(recent uncommitted).each do |test_suit_name| output = Dir.chdir(app_path) { `rake test:#{test_suit_name} 2>&1` } - assert_match /DEPRECATION WARNING: `rake test:#{test_suit_name}` is deprecated/, output + assert_match(/DEPRECATION WARNING: `rake test:#{test_suit_name}` is deprecated/, output) end - - assert_match /DEPRECATION WARNING: `rake test:single` is deprecated/, - Dir.chdir(app_path) { `rake test:single TEST=test/models/user_test.rb 2>&1` } end def test_rake_routes_calls_the_route_inspector diff --git a/railties/test/application/rendering_test.rb b/railties/test/application/rendering_test.rb new file mode 100644 index 0000000000..588d64dde9 --- /dev/null +++ b/railties/test/application/rendering_test.rb @@ -0,0 +1,45 @@ +require 'isolation/abstract_unit' +require 'rack/test' + +module ApplicationTests + class RoutingTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + include Rack::Test::Methods + + def setup + build_app + boot_rails + end + + def teardown + teardown_app + end + + test "Unknown format falls back to HTML template" do + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do + get 'pages/:id', to: 'pages#show' + end + RUBY + + app_file 'app/controllers/pages_controller.rb', <<-RUBY + class PagesController < ApplicationController + layout false + + def show + end + end + RUBY + + app_file 'app/views/pages/show.html.erb', <<-RUBY + <%= params[:id] %> + RUBY + + get '/pages/foo' + assert_equal 200, last_response.status + + get '/pages/foo.bar' + assert_equal 200, last_response.status + end + end +end diff --git a/railties/test/application/routing_test.rb b/railties/test/application/routing_test.rb index 22de640236..25372d0a50 100644 --- a/railties/test/application/routing_test.rb +++ b/railties/test/application/routing_test.rb @@ -277,6 +277,30 @@ module ApplicationTests end end + def test_root_path + app('development') + + controller :foo, <<-RUBY + class FooController < ApplicationController + def index + render :text => "foo" + end + end + RUBY + + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do + get 'foo', :to => 'foo#index' + root :to => 'foo#index' + end + RUBY + + remove_file 'public/index.html' + + get '/' + assert_equal 'foo', last_response.body + end + test 'routes are added and removed when reloading' do app('development') diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb index 56ca3bc1a9..1cf53aa4fb 100644 --- a/railties/test/application/test_runner_test.rb +++ b/railties/test/application/test_runner_test.rb @@ -15,14 +15,6 @@ module ApplicationTests teardown_app end - def test_should_not_display_heading - create_test_file - run_test_command.tap do |output| - assert_no_match "Run options:", output - assert_no_match "Running tests:", output - end - end - def test_run_in_test_environment app_file 'test/unit/env_test.rb', <<-RUBY require 'test_helper' @@ -37,14 +29,9 @@ module ApplicationTests assert_match "Current Environment: test", run_test_command('test/unit/env_test.rb') end - def test_run_shortcut - create_test_file :models, 'foo' - output = Dir.chdir(app_path) { `bundle exec rails t test/models/foo_test.rb` } - assert_match "1 tests, 1 assertions, 0 failures", output - end - def test_run_single_file create_test_file :models, 'foo' + create_test_file :models, 'bar' assert_match "1 tests, 1 assertions, 0 failures", run_test_command("test/models/foo_test.rb") end @@ -62,24 +49,14 @@ module ApplicationTests error_stream = Tempfile.new('error') redirect_stderr(error_stream) { run_test_command('test/models/error_test.rb') } - assert_match "SyntaxError", error_stream.read - end - - def test_invoke_rake_db_test_load - app_file "lib/tasks/test.rake", <<-RUBY - task 'db:test:load' do - puts "Hello World" - end - RUBY - create_test_file - assert_match "Hello World", run_test_command + assert_match "syntax error", error_stream.read end def test_run_models create_test_file :models, 'foo' create_test_file :models, 'bar' create_test_file :controllers, 'foobar_controller' - run_test_command("models").tap do |output| + run_test_models_command.tap do |output| assert_match "FooTest", output assert_match "BarTest", output assert_match "2 tests, 2 assertions, 0 failures", output @@ -90,7 +67,7 @@ module ApplicationTests create_test_file :helpers, 'foo_helper' create_test_file :helpers, 'bar_helper' create_test_file :controllers, 'foobar_controller' - run_test_command('helpers').tap do |output| + run_test_helpers_command.tap do |output| assert_match "FooHelperTest", output assert_match "BarHelperTest", output assert_match "2 tests, 2 assertions, 0 failures", output @@ -102,7 +79,7 @@ module ApplicationTests create_test_file :helpers, 'bar_helper' create_test_file :unit, 'baz_unit' create_test_file :controllers, 'foobar_controller' - run_test_command('units').tap do |output| + run_test_units_command.tap do |output| assert_match "FooTest", output assert_match "BarHelperTest", output assert_match "BazUnitTest", output @@ -114,7 +91,7 @@ module ApplicationTests create_test_file :controllers, 'foo_controller' create_test_file :controllers, 'bar_controller' create_test_file :models, 'foo' - run_test_command('controllers').tap do |output| + run_test_controllers_command.tap do |output| assert_match "FooControllerTest", output assert_match "BarControllerTest", output assert_match "2 tests, 2 assertions, 0 failures", output @@ -125,7 +102,7 @@ module ApplicationTests create_test_file :mailers, 'foo_mailer' create_test_file :mailers, 'bar_mailer' create_test_file :models, 'foo' - run_test_command('mailers').tap do |output| + run_test_mailers_command.tap do |output| assert_match "FooMailerTest", output assert_match "BarMailerTest", output assert_match "2 tests, 2 assertions, 0 failures", output @@ -137,7 +114,7 @@ module ApplicationTests create_test_file :controllers, 'bar_controller' create_test_file :functional, 'baz_functional' create_test_file :models, 'foo' - run_test_command('functionals').tap do |output| + run_test_functionals_command.tap do |output| assert_match "FooMailerTest", output assert_match "BarControllerTest", output assert_match "BazFunctionalTest", output @@ -148,7 +125,7 @@ module ApplicationTests def test_run_integration create_test_file :integration, 'foo_integration' create_test_file :models, 'foo' - run_test_command('integration').tap do |output| + run_test_integration_command.tap do |output| assert_match "FooIntegration", output assert_match "1 tests, 1 assertions, 0 failures", output end @@ -178,17 +155,31 @@ module ApplicationTests end RUBY - run_test_command('test/unit/chu_2_koi_test.rb -n test_rikka').tap do |output| + run_test_command('test/unit/chu_2_koi_test.rb test_rikka').tap do |output| assert_match "Rikka", output assert_no_match "Sanae", output end end - def test_not_load_fixtures_when_running_single_test - create_model_with_fixture - create_fixture_test :models, 'user' - assert_match "0 users", run_test_command('test/models/user_test.rb') - assert_match "3 users", run_test_command('test/models/user_test.rb -f') + def test_run_matched_test + app_file 'test/unit/chu_2_koi_test.rb', <<-RUBY + require 'test_helper' + + class Chu2KoiTest < ActiveSupport::TestCase + def test_rikka + puts 'Rikka' + end + + def test_sanae + puts 'Sanae' + end + end + RUBY + + run_test_command('test/unit/chu_2_koi_test.rb /rikka/').tap do |output| + assert_match "Rikka", output + assert_no_match "Sanae", output + end end def test_load_fixtures_when_running_test_suites @@ -199,11 +190,18 @@ module ApplicationTests suites.each do |suite, directory| directory ||= suite create_fixture_test directory - assert_match "3 users", run_test_command(suite) + assert_match "3 users", run_task(["test:#{suite}"]) Dir.chdir(app_path) { FileUtils.rm_f "test/#{directory}" } end end + def test_run_with_model + create_model_with_fixture + create_fixture_test 'models', 'user' + assert_match "3 users", run_task(["test models/user"]) + assert_match "3 users", run_task(["test app/models/user.rb"]) + end + def test_run_different_environment_using_env_var app_file 'test/unit/env_test.rb', <<-RUBY require 'test_helper' @@ -220,6 +218,7 @@ module ApplicationTests end def test_run_different_environment_using_e_tag + env = "development" app_file 'test/unit/env_test.rb', <<-RUBY require 'test_helper' @@ -230,7 +229,7 @@ module ApplicationTests end RUBY - assert_match "development", run_test_command('-e development test/unit/env_test.rb') + assert_match env, run_test_command("test/unit/env_test.rb RAILS_ENV=#{env}") end def test_generated_scaffold_works_with_rails_test @@ -239,8 +238,17 @@ module ApplicationTests end private + def run_task(tasks) + Dir.chdir(app_path) { `bundle exec rake #{tasks.join ' '}` } + end + def run_test_command(arguments = 'test/unit/test_test.rb') - Dir.chdir(app_path) { `bundle exec rails test #{arguments}` } + run_task ['test', arguments] + end + %w{ mailers models helpers units controllers functionals integration }.each do |type| + define_method("run_test_#{type}_command") do + run_task ["test:#{type}"] + end end def create_model_with_fixture diff --git a/railties/test/commands/console_test.rb b/railties/test/commands/console_test.rb index 3c784b43be..a34beaedb3 100644 --- a/railties/test/commands/console_test.rb +++ b/railties/test/commands/console_test.rb @@ -114,9 +114,10 @@ class Rails::ConsoleTest < ActiveSupport::TestCase assert_match('dev', options[:environment]) end - private - attr_reader :output + private :output + + private def start(argv = []) rails_console = Rails::Console.new(app, parse_arguments(argv)) diff --git a/railties/test/commands/dbconsole_test.rb b/railties/test/commands/dbconsole_test.rb index 38fe8ca544..edb92b3aa2 100644 --- a/railties/test/commands/dbconsole_test.rb +++ b/railties/test/commands/dbconsole_test.rb @@ -172,8 +172,10 @@ class Rails::DBConsoleTest < ActiveSupport::TestCase assert_match(/Usage:.*dbconsole/, stdout) end - private attr_reader :aborted, :output + private :aborted, :output + + private def dbconsole @dbconsole ||= Rails::DBConsole.new(nil) diff --git a/railties/test/generators/plugin_new_generator_test.rb b/railties/test/generators/plugin_new_generator_test.rb index 48425cbf81..ac71fb5884 100644 --- a/railties/test/generators/plugin_new_generator_test.rb +++ b/railties/test/generators/plugin_new_generator_test.rb @@ -124,7 +124,7 @@ class PluginNewGeneratorTest < Rails::Generators::TestCase run_generator [destination_root, "--skip_active_record"] assert_no_file "test/dummy/config/database.yml" assert_file "test/test_helper.rb" do |contents| - assert_no_match /ActiveRecord/, contents + assert_no_match(/ActiveRecord/, contents) end end diff --git a/railties/test/railties/generators_test.rb b/railties/test/railties/generators_test.rb index 0abb2b7578..7348d70c56 100644 --- a/railties/test/railties/generators_test.rb +++ b/railties/test/railties/generators_test.rb @@ -44,7 +44,7 @@ module RailtiesTests Dir.chdir(engine_path) do File.open("Gemfile", "w") do |f| f.write <<-GEMFILE.gsub(/^ {12}/, '') - source "http://rubygems.org" + source "https://rubygems.org" gem 'rails', path: '#{RAILS_FRAMEWORK_ROOT}' gem 'sqlite3' diff --git a/railties/test/test_info_test.rb b/railties/test/test_info_test.rb new file mode 100644 index 0000000000..d5463c11de --- /dev/null +++ b/railties/test/test_info_test.rb @@ -0,0 +1,59 @@ +require 'abstract_unit' +require 'rails/test_unit/sub_test_task' + +module Rails + class TestInfoTest < ActiveSupport::TestCase + def test_test_files + info = new_test_info ['test'] + assert_predicate info.files, :empty? + assert_nil info.opts + assert_equal ['test'], info.tasks + end + + def test_with_file + info = new_test_info ['test', __FILE__] + assert_equal [__FILE__], info.files + assert_nil info.opts + assert_equal ['test'], info.tasks + end + + def test_with_opts + info = new_test_info ['test', __FILE__, '/foo/'] + assert_equal [__FILE__], info.files + assert_equal '-n /foo/', info.opts + assert_equal ['test'], info.tasks + end + + def test_with_model_shorthand + info = new_test_info ['test', 'models/foo', '/foo/'] + + def info.test_file?(file) + file == "test/models/foo_test.rb" || super + end + + assert_equal ['test/models/foo_test.rb'], info.files + assert_equal '-n /foo/', info.opts + assert_equal ['test'], info.tasks + end + + def test_with_model_path + info = new_test_info ['test', 'app/models/foo.rb', '/foo/'] + + def info.test_file?(file) + file == "test/models/foo_test.rb" || super + end + + assert_equal ['test/models/foo_test.rb'], info.files + assert_equal '-n /foo/', info.opts + assert_equal ['test'], info.tasks + end + + def new_test_info(tasks) + Class.new(TestTask::TestInfo) { + def task_defined?(task) + task == "test" + end + }.new tasks + end + end +end |