minitest-rerun-failed 0.2.2 → 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 +5 -0
- data/.rubocop.yml +27 -4
- data/CHANGELOG.md +14 -1
- data/Gemfile +6 -3
- data/README.md +20 -38
- data/bin/rerun_failed_tests +9 -0
- 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 -1
- data/minitest_rerun_failed.gemspec +8 -8
- metadata +8 -8
- data/Gemfile.lock +0 -95
- data/assets/screenshot.png +0 -0
- data/script/release_gem.sh +0 -4
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,4 +1,17 @@
|
|
|
1
|
-
## [0.
|
|
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
|
+
|
|
11
|
+
## [0.2.3] - 2024-05-26
|
|
12
|
+
- Added: Rerun tests executable
|
|
13
|
+
|
|
14
|
+
## [0.2.2] - 2024-05-25
|
|
2
15
|
- Changed: Also strip file paths when writing to .minitest_failed_tests.txt
|
|
3
16
|
|
|
4
17
|
## [0.2.1] - 2023-03-31
|
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,27 +11,17 @@ 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
|
-
-
|
|
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
|
-
Add this line to your application's Gemfile:
|
|
23
|
-
|
|
24
|
-
```ruby
|
|
25
|
-
gem 'minitest-rerun-failed'
|
|
26
19
|
```
|
|
20
|
+
bundle add "minitest-rerun-failed" --group test
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
Or install it yourself as:
|
|
33
|
-
|
|
34
|
-
$ gem install minitest-rerun-failed
|
|
22
|
+
# installs executable bin/rerun_failed_tests
|
|
23
|
+
bundle binstubs minitest-rerun-failed
|
|
24
|
+
```
|
|
35
25
|
|
|
36
26
|
## Usage
|
|
37
27
|
|
|
@@ -40,34 +30,32 @@ Use it like any Minitest::Reporters like such:
|
|
|
40
30
|
```ruby
|
|
41
31
|
Minitest::Reporters.use! [
|
|
42
32
|
Minitest::Reporters::ProgressReporter.new, # This is just my preferred reporter. Use the one(s) you like.
|
|
43
|
-
Minitest::Reporters::FailedTestsReporter.new
|
|
33
|
+
Minitest::Reporters::FailedTestsReporter.new
|
|
44
34
|
]
|
|
45
35
|
```
|
|
46
36
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
In your `test_helper.rb` file, add the following lines
|
|
50
|
-
|
|
51
|
-
```ruby
|
|
52
|
-
require "minitest_rerun_failed"
|
|
53
|
-
|
|
54
|
-
Minitest::Reporters.use!(
|
|
55
|
-
[Minitest::Reporters::DefaultReporter.new(color: true),
|
|
56
|
-
Minitest::Reporters::FailedTestsReporter.new(verbose: true, include_line_numbers: true, output_path: "tmp")
|
|
57
|
-
],
|
|
58
|
-
ENV,
|
|
59
|
-
Minitest.backtrace_filter
|
|
60
|
-
)
|
|
37
|
+
Now failed tests and seed will be printed at the end of the test report.
|
|
61
38
|
|
|
39
|
+
If you have installed the binstub, you can rerun the failed tests with
|
|
40
|
+
```
|
|
41
|
+
bin/rerun_failed_tests
|
|
62
42
|
```
|
|
63
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)
|
|
64
48
|
|
|
49
|
+
# Rails:
|
|
50
|
+
bundle exec rails test $(cat .minitest_failed_tests.txt)
|
|
51
|
+
```
|
|
65
52
|
|
|
66
53
|
### Options
|
|
67
54
|
- include_line_numbers: Include line numbers in outputs. Defaults to true
|
|
68
55
|
- verbose: Output to stdout. Defaults to true
|
|
69
56
|
- file_output: Output to file. Defaults to true
|
|
70
57
|
- output_path: Path to place output files in. Defaults to '.'
|
|
58
|
+
- Note: If you use the output_path option, you need to have `ENV["MINITEST_FAILED_TESTS_REPORT_DIR"]` set to use the executable
|
|
71
59
|
|
|
72
60
|
## Other
|
|
73
61
|
### Why line numbers instead of test names? What if the lines change as I am fixing things?
|
|
@@ -91,10 +79,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/houen/
|
|
|
91
79
|
|
|
92
80
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
93
81
|
|
|
94
|
-
## TODO
|
|
95
|
-
- Better workflow for rerunning tests
|
|
96
|
-
- Executable for rerun? (https://stackoverflow.com/a/65707495)
|
|
97
|
-
- Rerun with same seed
|
|
98
|
-
- Minitest-reporters or minitest plugin?
|
|
99
|
-
|
|
100
82
|
https://stackoverflow.com/questions/19910533/minitest-rerun-only-failed-tests
|
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
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
require "minitest/reporters"
|
|
4
4
|
|
|
5
|
-
require_relative "minitest_rerun_failed/version"
|
|
6
5
|
require_relative "minitest_rerun_failed/failed_tests_reporter"
|
|
6
|
+
require_relative "minitest_rerun_failed/runner"
|
|
7
7
|
|
|
8
8
|
module MinitestRerunFailed
|
|
9
9
|
class Error < StandardError; 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"
|
|
@@ -20,15 +20,15 @@ Gem::Specification.new do |spec|
|
|
|
20
20
|
# Specify which files should be added to the gem when it is released.
|
|
21
21
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
22
22
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
23
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
23
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|script|assets)/}) }
|
|
24
24
|
end
|
|
25
|
-
spec.bindir = "
|
|
26
|
-
spec.
|
|
27
|
-
spec.
|
|
25
|
+
spec.bindir = "bin"
|
|
26
|
+
spec.require_paths = ["lib"]
|
|
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
|
-
bindir:
|
|
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
|
|
@@ -53,7 +53,8 @@ dependencies:
|
|
|
53
53
|
description:
|
|
54
54
|
email:
|
|
55
55
|
- s@houen.net
|
|
56
|
-
executables:
|
|
56
|
+
executables:
|
|
57
|
+
- rerun_failed_tests
|
|
57
58
|
extensions: []
|
|
58
59
|
extra_rdoc_files: []
|
|
59
60
|
files:
|
|
@@ -63,19 +64,18 @@ files:
|
|
|
63
64
|
- ".ruby-version"
|
|
64
65
|
- CHANGELOG.md
|
|
65
66
|
- Gemfile
|
|
66
|
-
- Gemfile.lock
|
|
67
67
|
- LICENSE.txt
|
|
68
68
|
- README.md
|
|
69
69
|
- Rakefile
|
|
70
|
-
- assets/screenshot.png
|
|
71
70
|
- bin/console
|
|
71
|
+
- bin/rerun_failed_tests
|
|
72
72
|
- bin/rubocop
|
|
73
73
|
- bin/setup
|
|
74
74
|
- lib/minitest_rerun_failed.rb
|
|
75
75
|
- lib/minitest_rerun_failed/failed_tests_reporter.rb
|
|
76
|
+
- lib/minitest_rerun_failed/runner.rb
|
|
76
77
|
- lib/minitest_rerun_failed/version.rb
|
|
77
78
|
- minitest_rerun_failed.gemspec
|
|
78
|
-
- script/release_gem.sh
|
|
79
79
|
homepage: https://www.github.com/houen/minitest-rerun-failed
|
|
80
80
|
licenses:
|
|
81
81
|
- MIT
|
|
@@ -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.2)
|
|
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
|
data/assets/screenshot.png
DELETED
|
Binary file
|
data/script/release_gem.sh
DELETED