Class: Flatware::RSpec::JobBuilder

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/flatware/rspec/job_builder.rb

Overview

groups spec files into one job per worker. reads from persisted example statuses, if available, and attempts to ballence the jobs accordingly.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args, workers:) ⇒ JobBuilder

Returns a new instance of JobBuilder.



17
18
19
20
21
22
23
24
25
# File 'lib/flatware/rspec/job_builder.rb', line 17

def initialize(args, workers:)
  @args = args
  @workers = workers

  @configuration = ::RSpec.configuration
  configuration.define_singleton_method(:command) { 'rspec' }

  ::RSpec::Core::ConfigurationOptions.new(args).configure(@configuration)
end

Instance Attribute Details

#argsObject (readonly)

Returns the value of attribute args.



10
11
12
# File 'lib/flatware/rspec/job_builder.rb', line 10

def args
  @args
end

#configurationObject (readonly)

Returns the value of attribute configuration.



10
11
12
# File 'lib/flatware/rspec/job_builder.rb', line 10

def configuration
  @configuration
end

#workersObject (readonly)

Returns the value of attribute workers.



10
11
12
# File 'lib/flatware/rspec/job_builder.rb', line 10

def workers
  @workers
end

Instance Method Details

#jobsObject



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/flatware/rspec/job_builder.rb', line 27

def jobs
  bucket_count = [files_to_run.size, workers].min

  seconds_per_file = load_persisted_example_statuses
                     .select(&passing)
                     .map(&parse_example)
                     .reduce({}, &sum_by_example_file)

  timed_files, untimed_files = files_to_run
                               .map(&method(:normalize_path))
                               .reduce(
                                 [[], []]
                               ) do |(timed, untimed), file|
    if (time = seconds_per_file[file])
      [timed.append([file, time]), untimed]
    else
      [timed, untimed.append(file)]
    end
  end

  balance_by(bucket_count, timed_files, &:last)
    .map { |bucket| bucket.map(&:first) }
    .zip(
      round_robin(bucket_count, untimed_files)
    ).map(&:flatten)
    .map do |files|
    Job.new(files, args)
  end
end