lib/parallel_tests/cli.rb in parallel_tests-1.3.9 vs lib/parallel_tests/cli.rb in parallel_tests-1.5.0
- old
+ new
@@ -1,8 +1,9 @@
require 'optparse'
require 'tempfile'
require 'parallel_tests'
+require 'shellwords'
module ParallelTests
class CLI
def run(argv)
options = parse_options!(argv)
@@ -104,13 +105,16 @@
options = {}
OptionParser.new do |opts|
opts.banner = <<-BANNER.gsub(/^ /, '')
Run all tests in parallel, giving each process ENV['TEST_ENV_NUMBER'] ('', '2', '3', ...)
- [optional] Only run selected files & folders:
- parallel_test test/bar test/baz/xxx_text.rb
+ [optional] Only selected files & folders:
+ parallel_test test/bar test/baz/xxx_text.rb
+ [optional] Pass test-options and files via `--`:
+ parallel_test -- -t acceptance -f progress -- spec/foo_spec.rb spec/acceptance
+
Options are:
BANNER
opts.on("-n [PROCESSES]", Integer, "How many processes to use, default: available CPUs") { |n| options[:count] = n }
opts.on("-p", "--pattern [PATTERN]", "run tests matching this pattern") { |pattern| options[:pattern] = /#{pattern}/ }
opts.on("--group-by [TYPE]", <<-TEXT.gsub(/^ /, '')
@@ -138,12 +142,12 @@
options[:isolate] = true
end
opts.on("--only-group INT[, INT]", Array) { |groups| options[:only_group] = groups.map(&:to_i) }
- opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUM']") { |path| options[:execute] = path }
- opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg }
+ opts.on("-e", "--exec [COMMAND]", "execute this code parallel and with ENV['TEST_ENV_NUMBER']") { |path| options[:execute] = path }
+ opts.on("-o", "--test-options '[OPTIONS]'", "execute test commands with those options") { |arg| options[:test_options] = arg.lstrip }
opts.on("-t", "--type [TYPE]", "test(default) / rspec / cucumber / spinach") do |type|
begin
@runner = load_runner(type)
rescue NameError, LoadError => e
puts "Runner for `#{type}` type has not been found! (#{e})"
@@ -165,22 +169,45 @@
if options[:count] == 0
options.delete(:count)
options[:non_parallel] = true
end
- abort "Pass files or folders to run" if argv.empty? && !options[:execute]
+ files, remaining = extract_file_paths(argv)
+ unless options[:execute]
+ abort "Pass files or folders to run" unless files.any?
+ options[:files] = files
+ end
- options[:files] = argv
+ append_test_options(options, remaining)
options[:group_by] ||= :filesize if options[:only_group]
raise "--group-by found and --single-process are not supported" if options[:group_by] == :found and options[:single_process]
allowed = [:filesize, :runtime, :found]
if !allowed.include?(options[:group_by]) && options[:only_group]
raise "--group-by #{allowed.join(" or ")} is required for --only-group"
end
options
+ end
+
+ def extract_file_paths(argv)
+ dash_index = argv.rindex("--")
+ file_args_at = (dash_index || -1) + 1
+ [argv[file_args_at..-1], argv[0...(dash_index || 0)]]
+ end
+
+ def extract_test_options(argv)
+ dash_index = argv.index("--") || -1
+ argv[dash_index+1..-1]
+ end
+
+ def append_test_options(options, argv)
+ new_opts = extract_test_options(argv)
+ return if new_opts.empty?
+
+ prev_and_new = [options[:test_options], new_opts.shelljoin]
+ options[:test_options] = prev_and_new.compact.join(' ')
end
def load_runner(type)
require "parallel_tests/#{type}/runner"
runner_classname = type.split("_").map(&:capitalize).join.sub("Rspec", "RSpec")