require 'parallel_split_test' require 'parallel_split_test/output_recorder' require 'parallel' require 'rspec/core' require 'parallel_split_test/core_ext/rspec_world' module ParallelSplitTest class CommandLine < RSpec::Core::Runner def initialize(args) @args = args super end def run(err, out) no_summary = @args.delete('--no-summary') no_merge = @args.delete('--no-merge') @options = RSpec::Core::ConfigurationOptions.new(@args) processes = ParallelSplitTest.choose_number_of_processes out.puts "Running examples in #{processes} processes" results = Parallel.in_processes(processes) do |process_number| ParallelSplitTest.example_counter = 0 ParallelSplitTest.process_number = process_number set_test_env_number(process_number) modify_out_file_in_args(process_number) if out_file out = OutputRecorder.new(out) [super(err, out), out.recorded] end combine_out_files if out_file unless no_merge reprint_result_lines(out, results.map(&:last)) unless no_summary results.map(&:first).max # combine exit status end private # modify + reparse args to unify output def modify_out_file_in_args(process_number) @args[out_file_position] = "#{out_file_parent_dir}/#{out_file_basename}.#{process_number}#{File.extname(out_file)}" @options = RSpec::Core::ConfigurationOptions.new(@args) end def set_test_env_number(process_number) ENV['TEST_ENV_NUMBER'] = (process_number == 0 ? '' : (process_number + 1).to_s) end def out_file @out_file ||= @args[out_file_position] if out_file_position end def out_file_parent_dir @out_file_parent_dir ||= File.expand_path("#{out_file}/../.") end def out_file_basename @out_file_basename ||= File.basename(out_file, File.extname(out_file)) end def out_file_position @out_file_position ||= begin if out_position = @args.index { |i| ["-o", "--out"].include?(i) } out_position + 1 end end end def combine_out_files File.open(out_file, "w") do |f| Dir["#{out_file_parent_dir}/#{out_file_basename}.*#{File.extname(out_file)}"].each do |file| f.write File.read(file) File.delete(file) end end end def reprint_result_lines(out, printed_outputs) out.puts out.puts "Summary:" out.puts printed_outputs.map{|o| o[/.*\d+ failure.*/] }.join("\n") end end end