diff options
Diffstat (limited to 'railties/lib/rails')
36 files changed, 189 insertions, 50 deletions
diff --git a/railties/lib/rails/application/default_middleware_stack.rb b/railties/lib/rails/application/default_middleware_stack.rb index ed6a1f82d3..4f1cc0703d 100644 --- a/railties/lib/rails/application/default_middleware_stack.rb +++ b/railties/lib/rails/application/default_middleware_stack.rb @@ -68,7 +68,7 @@ module Rails middleware.use ::ActionDispatch::Cookies unless config.api_only if !config.api_only && config.session_store - if config.force_ssl && !config.session_options.key?(:secure) + if config.force_ssl && config.ssl_options.fetch(:secure_cookies, true) && !config.session_options.key?(:secure) config.session_options[:secure] = true end middleware.use config.session_store, config.session_options diff --git a/railties/lib/rails/code_statistics.rb b/railties/lib/rails/code_statistics.rb index 8e9097e1ef..0997414482 100644 --- a/railties/lib/rails/code_statistics.rb +++ b/railties/lib/rails/code_statistics.rb @@ -33,7 +33,7 @@ class CodeStatistics #:nodoc: Hash[@pairs.map{|pair| [pair.first, calculate_directory_statistics(pair.last)]}] end - def calculate_directory_statistics(directory, pattern = /.*\.(rb|js|coffee|rake)$/) + def calculate_directory_statistics(directory, pattern = /^(?!\.).*?\.(rb|js|coffee|rake)$/) stats = CodeStatisticsCalculator.new Dir.foreach(directory) do |file_name| diff --git a/railties/lib/rails/commands/runner.rb b/railties/lib/rails/commands/runner.rb index 86bce9b2fe..babb197ba1 100644 --- a/railties/lib/rails/commands/runner.rb +++ b/railties/lib/rails/commands/runner.rb @@ -58,5 +58,11 @@ elsif File.exist?(code_or_file) $0 = code_or_file Kernel.load code_or_file else - eval(code_or_file, binding, __FILE__, __LINE__) + begin + eval(code_or_file, binding, __FILE__, __LINE__) + rescue SyntaxError,NameError => err + $stderr.puts "Please specify a valid ruby command or the path of a script to run." + $stderr.puts "Run '#{$0} -h' for help." + exit 1 + end end diff --git a/railties/lib/rails/commands/server.rb b/railties/lib/rails/commands/server.rb index d3ea441f8e..27cbaf360a 100644 --- a/railties/lib/rails/commands/server.rb +++ b/railties/lib/rails/commands/server.rb @@ -6,6 +6,8 @@ require 'rails' module Rails class Server < ::Rack::Server class Options + DEFAULT_PID_PATH = File.expand_path("tmp/pids/server.pid").freeze + def parse!(args) args, options = args.dup, {} @@ -91,7 +93,7 @@ module Rails environment: (ENV['RAILS_ENV'] || ENV['RACK_ENV'] || "development").dup, daemonize: false, caching: false, - pid: File.expand_path("tmp/pids/server.pid") + pid: Options::DEFAULT_PID_PATH }) end @@ -133,11 +135,13 @@ module Rails def log_to_stdout wrapped_app # touch the app so the logger is set up - console = ActiveSupport::Logger.new($stdout) + console = ActiveSupport::Logger.new(STDOUT) console.formatter = Rails.logger.formatter console.level = Rails.logger.level - Rails.logger.extend(ActiveSupport::Logger.broadcast(console)) + unless ActiveSupport::Logger.logger_outputs_to?(Rails.logger, STDOUT) + Rails.logger.extend(ActiveSupport::Logger.broadcast(console)) + end end end end diff --git a/railties/lib/rails/gem_version.rb b/railties/lib/rails/gem_version.rb index 92230a74e4..f4d5b660dc 100644 --- a/railties/lib/rails/gem_version.rb +++ b/railties/lib/rails/gem_version.rb @@ -8,7 +8,7 @@ module Rails MAJOR = 5 MINOR = 0 TINY = 0 - PRE = "beta1" + PRE = "beta1.1" STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".") end diff --git a/railties/lib/rails/generators/actions.rb b/railties/lib/rails/generators/actions.rb index cd83175da8..9ca731347a 100644 --- a/railties/lib/rails/generators/actions.rb +++ b/railties/lib/rails/generators/actions.rb @@ -20,7 +20,7 @@ module Rails # Set the message to be shown in logs. Uses the git repo if one is given, # otherwise use name (version). - parts, message = [ quote(name) ], name + parts, message = [ quote(name) ], name.dup if version ||= options.delete(:version) parts << quote(version) message << " (#{version})" diff --git a/railties/lib/rails/generators/app_base.rb b/railties/lib/rails/generators/app_base.rb index 2f18619e30..c629459d95 100644 --- a/railties/lib/rails/generators/app_base.rb +++ b/railties/lib/rails/generators/app_base.rb @@ -75,7 +75,7 @@ module Rails class_option :edge, type: :boolean, default: false, desc: "Setup the #{name} with Gemfile pointing to Rails repository" - class_option :rc, type: :string, default: false, + class_option :rc, type: :string, default: nil, desc: "Path to file containing extra configuration options for rails command" class_option :no_rc, type: :boolean, default: false, @@ -117,6 +117,7 @@ module Rails javascript_gemfile_entry, jbuilder_gemfile_entry, psych_gemfile_entry, + cable_gemfile_entry, @extra_entries].flatten.find_all(&@gem_filter) end @@ -281,6 +282,8 @@ module Rails return [] if options[:skip_sprockets] gems = [] + gems << GemfileEntry.version('sass-rails', '~> 5.0', + 'Use SCSS for stylesheets') gems << GemfileEntry.version('uglifier', '>= 1.3.0', @@ -337,6 +340,15 @@ module Rails GemfileEntry.new('psych', '~> 2.0', comment, platforms: :rbx) end + def cable_gemfile_entry + return [] if options[:skip_action_cable] + comment = 'Action Cable dependencies for the Redis adapter' + gems = [] + gems << GemfileEntry.new("em-hiredis", '~> 0.3.0', comment) + gems << GemfileEntry.new("redis", '~> 3.0', comment) + gems + end + def bundle_command(command) say_status :run, "bundle #{command}" diff --git a/railties/lib/rails/generators/generated_attribute.rb b/railties/lib/rails/generators/generated_attribute.rb index 8145a26e22..7e437e7344 100644 --- a/railties/lib/rails/generators/generated_attribute.rb +++ b/railties/lib/rails/generators/generated_attribute.rb @@ -23,8 +23,9 @@ module Rails type = type.to_sym if type if type && reference?(type) - references_index = UNIQ_INDEX_OPTIONS.include?(has_index) ? { unique: true } : true - attr_options[:index] = references_index + if UNIQ_INDEX_OPTIONS.include?(has_index) + attr_options[:index] = { unique: true } + end end new(name, type, has_index, attr_options) diff --git a/railties/lib/rails/generators/named_base.rb b/railties/lib/rails/generators/named_base.rb index 658d883883..efbf51ddfb 100644 --- a/railties/lib/rails/generators/named_base.rb +++ b/railties/lib/rails/generators/named_base.rb @@ -161,6 +161,10 @@ module Rails @route_url ||= class_path.collect {|dname| "/" + dname }.join + "/" + plural_file_name end + def url_helper_prefix + @url_helper_prefix ||= (class_path + [file_name]).join('_') + end + # Tries to retrieve the application name or simply return application. def application_name if defined?(Rails) && Rails.application diff --git a/railties/lib/rails/generators/rails/app/app_generator.rb b/railties/lib/rails/generators/rails/app/app_generator.rb index f4deec7135..a4758857f2 100644 --- a/railties/lib/rails/generators/rails/app/app_generator.rb +++ b/railties/lib/rails/generators/rails/app/app_generator.rb @@ -78,11 +78,11 @@ module Rails template "application.rb" template "environment.rb" template "secrets.yml" + template "cable.yml" unless options[:skip_action_cable] directory "environments" directory "initializers" directory "locales" - directory "redis" unless options[:skip_action_cable] end end @@ -315,9 +315,10 @@ module Rails def delete_action_cable_files_skipping_action_cable if options[:skip_action_cable] - remove_file 'config/redis/cable.yml' + remove_file 'config/cable.yml' remove_file 'app/assets/javascripts/cable.coffee' remove_dir 'app/channels' + gsub_file 'app/views/layouts/application.html.erb', /action_cable_meta_tag/, '' unless options[:api] end end @@ -326,6 +327,7 @@ module Rails remove_file 'config/initializers/session_store.rb' remove_file 'config/initializers/cookies_serializer.rb' remove_file 'config/initializers/request_forgery_protection.rb' + remove_file 'config/initializers/per_form_csrf_tokens.rb' end end diff --git a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.coffee b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.coffee index 49a7cfa69b..07934d026f 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.coffee +++ b/railties/lib/rails/generators/rails/app/templates/app/assets/javascripts/cable.coffee @@ -1,4 +1,4 @@ -# Action Cable provides the framework to deal with WebSockets in Rails. +# Action Cable provides the framework to deal with WebSockets in Rails. # You can generate new channels where WebSocket features live using the rails generate channel command. # # Turn on the cable connection by removing the comments after the require statements (and ensure it's also on in config/routes.rb). diff --git a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb index 438c84154d..d56fa30f4d 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb +++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/channel.rb @@ -1,4 +1,4 @@ -# Be sure to restart your server when you modify this file. Action Cable runs in an EventMachine loop that does not support auto reloading. +# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading. module ApplicationCable class Channel < ActionCable::Channel::Base end diff --git a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb index 965046f3c7..b4f41389ad 100644 --- a/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb +++ b/railties/lib/rails/generators/rails/app/templates/app/channels/application_cable/connection.rb @@ -1,4 +1,4 @@ -# Be sure to restart your server when you modify this file. Action Cable runs in an EventMachine loop that does not support auto reloading. +# Be sure to restart your server when you modify this file. Action Cable runs in a loop that does not support auto reloading. module ApplicationCable class Connection < ActionCable::Connection::Base end diff --git a/railties/lib/rails/generators/rails/app/templates/config.ru.tt b/railties/lib/rails/generators/rails/app/templates/config.ru.tt index 70556fcc99..343c0833d7 100644 --- a/railties/lib/rails/generators/rails/app/templates/config.ru.tt +++ b/railties/lib/rails/generators/rails/app/templates/config.ru.tt @@ -3,9 +3,8 @@ require ::File.expand_path('../config/environment', __FILE__) <%- unless options[:skip_action_cable] -%> -# Action Cable uses EventMachine which requires that all classes are loaded in advance +# Action Cable requires that all classes are loaded in advance Rails.application.eager_load! -require 'action_cable/process/logging' <%- end -%> run Rails.application diff --git a/railties/lib/rails/generators/rails/app/templates/config/cable.yml b/railties/lib/rails/generators/rails/app/templates/config/cable.yml new file mode 100644 index 0000000000..004adb7b3c --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/config/cable.yml @@ -0,0 +1,12 @@ +# Action Cable uses Redis by default to administer connections, channels, and sending/receiving messages over the WebSocket. +production: + adapter: redis + url: redis://localhost:6379/1 + +development: + adapter: redis + url: redis://localhost:6379/2 + +test: + adapter: redis + url: redis://localhost:6379/3 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 8d59a6fcf3..82509f5ef5 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 @@ -54,7 +54,7 @@ Rails.application.configure do config.log_level = :debug # Prepend all log lines with the following tags. - # config.log_tags = [ :subdomain, :request_id ] + config.log_tags = [ :request_id ] # Use a different logger for distributed setups. # require 'syslog/logger' diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb index 40c831ec58..f613b40f80 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/active_record_belongs_to_required_by_default.rb @@ -1,5 +1,6 @@ # Be sure to restart your server when you modify this file. -# Require `belongs_to` associations by default. This is a new Rails 5.0 default, -# so introduced as a config to ensure apps made with earlier versions of Rails aren't affected when upgrading. +# Require `belongs_to` associations by default. This is a new Rails 5.0 +# default, so it is introduced as a configuration option to ensure that apps +# made on earlier versions of Rails are not affected when upgrading. Rails.application.config.active_record.belongs_to_required_by_default = true diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb index 43510c244b..649e82280e 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/callback_terminator.rb @@ -1,5 +1,6 @@ # Be sure to restart your server when you modify this file. -# Do not halt callback chains when a callback returns false. This is a new Rails 5.0 default, -# so introduced as a config to ensure apps made with earlier versions of Rails aren't affected when upgrading. +# Do not halt callback chains when a callback returns false. This is a new +# Rails 5.0 default, so it is introduced as a configuration option to ensure +# that apps made with earlier versions of Rails are not affected when upgrading. ActiveSupport.halt_callback_chains_on_return_false = false diff --git a/railties/lib/rails/generators/rails/app/templates/config/initializers/per_form_csrf_tokens.rb b/railties/lib/rails/generators/rails/app/templates/config/initializers/per_form_csrf_tokens.rb new file mode 100644 index 0000000000..1f569dedfd --- /dev/null +++ b/railties/lib/rails/generators/rails/app/templates/config/initializers/per_form_csrf_tokens.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Enable per-form CSRF tokens. +Rails.application.config.action_controller.per_form_csrf_tokens = true diff --git a/railties/lib/rails/generators/rails/app/templates/config/redis/cable.yml b/railties/lib/rails/generators/rails/app/templates/config/redis/cable.yml deleted file mode 100644 index 0176be24f9..0000000000 --- a/railties/lib/rails/generators/rails/app/templates/config/redis/cable.yml +++ /dev/null @@ -1,9 +0,0 @@ -# Action Cable uses Redis to administer connections, channels, and sending/receiving messages over the WebSocket. -production: - url: redis://localhost:6379/1 - -development: - url: redis://localhost:6379/2 - -test: - url: redis://localhost:6379/3 diff --git a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml index b2669a0f79..cdea2fd060 100644 --- a/railties/lib/rails/generators/rails/app/templates/config/secrets.yml +++ b/railties/lib/rails/generators/rails/app/templates/config/secrets.yml @@ -5,7 +5,7 @@ # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. -# You can use `rake secret` to generate a secure secret key. +# You can use `rails secret` to generate a secure secret key. # Make sure the secrets in this file are kept private # if you're sharing your code publicly. diff --git a/railties/lib/rails/generators/rails/model/USAGE b/railties/lib/rails/generators/rails/model/USAGE index 11daa5c3cb..025bcf4774 100644 --- a/railties/lib/rails/generators/rails/model/USAGE +++ b/railties/lib/rails/generators/rails/model/USAGE @@ -8,14 +8,14 @@ Description: As a special case, specifying 'password:digest' will generate a password_digest field of string type, and configure your generated model and - tests for use with ActiveModel has_secure_password (assuming the default ORM + tests for use with Active Model has_secure_password (assuming the default ORM and test framework are being used). You don't have to think up every attribute up front, but it helps to sketch out a few so you can start working with the model immediately. This generator invokes your configured ORM and test framework, which - defaults to ActiveRecord and TestUnit. + defaults to Active Record and TestUnit. Finally, if --parent option is given, it's used as superclass of the created model. This allows you create Single Table Inheritance models. @@ -91,7 +91,7 @@ Available field types: Examples: `rails generate model account` - For ActiveRecord and TestUnit it creates: + For Active Record and TestUnit it creates: Model: app/models/account.rb Test: test/models/account_test.rb @@ -104,7 +104,7 @@ Examples: `rails generate model admin/account` - For ActiveRecord and TestUnit it creates: + For Active Record and TestUnit it creates: Module: app/models/admin.rb Model: app/models/admin/account.rb diff --git a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb index 7d7477de75..0c7a73a54e 100644 --- a/railties/lib/rails/generators/rails/plugin/plugin_generator.rb +++ b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb @@ -337,7 +337,7 @@ task default: :test end def wrap_in_modules(unwrapped_code) - unwrapped_code = "#{unwrapped_code}".strip.gsub(/\W$\n/, '') + unwrapped_code = "#{unwrapped_code}".strip.gsub(/\s$\n/, '') modules.reverse.inject(unwrapped_code) do |content, mod| str = "module #{mod}\n" str += content.lines.map { |line| " #{line}" }.join diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt new file mode 100644 index 0000000000..09aac13f42 --- /dev/null +++ b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/%namespaced_name%/application_mailer.rb.tt @@ -0,0 +1,7 @@ +<%= wrap_in_modules <<-rb.strip_heredoc + class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' + end +rb +%> diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory b/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/plugin/templates/app/mailers/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/models/application_record.rb.tt b/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt index 8aa3de78f1..8aa3de78f1 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/app/models/application_record.rb.tt +++ b/railties/lib/rails/generators/rails/plugin/templates/app/models/%namespaced_name%/application_record.rb.tt diff --git a/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory b/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory deleted file mode 100644 index e69de29bb2..0000000000 --- a/railties/lib/rails/generators/rails/plugin/templates/app/models/.empty_directory +++ /dev/null diff --git a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb index a0b00fc5c5..a5eebcb19f 100644 --- a/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb +++ b/railties/lib/rails/generators/rails/plugin/templates/test/test_helper.rb @@ -1,7 +1,7 @@ # Configure Rails Environment ENV["RAILS_ENV"] = "test" -require File.expand_path("../../<%= options[:dummy_path] -%>/config/environment.rb", __FILE__) +require File.expand_path("../../<%= options[:dummy_path] -%>/config/environment.rb", __FILE__) <% unless options[:skip_active_record] -%> ActiveRecord::Migrator.migrations_paths = [File.expand_path("../../<%= options[:dummy_path] -%>/db/migrate", __FILE__)] <% if options[:mountable] -%> diff --git a/railties/lib/rails/generators/rails/scaffold/USAGE b/railties/lib/rails/generators/rails/scaffold/USAGE index d2e495758d..c9283eda87 100644 --- a/railties/lib/rails/generators/rails/scaffold/USAGE +++ b/railties/lib/rails/generators/rails/scaffold/USAGE @@ -16,7 +16,7 @@ Description: As a special case, specifying 'password:digest' will generate a password_digest field of string type, and configure your generated model, - controller, views, and test suite for use with ActiveModel + controller, views, and test suite for use with Active Model has_secure_password (assuming they are using Rails defaults). Timestamps are added by default, so you don't have to specify them by hand diff --git a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb index 4f2ceb8589..ff41fef9e9 100644 --- a/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb +++ b/railties/lib/rails/generators/test_unit/controller/templates/functional_test.rb @@ -13,7 +13,7 @@ class <%= class_name %>ControllerTest < ActionDispatch::IntegrationTest <% else -%> <% actions.each do |action| -%> test "should get <%= action %>" do - get <%= file_name %>_<%= action %>_url + get <%= url_helper_prefix %>_<%= action %>_url assert_response :success end diff --git a/railties/lib/rails/tasks/log.rake b/railties/lib/rails/tasks/log.rake index 877f175ef3..073f235ec5 100644 --- a/railties/lib/rails/tasks/log.rake +++ b/railties/lib/rails/tasks/log.rake @@ -1,5 +1,12 @@ namespace :log do - desc "Truncates all *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)" + + ## + # Truncates all/specified log files + # ENV['LOGS'] + # - defaults to standard environment log files i.e. 'development,test,production' + # - ENV['LOGS']=all truncates all files i.e. log/*.log + # - ENV['LOGS']='test,development' truncates only specified files + desc "Truncates all/specified *.log files in log/ to zero bytes (specify which logs with LOGS=test,development)" task :clear do log_files.each do |file| clear_log_file(file) @@ -7,15 +14,21 @@ namespace :log do end def log_files - if ENV['LOGS'] - ENV['LOGS'].split(',') - .map { |file| "log/#{file.strip}.log" } - .select { |file| File.exist?(file) } - else + if ENV['LOGS'] == 'all' FileList["log/*.log"] + elsif ENV['LOGS'] + log_files_to_truncate(ENV['LOGS']) + else + log_files_to_truncate("development,test,production") end end + def log_files_to_truncate(envs) + envs.split(',') + .map { |file| "log/#{file.strip}.log" } + .select { |file| File.exist?(file) } + end + def clear_log_file(file) f = File.open(file, "w") f.close diff --git a/railties/lib/rails/test_unit/line_filtering.rb b/railties/lib/rails/test_unit/line_filtering.rb new file mode 100644 index 0000000000..dab4d3631d --- /dev/null +++ b/railties/lib/rails/test_unit/line_filtering.rb @@ -0,0 +1,70 @@ +require 'method_source' + +module Rails + module LineFiltering # :nodoc: + def run(reporter, options = {}) + if options[:patterns] && options[:patterns].any? { |p| p =~ /:\d+/ } + options[:filter] = \ + CompositeFilter.new(self, options[:filter], options[:patterns]) + end + + super + end + end + + class CompositeFilter # :nodoc: + def initialize(runnable, filter, patterns) + @runnable = runnable + @filters = [ derive_regexp(filter), *derive_line_filters(patterns) ].compact + end + + # Minitest uses === to find matching filters. + def ===(method) + @filters.any? { |filter| filter === method } + end + + private + def derive_regexp(filter) + # Regexp filtering copied from Minitest. + filter =~ %r%/(.*)/% ? Regexp.new($1) : filter + end + + def derive_line_filters(patterns) + patterns.flat_map do |file_and_line| + file, *lines = file_and_line.split(':') + + if lines.empty? + Filter.new(@runnable, file, nil) if file + else + lines.map { |line| Filter.new(@runnable, file, line) } + end + end + end + end + + class Filter # :nodoc: + def initialize(runnable, file, line) + @runnable, @file = runnable, File.expand_path(file) + @line = line.to_i if line + end + + def ===(method) + return unless @runnable.method_defined?(method) + + if @line + test_file, test_range = definition_for(@runnable.instance_method(method)) + test_file == @file && test_range.include?(@line) + else + @runnable.instance_method(method).source_location.first == @file + end + end + + private + def definition_for(method) + file, start_line = method.source_location + end_line = method.source.count("\n") + start_line - 1 + + return file, start_line..end_line + end + end +end diff --git a/railties/lib/rails/test_unit/minitest_plugin.rb b/railties/lib/rails/test_unit/minitest_plugin.rb index d4ab2ada66..29a3d991b8 100644 --- a/railties/lib/rails/test_unit/minitest_plugin.rb +++ b/railties/lib/rails/test_unit/minitest_plugin.rb @@ -80,7 +80,8 @@ module Minitest Minitest.backtrace_filter = ::Rails.backtrace_cleaner if ::Rails.respond_to?(:backtrace_cleaner) end - self.reporter.reporters.clear # Replace progress reporter for colors. + # Replace progress reporter for colors. + self.reporter.reporters.delete_if { |reporter| reporter.kind_of?(SummaryReporter) || reporter.kind_of?(ProgressReporter) } self.reporter << SuppressedSummaryReporter.new(options[:io], options) self.reporter << ::Rails::TestUnitReporter.new(options[:io], options) end diff --git a/railties/lib/rails/test_unit/railtie.rb b/railties/lib/rails/test_unit/railtie.rb index 75180ff978..511cee33bd 100644 --- a/railties/lib/rails/test_unit/railtie.rb +++ b/railties/lib/rails/test_unit/railtie.rb @@ -1,3 +1,5 @@ +require 'rails/test_unit/line_filtering' + if defined?(Rake.application) && Rake.application.top_level_tasks.grep(/^(default$|test(:|$))/).any? ENV['RAILS_ENV'] ||= 'test' end @@ -11,6 +13,10 @@ module Rails c.integration_tool :test_unit end + initializer "test_unit.line_filtering" do + ActiveSupport::TestCase.extend Rails::LineFiltering + end + rake_tasks do load "rails/test_unit/testing.rake" end diff --git a/railties/lib/rails/test_unit/test_requirer.rb b/railties/lib/rails/test_unit/test_requirer.rb index 83d2c55ffd..8b211ce130 100644 --- a/railties/lib/rails/test_unit/test_requirer.rb +++ b/railties/lib/rails/test_unit/test_requirer.rb @@ -15,7 +15,7 @@ module Rails private def expand_patterns(patterns) patterns.map do |arg| - arg = arg.gsub(/:(\d+)?$/, '') + arg = arg.gsub(/(:\d+)+?$/, '') if Dir.exist?(arg) "#{arg}/**/*_test.rb" else diff --git a/railties/lib/rails/test_unit/testing.rake b/railties/lib/rails/test_unit/testing.rake index 6676c6a079..41921e43f3 100644 --- a/railties/lib/rails/test_unit/testing.rake +++ b/railties/lib/rails/test_unit/testing.rake @@ -7,7 +7,12 @@ task default: :test desc "Runs all tests in test folder" task :test do $: << "test" - Minitest.rake_run(["test"]) + pattern = if ENV.key?('TEST') + ENV['TEST'] + else + "test" + end + Minitest.rake_run([pattern]) end namespace :test do |