minitest-rerun-failed 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +24 -15
- data/.gitignore +3 -0
- data/.rubocop.yml +27 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile +6 -3
- data/README.md +20 -10
- data/bin/rerun_failed_tests +3 -24
- data/bin/rubocop +5 -3
- data/lib/minitest_rerun_failed/failed_tests_reporter.rb +85 -54
- data/lib/minitest_rerun_failed/runner.rb +90 -0
- data/lib/minitest_rerun_failed/version.rb +1 -1
- data/lib/minitest_rerun_failed.rb +1 -0
- data/minitest_rerun_failed.gemspec +5 -5
- metadata +4 -4
- data/Gemfile.lock +0 -95
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 81e024c6fb3074145394e2117d57e3de293348c184b804605bfa58244c591030
|
|
4
|
+
data.tar.gz: d42f36b141436a907d7008116b858092673560966e4ed390622f8b936ecebdbb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: af18e927a16aaf4308f1bc2facb1e9f5c5e573638346f65dfb34e0fb40965952f9ac861999a5bedd7e59167818167e7ea240b8f83a40205ed8d9ba25fc9660b6
|
|
7
|
+
data.tar.gz: 0ea2ef65fde08be870b27f6157d62342bf2b11a8f59513a9cfdc8dcb096876de8ea6efd43d4ce5a5c6930401c69c0477fc65a632c179ba5ee2ddfba18921f696
|
data/.github/workflows/main.yml
CHANGED
|
@@ -1,28 +1,37 @@
|
|
|
1
1
|
name: Tests
|
|
2
2
|
|
|
3
|
-
on: [push,pull_request]
|
|
3
|
+
on: [push, pull_request]
|
|
4
4
|
|
|
5
5
|
jobs:
|
|
6
|
-
|
|
6
|
+
test:
|
|
7
7
|
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
fail-fast: false
|
|
10
|
+
matrix:
|
|
11
|
+
ruby:
|
|
12
|
+
- "2.7"
|
|
13
|
+
- "3.0"
|
|
14
|
+
- "3.3"
|
|
15
|
+
- "3.4"
|
|
16
|
+
- "4.0"
|
|
8
17
|
steps:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- name: Set up Ruby
|
|
20
|
+
uses: ruby/setup-ruby@v1
|
|
21
|
+
with:
|
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
|
23
|
+
bundler-cache: true
|
|
24
|
+
- name: Run rake test
|
|
25
|
+
run: bundle exec rake test
|
|
17
26
|
|
|
18
|
-
|
|
27
|
+
rubocop:
|
|
19
28
|
runs-on: ubuntu-latest
|
|
20
29
|
steps:
|
|
21
|
-
- uses: actions/checkout@
|
|
30
|
+
- uses: actions/checkout@v4
|
|
22
31
|
- name: Set up Ruby
|
|
23
32
|
uses: ruby/setup-ruby@v1
|
|
24
33
|
with:
|
|
25
|
-
ruby-version:
|
|
34
|
+
ruby-version: "3.3"
|
|
26
35
|
bundler-cache: true
|
|
27
|
-
- name: Run
|
|
28
|
-
run: bundle exec
|
|
36
|
+
- name: Run RuboCop
|
|
37
|
+
run: bundle exec rubocop --no-server
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -1,5 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
plugins:
|
|
2
|
+
- rubocop-minitest
|
|
3
|
+
- rubocop-rake
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
AllCops:
|
|
6
|
+
NewCops: enable
|
|
7
|
+
TargetRubyVersion: 2.7
|
|
8
|
+
|
|
9
|
+
Gemspec/RequireMFA:
|
|
10
|
+
Enabled: false
|
|
11
|
+
|
|
12
|
+
Metrics/AbcSize:
|
|
13
|
+
Max: 25
|
|
14
|
+
|
|
15
|
+
Metrics/ClassLength:
|
|
16
|
+
Max: 200
|
|
17
|
+
|
|
18
|
+
Metrics/MethodLength:
|
|
19
|
+
Max: 25
|
|
20
|
+
|
|
21
|
+
Minitest/AssertWithExpectedArgument:
|
|
22
|
+
Enabled: false
|
|
23
|
+
|
|
24
|
+
Style/Documentation:
|
|
25
|
+
Enabled: false
|
|
26
|
+
|
|
27
|
+
Style/StringLiterals:
|
|
28
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
## [0.3.0] - 2026-06-08
|
|
2
|
+
- Fixed: Preserve Minitest failure status when `FailedTestsReporter` is used alone.
|
|
3
|
+
- Fixed: Honor `file_output: false`.
|
|
4
|
+
- Fixed: Use the configured report directory when rerunning failed tests.
|
|
5
|
+
- Fixed: Handle rerun paths safely, support non-Rails test commands, and exit with the child test process status.
|
|
6
|
+
- Fixed: Use Minitest source locations for failure reports so Ruby test files beyond `_test.rb` and `_spec.rb` can be rerun.
|
|
7
|
+
- Added: `MinitestRerunFailed::Runner` for testable rerun command handling.
|
|
8
|
+
- Changed: Modernized CI and RuboCop tooling.
|
|
9
|
+
- Changed: Ignore local `Gemfile.lock` and `mise.toml` files for gem development.
|
|
10
|
+
|
|
1
11
|
## [0.2.3] - 2024-05-26
|
|
2
12
|
- Added: Rerun tests executable
|
|
3
13
|
|
data/Gemfile
CHANGED
|
@@ -8,6 +8,9 @@ gemspec
|
|
|
8
8
|
gem "minitest"
|
|
9
9
|
gem "minitest-reporters"
|
|
10
10
|
gem "rake"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
gem "rubocop
|
|
11
|
+
|
|
12
|
+
group :development do
|
|
13
|
+
gem "rubocop", require: false
|
|
14
|
+
gem "rubocop-minitest", require: false
|
|
15
|
+
gem "rubocop-rake", require: false
|
|
16
|
+
end
|
data/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|

