diff options
Diffstat (limited to 'railties')
47 files changed, 859 insertions, 631 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index a69920252c..e4a08f68c1 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,5 +1,10 @@ ## Rails 4.0.0 (unreleased) ## +* Move rails.png into a data-uri. One less file to get generated into a new + application. This is also consistent with the removal of index.html. + + *Steve Klabnik* + * The application rake task `doc:rails` generates now an API like the official one (except for the links to GitHub). @@ -17,10 +22,6 @@ *Gabe Kopley* -* `Rails.version` now returns an instance of `Gem::Version` - - *Charlie Somerville* - * Don't generate a scaffold.css when --no-assets is specified *Kevin Glowacz* @@ -37,39 +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. + $ rake test test/unit/foo_test.rb TESTOPTS='-n test_the_truth' - *Prem Sichanugrist and Chris Toomey* +* Improve service pages with new layout (404, etc). -* Improve service pages with new layout (404, etc). *Stanislav Sobolev* + *Stanislav Sobolev* ## Rails 4.0.0.beta1 (February 25, 2013) ## @@ -286,17 +275,25 @@ *Derek Prior & Francesco Rodriguez* -* Fixed support for DATABASE_URL environment variable for rake db tasks. *Grace Liu* +* Fixed support for `DATABASE_URL` environment variable for rake db tasks. -* rails dbconsole now can use SSL for MySQL. The database.yml options sslca, sslcert, sslcapath, sslcipher, - and sslkey now affect rails dbconsole. *Jim Kingdon and Lars Petrus* + *Grace Liu* + +* `rails dbconsole` now can use SSL for MySQL. The `database.yml` options sslca, sslcert, sslcapath, sslcipher + and sslkey now affect `rails dbconsole`. + + *Jim Kingdon and Lars Petrus* * Correctly handle SCRIPT_NAME when generating routes to engine in application that's mounted at a sub-uri. With this behavior, you *should not* use - default_url_options[:script_name] to set proper application's mount point by - yourself. *Piotr Sarnacki* + `default_url_options[:script_name]` to set proper application's mount point by + yourself. + + *Piotr Sarnacki* -* `config.threadsafe!` is deprecated in favor of `config.eager_load` which provides a more fine grained control on what is eager loaded *José Valim* +* `config.threadsafe!` is deprecated in favor of `config.eager_load` which provides a more fine grained control on what is eager loaded . + + *José Valim* * The migration generator will now produce AddXXXToYYY/RemoveXXXFromYYY migrations with references statements, for instance @@ -319,21 +316,35 @@ *Aleksey Magusev* -* Set `config.active_record.migration_error` to `:page_load` for development *Richard Schneeman* +* Set `config.active_record.migration_error` to `:page_load` for development. + + *Richard Schneeman* + +* Add runner to `Rails::Railtie` as a hook called just after runner starts. + + *José Valim & kennyj* + +* Add `/rails/info/routes` path, displays same information as `rake routes` . + + *Richard Schneeman & Andrew White* -* Add runner to Rails::Railtie as a hook called just after runner starts. *José Valim & kennyj* +* Improved `rake routes` output for redirects. -* Add `/rails/info/routes` path, displays same information as `rake routes` *Richard Schneeman & Andrew White* + *Łukasz Strzałkowski & Andrew White* -* Improved `rake routes` output for redirects *Łukasz Strzałkowski & Andrew White* +* Load all environments available in `config.paths["config/environments"]`. -* Load all environments available in `config.paths["config/environments"]`. *Piotr Sarnacki* + *Piotr Sarnacki* -* Remove Rack::SSL in favour of ActionDispatch::SSL. *Rafael Mendonça França* +* Remove `Rack::SSL` in favour of `ActionDispatch::SSL`. -* Remove Active Resource from Rails framework. *Prem Sichangrist* + *Rafael Mendonça França* -* Allow to set class that will be used to run as a console, other than IRB, with `Rails.application.config.console=`. It's best to add it to `console` block. *Piotr Sarnacki* +* Remove Active Resource from Rails framework. + + *Prem Sichangrist* + +* Allow to set class that will be used to run as a console, other than IRB, with `Rails.application.config.console=`. It's best to add it to `console` block. Example: @@ -345,12 +356,20 @@ config.console = Pry end + *Piotr Sarnacki* + * Add convenience `hide!` method to Rails generators to hide current generator - namespace from showing when running `rails generate`. *Carlos Antonio da Silva* + namespace from showing when running `rails generate`. -* Rails::Plugin has gone. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies. *Santiago Pastorino* + *Carlos Antonio da Silva* + +* Rails::Plugin has gone. Instead of adding plugins to vendor/plugins use gems or bundler with path or git dependencies. + + *Santiago Pastorino* * Set config.action_mailer.async = true to turn on asynchronous - message delivery *Brian Cardarella* + message delivery. + + *Brian Cardarella* Please check [3-2-stable](https://github.com/rails/rails/blob/3-2-stable/railties/CHANGELOG.md) for previous changes. diff --git a/railties/Rakefile b/railties/Rakefile index eb068fc526..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', @@ -22,7 +23,7 @@ namespace :test do "#{File.dirname(__FILE__)}/../actionpack/lib", "#{File.dirname(__FILE__)}/../activemodel/lib" ] - ruby "-I#{dash_i.join ':'}", file + ruby "-w", "-I#{dash_i.join ':'}", file end end end diff --git a/railties/lib/rails.rb b/railties/lib/rails.rb index 84f8b82ad5..bb98bbe5bf 100644 --- a/railties/lib/rails.rb +++ b/railties/lib/rails.rb @@ -82,6 +82,10 @@ module Rails groups end + def version + VERSION::STRING + end + def public_path application && Pathname.new(application.paths["public"].first) end 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 3e7223f075..c829873da4 100644 --- a/railties/lib/rails/api/task.rb +++ b/railties/lib/rails/api/task.rb @@ -57,24 +57,20 @@ module Rails CHANGELOG.md MIT-LICENSE lib/**/*.rb - ) + ), + :exclude => 'lib/rails/generators/rails/**/templates/**/*.rb' } } def initialize(name) super - self.title = 'Ruby on Rails API' - self.rdoc_dir = api_dir - - options << '-m' << api_main - options << '-e' << 'UTF-8' - options << '-f' << 'sdoc' - options << '-T' << 'rails' - - configure_rdoc_files - + # Every time rake runs this task is instantiated as all the rest. + # Be lazy computing stuff to have as light impact as possible to + # the rest of tasks. before_running_rdoc do + load_and_configure_sdoc + configure_rdoc_files setup_horo_variables end end @@ -84,6 +80,22 @@ module Rails # no-op end + def load_and_configure_sdoc + require 'sdoc' + + self.title = 'Ruby on Rails API' + self.rdoc_dir = api_dir + + options << '-m' << api_main + options << '-e' << 'UTF-8' + + options << '-f' << 'sdoc' + options << '-T' << 'rails' + rescue LoadError + $stderr.puts %(Unable to load SDoc, please add\n\n gem 'sdoc', require: false\n\nto the Gemfile.) + exit 1 + end + def configure_rdoc_files rdoc_files.include(api_main) @@ -111,9 +123,8 @@ module Rails end class RepoTask < Task - def initialize(name) + def load_and_configure_sdoc super - options << '-g' # link to GitHub, SDoc flag end 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 563905e8b3..2d5aa9d952 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -1,5 +1,5 @@ require 'fileutils' -# FIXME remove DummyKeyGenerator and this require in 4.1 +require 'active_support/core_ext/object/blank' require 'active_support/key_generator' require 'rails/engine' @@ -111,7 +111,7 @@ module Rails key_generator = ActiveSupport::KeyGenerator.new(config.secret_key_base, iterations: 1000) ActiveSupport::CachingKeyGenerator.new(key_generator) else - ActiveSupport::DummyKeyGenerator.new(config.secret_token) + ActiveSupport::LegacyKeyGenerator.new(config.secret_token) end end end @@ -122,7 +122,8 @@ module Rails # # * "action_dispatch.parameter_filter" => config.filter_parameters # * "action_dispatch.redirect_filter" => config.filter_redirect - # * "action_dispatch.secret_token" => config.secret_token, + # * "action_dispatch.secret_token" => config.secret_token + # * "action_dispatch.secret_key_base" => config.secret_key_base # * "action_dispatch.show_exceptions" => config.action_dispatch.show_exceptions # * "action_dispatch.show_detailed_exceptions" => config.consider_all_requests_local # * "action_dispatch.logger" => Rails.logger @@ -135,13 +136,12 @@ module Rails # def env_config @app_env_config ||= begin - if config.secret_key_base.nil? - ActiveSupport::Deprecation.warn "You didn't set config.secret_key_base in config/initializers/secret_token.rb file. " + - "This should be used instead of the old deprecated config.secret_token in order to use the new EncryptedCookieStore. " + - "To convert safely to the encrypted store (without losing existing cookies and sessions), see http://guides.rubyonrails.org/upgrading_ruby_on_rails.html#action-pack" + if config.secret_key_base.blank? + ActiveSupport::Deprecation.warn "You didn't set config.secret_key_base. " + + "Read the upgrade documentation to learn more about this new config option." if config.secret_token.blank? - raise "You must set config.secret_key_base in your app's config" + raise "You must set config.secret_key_base in your app's config." end end 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/application.rb b/railties/lib/rails/commands/application.rb index d7b8ff4439..2ff29418c6 100644 --- a/railties/lib/rails/commands/application.rb +++ b/railties/lib/rails/commands/application.rb @@ -1,7 +1,7 @@ require 'rails/version' if ['--version', '-v'].include?(ARGV.first) - puts "Rails #{Rails.version}" + puts "Rails #{Rails::VERSION::STRING}" exit(0) end 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 7971accef3..b62d1fff14 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -1,7 +1,7 @@ require 'digest/md5' require 'securerandom' require 'active_support/core_ext/string/strip' -require 'rails/version' unless defined?(Rails.version) +require 'rails/version' unless defined?(Rails::VERSION) require 'rbconfig' require 'open-uri' require 'uri' @@ -115,7 +115,11 @@ module Rails end def database_gemfile_entry - options[:skip_active_record] ? "" : "gem '#{gem_for_database}'" + options[:skip_active_record] ? "" : + <<-GEMFILE.gsub(/^ {12}/, '').strip + # Use #{options[:database]} as the database for ActiveRecord + gem '#{gem_for_database}' + GEMFILE end def include_all_railties? @@ -142,7 +146,7 @@ module Rails else <<-GEMFILE.strip_heredoc # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' - gem 'rails', '#{Rails.version}' + gem 'rails', '#{Rails::VERSION::STRING}' GEMFILE end end @@ -185,16 +189,16 @@ module Rails # Use SCSS for stylesheets 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}/, '') # Use SCSS for stylesheets 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 @@ -225,14 +229,12 @@ module Rails end def javascript_gemfile_entry - args = {'jquery' => ", github: 'rails/jquery-rails'"} - unless options[:skip_javascript] <<-GEMFILE.gsub(/^ {12}/, '').strip_heredoc #{coffee_gemfile_entry} #{javascript_runtime_gemfile_entry} - - gem '#{options[:javascript]}-rails'#{args[options[:javascript]]} + # 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 gem 'turbolinks' 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 b3883a94fc..1842e09bae 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -11,22 +11,22 @@ source 'https://rubygems.org' group :doc do # bundle exec rake doc:rails generates the API under doc/api. - gem 'sdoc' + gem 'sdoc', require: false 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/app/assets/images/.keep b/railties/lib/rails/generators/rails/app/templates/app/assets/images/.keep new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/images/.keep diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png b/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png Binary files differdeleted file mode 100644 index d5edc04e65..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/images/rails.png +++ /dev/null diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt index df07de9922..4a099a4ce2 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt @@ -1,3 +1,3 @@ # Be sure to restart your server when you modify this file. -<%= app_const %>.config.session_store :encrypted_cookie_store, key: <%= "'_#{app_name}_session'" %> +<%= app_const %>.config.session_store :cookie_store, key: <%= "'_#{app_name}_session'" %> 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/rails/plugin_new/plugin_new_generator.rb b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb index 5fe01d0961..850c9d5c0d 100644 --- a/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb +++ b/railties/lib/rails/generators/rails/plugin_new/plugin_new_generator.rb @@ -106,8 +106,6 @@ task default: :test remove_file "doc" remove_file "Gemfile" remove_file "lib/tasks" - remove_file "app/assets/images/rails.png" - remove_file "public/index.html" remove_file "public/robots.txt" remove_file "README" remove_file "test" diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec index 6373ca711e..f7c12e67dd 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec +++ b/railties/lib/rails/generators/rails/plugin_new/templates/%name%.gemspec @@ -18,7 +18,7 @@ Gem::Specification.new do |s| s.test_files = Dir["test/**/*"] <% end -%> - <%= '# ' if options.dev? || options.edge? -%>s.add_dependency "rails", "~> <%= Rails.version %>" + <%= '# ' if options.dev? || options.edge? -%>s.add_dependency "rails", "~> <%= Rails::VERSION::STRING %>" <% unless options[:skip_active_record] -%> s.add_development_dependency "<%= gem_for_database %>" diff --git a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile index de00ab057d..3f2b78f2fd 100644 --- a/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile +++ b/railties/lib/rails/generators/rails/plugin_new/templates/Gemfile @@ -1,7 +1,7 @@ source "https://rubygems.org" <% if options[:skip_gemspec] -%> -<%= '# ' if options.dev? || options.edge? -%>gem "rails", "~> <%= Rails.version %>" +<%= '# ' if options.dev? || options.edge? -%>gem "rails", "~> <%= Rails::VERSION::STRING %>" <% else -%> # Declare your gem's dependencies in <%= name %>.gemspec. # Bundler will treat runtime dependencies like base dependencies, and diff --git a/railties/lib/rails/generators/test_case.rb b/railties/lib/rails/generators/test_case.rb index 85a8914ccc..58592b4f8e 100644 --- a/railties/lib/rails/generators/test_case.rb +++ b/railties/lib/rails/generators/test_case.rb @@ -1,8 +1,7 @@ -require 'active_support/core_ext/class/attribute' -require 'active_support/core_ext/module/delegation' -require 'active_support/core_ext/hash/reverse_merge' -require 'active_support/core_ext/kernel/reporting' require 'rails/generators' +require 'rails/generators/testing/behaviour' +require 'rails/generators/testing/setup_and_teardown' +require 'rails/generators/testing/assertions' require 'fileutils' module Rails @@ -27,215 +26,11 @@ module Rails # setup :prepare_destination # end class TestCase < ActiveSupport::TestCase + include Rails::Generators::Testing::Behaviour + include Rails::Generators::Testing::SetupAndTeardown + include Rails::Generators::Testing::Assertions include FileUtils - class_attribute :destination_root, :current_path, :generator_class, :default_arguments - - # Generators frequently change the current path using +FileUtils.cd+. - # So we need to store the path at file load and revert back to it after each test. - self.current_path = File.expand_path(Dir.pwd) - self.default_arguments = [] - - def setup # :nodoc: - destination_root_is_set? - ensure_current_path - super - end - - def teardown # :nodoc: - ensure_current_path - super - end - - # Sets which generator should be tested: - # - # tests AppGenerator - def self.tests(klass) - self.generator_class = klass - end - - # Sets default arguments on generator invocation. This can be overwritten when - # invoking it. - # - # arguments %w(app_name --skip-active-record) - def self.arguments(array) - self.default_arguments = array - end - - # Sets the destination of generator files: - # - # destination File.expand_path("../tmp", File.dirname(__FILE__)) - def self.destination(path) - self.destination_root = path - end - - # Asserts a given file exists. You need to supply an absolute path or a path relative - # to the configured destination: - # - # assert_file "config/environment.rb" - # - # You can also give extra arguments. If the argument is a regexp, it will check if the - # regular expression matches the given file content. If it's a string, it compares the - # file with the given string: - # - # assert_file "config/environment.rb", /initialize/ - # - # Finally, when a block is given, it yields the file content: - # - # assert_file "app/controllers/products_controller.rb" do |controller| - # assert_instance_method :index, controller do |index| - # assert_match(/Product\.all/, index) - # end - # end - def assert_file(relative, *contents) - absolute = File.expand_path(relative, destination_root) - assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" - - read = File.read(absolute) if block_given? || !contents.empty? - yield read if block_given? - - contents.each do |content| - case content - when String - assert_equal content, read - when Regexp - assert_match content, read - end - end - end - alias :assert_directory :assert_file - - # Asserts a given file does not exist. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_no_file "config/random.rb" - def assert_no_file(relative) - absolute = File.expand_path(relative, destination_root) - assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" - end - alias :assert_no_directory :assert_no_file - - # Asserts a given migration exists. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_migration "db/migrate/create_products.rb" - # - # This method manipulates the given path and tries to find any migration which - # matches the migration name. For example, the call above is converted to: - # - # assert_file "db/migrate/003_create_products.rb" - # - # Consequently, assert_migration accepts the same arguments has assert_file. - def assert_migration(relative, *contents, &block) - file_name = migration_file_name(relative) - assert file_name, "Expected migration #{relative} to exist, but was not found" - assert_file file_name, *contents, &block - end - - # Asserts a given migration does not exist. You need to supply an absolute path or a - # path relative to the configured destination: - # - # assert_no_migration "db/migrate/create_products.rb" - def assert_no_migration(relative) - file_name = migration_file_name(relative) - assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" - end - - # Asserts the given class method exists in the given content. This method does not detect - # class methods inside (class << self), only class methods which starts with "self.". - # When a block is given, it yields the content of the method. - # - # assert_migration "db/migrate/create_products.rb" do |migration| - # assert_class_method :up, migration do |up| - # assert_match(/create_table/, up) - # end - # end - def assert_class_method(method, content, &block) - assert_instance_method "self.#{method}", content, &block - end - - # Asserts the given method exists in the given content. When a block is given, - # it yields the content of the method. - # - # assert_file "app/controllers/products_controller.rb" do |controller| - # assert_instance_method :index, controller do |index| - # assert_match(/Product\.all/, index) - # end - # end - def assert_instance_method(method, content) - assert content =~ /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m, "Expected to have method #{method}" - yield $3.strip if block_given? - end - alias :assert_method :assert_instance_method - - # Asserts the given attribute type gets translated to a field type - # properly: - # - # assert_field_type :date, :date_select - def assert_field_type(attribute_type, field_type) - assert_equal(field_type, create_generated_attribute(attribute_type).field_type) - end - - # Asserts the given attribute type gets a proper default value: - # - # assert_field_default_value :string, "MyString" - def assert_field_default_value(attribute_type, value) - assert_equal(value, create_generated_attribute(attribute_type).default) - end - - # Runs the generator configured for this class. The first argument is an array like - # command line arguments: - # - # class AppGeneratorTest < Rails::Generators::TestCase - # tests AppGenerator - # destination File.expand_path("../tmp", File.dirname(__FILE__)) - # teardown :cleanup_destination_root - # - # test "database.yml is not created when skipping Active Record" do - # run_generator %w(myapp --skip-active-record) - # assert_no_file "config/database.yml" - # end - # end - # - # 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)) } - end - - # Instantiate the generator. - def generator(args=self.default_arguments, options={}, config={}) - @generator ||= self.generator_class.new(args, options, config.reverse_merge(destination_root: destination_root)) - end - - # Create a Rails::Generators::GeneratedAttribute by supplying the - # attribute type and, optionally, the attribute name: - # - # create_generated_attribute(:string, 'name') - def create_generated_attribute(attribute_type, name = 'test', index = nil) - Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':')) - end - - protected - - def destination_root_is_set? # :nodoc: - raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root - end - - def ensure_current_path # :nodoc: - cd current_path - end - - def prepare_destination # :nodoc: - rm_rf(destination_root) - mkdir_p(destination_root) - end - - def migration_file_name(relative) # :nodoc: - absolute = File.expand_path(relative, destination_root) - dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') - Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first - end end end end diff --git a/railties/lib/rails/generators/testing/assertions.rb b/railties/lib/rails/generators/testing/assertions.rb new file mode 100644 index 0000000000..6267b2f2ee --- /dev/null +++ b/railties/lib/rails/generators/testing/assertions.rb @@ -0,0 +1,121 @@ +module Rails + module Generators + module Testing + module Assertions + # Asserts a given file exists. You need to supply an absolute path or a path relative + # to the configured destination: + # + # assert_file "config/environment.rb" + # + # You can also give extra arguments. If the argument is a regexp, it will check if the + # regular expression matches the given file content. If it's a string, it compares the + # file with the given string: + # + # assert_file "config/environment.rb", /initialize/ + # + # Finally, when a block is given, it yields the file content: + # + # assert_file "app/controllers/products_controller.rb" do |controller| + # assert_instance_method :index, controller do |index| + # assert_match(/Product\.all/, index) + # end + # end + def assert_file(relative, *contents) + absolute = File.expand_path(relative, destination_root) + assert File.exists?(absolute), "Expected file #{relative.inspect} to exist, but does not" + + read = File.read(absolute) if block_given? || !contents.empty? + yield read if block_given? + + contents.each do |content| + case content + when String + assert_equal content, read + when Regexp + assert_match content, read + end + end + end + alias :assert_directory :assert_file + + # Asserts a given file does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_file "config/random.rb" + def assert_no_file(relative) + absolute = File.expand_path(relative, destination_root) + assert !File.exists?(absolute), "Expected file #{relative.inspect} to not exist, but does" + end + alias :assert_no_directory :assert_no_file + + # Asserts a given migration exists. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_migration "db/migrate/create_products.rb" + # + # This method manipulates the given path and tries to find any migration which + # matches the migration name. For example, the call above is converted to: + # + # assert_file "db/migrate/003_create_products.rb" + # + # Consequently, assert_migration accepts the same arguments has assert_file. + def assert_migration(relative, *contents, &block) + file_name = migration_file_name(relative) + assert file_name, "Expected migration #{relative} to exist, but was not found" + assert_file file_name, *contents, &block + end + + # Asserts a given migration does not exist. You need to supply an absolute path or a + # path relative to the configured destination: + # + # assert_no_migration "db/migrate/create_products.rb" + def assert_no_migration(relative) + file_name = migration_file_name(relative) + assert_nil file_name, "Expected migration #{relative} to not exist, but found #{file_name}" + end + + # Asserts the given class method exists in the given content. This method does not detect + # class methods inside (class << self), only class methods which starts with "self.". + # When a block is given, it yields the content of the method. + # + # assert_migration "db/migrate/create_products.rb" do |migration| + # assert_class_method :up, migration do |up| + # assert_match(/create_table/, up) + # end + # end + def assert_class_method(method, content, &block) + assert_instance_method "self.#{method}", content, &block + end + + # Asserts the given method exists in the given content. When a block is given, + # it yields the content of the method. + # + # assert_file "app/controllers/products_controller.rb" do |controller| + # assert_instance_method :index, controller do |index| + # assert_match(/Product\.all/, index) + # end + # end + def assert_instance_method(method, content) + assert content =~ /(\s+)def #{method}(\(.+\))?(.*?)\n\1end/m, "Expected to have method #{method}" + yield $3.strip if block_given? + end + alias :assert_method :assert_instance_method + + # Asserts the given attribute type gets translated to a field type + # properly: + # + # assert_field_type :date, :date_select + def assert_field_type(attribute_type, field_type) + assert_equal(field_type, create_generated_attribute(attribute_type).field_type) + end + + # Asserts the given attribute type gets a proper default value: + # + # assert_field_default_value :string, "MyString" + def assert_field_default_value(attribute_type, value) + assert_equal(value, create_generated_attribute(attribute_type).default) + end + end + end + end +end diff --git a/railties/lib/rails/generators/testing/behaviour.rb b/railties/lib/rails/generators/testing/behaviour.rb new file mode 100644 index 0000000000..7576eba6e0 --- /dev/null +++ b/railties/lib/rails/generators/testing/behaviour.rb @@ -0,0 +1,106 @@ +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/module/delegation' +require 'active_support/core_ext/hash/reverse_merge' +require 'active_support/core_ext/kernel/reporting' +require 'active_support/concern' +require 'rails/generators' + +module Rails + module Generators + module Testing + module Behaviour + extend ActiveSupport::Concern + + included do + class_attribute :destination_root, :current_path, :generator_class, :default_arguments + + # Generators frequently change the current path using +FileUtils.cd+. + # So we need to store the path at file load and revert back to it after each test. + self.current_path = File.expand_path(Dir.pwd) + self.default_arguments = [] + end + + module ClassMethods + # Sets which generator should be tested: + # + # tests AppGenerator + def tests(klass) + self.generator_class = klass + end + + # Sets default arguments on generator invocation. This can be overwritten when + # invoking it. + # + # arguments %w(app_name --skip-active-record) + def arguments(array) + self.default_arguments = array + end + + # Sets the destination of generator files: + # + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + def destination(path) + self.destination_root = path + end + end + + # Runs the generator configured for this class. The first argument is an array like + # command line arguments: + # + # class AppGeneratorTest < Rails::Generators::TestCase + # tests AppGenerator + # destination File.expand_path("../tmp", File.dirname(__FILE__)) + # teardown :cleanup_destination_root + # + # test "database.yml is not created when skipping Active Record" do + # run_generator %w(myapp --skip-active-record) + # assert_no_file "config/database.yml" + # end + # end + # + # 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) 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. + def generator(args=self.default_arguments, options={}, config={}) + @generator ||= self.generator_class.new(args, options, config.reverse_merge(destination_root: destination_root)) + end + + # Create a Rails::Generators::GeneratedAttribute by supplying the + # attribute type and, optionally, the attribute name: + # + # create_generated_attribute(:string, 'name') + def create_generated_attribute(attribute_type, name = 'test', index = nil) + Rails::Generators::GeneratedAttribute.parse([name, attribute_type, index].compact.join(':')) + end + + protected + + def destination_root_is_set? # :nodoc: + raise "You need to configure your Rails::Generators::TestCase destination root." unless destination_root + end + + def ensure_current_path # :nodoc: + cd current_path + end + + def prepare_destination # :nodoc: + rm_rf(destination_root) + mkdir_p(destination_root) + end + + def migration_file_name(relative) # :nodoc: + absolute = File.expand_path(relative, destination_root) + dirname, file_name = File.dirname(absolute), File.basename(absolute).sub(/\.rb$/, '') + Dir.glob("#{dirname}/[0-9]*_*.rb").grep(/\d+_#{file_name}.rb$/).first + end + end + end + end +end diff --git a/railties/lib/rails/generators/testing/setup_and_teardown.rb b/railties/lib/rails/generators/testing/setup_and_teardown.rb new file mode 100644 index 0000000000..73102a283f --- /dev/null +++ b/railties/lib/rails/generators/testing/setup_and_teardown.rb @@ -0,0 +1,18 @@ +module Rails + module Generators + module Testing + module SetupAndTeardown + def setup # :nodoc: + destination_root_is_set? + ensure_current_path + super + end + + def teardown # :nodoc: + ensure_current_path + super + end + end + end + end +end diff --git a/railties/lib/rails/templates/rails/welcome/index.html.erb b/railties/lib/rails/templates/rails/welcome/index.html.erb index e239e1695e..4c4c80ecda 100644 --- a/railties/lib/rails/templates/rails/welcome/index.html.erb +++ b/railties/lib/rails/templates/rails/welcome/index.html.erb @@ -59,7 +59,7 @@ #header { - background-image: url("/assets/rails.png"); + background-image: url(data:image/png;base64,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); background-repeat: no-repeat; background-position: top left; height: 64px; 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/lib/rails/version.rb b/railties/lib/rails/version.rb index d1d02e086d..fee352db5a 100644 --- a/railties/lib/rails/version.rb +++ b/railties/lib/rails/version.rb @@ -1,11 +1,10 @@ module Rails - # Returns the version of the currently loaded Rails as a Gem::Version - def self.version - Gem::Version.new "4.0.0.beta1" - end + module VERSION + MAJOR = 4 + MINOR = 0 + TINY = 0 + PRE = "beta1" - module VERSION #:nodoc: - MAJOR, MINOR, TINY, PRE = Rails.version.segments - STRING = Rails.version.to_s + STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end end diff --git a/railties/railties.gemspec b/railties/railties.gemspec index 276cce3a77..45968052a8 100644 --- a/railties/railties.gemspec +++ b/railties/railties.gemspec @@ -27,5 +27,5 @@ Gem::Specification.new do |s| s.add_dependency 'actionpack', version s.add_dependency 'rake', '>= 0.8.7' - s.add_dependency 'thor', '>= 0.17.0', '< 2.0' + s.add_dependency 'thor', '>= 0.18.1', '< 2.0' end diff --git a/railties/test/app_rails_loader_test.rb b/railties/test/app_rails_loader_test.rb index 63ed9eaef0..a16b8d3302 100644 --- a/railties/test/app_rails_loader_test.rb +++ b/railties/test/app_rails_loader_test.rb @@ -1,48 +1,73 @@ +require 'tmpdir' +require 'pathname' require 'abstract_unit' require 'rails/app_rails_loader' class AppRailsLoaderTest < ActiveSupport::TestCase + def write(filename, contents=nil) + FileUtils.mkdir_p(Pathname.new(filename).dirname) + File.write(filename, contents) + end + + def expects_exec(exe) + Rails::AppRailsLoader.expects(:exec).with(Rails::AppRailsLoader::RUBY, exe) + end + + def realpath(filename) + Pathname.new(filename).realpath + 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 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 - 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 + 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 realpath("#@tmp/foo"), realpath(Dir.pwd) + end end end + + teardown do + Dir.chdir(@cwd) + FileUtils.rm_rf(@tmp) + end end diff --git a/railties/test/application/assets_test.rb b/railties/test/application/assets_test.rb index e5503b1eff..34432eac3a 100644 --- a/railties/test/application/assets_test.rb +++ b/railties/test/application/assets_test.rb @@ -41,6 +41,7 @@ module ApplicationTests end test "assets routes have higher priority" do + app_file "app/assets/images/rails.png", "notactuallyapng" app_file "app/assets/javascripts/demo.js.erb", "a = <%= image_path('rails.png').inspect %>;" app_file 'config/routes.rb', <<-RUBY @@ -222,6 +223,7 @@ module ApplicationTests end test "precompile properly refers files referenced with asset_path and runs in the provided RAILS_ENV" do + app_file "app/assets/images/rails.png", "notactuallyapng" app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>" # digest is default in false, we must enable it for test environment add_to_env_config "test", "config.assets.digest = true" @@ -233,6 +235,8 @@ module ApplicationTests end test "precompile shouldn't use the digests present in manifest.json" do + app_file "app/assets/images/rails.png", "notactuallyapng" + app_file "app/assets/stylesheets/application.css.erb", "//= depend_on rails.png\np { url: <%= asset_path('rails.png') %> }" ENV["RAILS_ENV"] = "production" @@ -251,6 +255,7 @@ module ApplicationTests end test "precompile appends the md5 hash to files referenced with asset_path and run in production with digest true" do + app_file "app/assets/images/rails.png", "notactuallyapng" app_file "app/assets/stylesheets/application.css.erb", "<%= asset_path('rails.png') %>" add_to_config "config.assets.compile = true" add_to_config "config.assets.digest = true" @@ -272,7 +277,7 @@ module ApplicationTests manifest = Dir["#{app_path}/public/assets/manifest-*.json"].first assets = ActiveSupport::JSON.decode(File.read(manifest)) - assert asset_path = assets["assets"].find { |(k, _)| k !~ /rails.png/ && k =~ /.png/ }[1] + assert asset_path = assets["assets"].find { |(k, _)| k && k =~ /.png/ }[1] require "#{app_path}/config/environment" @@ -431,6 +436,7 @@ module ApplicationTests end test "asset urls should be protocol-relative if no request is in scope" do + app_file "app/assets/images/rails.png", "notreallyapng" app_file "app/assets/javascripts/image_loader.js.erb", 'var src="<%= image_path("rails.png") %>";' add_to_config "config.assets.precompile = %w{image_loader.js}" add_to_config "config.asset_host = 'example.com'" @@ -441,6 +447,7 @@ module ApplicationTests test "asset paths should use RAILS_RELATIVE_URL_ROOT by default" do ENV["RAILS_RELATIVE_URL_ROOT"] = "/sub/uri" + app_file "app/assets/images/rails.png", "notreallyapng" app_file "app/assets/javascripts/app.js.erb", 'var src="<%= image_path("rails.png") %>";' add_to_config "config.assets.precompile = %w{app.js}" diff --git a/railties/test/application/console_test.rb b/railties/test/application/console_test.rb index 80700a1d64..31bc003dcb 100644 --- a/railties/test/application/console_test.rb +++ b/railties/test/application/console_test.rb @@ -127,24 +127,23 @@ class FullStackConsoleTest < ActiveSupport::TestCase end def spawn_console - pid = Process.spawn( + Process.spawn( "#{app_path}/bin/rails console --sandbox", in: @slave, out: @slave, err: @slave ) assert_output "> ", 30 - pid end def test_sandbox - pid = spawn_console + spawn_console write_prompt "Post.count", "=> 0" write_prompt "Post.create" write_prompt "Post.count", "=> 1" @master.puts "quit" - pid = spawn_console + spawn_console write_prompt "Post.count", "=> 0" write_prompt "Post.transaction { Post.create; raise }" 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 f0d3438aa4..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 DummyKeyGenerator and this require in 4.1 require 'active_support/key_generator' module ApplicationTests @@ -10,7 +9,7 @@ module ApplicationTests remote_ip = nil env = Rack::MockRequest.env_for("/").merge(env).merge!( 'action_dispatch.show_exceptions' => false, - 'action_dispatch.key_generator' => ActiveSupport::DummyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33') + 'action_dispatch.key_generator' => ActiveSupport::LegacyKeyGenerator.new('b3c631c314c0bbca50c1b2843150fe33') ) endpoint = Proc.new do |e| diff --git a/railties/test/application/middleware/session_test.rb b/railties/test/application/middleware/session_test.rb index a5fdfbf887..8cb0dfeb63 100644 --- a/railties/test/application/middleware/session_test.rb +++ b/railties/test/application/middleware/session_test.rb @@ -157,10 +157,6 @@ module ApplicationTests end RUBY - add_to_config <<-RUBY - config.session_store :encrypted_cookie_store, key: '_myapp_session' - RUBY - require "#{app_path}/config/environment" get '/foo/write_session' @@ -178,7 +174,7 @@ module ApplicationTests assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo'] end - test "session using upgrade signature to encryption cookie store works the same way as encrypted cookie store" do + test "session upgrading signature to encryption cookie store works the same way as encrypted cookie store" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do get ':controller(/:action)' @@ -208,7 +204,6 @@ module ApplicationTests add_to_config <<-RUBY config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" - config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session' RUBY require "#{app_path}/config/environment" @@ -228,7 +223,7 @@ module ApplicationTests assert_equal 1, encryptor.decrypt_and_verify(last_response.body)['foo'] end - test "session using upgrade signature to encryption cookie store upgrades session to encrypted mode" do + test "session upgrading signature to encryption cookie store upgrades session to encrypted mode" do app_file 'config/routes.rb', <<-RUBY AppTemplate::Application.routes.draw do get ':controller(/:action)' @@ -264,7 +259,6 @@ module ApplicationTests add_to_config <<-RUBY config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" - config.session_store :upgrade_signature_to_encryption_cookie_store, key: '_myapp_session' RUBY require "#{app_path}/config/environment" @@ -287,5 +281,63 @@ module ApplicationTests get '/foo/read_raw_cookie' assert_equal 2, encryptor.decrypt_and_verify(last_response.body)['foo'] end + + test "session upgrading legacy signed cookies to new signed cookies" do + app_file 'config/routes.rb', <<-RUBY + AppTemplate::Application.routes.draw do + get ':controller(/:action)' + end + RUBY + + controller :foo, <<-RUBY + class FooController < ActionController::Base + def write_raw_session + # {"session_id"=>"1965d95720fffc123941bdfb7d2e6870", "foo"=>1} + cookies[:_myapp_session] = "BAh7B0kiD3Nlc3Npb25faWQGOgZFRkkiJTE5NjVkOTU3MjBmZmZjMTIzOTQxYmRmYjdkMmU2ODcwBjsAVEkiCGZvbwY7AEZpBg==--315fb9931921a87ae7421aec96382f0294119749" + render nothing: true + end + + def write_session + session[:foo] = session[:foo] + 1 + render nothing: true + end + + def read_session + render text: session[:foo] + end + + def read_signed_cookie + render text: cookies.signed[:_myapp_session]['foo'] + end + + def read_raw_cookie + render text: cookies[:_myapp_session] + end + end + RUBY + + add_to_config <<-RUBY + config.secret_token = "3b7cd727ee24e8444053437c36cc66c4" + config.secret_key_base = nil + RUBY + + require "#{app_path}/config/environment" + + get '/foo/write_raw_session' + get '/foo/read_session' + assert_equal '1', last_response.body + + get '/foo/write_session' + get '/foo/read_session' + assert_equal '2', last_response.body + + get '/foo/read_signed_cookie' + assert_equal '2', last_response.body + + verifier = ActiveSupport::MessageVerifier.new(app.config.secret_token) + + get '/foo/read_raw_cookie' + assert_equal 2, verifier.verify(last_response.body)['foo'] + end end end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index a9e0e1bcb7..eb590da678 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -84,20 +84,8 @@ module ApplicationTests Dir.chdir(app_path){ `rake stats` } end - def test_rake_test_error_output - Dir.chdir(app_path){ `rake db:migrate` } - - app_file "test/models/one_model_test.rb", <<-RUBY - raise 'models' - RUBY - - silence_stderr do - output = Dir.chdir(app_path) { `rake test 2>&1` } - assert_match 'models', output - end - 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 +117,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/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/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index b813a7f6bb..5fdf58c8ee 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -303,6 +303,11 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "Gemfile", /# gem 'debugger'/ end + def test_inclusion_of_lazy_loaded_sdoc + run_generator + assert_file 'Gemfile', /gem 'sdoc', require: false/ + end + def test_template_from_dir_pwd FileUtils.cd(Rails.root) assert_match(/It works from file!/, run_generator([destination_root, "-m", "lib/template.rb"])) @@ -341,7 +346,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_new_hash_style run_generator [destination_root] assert_file "config/initializers/session_store.rb" do |file| - assert_match(/config.session_store :encrypted_cookie_store, key: '_.+_session'/, file) + assert_match(/config.session_store :cookie_store, key: '_.+_session'/, file) end end 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/generators_test.rb b/railties/test/generators_test.rb index 9953aa929b..361784f509 100644 --- a/railties/test/generators_test.rb +++ b/railties/test/generators_test.rb @@ -164,7 +164,7 @@ class GeneratorsTest < Rails::Generators::TestCase Rails::Generators.invoke "super_shoulda:model", ["Account"] end - def test_developer_options_are_overwriten_by_user_options + def test_developer_options_are_overwritten_by_user_options Rails::Generators.options[:with_options] = { generate: false } self.class.class_eval(<<-end_eval, __FILE__, __LINE__ + 1) diff --git a/railties/test/railties/engine_test.rb b/railties/test/railties/engine_test.rb index 26b388b6f9..01fa2c6864 100644 --- a/railties/test/railties/engine_test.rb +++ b/railties/test/railties/engine_test.rb @@ -187,7 +187,7 @@ module RailtiesTest assert_equal "Hello bukkits\n", response[2].body end - test "adds its views to view paths with lower proriority than app ones" do + test "adds its views to view paths with lower priority than app ones" do @plugin.write "app/controllers/bukkit_controller.rb", <<-RUBY class BukkitController < ActionController::Base def index 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 |