mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
3064533076
use `Dir.exist?` instead of deprecated `Dir.exists?`
137 lines
3.8 KiB
Ruby
137 lines
3.8 KiB
Ruby
require "optparse"
|
|
require "rake/file_list"
|
|
require "method_source"
|
|
|
|
module Rails
|
|
class TestRunner
|
|
class Options
|
|
def self.parse(args)
|
|
options = { backtrace: !ENV["BACKTRACE"].nil?, name: nil, environment: "test" }
|
|
|
|
opt_parser = ::OptionParser.new do |opts|
|
|
opts.banner = "Usage: bin/rails test [options] [file or directory]"
|
|
|
|
opts.separator ""
|
|
opts.on("-e", "--environment [ENV]",
|
|
"Run tests in the ENV environment") do |env|
|
|
options[:environment] = env.strip
|
|
end
|
|
opts.separator ""
|
|
opts.separator "Filter options:"
|
|
opts.separator ""
|
|
opts.separator <<-DESC
|
|
You can run a single test by appending the line number to filename:
|
|
|
|
bin/rails test test/models/user_test.rb:27
|
|
|
|
DESC
|
|
|
|
opts.on("-n", "--name [NAME]",
|
|
"Only run tests matching NAME") do |name|
|
|
options[:name] = name
|
|
end
|
|
opts.on("-p", "--pattern [PATTERN]",
|
|
"Only run tests matching PATTERN") do |pattern|
|
|
options[:name] = "/#{pattern}/"
|
|
end
|
|
|
|
opts.separator ""
|
|
opts.separator "Output options:"
|
|
|
|
opts.on("-b", "--backtrace",
|
|
"Show the complete backtrace") do
|
|
options[:backtrace] = true
|
|
end
|
|
|
|
opts.separator ""
|
|
opts.separator "Common options:"
|
|
|
|
opts.on_tail("-h", "--help", "Show this message") do
|
|
puts opts
|
|
exit
|
|
end
|
|
end
|
|
|
|
opt_parser.order!(args)
|
|
|
|
options[:patterns] = []
|
|
while arg = args.shift
|
|
if (file_and_line = arg.split(':')).size > 1
|
|
options[:filename], options[:line] = file_and_line
|
|
options[:filename] = File.expand_path options[:filename]
|
|
options[:line] &&= options[:line].to_i
|
|
else
|
|
arg = arg.gsub(':', '')
|
|
if Dir.exist?("#{arg}")
|
|
options[:patterns] << File.expand_path("#{arg}/**/*_test.rb")
|
|
elsif File.file?(arg)
|
|
options[:patterns] << File.expand_path(arg)
|
|
end
|
|
end
|
|
end
|
|
options
|
|
end
|
|
end
|
|
|
|
def initialize(options = {})
|
|
@options = options
|
|
end
|
|
|
|
def self.run(arguments)
|
|
options = Rails::TestRunner::Options.parse(arguments)
|
|
Rails::TestRunner.new(options).run
|
|
end
|
|
|
|
def run
|
|
$rails_test_runner = self
|
|
ENV["RAILS_ENV"] = @options[:environment]
|
|
run_tests
|
|
end
|
|
|
|
def find_method
|
|
return @options[:name] if @options[:name]
|
|
return unless @options[:line]
|
|
method = test_methods.find do |location, test_method, start_line, end_line|
|
|
location == @options[:filename] &&
|
|
(start_line..end_line).include?(@options[:line].to_i)
|
|
end
|
|
method[1] if method
|
|
end
|
|
|
|
def show_backtrace?
|
|
@options[:backtrace]
|
|
end
|
|
|
|
def test_files
|
|
return [@options[:filename]] if @options[:filename]
|
|
if @options[:patterns] && @options[:patterns].count > 0
|
|
pattern = @options[:patterns]
|
|
else
|
|
pattern = "test/**/*_test.rb"
|
|
end
|
|
Rake::FileList[pattern]
|
|
end
|
|
|
|
private
|
|
def run_tests
|
|
test_files.to_a.each do |file|
|
|
require File.expand_path file
|
|
end
|
|
end
|
|
|
|
def test_methods
|
|
methods_map = []
|
|
suites = Minitest::Runnable.runnables.shuffle
|
|
suites.each do |suite_class|
|
|
suite_class.runnable_methods.each do |test_method|
|
|
method = suite_class.instance_method(test_method)
|
|
location = method.source_location
|
|
start_line = location.last
|
|
end_line = method.source.split("\n").size + start_line - 1
|
|
methods_map << [File.expand_path(location.first), test_method, start_line, end_line]
|
|
end
|
|
end
|
|
methods_map
|
|
end
|
|
end
|
|
end
|