|
|
4
4
|
[](https://badge.fury.io/rb/minitest-rerun-failed)
|
|
5
5
|
|
|
6
|
-
Easy rerun of failed tests with minitest. Prints a list of failed tests and seed at the end of the test run to console and file.
|
|
6
|
+
Easy rerun of failed tests with minitest. Prints a list of failed tests and seed at the end of the test run to console and file. Re-run the failed tests with `bin/rerun_failed_tests`.
|
|
7
7
|
|
|
8
8
|

|
|
9
9
|
|
|
@@ -11,21 +11,15 @@ Easy rerun of failed tests with minitest. Prints a list of failed tests and seed
|
|
|
11
11
|
- Outputs all failed tests in short summary at end of test run.
|
|
12
12
|
- To console and / or to file
|
|
13
13
|
- Optionally includes line numbers
|
|
14
|
-
- Lists seed
|
|
15
|
-
- Executable for running only failed tests
|
|
16
|
-
- Until done, use something like
|
|
17
|
-
- `ruby $(cat .minitest_failed_tests.txt)`
|
|
18
|
-
- `bundle exec rails test $(cat .minitest_failed_tests.txt)`
|
|
14
|
+
- Lists seed for re-running with same seed.
|
|
15
|
+
- Executable for re-running only failed tests
|
|
19
16
|
|
|
20
17
|
## Installation
|
|
21
18
|
|
|
22
19
|
```
|
|
23
20
|
bundle add "minitest-rerun-failed" --group test
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
If you want to install the executable to `bin/rerun_failed_tests`:
|
|
27
21
|
|
|
28
|
-
|
|
22
|
+
# installs executable bin/rerun_failed_tests
|
|
29
23
|
bundle binstubs minitest-rerun-failed
|
|
30
24
|
```
|
|
31
25
|
|
|
@@ -40,6 +34,22 @@ Minitest::Reporters.use! [
|
|
|
40
34
|
]
|
|
41
35
|
```
|
|
42
36
|
|
|
37
|
+
Now failed tests and seed will be printed at the end of the test report.
|
|
38
|
+
|
|
39
|
+
If you have installed the binstub, you can rerun the failed tests with
|
|
40
|
+
```
|
|
41
|
+
bin/rerun_failed_tests
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If you have not installed the binstub, you can rerun the failed tests with something like:
|
|
45
|
+
```
|
|
46
|
+
# Ruby, when using include_line_numbers: false:
|
|
47
|
+
bundle exec ruby $(cat .minitest_failed_tests.txt)
|
|
48
|
+
|
|
49
|
+
# Rails:
|
|
50
|
+
bundle exec rails test $(cat .minitest_failed_tests.txt)
|
|
51
|
+
```
|
|
52
|
+
|
|
43
53
|
### Options
|
|
44
54
|
- include_line_numbers: Include line numbers in outputs. Defaults to true
|
|
45
55
|
- verbose: Output to stdout. Defaults to true
|
data/bin/rerun_failed_tests
CHANGED
|
@@ -1,30 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
2
3
|
|
|
3
4
|
# See also:
|
|
4
5
|
# https://guides.rubygems.org/make-your-own-gem/#adding-an-executable
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
dirpath = ENV["MINITEST_FAILED_TESTS_REPORT_DIR"] || "./"
|
|
8
|
-
filepath = File.join(dirpath, filename)
|
|
7
|
+
require "minitest_rerun_failed/runner"
|
|
9
8
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
if !File.exist?(filename)
|
|
13
|
-
puts "No #{filename} found"
|
|
14
|
-
elsif File.empty?(filename)
|
|
15
|
-
puts "No failed tests in #{filename}"
|
|
16
|
-
else
|
|
17
|
-
failed_tests += File.readlines(filepath).map{ _1.strip }
|
|
18
|
-
rails_installed = Gem.loaded_specs.has_key?("rails")
|
|
19
|
-
if rails_installed
|
|
20
|
-
cmd = "bundle exec rails test #{failed_tests.join(" ")}"
|
|
21
|
-
else
|
|
22
|
-
cmd = "bundle exec ruby #{failed_tests.join(" ")}"
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
IO.popen(cmd) do |io|
|
|
26
|
-
io.each do |line|
|
|
27
|
-
puts line
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
9
|
+
exit MinitestRerunFailed::Runner.new.call
|
data/bin/rubocop
CHANGED
|
@@ -9,10 +9,12 @@
|
|
|
9
9
|
#
|
|
10
10
|
|
|
11
11
|
require "pathname"
|
|
12
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
|
|
13
|
-
|
|
12
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path(
|
|
13
|
+
"../../Gemfile",
|
|
14
|
+
Pathname.new(__FILE__).realpath
|
|
15
|
+
)
|
|
14
16
|
|
|
15
|
-
bundle_binstub = File.expand_path("
|
|
17
|
+
bundle_binstub = File.expand_path("bundle", __dir__)
|
|
16
18
|
|
|
17
19
|
if File.file?(bundle_binstub)
|
|
18
20
|
if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/
|
|
@@ -10,13 +10,16 @@ module Minitest
|
|
|
10
10
|
#
|
|
11
11
|
# Example:
|
|
12
12
|
# In test_helper.rb or similar:
|
|
13
|
-
# Minitest::Reporters.use! [
|
|
13
|
+
# Minitest::Reporters.use! [
|
|
14
|
+
# Minitest::Reporters::ProgressReporter.new,
|
|
15
|
+
# Minitest::Reporters::FailedTestsReporter.new(verbose: true, include_line_numbers: true)
|
|
16
|
+
# ]
|
|
14
17
|
#
|
|
15
|
-
# Now after a failed test run, rerun failed tests only with: `
|
|
18
|
+
# Now after a failed test run, rerun failed tests only with: `bin/rerun_failed_tests`
|
|
16
19
|
#
|
|
17
20
|
class FailedTestsReporter < Minitest::Reporters::BaseReporter
|
|
18
21
|
def initialize(options = {})
|
|
19
|
-
super
|
|
22
|
+
super
|
|
20
23
|
@options = options
|
|
21
24
|
|
|
22
25
|
# Include line numbers? (failed_test.rb:42 or just failed_test.rb)
|
|
@@ -27,110 +30,138 @@ module Minitest
|
|
|
27
30
|
@file_output = options.fetch(:file_output, true)
|
|
28
31
|
# What path to file?
|
|
29
32
|
@output_path = options.fetch(:output_path, ".")
|
|
30
|
-
FileUtils.mkdir_p(@output_path) if @output_path
|
|
33
|
+
FileUtils.mkdir_p(@output_path) if @file_output && @output_path
|
|
31
34
|
|
|
32
35
|
@output_file_path = File.join(@output_path, ".minitest_failed_tests.txt")
|
|
33
36
|
end
|
|
34
37
|
|
|
35
|
-
def record(test)
|
|
36
|
-
tests << test
|
|
37
|
-
end
|
|
38
|
-
|
|
39
38
|
def report
|
|
40
39
|
super
|
|
41
40
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
curdir = FileUtils.pwd
|
|
42
|
+
failures = failed_results
|
|
43
|
+
output_paths = failed_test_locations(failures, curdir).map(&:strip).uniq
|
|
45
44
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
output_results(failures.count, output_paths)
|
|
46
|
+
output_missing_locations(failures.count) if failures.any? && output_paths.empty?
|
|
47
|
+
write_file_output(output_paths) if @file_output
|
|
48
|
+
end
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
# p '============================================='
|
|
52
|
-
# p "Failure:\n#{test.class}##{test.name} [#{test.failure.location}]\n#{test.failure.class}: #{test.failure.message}"
|
|
53
|
-
# p '============================================='
|
|
50
|
+
private
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
def failed_results
|
|
53
|
+
tests.reject do |test|
|
|
54
|
+
test.skipped? || test.failure.nil?
|
|
57
55
|
end
|
|
58
|
-
|
|
59
|
-
output_results(failure_paths, file_output)
|
|
60
|
-
File.write(@output_file_path, file_output.join("\n"), encoding: "UTF-8")
|
|
61
56
|
end
|
|
62
57
|
|
|
63
|
-
|
|
58
|
+
def failed_test_locations(failed_results, curdir)
|
|
59
|
+
failed_results.filter_map do |test|
|
|
60
|
+
find_failure_location(test, curdir)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
64
63
|
|
|
65
64
|
def find_failure_location(test, curdir)
|
|
65
|
+
failure_file_location = location_from_source_location(test) || location_from_failure_output(test)
|
|
66
|
+
return unless failure_file_location
|
|
67
|
+
|
|
68
|
+
relative_location(failure_file_location, curdir)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def location_from_source_location(test)
|
|
72
|
+
return unless test.respond_to?(:source_location)
|
|
73
|
+
|
|
74
|
+
path, line_number = test.source_location
|
|
75
|
+
return unless ruby_file_path?(path)
|
|
76
|
+
|
|
77
|
+
location_for(path, line_number)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def location_from_failure_output(test)
|
|
66
81
|
# Build a haystack string from failures and errors to find test file location in
|
|
67
82
|
tmp_haystack = []
|
|
68
83
|
tmp_haystack << test.failure.location
|
|
69
84
|
tmp_haystack << test.to_s
|
|
70
85
|
# Add filtered backtrace unless it is an unexpected error, which do not have a useful trace
|
|
71
|
-
|
|
86
|
+
unless test.failure.is_a?(Minitest::UnexpectedError)
|
|
87
|
+
tmp_haystack << filter_backtrace(test.failure.backtrace).join("\n")
|
|
88
|
+
end
|
|
72
89
|
|
|
73
90
|
# Get failure location as best we can from haystack
|
|
74
91
|
if @include_line_numbers
|
|
75
|
-
regex_keeping_line_numbers = /(
|
|
76
|
-
failure_file_location = tmp_haystack.join[regex_keeping_line_numbers, 1]
|
|
92
|
+
regex_keeping_line_numbers = /([^\n\[]+?\.rb:[0-9]+)/
|
|
93
|
+
failure_file_location = tmp_haystack.compact.join("\n")[regex_keeping_line_numbers, 1]
|
|
77
94
|
else
|
|
78
|
-
regex_removing_line_numbers = /(
|
|
79
|
-
failure_file_location = tmp_haystack.join[regex_removing_line_numbers, 1]
|
|
95
|
+
regex_removing_line_numbers = /([^\n\[]+?\.rb):[0-9]+/
|
|
96
|
+
failure_file_location = tmp_haystack.compact.join("\n")[regex_removing_line_numbers, 1]
|
|
80
97
|
end
|
|
81
98
|
|
|
82
|
-
|
|
99
|
+
failure_file_location&.strip
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def location_for(path, line_number)
|
|
103
|
+
return path unless @include_line_numbers && line_number
|
|
104
|
+
|
|
105
|
+
"#{path}:#{line_number}"
|
|
106
|
+
end
|
|
83
107
|
|
|
108
|
+
def ruby_file_path?(path)
|
|
109
|
+
path.to_s.end_with?(".rb")
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def relative_location(failure_file_location, curdir)
|
|
84
113
|
# Make path relative if absolute
|
|
85
|
-
failure_file_location.
|
|
86
|
-
failure_file_location.
|
|
114
|
+
failure_file_location = failure_file_location.to_s.strip
|
|
115
|
+
failure_file_location = failure_file_location.sub(%r{\A#{Regexp.escape(curdir)}/?}, "")
|
|
87
116
|
|
|
88
|
-
failure_file_location.
|
|
117
|
+
failure_file_location.strip
|
|
89
118
|
end
|
|
90
119
|
|
|
91
|
-
def output_results(
|
|
92
|
-
return if
|
|
120
|
+
def output_results(failure_count, output_paths)
|
|
121
|
+
return if output_paths.empty?
|
|
93
122
|
|
|
94
123
|
_puts("")
|
|
95
|
-
headline =
|
|
124
|
+
headline =
|
|
125
|
+
if @include_line_numbers
|
|
126
|
+
"Failed tests: #{failure_count} (seed #{@options[:seed]}):"
|
|
127
|
+
else
|
|
128
|
+
"Failed test files: #{failure_count} (seed #{@options[:seed]}):"
|
|
129
|
+
end
|
|
96
130
|
_puts(headline)
|
|
97
131
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
file_output << stripped_path
|
|
101
|
-
_puts color_red(stripped_path)
|
|
132
|
+
output_paths.each do |file_path|
|
|
133
|
+
_puts color_red(file_path)
|
|
102
134
|
end
|
|
103
135
|
end
|
|
104
136
|
|
|
137
|
+
def output_missing_locations(failure_count)
|
|
138
|
+
_puts("")
|
|
139
|
+
_puts "Failed tests: #{failure_count}, but no rerunnable Ruby file locations could be detected."
|
|
140
|
+
_puts "#{@output_file_path} was left empty."
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def write_file_output(file_output)
|
|
144
|
+
output = file_output.empty? ? "" : "#{file_output.join("\n")}\n"
|
|
145
|
+
File.write(@output_file_path, output, encoding: "UTF-8")
|
|
146
|
+
end
|
|
147
|
+
|
|
105
148
|
def _puts(str)
|
|
106
149
|
return unless @verbose
|
|
107
150
|
|
|
108
151
|
puts(str)
|
|
109
152
|
end
|
|
110
153
|
|
|
111
|
-
def print_padded_comment(line)
|
|
112
|
-
puts "##{pad(line)}"
|
|
113
|
-
end
|
|
114
|
-
|
|
115
154
|
def color?
|
|
116
155
|
return @color if defined?(@color)
|
|
117
156
|
|
|
118
157
|
@color = @options.fetch(:color) do
|
|
119
158
|
io.tty? && (
|
|
120
|
-
ENV
|
|
121
|
-
ENV
|
|
159
|
+
ENV.fetch("TERM", nil) =~ /^screen|color/ ||
|
|
160
|
+
ENV.fetch("EMACS", nil) == "t"
|
|
122
161
|
)
|
|
123
162
|
end
|
|
124
163
|
end
|
|
125
164
|
|
|
126
|
-
def color_green(string)
|
|
127
|
-
color? ? ANSI::Code.green(string) : string
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def color_yellow(string)
|
|
131
|
-
color? ? ANSI::Code.yellow(string) : string
|
|
132
|
-
end
|
|
133
|
-
|
|
134
165
|
def color_red(string)
|
|
135
166
|
color? ? ANSI::Code.red(string) : string
|
|
136
167
|
end
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "English"
|
|
4
|
+
|
|
5
|
+
module MinitestRerunFailed
|
|
6
|
+
class Runner
|
|
7
|
+
DEFAULT_FILENAME = ".minitest_failed_tests.txt"
|
|
8
|
+
DEFAULT_REPORT_DIR = "./"
|
|
9
|
+
|
|
10
|
+
def initialize(
|
|
11
|
+
report_dir: ENV.fetch("MINITEST_FAILED_TESTS_REPORT_DIR", DEFAULT_REPORT_DIR),
|
|
12
|
+
filename: DEFAULT_FILENAME,
|
|
13
|
+
io: $stdout,
|
|
14
|
+
command_runner: nil
|
|
15
|
+
)
|
|
16
|
+
@report_dir = report_dir
|
|
17
|
+
@filename = filename
|
|
18
|
+
@io = io
|
|
19
|
+
@command_runner = command_runner
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def call
|
|
23
|
+
return report_missing_file unless File.exist?(filepath)
|
|
24
|
+
return report_empty_file if File.empty?(filepath)
|
|
25
|
+
|
|
26
|
+
failed_tests = read_failed_tests
|
|
27
|
+
return report_empty_file if failed_tests.empty?
|
|
28
|
+
|
|
29
|
+
run_commands(commands_for(failed_tests))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def commands_for(failed_tests)
|
|
33
|
+
if rails_installed?
|
|
34
|
+
[
|
|
35
|
+
["bundle", "exec", "rails", "test", *failed_tests]
|
|
36
|
+
]
|
|
37
|
+
else
|
|
38
|
+
ruby_test_files(failed_tests).map do |test_file|
|
|
39
|
+
["bundle", "exec", "ruby", test_file]
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
attr_reader :report_dir, :filename, :io, :command_runner
|
|
47
|
+
|
|
48
|
+
def filepath
|
|
49
|
+
File.join(report_dir, filename)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def read_failed_tests
|
|
53
|
+
File.readlines(filepath, chomp: true).map(&:strip).reject(&:empty?)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def ruby_test_files(failed_tests)
|
|
57
|
+
failed_tests.map { |test_file| test_file.sub(/:[0-9]+\z/, "") }.uniq
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def rails_installed?
|
|
61
|
+
Gem.loaded_specs.key?("rails")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def run_commands(commands)
|
|
65
|
+
commands.each do |command|
|
|
66
|
+
exit_status = run_command(command)
|
|
67
|
+
return exit_status unless exit_status.zero?
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
0
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def run_command(command)
|
|
74
|
+
return command_runner.call(command) if command_runner
|
|
75
|
+
|
|
76
|
+
system(*command)
|
|
77
|
+
$CHILD_STATUS&.exitstatus || 1
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def report_missing_file
|
|
81
|
+
io.puts "No #{filename} found"
|
|
82
|
+
0
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def report_empty_file
|
|
86
|
+
io.puts "No failed tests in #{filename}"
|
|
87
|
+
0
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
@@ -5,8 +5,8 @@ require_relative "lib/minitest_rerun_failed/version"
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "minitest-rerun-failed"
|
|
7
7
|
spec.version = MinitestRerunFailed::VERSION
|
|
8
|
-
spec.authors = [
|
|
9
|
-
spec.email = [
|
|
8
|
+
spec.authors = ["Søren Houen"]
|
|
9
|
+
spec.email = ["s@houen.net"]
|
|
10
10
|
|
|
11
11
|
spec.summary = "Easily rerun failed tests with Minitest"
|
|
12
12
|
spec.homepage = "https://www.github.com/houen/minitest-rerun-failed"
|
|
@@ -23,12 +23,12 @@ Gem::Specification.new do |spec|
|
|
|
23
23
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|script|assets)/}) }
|
|
24
24
|
end
|
|
25
25
|
spec.bindir = "bin"
|
|
26
|
-
spec.require_paths = [
|
|
26
|
+
spec.require_paths = ["lib"]
|
|
27
27
|
spec.executables << "rerun_failed_tests"
|
|
28
28
|
|
|
29
29
|
# Uncomment to register a new dependency of your gem
|
|
30
|
-
spec.
|
|
31
|
-
spec.
|
|
30
|
+
spec.add_dependency "minitest", "~> 5.0", ">= 5.0.0"
|
|
31
|
+
spec.add_dependency "minitest-reporters", "~> 1.4", ">= 1.4.0"
|
|
32
32
|
|
|
33
33
|
# For more information and examples about making a new gem, checkout our
|
|
34
34
|
# guide at: https://bundler.io/guides/creating_gem.html
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: minitest-rerun-failed
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Søren Houen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2026-06-08 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: minitest
|
|
@@ -64,7 +64,6 @@ files:
|
|
|
64
64
|
- ".ruby-version"
|
|
65
65
|
- CHANGELOG.md
|
|
66
66
|
- Gemfile
|
|
67
|
-
- Gemfile.lock
|
|
68
67
|
- LICENSE.txt
|
|
69
68
|
- README.md
|
|
70
69
|
- Rakefile
|
|
@@ -74,6 +73,7 @@ files:
|
|
|
74
73
|
- bin/setup
|
|
75
74
|
- lib/minitest_rerun_failed.rb
|
|
76
75
|
- lib/minitest_rerun_failed/failed_tests_reporter.rb
|
|
76
|
+
- lib/minitest_rerun_failed/runner.rb
|
|
77
77
|
- lib/minitest_rerun_failed/version.rb
|
|
78
78
|
- minitest_rerun_failed.gemspec
|
|
79
79
|
homepage: https://www.github.com/houen/minitest-rerun-failed
|
|
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
98
98
|
- !ruby/object:Gem::Version
|
|
99
99
|
version: '0'
|
|
100
100
|
requirements: []
|
|
101
|
-
rubygems_version: 3.5.
|
|
101
|
+
rubygems_version: 3.5.3
|
|
102
102
|
signing_key:
|
|
103
103
|
specification_version: 4
|
|
104
104
|
summary: Easily rerun failed tests with Minitest
|
data/Gemfile.lock
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
minitest-rerun-failed (0.2.3)
|
|
5
|
-
minitest (~> 5.0, >= 5.0.0)
|
|
6
|
-
minitest-reporters (~> 1.4, >= 1.4.0)
|
|
7
|
-
|
|
8
|
-
GEM
|
|
9
|
-
remote: https://rubygems.org/
|
|
10
|
-
specs:
|
|
11
|
-
activesupport (7.1.3.2)
|
|
12
|
-
base64
|
|
13
|
-
bigdecimal
|
|
14
|
-
concurrent-ruby (~> 1.0, >= 1.0.2)
|
|
15
|
-
connection_pool (>= 2.2.5)
|
|
16
|
-
drb
|
|
17
|
-
i18n (>= 1.6, < 2)
|
|
18
|
-
minitest (>= 5.1)
|
|
19
|
-
mutex_m
|
|
20
|
-
tzinfo (~> 2.0)
|
|
21
|
-
ansi (1.5.0)
|
|
22
|
-
ast (2.4.2)
|
|
23
|
-
base64 (0.2.0)
|
|
24
|
-
bigdecimal (3.1.7)
|
|
25
|
-
builder (3.2.4)
|
|
26
|
-
concurrent-ruby (1.2.3)
|
|
27
|
-
connection_pool (2.4.1)
|
|
28
|
-
drb (2.2.1)
|
|
29
|
-
i18n (1.14.4)
|
|
30
|
-
concurrent-ruby (~> 1.0)
|
|
31
|
-
minitest (5.14.4)
|
|
32
|
-
minitest-reporters (1.4.3)
|
|
33
|
-
ansi
|
|
34
|
-
builder
|
|
35
|
-
minitest (>= 5.0)
|
|
36
|
-
ruby-progressbar
|
|
37
|
-
mutex_m (0.2.0)
|
|
38
|
-
parallel (1.20.1)
|
|
39
|
-
parser (3.0.2.0)
|
|
40
|
-
ast (~> 2.4.1)
|
|
41
|
-
rack (3.0.10)
|
|
42
|
-
rainbow (3.0.0)
|
|
43
|
-
rake (13.0.6)
|
|
44
|
-
regexp_parser (2.1.1)
|
|
45
|
-
rexml (3.2.5)
|
|
46
|
-
rubocop (1.20.0)
|
|
47
|
-
parallel (~> 1.10)
|
|
48
|
-
parser (>= 3.0.0.0)
|
|
49
|
-
rainbow (>= 2.2.2, < 4.0)
|
|
50
|
-
regexp_parser (>= 1.8, < 3.0)
|
|
51
|
-
rexml
|
|
52
|
-
rubocop-ast (>= 1.9.1, < 2.0)
|
|
53
|
-
ruby-progressbar (~> 1.7)
|
|
54
|
-
unicode-display_width (>= 1.4.0, < 3.0)
|
|
55
|
-
rubocop-ast (1.11.0)
|
|
56
|
-
parser (>= 3.0.1.1)
|
|
57
|
-
rubocop-minitest (0.15.0)
|
|
58
|
-
rubocop (>= 0.90, < 2.0)
|
|
59
|
-
rubocop-performance (1.19.1)
|
|
60
|
-
rubocop (>= 1.7.0, < 2.0)
|
|
61
|
-
rubocop-ast (>= 0.4.0)
|
|
62
|
-
rubocop-rails (2.15.2)
|
|
63
|
-
activesupport (>= 4.2.0)
|
|
64
|
-
rack (>= 1.1)
|
|
65
|
-
rubocop (>= 1.7.0, < 2.0)
|
|
66
|
-
rubocop-rails-omakase (1.0.0)
|
|
67
|
-
rubocop
|
|
68
|
-
rubocop-minitest
|
|
69
|
-
rubocop-performance
|
|
70
|
-
rubocop-rails
|
|
71
|
-
rubocop-rake (0.6.0)
|
|
72
|
-
rubocop (~> 1.0)
|
|
73
|
-
ruby-progressbar (1.11.0)
|
|
74
|
-
tzinfo (2.0.6)
|
|
75
|
-
concurrent-ruby (~> 1.0)
|
|
76
|
-
unicode-display_width (2.0.0)
|
|
77
|
-
|
|
78
|
-
PLATFORMS
|
|
79
|
-
arm64-darwin-21
|
|
80
|
-
arm64-darwin-22
|
|
81
|
-
x86_64-darwin-19
|
|
82
|
-
x86_64-darwin-20
|
|
83
|
-
x86_64-linux
|
|
84
|
-
|
|
85
|
-
DEPENDENCIES
|
|
86
|
-
minitest
|
|
87
|
-
minitest-reporters
|
|
88
|
-
minitest-rerun-failed!
|
|
89
|
-
rake
|
|
90
|
-
rubocop-minitest
|
|
91
|
-
rubocop-rails-omakase
|
|
92
|
-
rubocop-rake
|
|
93
|
-
|
|
94
|
-
BUNDLED WITH
|
|
95
|
-
2.2.22
|