diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index 36d80ac..52cc588 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -20,7 +20,12 @@ jobs: strategy: matrix: rspec-minor-versions: [6, 7, 8, 9, 10, 11, 12, 13] - ruby-versions: ["3.1", "3.2", "3.3", "3.4"] + ruby-versions: ["3.1", "3.2", "3.3", "3.4", "4.0"] + exclude: + - ruby-versions: 4.0 + rspec-minor-versions: 6 + - ruby-versions: 4.0 + rspec-minor-versions: 7 env: BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rspec_3.${{ matrix.rspec-minor-versions }}.gemfile diff --git a/.rubocop.yml b/.rubocop.yml index eff9a44..09f78a6 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -25,6 +25,9 @@ Style/FrozenStringLiteralComment: Naming/FileName: Exclude: - lib/flatware-*.rb +Naming/PredicateMethod: + Exclude: + - lib/flatware/sink.rb Style/Documentation: Enabled: false Metrics/BlockLength: diff --git a/Gemfile b/Gemfile index aec2f52..2824f9d 100644 --- a/Gemfile +++ b/Gemfile @@ -5,7 +5,7 @@ gemspec name: 'flatware-cucumber' group :development do gem 'appraisal' - gem 'aruba', '~> 0.14' + gem 'aruba' gem 'logger' gem 'ostruct' gem 'pry' diff --git a/Rakefile b/Rakefile index cbf8929..d82c101 100644 --- a/Rakefile +++ b/Rakefile @@ -19,7 +19,7 @@ end RuboCop::RakeTask.new :lint Cucumber::Rake::Task.new :cucumber do |task| - task.cucumber_opts = ['--tags', 'not @wip'] + task.cucumber_opts = ['--tags', 'not @wip', '--publish-quiet'] task.cucumber_opts += %w[-f progress] unless ENV['TRAVIS'] task.fork = false end diff --git a/features/step_definitions/flatware_steps.rb b/features/step_definitions/flatware_steps.rb index 69711f1..5edd39d 100644 --- a/features/step_definitions/flatware_steps.rb +++ b/features/step_definitions/flatware_steps.rb @@ -77,7 +77,7 @@ def duration(&block) command = ['flatware', args, '-w', max_workers].flatten.compact.join(' ') @duration = duration do - run_command_and_stop(command, fail_on_exit: false) + run_command_and_stop(command, fail_on_error: false) end end @@ -113,7 +113,7 @@ def duration(&block) Then 'the output contains a backtrace' do trace = <<-TXT.gsub(/^ +/, '') - features/flunk.feature:4:in `Given flunk' + features/flunk.feature:4:in `flunk' TXT expect(flatware_process).to have_output Regexp.new Regexp.escape trace diff --git a/flatware-cucumber.gemspec b/flatware-cucumber.gemspec index 47b6694..6f81999 100644 --- a/flatware-cucumber.gemspec +++ b/flatware-cucumber.gemspec @@ -20,9 +20,10 @@ Gem::Specification.new do |s| ) s.homepage = 'http://github.com/briandunn/flatware' s.licenses = ['MIT'] - s.required_ruby_version = ['>= 2.6', '< 3.5'] + s.required_ruby_version = ['>= 2.6', '< 4.1'] s.require_paths = ['lib'] - s.add_dependency %(cucumber), '~> 3.0' + s.add_dependency %(cucumber), '>= 10.0' s.add_dependency %(flatware), Flatware::VERSION + s.add_dependency %(ostruct) # s.metadata['rubygems_mfa_required'] = 'true' end diff --git a/flatware-rspec.gemspec b/flatware-rspec.gemspec index d534c32..db5a2de 100644 --- a/flatware-rspec.gemspec +++ b/flatware-rspec.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| ) s.homepage = 'http://github.com/briandunn/flatware' s.licenses = ['MIT'] - s.required_ruby_version = ['>= 2.6', '< 3.5'] + s.required_ruby_version = ['>= 2.6', '< 4.1'] s.require_paths = ['lib'] s.add_dependency %(flatware), Flatware::VERSION s.add_dependency %(rspec), '>= 3.6' diff --git a/flatware.gemspec b/flatware.gemspec index 20121be..72eec68 100644 --- a/flatware.gemspec +++ b/flatware.gemspec @@ -26,10 +26,12 @@ Gem::Specification.new do |s| s.homepage = 'http://github.com/briandunn/flatware' s.licenses = ['MIT'] - s.required_ruby_version = ['>= 2.6', '< 3.5'] + s.required_ruby_version = ['>= 2.6', '< 4.1'] s.require_paths = ['lib'] s.executables = ['flatware'] + s.add_dependency %(benchmark) s.add_dependency %(drb) + s.add_dependency %(logger) s.add_dependency %(thor), '< 2.0' # s.metadata['rubygems_mfa_required'] = 'true' end diff --git a/gemfiles/rspec_3.10.gemfile b/gemfiles/rspec_3.10.gemfile index 0b27a9e..186cb79 100644 --- a/gemfiles/rspec_3.10.gemfile +++ b/gemfiles/rspec_3.10.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.10.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/gemfiles/rspec_3.11.gemfile b/gemfiles/rspec_3.11.gemfile index 05e24b2..9f3c0e0 100644 --- a/gemfiles/rspec_3.11.gemfile +++ b/gemfiles/rspec_3.11.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.11.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/gemfiles/rspec_3.12.gemfile b/gemfiles/rspec_3.12.gemfile index 6264d6f..ed81aea 100644 --- a/gemfiles/rspec_3.12.gemfile +++ b/gemfiles/rspec_3.12.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.12.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/gemfiles/rspec_3.13.gemfile b/gemfiles/rspec_3.13.gemfile index 9a4a683..e8648d4 100644 --- a/gemfiles/rspec_3.13.gemfile +++ b/gemfiles/rspec_3.13.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.13.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/gemfiles/rspec_3.6.gemfile b/gemfiles/rspec_3.6.gemfile index 7283dd8..ea2e2bf 100644 --- a/gemfiles/rspec_3.6.gemfile +++ b/gemfiles/rspec_3.6.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.6.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/gemfiles/rspec_3.7.gemfile b/gemfiles/rspec_3.7.gemfile index 9fcc482..411db5e 100644 --- a/gemfiles/rspec_3.7.gemfile +++ b/gemfiles/rspec_3.7.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.7.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/gemfiles/rspec_3.8.gemfile b/gemfiles/rspec_3.8.gemfile index a55a9bf..c9f5f97 100644 --- a/gemfiles/rspec_3.8.gemfile +++ b/gemfiles/rspec_3.8.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.8.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/gemfiles/rspec_3.9.gemfile b/gemfiles/rspec_3.9.gemfile index 559951b..d60226a 100644 --- a/gemfiles/rspec_3.9.gemfile +++ b/gemfiles/rspec_3.9.gemfile @@ -6,7 +6,7 @@ gem "rspec", "3.9.0" group :development do gem "appraisal" - gem "aruba", "~> 0.14" + gem "aruba" gem "pry" gem "racc" gem "rake" diff --git a/lib/flatware/cucumber.rb b/lib/flatware/cucumber.rb index e821905..18c800b 100644 --- a/lib/flatware/cucumber.rb +++ b/lib/flatware/cucumber.rb @@ -35,12 +35,23 @@ def feature_files def configure(args, out_stream = $stdout, error_stream = $stderr) raw_args = args.dup cli_config = ::Cucumber::Cli::Configuration.new(out_stream, error_stream) - cli_config.parse! args + %w[--format Flatware::Cucumber::Formatter] + cli_config.parse! args + %w[--format Flatware::Cucumber::Formatter --publish-quiet] cucumber_config = ::Cucumber::Configuration.new cli_config Config.new cucumber_config, raw_args end def run(feature_files, options) + # TODO: This will eventually stop working. This ensures step definitions are evaluated on each execution + # by using `load` instead of once per Ruby runtime using `require`. + # + # If we use the same runtime object and reconfigure it on each execution here, the wrong feature files will + # be evaluated since their memoized. Unfortunately, this means there's no straightforward way to both ensure + # step definitions are available on every runtime *and* also ensure Cucumber isn't memoizing the feature files + # to run. + # + # For now, the legacy autoloader is the only option to keep everything working properly. + ::Cucumber.use_legacy_autoloader ||= true + runtime(Array(feature_files) + options).run! end diff --git a/lib/flatware/cucumber/formatters/console/summary.rb b/lib/flatware/cucumber/formatters/console/summary.rb index 57ea023..bc5c571 100644 --- a/lib/flatware/cucumber/formatters/console/summary.rb +++ b/lib/flatware/cucumber/formatters/console/summary.rb @@ -7,6 +7,7 @@ module Formatters class Console class Summary include ::Cucumber::Formatter::Console + attr_reader :io, :steps, :scenarios def initialize(steps, scenarios = [], io = StringIO.new) diff --git a/lib/flatware/pid.rb b/lib/flatware/pid.rb index 7914963..d478380 100644 --- a/lib/flatware/pid.rb +++ b/lib/flatware/pid.rb @@ -27,9 +27,9 @@ def self.ps .popen(['ps', *args]) .readlines .map do |row| - fields = row.strip.split(/\s+/, 4) - new(*fields.take(3).map(&:to_i), fields.last) - end + fields = row.strip.split(/\s+/, 4) + new(*fields.take(3).map(&:to_i), fields.last) + end end def pids_of_group(group_pid) diff --git a/lib/flatware/rspec/formatters/console.rb b/lib/flatware/rspec/formatters/console.rb index 5429a77..154b587 100644 --- a/lib/flatware/rspec/formatters/console.rb +++ b/lib/flatware/rspec/formatters/console.rb @@ -63,12 +63,12 @@ def spec_list(remaining) remaining .flat_map(&:id).sort.each_with_index .map do |example, index| - format( - '%4d) %s', - index: index.next, - example: example - ) - end.join("\n") + format( + '%4d) %s', + index: index.next, + example: example + ) + end.join("\n") end def colorizer diff --git a/lib/flatware/rspec/job_builder.rb b/lib/flatware/rspec/job_builder.rb index 2691aef..5d3c110 100644 --- a/lib/flatware/rspec/job_builder.rb +++ b/lib/flatware/rspec/job_builder.rb @@ -9,6 +9,7 @@ module RSpec # and attempts to ballence the jobs accordingly. class JobBuilder extend Forwardable + attr_reader :args, :workers, :configuration def_delegators( @@ -54,12 +55,12 @@ def timed_and_untimed_files(seconds_per_file) files_to_run .map(&method(:normalize_path)) .reduce([[], []]) do |(timed, untimed), file| - if (time = seconds_per_file[file]) - [timed + [[file, time]], untimed] - else - [timed, untimed + [file]] + if (time = seconds_per_file[file]) + [timed + [[file, time]], untimed] + else + [timed, untimed + [file]] + end end - end end def normalize_path(path) @@ -73,14 +74,15 @@ def load_persisted_example_statuses end def sum_seconds(statuses) - statuses.select(&passing) - .map { |example| parse_example(**example) } - .reduce({}) do |times, example| - times.merge( - example.fetch(:file_name) => example.fetch(:seconds) - ) do |_, old = 0, new| - old + new - end + statuses + .select(&passing) + .map { |example| parse_example(**example) } + .reduce({}) do |times, example| + times.merge( + example.fetch(:file_name) => example.fetch(:seconds) + ) do |_, old = 0, new| + old + new + end end end @@ -109,10 +111,10 @@ def balance_by(count, items, &block) .sort_by(&block) .reverse .each do |entry| - groups.min_by do |group| - group.map(&block).reduce(:+) || 0 - end.push(entry) - end + groups.min_by do |group| + group.map(&block).reduce(:+) || 0 + end.push(entry) + end end end end diff --git a/lib/flatware/sink.rb b/lib/flatware/sink.rb index 2788487..2227ac8 100644 --- a/lib/flatware/sink.rb +++ b/lib/flatware/sink.rb @@ -117,8 +117,8 @@ def group_jobs(jobs, worker_count) .with_index { |_, i| i % worker_count } .values .map do |job_group| - Job.new(job_group.map(&:id).flatten, jobs.first.args) - end + Job.new(job_group.map(&:id).flatten, jobs.first.args) + end end end end diff --git a/spec/flatware/sink/signal_spec.rb b/spec/flatware/sink/signal_spec.rb index bc62baa..2d8e21d 100644 --- a/spec/flatware/sink/signal_spec.rb +++ b/spec/flatware/sink/signal_spec.rb @@ -53,7 +53,7 @@ def send_signal(signal) end it 'tells the formatter to emit the signal message' do - expect(messages).to match([include(expected_message), 'done.']) + expect(messages).to match([match(expected_message), 'done.']) end it 'calls on_interrupt' do