Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,15 @@ jobs:
- { name: cucumber1_3, bats: test/cucumber.bats }
- { name: cucumber2_4, bats: test/cucumber.bats }
- { name: minitest5, bats: test/minitest5.bats }
- { name: minitest6, bats: test/minitest6.bats }
- { name: rspec3, bats: test/rspec3.bats }
- { name: rspec4, bats: test/rspec4.bats }
- { name: testunit, bats: test/testunit.bats }
- { name: turnip, bats: test/turnip.bats }
exclude:
# Minitest 6 requires Ruby 3.2+
- ruby: '2.7'
entry: { name: minitest6, bats: test/minitest6.bats }

steps:
- name: checkout
Expand Down
5 changes: 5 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ appraise 'minitest5' do
gem 'minitest', '5.10.0'
end

appraise 'minitest6' do
gem 'rake'
gem 'minitest', '~> 6.0'
end

appraise 'rspec3' do
gem 'rspec', '~> 3.12'
end
Expand Down
10 changes: 10 additions & 0 deletions gemfiles/minitest6.gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

# This file was generated by Appraisal

source 'https://rubygems.org'

gem 'minitest', '~> 6.0'
gem 'rake'

gemspec path: '../'
9 changes: 7 additions & 2 deletions lib/test_queue/runner/minitest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,14 @@

require 'minitest'

raise 'requires Minitest version 5' unless Minitest::VERSION.to_i == 5
minitest_version = Minitest::VERSION.to_i
raise 'requires Minitest version 5 or 6' unless minitest_version == 5 || minitest_version == 6

require_relative '../runner/minitest5'
if minitest_version == 5
require_relative '../runner/minitest5'
else
require_relative '../runner/minitest6'
end
Comment on lines +5 to +12
Copy link
Collaborator

@koic koic Dec 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you update it using case?

case Minitest::VERSION.to_i
when 5
  require_relative '../runner/minitest5'
when 6
  require_relative '../runner/minitest6'
else
  raise 'requires Minitest version 5 or 6'
end


module TestQueue
class Runner
Expand Down
107 changes: 107 additions & 0 deletions lib/test_queue/runner/minitest6.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# frozen_string_literal: true

require_relative '../runner'

module Minitest
def self.run_all_suites(reporter, options)
suites = Runnable.runnables
suites.map { |suite| suite.run_suite reporter, options }
end

class Runnable
def failure_count
failures.length
end
end

class Test
def self.runnables=(runnables)
@@runnables = runnables
end

# Synchronize all tests, even serial ones.
#
# Minitest runs serial tests before parallel ones to ensure the
# unsynchronized serial tests don't overlap the parallel tests. But since
# the test-queue master hands out tests without actually loading their
# code, there's no way to know which are parallel and which are serial.
# Synchronizing serial tests does add some overhead, but hopefully this is
# outweighed by the speed benefits of using test-queue.
def _synchronize
Test.io_lock.synchronize { yield }
end
end

class ProgressReporter
# Override original method to make test-queue specific output
def record(result)
io.print ' '
io.print result.klass
io.print ': '
io.print result.result_code
io.puts(' <%.3f>' % result.time)
end
end

begin
require 'minitest/minitest_reporter_plugin'

class << self
private

def total_count(_options)
0
end
end
rescue LoadError
# noop
end
end

module TestQueue
class Runner
class Minitest < Runner
def initialize
@options = ::Minitest.process_args ARGV

if ::Minitest.respond_to?(:seed)
::Minitest.seed = @options[:seed]
srand ::Minitest.seed
end

if ::Minitest::Test.runnables.any? { |r| r.runnable_methods.any? }
raise 'Do not `require` test files. Pass them via ARGV instead and they will be required as needed.'
end

super(TestFramework::Minitest.new)
end

def start_master
puts "Run options: #{@options[:args]}\n\n"

super
end

def run_worker(iterator)
::Minitest::Test.runnables = iterator
::Minitest.run ? 0 : 1
end
end
end

class TestFramework
class Minitest < TestFramework
def all_suite_files
ARGV
end

def suites_from_file(path)
::Minitest::Test.reset
require File.absolute_path(path)
::Minitest::Test.runnables
.reject { |s| s.runnable_methods.empty? }
.map { |s| [s.name, s] }
end
end
end
end
39 changes: 39 additions & 0 deletions test/examples/example_minispec6.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# frozen_string_literal: true

require 'minitest/spec'

class Meme
def i_can_has_cheezburger?
'OHAI!'
end

def will_it_blend?
'YES!'
end
end

describe Meme do
before do
@meme = Meme.new
end

describe 'when asked about cheeseburgers' do
it 'must respond positively' do
sleep 0.1
_(@meme.i_can_has_cheezburger?).must_equal 'OHAI!'
end
end

describe 'when asked about blending possibilities' do
it "won't say no" do
sleep 0.1
_(@meme.will_it_blend?).wont_match(/^no/i)
end

if ENV['FAIL']
it 'fails' do
_(@meme.will_it_blend?).must_equal 'NO!'
end
end
end
end
35 changes: 35 additions & 0 deletions test/examples/example_minitest6.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

require 'minitest/autorun'

class MinitestEqual < Minitest::Test
def test_equal
assert_equal 1, 1
end
end

30.times do |i|
Object.const_set("MinitestSleep#{i}", Class.new(Minitest::Test) do
define_method(:test_sleep) do
start = Time.now
sleep(0.25)
assert_in_delta Time.now - start, 0.25, 0.02
end
end)
end

if ENV['FAIL']
class MinitestFailure < Minitest::Test
def test_fail
assert_equal 0, 1
end
end
end

if ENV['KILL']
class MinitestKilledFailure < Minitest::Test
def test_kill
Process.kill(9, $$)
end
end
end
Loading
Loading