diff options
Diffstat (limited to 'railties')
56 files changed, 531 insertions, 185 deletions
diff --git a/railties/CHANGELOG.md b/railties/CHANGELOG.md index 96149acc08..782a53bf82 100644 --- a/railties/CHANGELOG.md +++ b/railties/CHANGELOG.md @@ -1,3 +1,30 @@ +* Alias `rake` with `rails_command` in the Rails Application Templates API + following Rails 5 convention of preferring "rails" to "rake" to run tasks. + + *claudiob* + +* Change fail fast of `bin/rails test` interrupts run on error. + + *Yuji Yaginuma* + +* The application generator supports `--skip-listen` to opt-out of features + that depend on the listen gem. As of this writing they are the evented file + system monitor and the async plugin for spring. + +* The Gemfiles of new applications include spring-watcher-listen on Linux and + Mac OS X (unless --skip-spring). + + *Xavier Noria* + +* New applications are generated with the evented file system monitor enabled + on Linux and Mac OS X. + + *Xavier Noria* + +* Add dummy files for apple-touch-icon.png and apple-touch-icon.png. GH#23427 + + *Alexey Zabelin* + ## Rails 5.0.0.beta2 (February 01, 2016) ## * Add `after_bundle` callbacks in Rails plugin templates. Useful for allowing diff --git a/railties/RDOC_MAIN.rdoc b/railties/RDOC_MAIN.rdoc index ce024563c4..26a25ee9dc 100644 --- a/railties/RDOC_MAIN.rdoc +++ b/railties/RDOC_MAIN.rdoc @@ -51,7 +51,7 @@ can read more about Action Pack in its {README}[link:files/actionpack/README_rdo 4. Go to http://localhost:3000 and you'll see: - "Welcome aboard: You're riding Ruby on Rails!" + "Yay! You’re on Rails!" 5. Follow the guidelines to start developing your application. You may find the following resources handy: diff --git a/railties/lib/rails/application.rb b/railties/lib/rails/application.rb index cac31e1eed..bff33ff42e 100644 --- a/railties/lib/rails/application.rb +++ b/railties/lib/rails/application.rb @@ -214,7 +214,7 @@ module Rails # url: http://localhost:3001 # namespace: my_app_development # - # # config/production.rb + # # config/environments/production.rb # Rails.application.configure do # config.middleware.use ExceptionNotifier, config_for(:exception_notification) # end diff --git a/railties/lib/rails/application/finisher.rb b/railties/lib/rails/application/finisher.rb index 411cdbad19..64ec539564 100644 --- a/railties/lib/rails/application/finisher.rb +++ b/railties/lib/rails/application/finisher.rb @@ -22,10 +22,10 @@ module Rails initializer :add_builtin_route do |app| if Rails.env.development? app.routes.append do - get '/rails/info/properties' => "rails/info#properties" - get '/rails/info/routes' => "rails/info#routes" - get '/rails/info' => "rails/info#index" - get '/' => "rails/welcome#index" + get '/rails/info/properties' => "rails/info#properties", internal: true + get '/rails/info/routes' => "rails/info#routes", internal: true + get '/rails/info' => "rails/info#index", internal: true + get '/' => "rails/welcome#index", internal: true end end end diff --git a/railties/lib/rails/code_statistics.rb b/railties/lib/rails/code_statistics.rb index 0997414482..fc8717c752 100644 --- a/railties/lib/rails/code_statistics.rb +++ b/railties/lib/rails/code_statistics.rb @@ -9,6 +9,8 @@ class CodeStatistics #:nodoc: 'Job tests', 'Integration tests'] + HEADERS = {lines: ' Lines', code_lines: ' LOC', classes: 'Classes', methods: 'Methods'} + def initialize(*pairs) @pairs = pairs @statistics = calculate_statistics @@ -67,27 +69,37 @@ class CodeStatistics #:nodoc: test_loc end + def width_for(label) + [@statistics.values.sum {|s| s.send(label) }.to_s.size, HEADERS[label].length].max + end + def print_header print_splitter - puts "| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |" + print '| Name ' + HEADERS.each do |k, v| + print " | #{v.rjust(width_for(k))}" + end + puts ' | M/C | LOC/M |' print_splitter end def print_splitter - puts "+----------------------+--------+--------+---------+---------+-----+-------+" + print '+----------------------' + HEADERS.each_key do |k| + print "+#{'-' * (width_for(k) + 2)}" + end + puts '+-----+-------+' end def print_line(name, statistics) m_over_c = (statistics.methods / statistics.classes) rescue m_over_c = 0 loc_over_m = (statistics.code_lines / statistics.methods) - 2 rescue loc_over_m = 0 - puts "| #{name.ljust(20)} " \ - "| #{statistics.lines.to_s.rjust(6)} " \ - "| #{statistics.code_lines.to_s.rjust(6)} " \ - "| #{statistics.classes.to_s.rjust(7)} " \ - "| #{statistics.methods.to_s.rjust(7)} " \ - "| #{m_over_c.to_s.rjust(3)} " \ - "| #{loc_over_m.to_s.rjust(5)} |" + print "| #{name.ljust(20)} " + HEADERS.each_key do |k| + print "| #{statistics.send(k).to_s.rjust(width_for(k))} " + end + puts "| #{m_over_c.to_s.rjust(3)} | #{loc_over_m.to_s.rjust(5)} |" end def print_code_test_stats diff --git a/railties/lib/rails/commands.rb b/railties/lib/rails/commands.rb index 7627fcf5a0..fa47c52b96 100644 --- a/railties/lib/rails/commands.rb +++ b/railties/lib/rails/commands.rb @@ -14,6 +14,5 @@ command = ARGV.shift command = aliases[command] || command require 'rails/command' -require 'rails/commands/dev_cache' Rails::Command.run(command, ARGV) diff --git a/railties/lib/rails/commands/dev_cache.rb b/railties/lib/rails/commands/dev_cache.rb deleted file mode 100644 index ec96e8f630..0000000000 --- a/railties/lib/rails/commands/dev_cache.rb +++ /dev/null @@ -1,21 +0,0 @@ -require 'rails/command' - -module Rails - module Commands - # This is a wrapper around the Rails dev:cache command - class DevCache < Command - set_banner :dev_cache, 'Toggle development mode caching on/off' - def dev_cache - if File.exist? 'tmp/caching-dev.txt' - File.delete 'tmp/caching-dev.txt' - puts 'Development mode is no longer being cached.' - else - FileUtils.touch 'tmp/caching-dev.txt' - puts 'Development mode is now being cached.' - end - - FileUtils.touch 'tmp/restart.txt' - end - end - end -end diff --git a/railties/lib/rails/engine/configuration.rb b/railties/lib/rails/engine/configuration.rb index 8cadbc3ddd..294d07446f 100644 --- a/railties/lib/rails/engine/configuration.rb +++ b/railties/lib/rails/engine/configuration.rb @@ -39,6 +39,7 @@ module Rails paths.add "app", eager_load: true, glob: "{*,*/concerns}" paths.add "app/assets", glob: "*" paths.add "app/controllers", eager_load: true + paths.add "app/channels", eager_load: true, glob: "**/*_channel.rb" paths.add "app/helpers", eager_load: true paths.add "app/models", eager_load: true paths.add "app/mailers", eager_load: true diff --git a/railties/lib/rails/generators.rb b/railties/lib/rails/generators.rb index e3d79521e7..330bd7ec5d 100644 --- a/railties/lib/rails/generators.rb +++ b/railties/lib/rails/generators.rb @@ -105,7 +105,7 @@ module Rails # Configure generators for API only applications. It basically hides # everything that is usually browser related, such as assets and session - # migration generators, and completely disable views, helpers and assets + # migration generators, and completely disable helpers and assets # so generators such as scaffold won't create them. def self.api_only! hide_namespaces "assets", "helper", "css", "js" @@ -116,6 +116,10 @@ module Rails helper: false, template_engine: nil ) + + if ARGV.first == 'mailer' + options[:rails].merge!(template_engine: :erb) + end end # Remove the color from output. diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index 9ca731347a..5fa487b78e 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -216,8 +216,9 @@ module Rails log :rake, command env = options[:env] || ENV["RAILS_ENV"] || 'development' sudo = options[:sudo] && RbConfig::CONFIG['host_os'] !~ /mswin|mingw/ ? 'sudo ' : '' - in_root { run("#{sudo}#{extify(:rake)} #{command} RAILS_ENV=#{env}", verbose: false) } + in_root { run("#{sudo}#{extify(:rails)} #{command} RAILS_ENV=#{env}", verbose: false) } end + alias :rails_command :rake # Just run the capify command in root # diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 8bc7dd63f9..ed4e73fb90 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -63,6 +63,9 @@ module Rails class_option :skip_spring, type: :boolean, default: false, desc: "Don't install Spring application preloader" + class_option :skip_listen, type: :boolean, default: false, + desc: "Don't generate configuration that depends on the listen gem" + class_option :skip_javascript, type: :boolean, aliases: '-J', default: false, desc: 'Skip JavaScript files' @@ -308,16 +311,11 @@ module Rails end def coffee_gemfile_entry - comment = 'Use CoffeeScript for .coffee assets and views' - if options.dev? || options.edge? - GemfileEntry.github 'coffee-rails', 'rails/coffee-rails', nil, comment - else - GemfileEntry.version 'coffee-rails', '~> 4.1.0', comment - end + GemfileEntry.version 'coffee-rails', '~> 4.1.0', 'Use CoffeeScript for .coffee assets and views' end def javascript_gemfile_entry - if options[:skip_javascript] + if options[:skip_javascript] || options[:skip_sprockets] [] else gems = [coffee_gemfile_entry, javascript_runtime_gemfile_entry] @@ -325,8 +323,8 @@ module Rails "Use #{options[:javascript]} as the JavaScript library") unless options[:skip_turbolinks] - gems << GemfileEntry.version("turbolinks", nil, - "Turbolinks makes following links in your web application faster. Read more: https://github.com/rails/turbolinks") + gems << GemfileEntry.version("turbolinks", "~> 5.x", + "Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks") end gems @@ -352,9 +350,9 @@ module Rails def cable_gemfile_entry return [] if options[:skip_action_cable] - comment = 'Action Cable dependencies for the Redis adapter' + comment = 'Use Redis adapter to run Action Cable in production' gems = [] - gems << GemfileEntry.new("redis", '~> 3.0', comment) + gems << GemfileEntry.new("redis", '~> 3.0', comment, {}, true) gems end @@ -390,6 +388,14 @@ module Rails !options[:skip_spring] && !options.dev? && Process.respond_to?(:fork) && !RUBY_PLATFORM.include?("cygwin") end + def depend_on_listen? + !options[:skip_listen] && os_supports_listen_out_of_the_box? + end + + def os_supports_listen_out_of_the_box? + RbConfig::CONFIG['host_os'] =~ /darwin|linux/ + end + def run_bundle bundle_command('install') if bundle_install? end diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index 248ad20019..07d38605a2 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -91,6 +91,7 @@ module Rails cookie_serializer_config_exist = File.exist?('config/initializers/cookies_serializer.rb') callback_terminator_config_exist = File.exist?('config/initializers/callback_terminator.rb') active_record_belongs_to_required_by_default_config_exist = File.exist?('config/initializers/active_record_belongs_to_required_by_default.rb') + action_cable_config_exist = File.exist?('config/cable.yml') config @@ -105,6 +106,10 @@ module Rails unless active_record_belongs_to_required_by_default_config_exist remove_file 'config/initializers/active_record_belongs_to_required_by_default.rb' end + + unless action_cable_config_exist + template 'config/cable.yml' + end end def database_yml @@ -276,9 +281,9 @@ module Rails end end - def delete_app_views_if_api_option + def delete_application_layout_file_if_api_option if options[:api] - remove_dir 'app/views' + remove_file 'app/views/layouts/application.html.erb' end end diff --git a/railties/lib/rails/generators/rails/app/templates/Gemfile b/railties/lib/rails/generators/rails/app/templates/Gemfile index 3825dc4e38..f3bc9d9734 100644 --- a/railties/lib/rails/generators/rails/app/templates/Gemfile +++ b/railties/lib/rails/generators/rails/app/templates/Gemfile @@ -38,9 +38,15 @@ group :development do gem 'web-console', '~> 3.0' <%- end -%> <%- end -%> +<% if depend_on_listen? -%> + gem 'listen', '~> 3.0.5' +<% end -%> <% if spring_install? -%> # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' +<% if depend_on_listen? -%> + gem 'spring-watcher-listen', '~> 2.0.0' +<% end -%> <% end -%> end <% end -%> diff --git a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt index 68b5c051b2..ec781721cb 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt +++ b/railties/lib/rails/generators/rails/app/templates/app/views/layouts/application.html.erb.tt @@ -11,8 +11,8 @@ <%%= stylesheet_link_tag 'application', media: 'all' %> <%- else -%> <%- if gemfile_entries.any? { |m| m.name == 'turbolinks' } -%> - <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> - <%%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> + <%%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => 'reload' %> + <%%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload' %> <%- else -%> <%%= stylesheet_link_tag 'application', media: 'all' %> <%%= javascript_include_tag 'application' %> diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml index 5ca549a8c8..f2c4922e7d 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/jdbcmysql.yml @@ -1,4 +1,4 @@ -# MySQL. Versions 4.1 and 5.0 are recommended. +# MySQL. Versions 5.0 and up are supported. # # Install the MySQL driver: # gem install activerecord-jdbcmysql-adapter diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml index 119c2fe2c3..193423e84a 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/mysql.yml @@ -1,4 +1,4 @@ -# MySQL. Versions 5.0+ are recommended. +# MySQL. Versions 5.0 and up are supported. # # Install the MySQL driver # gem install mysql2 diff --git a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml index d51b2ec199..bd5c0b10f6 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/databases/postgresql.yml @@ -19,7 +19,7 @@ default: &default encoding: unicode # For details on connection pooling, see rails configuration guide # http://guides.rubyonrails.org/configuring.html#database-pooling - pool: 5 + pool: <%%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> development: <<: *default diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt index fd41372d9c..8e9890378a 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt @@ -15,12 +15,22 @@ Rails.application.configure do # Enable/disable caching. By default caching is disabled. if Rails.root.join('tmp/caching-dev.txt').exist? config.action_controller.perform_caching = true + + <%- unless options.skip_action_mailer? -%> + config.action_mailer.perform_caching = false + <%- end -%> + config.cache_store = :memory_store config.public_file_server.headers = { 'Cache-Control' => 'public, max-age=172800' } else config.action_controller.perform_caching = false + + <%- unless options.skip_action_mailer? -%> + config.action_mailer.perform_caching = false + <%- end -%> + config.cache_store = :null_store end <%- unless options.skip_action_mailer? -%> @@ -58,5 +68,5 @@ Rails.application.configure do # Use an evented file watcher to asynchronously detect changes in source code, # routes, locales, etc. This feature depends on the listen gem. - # config.file_watcher = ActiveSupport::EventedFileUpdateChecker + <%= '# ' unless depend_on_listen? %>config.file_watcher = ActiveSupport::EventedFileUpdateChecker end diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt index 82509f5ef5..236e42fcd7 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt @@ -60,6 +60,10 @@ Rails.application.configure do # require 'syslog/logger' # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + if ENV["RAILS_LOG_TO_STDOUT"].present? + config.logger = ActiveSupport::TaggedLogging.new(Logger.new(STDOUT)) + end + # Use a different cache store in production. # config.cache_store = :mem_cache_store @@ -67,6 +71,7 @@ Rails.application.configure do # config.active_job.queue_adapter = :resque # config.active_job.queue_name_prefix = "<%= app_name %>_#{Rails.env}" <%- unless options.skip_action_mailer? -%> + config.action_mailer.perform_caching = false # Ignore bad email addresses and do not raise email delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors. diff --git a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt index 8133917591..42fee3b036 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +++ b/railties/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt @@ -28,6 +28,7 @@ Rails.application.configure do # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false <%- unless options.skip_action_mailer? -%> + config.action_mailer.perform_caching = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the @@ -35,9 +36,6 @@ Rails.application.configure do config.action_mailer.delivery_method = :test <%- end -%> - # Randomize the order test cases are executed. - config.active_support.test_order = :random - # Print deprecation notices to the stderr. config.active_support.deprecation = :stderr diff --git a/railties/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png b/railties/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/public/apple-touch-icon-precomposed.png diff --git a/railties/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png b/railties/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/public/apple-touch-icon.png diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index b5e836b584..56efd35a95 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -90,6 +90,7 @@ task default: :test opts[:force] = force opts[:skip_bundle] = true opts[:api] = options.api? + opts[:skip_listen] = true invoke Rails::Generators::AppGenerator, [ File.expand_path(dummy_path, destination_root) ], opts @@ -287,10 +288,6 @@ task default: :test protected - def app_templates_dir - "../../app/templates" - end - def create_dummy_app(path = nil) dummy_path(path) if path diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt index 83807f14b4..abbacd9bec 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/controllers/%namespaced_name%/application_controller.rb.tt @@ -1,6 +1,6 @@ <%= wrap_in_modules <<-rb.strip_heredoc class ApplicationController < ActionController::#{api? ? "API" : "Base"} - #{ api? ? '# ' : '' }protect_from_forgery :with => :exception + #{ api? ? '# ' : '' }protect_from_forgery with: :exception end rb %> diff --git a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml index 2656767eb4..0681780c97 100644 --- a/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml +++ b/railties/lib/rails/generators/test_unit/model/templates/fixtures.yml @@ -6,7 +6,7 @@ <%- if attribute.password_digest? -%> password_digest: <%%= BCrypt::Password.create('secret') %> <%- elsif attribute.reference? -%> - <%= yaml_key_value(attribute.column_name.sub(/_id$/, ''), attribute.default) %> + <%= yaml_key_value(attribute.column_name.sub(/_id$/, ''), attribute.default || name) %> <%- else -%> <%= yaml_key_value(attribute.column_name, attribute.default) %> <%- end -%> diff --git a/railties/lib/rails/rack/logger.rb b/railties/lib/rails/rack/logger.rb index aa7d3ca6c6..b63d3a58d2 100644 --- a/railties/lib/rails/rack/logger.rb +++ b/railties/lib/rails/rack/logger.rb @@ -72,10 +72,6 @@ module Rails instrumenter.finish 'request.action_dispatch', request: request end - def development? - Rails.env.development? - end - def logger Rails.logger end diff --git a/railties/lib/rails/railtie.rb b/railties/lib/rails/railtie.rb index 8c24d1d56d..99dd571a00 100644 --- a/railties/lib/rails/railtie.rb +++ b/railties/lib/rails/railtie.rb @@ -183,7 +183,7 @@ module Rails end protected - def generate_railtie_name(string) + def generate_railtie_name(string) #:nodoc: ActiveSupport::Inflector.underscore(string).tr("/", "_") end @@ -200,21 +200,24 @@ module Rails delegate :railtie_name, to: :class - def initialize + def initialize #:nodoc: if self.class.abstract_railtie? raise "#{self.class.name} is abstract, you cannot instantiate it directly." end end - def configure(&block) + def configure(&block) #:nodoc: instance_eval(&block) end + # This is used to create the <tt>config</tt> object on Railties, an instance of + # Railtie::Configuration, that is used by Railties and Application to store + # related configuration. def config @config ||= Railtie::Configuration.new end - def railtie_namespace + def railtie_namespace #:nodoc: @railtie_namespace ||= self.class.parents.detect { |n| n.respond_to?(:railtie_namespace) } end diff --git a/railties/lib/rails/tasks.rb b/railties/lib/rails/tasks.rb index d60eaf6f4f..d3e33584d7 100644 --- a/railties/lib/rails/tasks.rb +++ b/railties/lib/rails/tasks.rb @@ -3,6 +3,7 @@ require 'rake' # Load Rails Rakefile extensions %w( annotations + dev framework initializers log diff --git a/railties/lib/rails/tasks/dev.rake b/railties/lib/rails/tasks/dev.rake new file mode 100644 index 0000000000..4593100465 --- /dev/null +++ b/railties/lib/rails/tasks/dev.rake @@ -0,0 +1,14 @@ +namespace :dev do + desc 'Toggle development mode caching on/off' + task :cache do + if File.exist? 'tmp/caching-dev.txt' + File.delete 'tmp/caching-dev.txt' + puts 'Development mode is no longer being cached.' + else + FileUtils.touch 'tmp/caching-dev.txt' + puts 'Development mode is now being cached.' + end + + FileUtils.touch 'tmp/restart.txt' + end +end diff --git a/railties/lib/rails/tasks/framework.rake b/railties/lib/rails/tasks/framework.rake index 904b9d9ad6..7601836809 100644 --- a/railties/lib/rails/tasks/framework.rake +++ b/railties/lib/rails/tasks/framework.rake @@ -45,7 +45,7 @@ namespace :rails do @app_generator ||= begin require 'rails/generators' require 'rails/generators/rails/app/app_generator' - gen = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true }, + gen = Rails::Generators::AppGenerator.new ["rails"], { with_dispatchers: true, api: !!Rails.application.config.api_only }, destination_root: Rails.root File.exist?(Rails.root.join("config", "application.rb")) ? gen.send(:app_const) : gen.send(:valid_const?) diff --git a/railties/lib/rails/tasks/routes.rake b/railties/lib/rails/tasks/routes.rake index 939fa59c75..69103aa5d9 100644 --- a/railties/lib/rails/tasks/routes.rake +++ b/railties/lib/rails/tasks/routes.rake @@ -2,7 +2,7 @@ require 'active_support/deprecation' require 'active_support/core_ext/string/strip' # for strip_heredoc require 'optparse' -desc 'Print out all defined routes in match order, with names. Target specific controller with --controller option - or its -c shorthand.' +desc 'Print out all defined routes in match order, with names. Target specific controller with -c option, or grep routes using -g option' task routes: :environment do all_routes = Rails.application.routes.routes require 'action_dispatch/routing/inspector' @@ -19,11 +19,11 @@ task routes: :environment do OptionParser.new do |opts| opts.banner = "Usage: rails routes [options]" - opts.on("-c", "--controller [CONTROLLER]") do |controller| + opts.on("-c CONTROLLER") do |controller| routes_filter = { controller: controller } end - opts.on("-g", "--grep [PATTERN]") do |pattern| + opts.on("-g PATTERN") do |pattern| routes_filter = pattern end diff --git a/railties/lib/rails/test_unit/line_filtering.rb b/railties/lib/rails/test_unit/line_filtering.rb index dab4d3631d..dd9732bb12 100644 --- a/railties/lib/rails/test_unit/line_filtering.rb +++ b/railties/lib/rails/test_unit/line_filtering.rb @@ -13,9 +13,12 @@ module Rails end class CompositeFilter # :nodoc: + attr_reader :named_filter + def initialize(runnable, filter, patterns) @runnable = runnable - @filters = [ derive_regexp(filter), *derive_line_filters(patterns) ].compact + @named_filter = derive_named_filter(filter) + @filters = [ @named_filter, *derive_line_filters(patterns) ].compact end # Minitest uses === to find matching filters. @@ -24,9 +27,14 @@ module Rails end private - def derive_regexp(filter) - # Regexp filtering copied from Minitest. - filter =~ %r%/(.*)/% ? Regexp.new($1) : filter + def derive_named_filter(filter) + if filter.respond_to?(:named_filter) + filter.named_filter + elsif filter =~ %r%/(.*)/% # Regexp filtering copied from Minitest. + Regexp.new $1 + elsif filter.is_a?(String) + filter + end end def derive_line_filters(patterns) diff --git a/railties/lib/rails/test_unit/minitest_plugin.rb b/railties/lib/rails/test_unit/minitest_plugin.rb index 29a3d991b8..f22139490b 100644 --- a/railties/lib/rails/test_unit/minitest_plugin.rb +++ b/railties/lib/rails/test_unit/minitest_plugin.rb @@ -1,6 +1,7 @@ require "active_support/core_ext/module/attribute_accessors" require "rails/test_unit/reporter" require "rails/test_unit/test_requirer" +require 'shellwords' module Minitest class SuppressedSummaryReporter < SummaryReporter @@ -42,7 +43,7 @@ module Minitest end opts.on("-f", "--fail-fast", - "Abort test run on first failure") do + "Abort test run on first failure or error") do options[:fail_fast] = true end @@ -60,11 +61,13 @@ module Minitest # as the patterns would also contain the other Rake tasks. def self.rake_run(patterns) # :nodoc: @rake_patterns = patterns - passed = run + passed = run(Shellwords.split(ENV['TESTOPTS'] || '')) exit passed unless passed passed end + # Owes great inspiration to test runner trailblazers like RSpec, + # minitest-reporters, maxitest and others. def self.plugin_rails_init(options) self.run_with_rails_extension = true diff --git a/railties/lib/rails/test_unit/reporter.rb b/railties/lib/rails/test_unit/reporter.rb index 73b8d7d27b..4086d5b731 100644 --- a/railties/lib/rails/test_unit/reporter.rb +++ b/railties/lib/rails/test_unit/reporter.rb @@ -18,13 +18,13 @@ module Rails if output_inline? && result.failure && (!result.skipped? || options[:verbose]) io.puts io.puts - io.puts format_failures(result).map { |line| color_output(line, by: result) } + io.puts color_output(result, by: result) io.puts io.puts format_rerun_snippet(result) io.puts end - if fail_fast? && result.failure && !result.error? && !result.skipped? + if fail_fast? && result.failure && !result.skipped? raise Interrupt end end @@ -66,21 +66,9 @@ module Rails "%s#%s = %.2f s = %s" % [result.class, result.name, result.time, result.result_code] end - def format_failures(result) - result.failures.map do |failure| - "#{failure.result_label}:\n#{result.class}##{result.name}:\n#{failure.message}\n" - end - end - def format_rerun_snippet(result) - # Try to extract path to assertion from backtrace. - if result.location =~ /\[(.*)\]\z/ - assertion_path = $1 - else - assertion_path = result.method(result.name).source_location.join(':') - end - - "#{self.executable} #{relative_path_for(assertion_path)}" + location, line = result.method(result.name).source_location + "#{self.executable} #{relative_path_for(location)}:#{line}" end def app_root diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 7bcfc86d03..d03dd1afcc 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -348,6 +348,17 @@ module ApplicationTests end end + test "In production mode, STDOUT logging is enabled when RAILS_LOG_TO_STDOUT is set" do + restore_default_config + + with_rails_env "production" do + switch_env "RAILS_LOG_TO_STDOUT", "1" do + app 'production' + assert ActiveSupport::Logger.logger_outputs_to?(app.config.logger, STDOUT) + end + end + end + test "In production mode, config.public_file_server.enabled is disabled when RAILS_SERVE_STATIC_FILES is blank" do restore_default_config @@ -988,7 +999,7 @@ module ApplicationTests app 'development' post "/posts.json", '{ "title": "foo", "name": "bar" }', "CONTENT_TYPE" => "application/json" - assert_equal '{"title"=>"foo"}', last_response.body + assert_equal '<ActionController::Parameters {"title"=>"foo"} permitted: false>', last_response.body end test "config.action_controller.permit_all_parameters = true" do @@ -1444,7 +1455,7 @@ module ApplicationTests assert Rails.configuration.api_only end - test "debug_exception_response_format is :api by default if only_api is enabled" do + test "debug_exception_response_format is :api by default if api_only is enabled" do add_to_config <<-RUBY config.api_only = true RUBY diff --git a/railties/test/application/generators_test.rb b/railties/test/application/generators_test.rb index 84cc6e120b..644af0e737 100644 --- a/railties/test/application/generators_test.rb +++ b/railties/test/application/generators_test.rb @@ -160,5 +160,15 @@ module ApplicationTests assert Rails::Generators.options[:rails][:helper] assert_equal :my_template, Rails::Generators.options[:rails][:template_engine] end + + test "api only generator generate mailer views" do + add_to_config <<-RUBY + config.api_only = true + RUBY + + FileUtils.cd(rails_root){ `bin/rails generate mailer notifier foo` } + assert File.exist?(File.join(rails_root, "app/views/notifier_mailer/foo.text.erb")) + assert File.exist?(File.join(rails_root, "app/views/notifier_mailer/foo.html.erb")) + end end end diff --git a/railties/test/application/initializers/frameworks_test.rb b/railties/test/application/initializers/frameworks_test.rb index 4c06b6324c..44209a52f7 100644 --- a/railties/test/application/initializers/frameworks_test.rb +++ b/railties/test/application/initializers/frameworks_test.rb @@ -16,7 +16,7 @@ module ApplicationTests # AC & AM test "set load paths set only if action controller or action mailer are in use" do - assert_nothing_raised NameError do + assert_nothing_raised do add_to_config <<-RUBY config.root = "#{app_path}" RUBY diff --git a/railties/test/application/integration_test_case_test.rb b/railties/test/application/integration_test_case_test.rb new file mode 100644 index 0000000000..40a79fc636 --- /dev/null +++ b/railties/test/application/integration_test_case_test.rb @@ -0,0 +1,46 @@ +require 'isolation/abstract_unit' + +module ApplicationTests + class IntegrationTestCaseTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + setup do + build_app + boot_rails + end + + teardown do + teardown_app + end + + test "resets Action Mailer test deliveries" do + script('generate mailer BaseMailer welcome') + + app_file 'test/integration/mailer_integration_test.rb', <<-RUBY + require 'test_helper' + + class MailerIntegrationTest < ActionDispatch::IntegrationTest + setup do + @old_delivery_method = ActionMailer::Base.delivery_method + ActionMailer::Base.delivery_method = :test + end + + teardown do + ActionMailer::Base.delivery_method = @old_delivery_method + end + + 2.times do |i| + define_method "test_resets_deliveries_\#{i}" do + BaseMailer.welcome.deliver_now + assert_equal 1, ActionMailer::Base.deliveries.count + end + end + end + RUBY + + output = Dir.chdir(app_path) { `bin/rails test 2>&1` } + assert_equal 0, $?.to_i, output + assert_match /0 failures, 0 errors/, output + end + end +end diff --git a/railties/test/application/loading_test.rb b/railties/test/application/loading_test.rb index 40abaf860d..efb21ae473 100644 --- a/railties/test/application/loading_test.rb +++ b/railties/test/application/loading_test.rb @@ -56,10 +56,10 @@ class LoadingTest < ActiveSupport::TestCase require "#{rails_root}/config/environment" - assert_nothing_raised(NameError) { Trackable } - assert_nothing_raised(NameError) { EmailLoggable } - assert_nothing_raised(NameError) { Orderable } - assert_nothing_raised(NameError) { Matchable } + assert_nothing_raised { Trackable } + assert_nothing_raised { EmailLoggable } + assert_nothing_raised { Orderable } + assert_nothing_raised { Matchable } end test "models without table do not panic on scope definitions when loaded" do diff --git a/railties/test/application/middleware/exceptions_test.rb b/railties/test/application/middleware/exceptions_test.rb index 7b4babb13b..639b01b562 100644 --- a/railties/test/application/middleware/exceptions_test.rb +++ b/railties/test/application/middleware/exceptions_test.rb @@ -85,7 +85,7 @@ module ApplicationTests test "unspecified route when action_dispatch.show_exceptions is set shows 404" do app.config.action_dispatch.show_exceptions = true - assert_nothing_raised(ActionController::RoutingError) do + assert_nothing_raised do get '/foo' assert_match "The page you were looking for doesn't exist.", last_response.body end @@ -95,7 +95,7 @@ module ApplicationTests app.config.action_dispatch.show_exceptions = true app.config.consider_all_requests_local = true - assert_nothing_raised(ActionController::RoutingError) do + assert_nothing_raised do get '/foo' assert_match "No route matches", last_response.body end diff --git a/railties/test/application/middleware/remote_ip_test.rb b/railties/test/application/middleware/remote_ip_test.rb index 97d5b5c698..37bd8a25c1 100644 --- a/railties/test/application/middleware/remote_ip_test.rb +++ b/railties/test/application/middleware/remote_ip_test.rb @@ -36,10 +36,10 @@ module ApplicationTests test "works with both headers individually" do make_basic_app - assert_nothing_raised(ActionDispatch::RemoteIp::IpSpoofAttackError) do + assert_nothing_raised do assert_equal "1.1.1.1", remote_ip("HTTP_X_FORWARDED_FOR" => "1.1.1.1") end - assert_nothing_raised(ActionDispatch::RemoteIp::IpSpoofAttackError) do + assert_nothing_raised do assert_equal "1.1.1.2", remote_ip("HTTP_CLIENT_IP" => "1.1.1.2") end end @@ -49,7 +49,7 @@ module ApplicationTests app.config.action_dispatch.ip_spoofing_check = false end - assert_nothing_raised(ActionDispatch::RemoteIp::IpSpoofAttackError) do + assert_nothing_raised do assert_equal "1.1.1.1", remote_ip("HTTP_X_FORWARDED_FOR" => "1.1.1.1", "HTTP_CLIENT_IP" => "1.1.1.2") end end diff --git a/railties/test/application/per_request_digest_cache_test.rb b/railties/test/application/per_request_digest_cache_test.rb index 3198e12662..dfe3fc9354 100644 --- a/railties/test/application/per_request_digest_cache_test.rb +++ b/railties/test/application/per_request_digest_cache_test.rb @@ -29,6 +29,8 @@ class PerRequestDigestCacheTest < ActiveSupport::TestCase app_file 'app/controllers/customers_controller.rb', <<-RUBY class CustomersController < ApplicationController + self.perform_caching = true + def index render [ Customer.new('david', 1), Customer.new('dingus', 2) ] end @@ -50,12 +52,13 @@ class PerRequestDigestCacheTest < ActiveSupport::TestCase get '/customers' assert_equal 200, last_response.status - assert_equal [ '8ba099b7749542fe765ff34a6824d548' ], ActionView::Digestor.cache.values + values = ActionView::LookupContext::DetailsKey.digest_caches.first.values + assert_equal [ '8ba099b7749542fe765ff34a6824d548' ], values assert_equal %w(david dingus), last_response.body.split.map(&:strip) end test "template digests are cleared before a request" do - assert_called(ActionView::Digestor.cache, :clear) do + assert_called(ActionView::LookupContext::DetailsKey, :clear) do get '/customers' assert_equal 200, last_response.status end diff --git a/railties/test/application/rake/dev_test.rb b/railties/test/application/rake/dev_test.rb new file mode 100644 index 0000000000..43d7a5e156 --- /dev/null +++ b/railties/test/application/rake/dev_test.rb @@ -0,0 +1,34 @@ +require 'isolation/abstract_unit' + +module ApplicationTests + module RakeTests + class RakeDevTest < ActiveSupport::TestCase + include ActiveSupport::Testing::Isolation + + def setup + build_app + end + + def teardown + teardown_app + end + + test 'dev:cache creates file and outputs message' do + Dir.chdir(app_path) do + output = `rake dev:cache` + assert File.exist?('tmp/caching-dev.txt') + assert_match(/Development mode is now being cached/, output) + end + end + + test 'dev:cache deletes file and outputs message' do + Dir.chdir(app_path) do + `rails dev:cache` # Create caching file. + output = `rails dev:cache` # Delete caching file. + assert_not File.exist?('tmp/caching-dev.txt') + assert_match(/Development mode is no longer being cached/, output) + end + end + end + end +end diff --git a/railties/test/application/rake_test.rb b/railties/test/application/rake_test.rb index 745a3e3ec5..d1c828b509 100644 --- a/railties/test/application/rake_test.rb +++ b/railties/test/application/rake_test.rb @@ -179,12 +179,20 @@ module ApplicationTests app_file "config/routes.rb", <<-RUBY Rails.application.routes.draw do get '/cart', to: 'cart#show' - get '/basketball', to: 'basketball#index' + post '/cart', to: 'cart#create' + get '/basketballs', to: 'basketball#index' end RUBY output = Dir.chdir(app_path){ `bin/rails routes -g show` } assert_equal "Prefix Verb URI Pattern Controller#Action\n cart GET /cart(.:format) cart#show\n", output + + output = Dir.chdir(app_path){ `bin/rails routes -g POST` } + assert_equal "Prefix Verb URI Pattern Controller#Action\n POST /cart(.:format) cart#create\n", output + + output = Dir.chdir(app_path){ `bin/rails routes -g basketballs` } + assert_equal " Prefix Verb URI Pattern Controller#Action\n" \ + "basketballs GET /basketballs(.:format) basketball#index\n", output end def test_rake_routes_with_controller_search_key @@ -291,12 +299,11 @@ module ApplicationTests assert_no_match(/Errors running/, output) end - def test_scaffold_with_references_columns_tests_pass_when_belongs_to_is_optional - app_file "config/initializers/active_record_belongs_to_required_by_default.rb", - "Rails.application.config.active_record.belongs_to_required_by_default = false" - + def test_scaffold_with_references_columns_tests_pass_by_default output = Dir.chdir(app_path) do - `bin/rails generate scaffold LineItems product:references cart:belongs_to; + `bin/rails generate model Product; + bin/rails generate model Cart; + bin/rails generate scaffold LineItems product:references cart:belongs_to; RAILS_ENV=test bin/rails db:migrate test` end diff --git a/railties/test/application/test_runner_test.rb b/railties/test/application/test_runner_test.rb index a7eb0feb11..a1735db5b3 100644 --- a/railties/test/application/test_runner_test.rb +++ b/railties/test/application/test_runner_test.rb @@ -363,7 +363,7 @@ module ApplicationTests end RUBY - run_test_command('test/models/account_test.rb:4:9 test/models/post_test:4:9').tap do |output| + run_test_command('test/models/account_test.rb:4:9 test/models/post_test.rb:4:9').tap do |output| assert_match 'AccountTest:FirstFilter', output assert_match 'AccountTest:SecondFilter', output assert_match 'PostTest:FirstFilter', output @@ -382,6 +382,54 @@ module ApplicationTests end end + def test_line_filters_trigger_only_one_runnable + app_file 'test/models/post_test.rb', <<-RUBY + require 'test_helper' + + class PostTest < ActiveSupport::TestCase + test 'truth' do + assert true + end + end + + class SecondPostTest < ActiveSupport::TestCase + test 'truth' do + assert false, 'ran second runnable' + end + end + RUBY + + # Pass seed guaranteeing failure. + run_test_command('test/models/post_test.rb:4 --seed 30410').tap do |output| + assert_no_match 'ran second runnable', output + assert_match '1 runs, 1 assertions', output + end + end + + def test_line_filter_with_minitest_string_filter + app_file 'test/models/post_test.rb', <<-RUBY + require 'test_helper' + + class PostTest < ActiveSupport::TestCase + test 'by line' do + puts 'by line' + assert true + end + + test 'by name' do + puts 'by name' + assert true + end + end + RUBY + + run_test_command('test/models/post_test.rb:4 -n test_by_name').tap do |output| + assert_match 'by line', output + assert_match 'by name', output + assert_match '2 runs, 2 assertions', output + end + end + def test_shows_filtered_backtrace_by_default create_backtrace_test @@ -419,7 +467,7 @@ module ApplicationTests create_test_file :models, 'post', pass: false output = run_test_command('test/models/post_test.rb') - expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth:\nwups!\n\nbin/rails test test/models/post_test.rb:6\n\n\n\n} + expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth \[[^\]]+test/models/post_test.rb:6\]:\nwups!\n\nbin/rails test test/models/post_test.rb:4\n\n\n\n} assert_match expect, output end @@ -454,6 +502,32 @@ module ApplicationTests assert_match '1 runs, 1 assertions', output end + def test_rails_db_create_all_restores_db_connection + create_test_file :models, 'account' + output = Dir.chdir(app_path) { `bin/rails db:create:all db:migrate && echo ".tables" | rails dbconsole` } + assert_match "ar_internal_metadata", output, "tables should be dumped" + end + + def test_rails_db_create_all_restores_db_connection_after_drop + create_test_file :models, 'account' + Dir.chdir(app_path) { `bin/rails db:create:all` } # create all to avoid warnings + output = Dir.chdir(app_path) { `bin/rails db:drop:all db:create:all db:migrate && echo ".tables" | rails dbconsole` } + assert_match "ar_internal_metadata", output, "tables should be dumped" + end + + def test_rake_passes_TESTOPTS_to_minitest + create_test_file :models, 'account' + output = Dir.chdir(app_path) { `bin/rake test TESTOPTS=-v` } + assert_match "AccountTest#test_truth", output, "passing TEST= should run selected test" + end + + def test_rake_passes_multiple_TESTOPTS_to_minitest + create_test_file :models, 'account' + output = Dir.chdir(app_path) { `bin/rake test TESTOPTS='-v --seed=1234'` } + assert_match "AccountTest#test_truth", output, "passing TEST= should run selected test" + assert_match "seed=1234", output, "passing TEST= should run selected test" + end + private def run_test_command(arguments = 'test/unit/test_test.rb') Dir.chdir(app_path) { `bin/rails t #{arguments}` } diff --git a/railties/test/commands/dev_cache_test.rb b/railties/test/commands/dev_cache_test.rb deleted file mode 100644 index 1b7a72e7fc..0000000000 --- a/railties/test/commands/dev_cache_test.rb +++ /dev/null @@ -1,32 +0,0 @@ -require_relative '../isolation/abstract_unit' - -module CommandsTests - class DevCacheTest < ActiveSupport::TestCase - include ActiveSupport::Testing::Isolation - - def setup - build_app - end - - def teardown - teardown_app - end - - test 'dev:cache creates file and outputs message' do - Dir.chdir(app_path) do - output = `rails dev:cache` - assert File.exist?('tmp/caching-dev.txt') - assert_match(%r{Development mode is now being cached}, output) - end - end - - test 'dev:cache deletes file and outputs message' do - Dir.chdir(app_path) do - `rails dev:cache` # Create caching file. - output = `rails dev:cache` # Delete caching file. - assert_not File.exist?('tmp/caching-dev.txt') - assert_match(%r{Development mode is no longer being cached}, output) - end - end - end -end diff --git a/railties/test/generators/actions_test.rb b/railties/test/generators/actions_test.rb index 3300850604..6158748194 100644 --- a/railties/test/generators/actions_test.rb +++ b/railties/test/generators/actions_test.rb @@ -202,7 +202,7 @@ class ActionsTest < Rails::Generators::TestCase end def test_rake_should_run_rake_command_with_default_env - assert_called_with(generator, :run, ["rake log:clear RAILS_ENV=development", verbose: false]) do + assert_called_with(generator, :run, ["rails log:clear RAILS_ENV=development", verbose: false]) do with_rails_env nil do action :rake, 'log:clear' end @@ -210,13 +210,13 @@ class ActionsTest < Rails::Generators::TestCase end def test_rake_with_env_option_should_run_rake_command_in_env - assert_called_with(generator, :run, ['rake log:clear RAILS_ENV=production', verbose: false]) do + assert_called_with(generator, :run, ['rails log:clear RAILS_ENV=production', verbose: false]) do action :rake, 'log:clear', env: 'production' end end def test_rake_with_rails_env_variable_should_run_rake_command_in_env - assert_called_with(generator, :run, ['rake log:clear RAILS_ENV=production', verbose: false]) do + assert_called_with(generator, :run, ['rails log:clear RAILS_ENV=production', verbose: false]) do with_rails_env "production" do action :rake, 'log:clear' end @@ -224,7 +224,7 @@ class ActionsTest < Rails::Generators::TestCase end def test_env_option_should_win_over_rails_env_variable_when_running_rake - assert_called_with(generator, :run, ['rake log:clear RAILS_ENV=production', verbose: false]) do + assert_called_with(generator, :run, ['rails log:clear RAILS_ENV=production', verbose: false]) do with_rails_env "staging" do action :rake, 'log:clear', env: 'production' end @@ -232,13 +232,51 @@ class ActionsTest < Rails::Generators::TestCase end def test_rake_with_sudo_option_should_run_rake_command_with_sudo - assert_called_with(generator, :run, ["sudo rake log:clear RAILS_ENV=development", verbose: false]) do + assert_called_with(generator, :run, ["sudo rails log:clear RAILS_ENV=development", verbose: false]) do with_rails_env nil do action :rake, 'log:clear', sudo: true end end end + def test_rails_command_should_run_rails_command_with_default_env + assert_called_with(generator, :run, ["rails log:clear RAILS_ENV=development", verbose: false]) do + with_rails_env nil do + action :rails_command, 'log:clear' + end + end + end + + def test_rails_command_with_env_option_should_run_rails_command_in_env + assert_called_with(generator, :run, ['rails log:clear RAILS_ENV=production', verbose: false]) do + action :rails_command, 'log:clear', env: 'production' + end + end + + def test_rails_command_with_rails_env_variable_should_run_rails_command_in_env + assert_called_with(generator, :run, ['rails log:clear RAILS_ENV=production', verbose: false]) do + with_rails_env "production" do + action :rails_command, 'log:clear' + end + end + end + + def test_env_option_should_win_over_rails_env_variable_when_running_rails + assert_called_with(generator, :run, ['rails log:clear RAILS_ENV=production', verbose: false]) do + with_rails_env "staging" do + action :rails_command, 'log:clear', env: 'production' + end + end + end + + def test_rails_command_with_sudo_option_should_run_rails_command_with_sudo + assert_called_with(generator, :run, ["sudo rails log:clear RAILS_ENV=development", verbose: false]) do + with_rails_env nil do + action :rails_command, 'log:clear', sudo: true + end + end + end + def test_capify_should_run_the_capify_command assert_called_with(generator, :run, ['capify .', verbose: false]) do action :capify! diff --git a/railties/test/generators/api_app_generator_test.rb b/railties/test/generators/api_app_generator_test.rb index 1ea5661006..8e1cd0891a 100644 --- a/railties/test/generators/api_app_generator_test.rb +++ b/railties/test/generators/api_app_generator_test.rb @@ -73,6 +73,8 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase app/controllers app/mailers app/models + app/views/layouts/mailer.html.erb + app/views/layouts/mailer.text.erb config/environments config/initializers config/locales @@ -94,7 +96,7 @@ class ApiAppGeneratorTest < Rails::Generators::TestCase def skipped_files %w(app/assets app/helpers - app/views + app/views/layouts/application.html.erb config/initializers/assets.rb config/initializers/cookies_serializer.rb config/initializers/session_store.rb diff --git a/railties/test/generators/app_generator_test.rb b/railties/test/generators/app_generator_test.rb index 9595d2a0ef..c2c3638f07 100644 --- a/railties/test/generators/app_generator_test.rb +++ b/railties/test/generators/app_generator_test.rb @@ -64,8 +64,8 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_assets run_generator - assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track' => true/) - assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+'application', 'data-turbolinks-track' => true/) + assert_file("app/views/layouts/application.html.erb", /stylesheet_link_tag\s+'application', media: 'all', 'data-turbolinks-track' => 'reload'/) + assert_file("app/views/layouts/application.html.erb", /javascript_include_tag\s+'application', 'data-turbolinks-track' => 'reload'/) assert_file("app/assets/stylesheets/application.css") assert_file("app/assets/javascripts/application.js") end @@ -385,9 +385,10 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_match(/#\s+require\s+["']sprockets\/railtie["']/, content) end assert_file "Gemfile" do |content| + assert_no_match(/jquery-rails/, content) assert_no_match(/sass-rails/, content) assert_no_match(/uglifier/, content) - assert_match(/coffee-rails/, content) + assert_no_match(/coffee-rails/, content) end assert_file "config/environments/development.rb" do |content| assert_no_match(/config\.assets\.debug = true/, content) @@ -415,7 +416,7 @@ class AppGeneratorTest < Rails::Generators::TestCase def test_action_cable_redis_gems run_generator - assert_gem 'redis' + assert_file "Gemfile", /^# gem 'redis'/ end def test_inclusion_of_javascript_runtime @@ -478,6 +479,31 @@ class AppGeneratorTest < Rails::Generators::TestCase end end + def test_inclusion_of_listen_related_configuration_by_default + run_generator + if RbConfig::CONFIG['host_os'] =~ /darwin|linux/ + assert_listen_related_configuration + else + assert_no_listen_related_configuration + end + end + + def test_non_inclusion_of_listen_related_configuration_if_skip_listen + run_generator [destination_root, '--skip-listen'] + assert_no_listen_related_configuration + end + + def test_evented_file_update_checker_config + run_generator + assert_file 'config/environments/development.rb' do |content| + if RbConfig::CONFIG['host_os'] =~ /darwin|linux/ + assert_match(/^\s*config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content) + else + assert_match(/^\s*# config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content) + end + end + 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"])) @@ -735,4 +761,23 @@ class AppGeneratorTest < Rails::Generators::TestCase assert_file "Gemfile", /^\s*gem\s+["']#{gem}["']$*/ end end + + def assert_listen_related_configuration + assert_gem 'listen' + assert_gem 'spring-watcher-listen' + + assert_file 'config/environments/development.rb' do |content| + assert_match(/^\s*config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content) + end + end + + def assert_no_listen_related_configuration + assert_file 'Gemfile' do |content| + assert_no_match(/listen/, content) + end + + assert_file 'config/environments/development.rb' do |content| + assert_match(/^\s*# config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, content) + end + end end diff --git a/railties/test/generators/channel_generator_test.rb b/railties/test/generators/channel_generator_test.rb index c1f0c03fbf..e31736a74c 100644 --- a/railties/test/generators/channel_generator_test.rb +++ b/railties/test/generators/channel_generator_test.rb @@ -5,6 +5,18 @@ class ChannelGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper tests Rails::Generators::ChannelGenerator + def test_application_cable_skeleton_is_created + run_generator ['books'] + + assert_file "app/channels/application_cable/channel.rb" do |cable| + assert_match(/module ApplicationCable\n class Channel < ActionCable::Channel::Base\n/, cable) + end + + assert_file "app/channels/application_cable/connection.rb" do |cable| + assert_match(/module ApplicationCable\n class Connection < ActionCable::Connection::Base\n/, cable) + end + end + def test_channel_is_created run_generator ['chat'] diff --git a/railties/test/generators/model_generator_test.rb b/railties/test/generators/model_generator_test.rb index 814f4c050e..ed6846abc3 100644 --- a/railties/test/generators/model_generator_test.rb +++ b/railties/test/generators/model_generator_test.rb @@ -6,6 +6,14 @@ class ModelGeneratorTest < Rails::Generators::TestCase include GeneratorsTestHelper arguments %w(Account name:string age:integer) + def test_application_record_skeleton_is_created + run_generator + assert_file "app/models/application_record.rb" do |record| + assert_match(/class ApplicationRecord < ActiveRecord::Base/, record) + assert_match(/self.abstract_class = true/, record) + end + end + def test_help_shows_invoked_generators_options content = run_generator ["--help"] assert_match(/ActiveRecord options:/, content) @@ -298,18 +306,18 @@ class ModelGeneratorTest < Rails::Generators::TestCase def test_fixtures_use_the_references_ids run_generator ["LineItem", "product:references", "cart:belongs_to"] - assert_file "test/fixtures/line_items.yml", /product: \n cart: / + assert_file "test/fixtures/line_items.yml", /product: one\n cart: one/ assert_generated_fixture("test/fixtures/line_items.yml", - {"one"=>{"product"=>nil, "cart"=>nil}, "two"=>{"product"=>nil, "cart"=>nil}}) + {"one"=>{"product"=>"one", "cart"=>"one"}, "two"=>{"product"=>"two", "cart"=>"two"}}) end def test_fixtures_use_the_references_ids_and_type run_generator ["LineItem", "product:references{polymorphic}", "cart:belongs_to"] - assert_file "test/fixtures/line_items.yml", /product: \n product_type: Product\n cart: / + assert_file "test/fixtures/line_items.yml", /product: one\n product_type: Product\n cart: one/ assert_generated_fixture("test/fixtures/line_items.yml", - {"one"=>{"product"=>nil, "product_type"=>"Product", "cart"=>nil}, - "two"=>{"product"=>nil, "product_type"=>"Product", "cart"=>nil}}) + {"one"=>{"product"=>"one", "product_type"=>"Product", "cart"=>"one"}, + "two"=>{"product"=>"two", "product_type"=>"Product", "cart"=>"two"}}) end def test_fixtures_respect_reserved_yml_keywords diff --git a/railties/test/generators/plugin_generator_test.rb b/railties/test/generators/plugin_generator_test.rb index 6e5132e849..d7d27e6b2e 100644 --- a/railties/test/generators/plugin_generator_test.rb +++ b/railties/test/generators/plugin_generator_test.rb @@ -335,7 +335,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "hyphenated-name/lib/hyphenated/name/engine.rb", /module Hyphenated\n module Name\n class Engine < ::Rails::Engine\n isolate_namespace Hyphenated::Name\n end\n end\nend/ assert_file "hyphenated-name/lib/hyphenated/name.rb", /require "hyphenated\/name\/engine"/ assert_file "hyphenated-name/test/dummy/config/routes.rb", /mount Hyphenated::Name::Engine => "\/hyphenated-name"/ - assert_file "hyphenated-name/app/controllers/hyphenated/name/application_controller.rb", /module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n protect_from_forgery :with => :exception\n end\n end\nend\n/ + assert_file "hyphenated-name/app/controllers/hyphenated/name/application_controller.rb", /module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n protect_from_forgery with: :exception\n end\n end\nend\n/ assert_file "hyphenated-name/app/models/hyphenated/name/application_record.rb", /module Hyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\nend/ assert_file "hyphenated-name/app/jobs/hyphenated/name/application_job.rb", /module Hyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/ assert_file "hyphenated-name/app/mailers/hyphenated/name/application_mailer.rb", /module Hyphenated\n module Name\n class ApplicationMailer < ActionMailer::Base\n default from: 'from@example.com'\n layout 'mailer'\n end\n end\nend/ @@ -357,7 +357,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "my_hyphenated-name/lib/my_hyphenated/name/engine.rb", /module MyHyphenated\n module Name\n class Engine < ::Rails::Engine\n isolate_namespace MyHyphenated::Name\n end\n end\nend/ assert_file "my_hyphenated-name/lib/my_hyphenated/name.rb", /require "my_hyphenated\/name\/engine"/ assert_file "my_hyphenated-name/test/dummy/config/routes.rb", /mount MyHyphenated::Name::Engine => "\/my_hyphenated-name"/ - assert_file "my_hyphenated-name/app/controllers/my_hyphenated/name/application_controller.rb", /module MyHyphenated\n module Name\n class ApplicationController < ActionController::Base\n protect_from_forgery :with => :exception\n end\n end\nend\n/ + assert_file "my_hyphenated-name/app/controllers/my_hyphenated/name/application_controller.rb", /module MyHyphenated\n module Name\n class ApplicationController < ActionController::Base\n protect_from_forgery with: :exception\n end\n end\nend\n/ assert_file "my_hyphenated-name/app/models/my_hyphenated/name/application_record.rb", /module MyHyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\nend/ assert_file "my_hyphenated-name/app/jobs/my_hyphenated/name/application_job.rb", /module MyHyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/ assert_file "my_hyphenated-name/app/mailers/my_hyphenated/name/application_mailer.rb", /module MyHyphenated\n module Name\n class ApplicationMailer < ActionMailer::Base\n default from: 'from@example.com'\n layout 'mailer'\n end\n end\nend/ @@ -379,7 +379,7 @@ class PluginGeneratorTest < Rails::Generators::TestCase assert_file "deep-hyphenated-name/lib/deep/hyphenated/name/engine.rb", /module Deep\n module Hyphenated\n module Name\n class Engine < ::Rails::Engine\n isolate_namespace Deep::Hyphenated::Name\n end\n end\n end\nend/ assert_file "deep-hyphenated-name/lib/deep/hyphenated/name.rb", /require "deep\/hyphenated\/name\/engine"/ assert_file "deep-hyphenated-name/test/dummy/config/routes.rb", /mount Deep::Hyphenated::Name::Engine => "\/deep-hyphenated-name"/ - assert_file "deep-hyphenated-name/app/controllers/deep/hyphenated/name/application_controller.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n protect_from_forgery :with => :exception\n end\n end\n end\nend\n/ + assert_file "deep-hyphenated-name/app/controllers/deep/hyphenated/name/application_controller.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationController < ActionController::Base\n protect_from_forgery with: :exception\n end\n end\n end\nend\n/ assert_file "deep-hyphenated-name/app/models/deep/hyphenated/name/application_record.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationRecord < ActiveRecord::Base\n self\.abstract_class = true\n end\n end\n end\nend/ assert_file "deep-hyphenated-name/app/jobs/deep/hyphenated/name/application_job.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationJob < ActiveJob::Base/ assert_file "deep-hyphenated-name/app/mailers/deep/hyphenated/name/application_mailer.rb", /module Deep\n module Hyphenated\n module Name\n class ApplicationMailer < ActionMailer::Base\n default from: 'from@example.com'\n layout 'mailer'\n end\n end\n end\nend/ @@ -444,6 +444,14 @@ class PluginGeneratorTest < Rails::Generators::TestCase end end + def test_dummy_appplication_skip_listen_by_default + run_generator + + assert_file 'test/dummy/config/environments/development.rb' do |contents| + assert_match(/^\s*# config.file_watcher = ActiveSupport::EventedFileUpdateChecker/, contents) + end + end + def test_ensure_that_gitignore_can_be_generated_from_a_template_for_dummy_path FileUtils.cd(Rails.root) run_generator([destination_root, "--dummy_path", "spec/dummy", "--skip-test"]) diff --git a/railties/test/generators/plugin_test_runner_test.rb b/railties/test/generators/plugin_test_runner_test.rb index f492cd49ef..ef6359fece 100644 --- a/railties/test/generators/plugin_test_runner_test.rb +++ b/railties/test/generators/plugin_test_runner_test.rb @@ -63,7 +63,7 @@ class PluginTestRunnerTest < ActiveSupport::TestCase create_test_file 'post', pass: false output = run_test_command('test/post_test.rb') - expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth:\nwups!\n\nbin/test (/private)?#{plugin_path}/test/post_test.rb:6} + expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth \[[^\]]+test/post_test.rb:6\]:\nwups!\n\nbin/test (/private)?#{plugin_path}/test/post_test.rb:4} assert_match expect, output end diff --git a/railties/test/generators/test_runner_in_engine_test.rb b/railties/test/generators/test_runner_in_engine_test.rb index 69906b962b..d37e261fbb 100644 --- a/railties/test/generators/test_runner_in_engine_test.rb +++ b/railties/test/generators/test_runner_in_engine_test.rb @@ -17,7 +17,7 @@ class TestRunnerInEngineTest < ActiveSupport::TestCase create_test_file 'post', pass: false output = run_test_command('test/post_test.rb') - expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth:\nwups!\n\nbin/rails test test/post_test.rb:6} + expect = %r{Running:\n\nPostTest\nF\n\nFailure:\nPostTest#test_truth \[[^\]]+test/post_test.rb:6\]:\nwups!\n\nbin/rails test test/post_test.rb:4} assert_match expect, output end diff --git a/railties/test/isolation/abstract_unit.rb b/railties/test/isolation/abstract_unit.rb index dddf8bd257..66a8cf54af 100644 --- a/railties/test/isolation/abstract_unit.rb +++ b/railties/test/isolation/abstract_unit.rb @@ -272,10 +272,17 @@ module TestHelpers end def remove_from_config(str) - file = "#{app_path}/config/application.rb" + remove_from_file("#{app_path}/config/application.rb", str) + end + + def remove_from_env_config(env, str) + remove_from_file("#{app_path}/config/environments/#{env}.rb", str) + end + + def remove_from_file(file, str) contents = File.read(file) - contents.sub!(/#{str}/, "") - File.open(file, "w+") { |f| f.puts contents } + contents.sub!(/#{str}/, '') + File.write(file, contents) end def app_file(path, contents, mode = 'w') @@ -319,7 +326,6 @@ class ActiveSupport::TestCase include ActiveSupport::Testing::Stream self.test_order = :sorted - end # Create a scope and build a fixture rails app @@ -333,7 +339,7 @@ Module.new do environment = File.expand_path('../../../../load_paths', __FILE__) require_environment = "-r #{environment}" - `#{Gem.ruby} #{require_environment} #{RAILS_FRAMEWORK_ROOT}/railties/exe/rails new #{app_template_path} --skip-gemfile --no-rc` + `#{Gem.ruby} #{require_environment} #{RAILS_FRAMEWORK_ROOT}/railties/exe/rails new #{app_template_path} --skip-gemfile --skip-listen --no-rc` File.open("#{app_template_path}/config/boot.rb", 'w') do |f| f.puts "require '#{environment}'" f.puts "require 'rails/all'" diff --git a/railties/test/test_unit/reporter_test.rb b/railties/test/test_unit/reporter_test.rb index 2d08d4ec30..0d64b48550 100644 --- a/railties/test/test_unit/reporter_test.rb +++ b/railties/test/test_unit/reporter_test.rb @@ -62,7 +62,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase @reporter.record(failed_test) @reporter.report - expect = %r{\AF\n\nFailure:\nTestUnitReporterTest::ExampleTest#woot:\nboo\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z} + expect = %r{\AF\n\nFailure:\nTestUnitReporterTest::ExampleTest#woot \[[^\]]+\]:\nboo\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z} assert_match expect, @output.string end @@ -79,7 +79,7 @@ class TestUnitReporterTest < ActiveSupport::TestCase verbose.record(skipped_test) verbose.report - expect = %r{\ATestUnitReporterTest::ExampleTest#woot = 10\.00 s = S\n\n\nSkipped:\nTestUnitReporterTest::ExampleTest#woot:\nskipchurches, misstemples\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z} + expect = %r{\ATestUnitReporterTest::ExampleTest#woot = 10\.00 s = S\n\n\nSkipped:\nTestUnitReporterTest::ExampleTest#woot \[[^\]]+\]:\nskipchurches, misstemples\n\nbin/rails test test/test_unit/reporter_test.rb:\d+\n\n\z} assert_match expect, @output.string end @@ -104,11 +104,22 @@ class TestUnitReporterTest < ActiveSupport::TestCase end end - test "fail fast does not interrupt run errors or skips" do + test "fail fast interrupts run on error" do fail_fast = Rails::TestUnitReporter.new @output, fail_fast: true + interrupt_raised = false - fail_fast.record(errored_test) - assert_no_match 'Failed tests:', @output.string + # Minitest passes through Interrupt, catch it manually. + begin + fail_fast.record(errored_test) + rescue Interrupt + interrupt_raised = true + ensure + assert interrupt_raised, 'Expected Interrupt to be raised.' + end + end + + test "fail fast does not interrupt run skips" do + fail_fast = Rails::TestUnitReporter.new @output, fail_fast: true fail_fast.record(skipped_test) assert_no_match 'Failed tests:', @output.string |