minitest-heat 2.1.1 → 2.2.1
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 +39 -2
- data/CHANGELOG.md +25 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +5 -5
- data/README.md +30 -2
- data/favicon.svg +3 -0
- data/lib/minitest/heat/backtrace/line_parser.rb +2 -2
- data/lib/minitest/heat/hit.rb +1 -1
- data/lib/minitest/heat/issue.rb +28 -4
- data/lib/minitest/heat/location.rb +3 -3
- data/lib/minitest/heat/output/backtrace.rb +1 -1
- data/lib/minitest/heat/output/map.rb +1 -1
- data/lib/minitest/heat/source.rb +8 -3
- data/lib/minitest/heat/version.rb +1 -1
- data/lib/minitest/heat.rb +25 -0
- data/lib/minitest/heat_plugin.rb +2 -0
- data/lib/minitest/heat_reporter.rb +16 -8
- data/minitest-heat.gemspec +1 -1
- metadata +10 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 5002a70b8781d74165f357718b769508a49fdb1f0de8c5321c7d2001c0e5a35c
|
|
4
|
+
data.tar.gz: 964154c41295fbbdf2ddd3d1111b917649d6e27ed9e741dabecab3701d81f3b6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: de8d4e9468a3cd311517cb4c618d60c0b619f456df3f0f04a1184fd9c6f5aaa5bbb27b7790ad789f917d5f76e3f8dfb23bef247ec9010ced9b417f0c01476dc2
|
|
7
|
+
data.tar.gz: c3deb15724cf7f10656fb9ca5f2ad76079cd4c4ec3aa3a1a9eb907c246bad9197232ea43f78466456b47fa4d3414644613175390946678051f28247c92e33f69
|
data/.github/workflows/main.yml
CHANGED
|
@@ -27,11 +27,21 @@ jobs:
|
|
|
27
27
|
run: bundle exec bundle-audit check
|
|
28
28
|
|
|
29
29
|
test:
|
|
30
|
-
name: Test (Ruby ${{ matrix.ruby }})
|
|
30
|
+
name: Test (Ruby ${{ matrix.ruby }}, Minitest ${{ matrix.minitest }})
|
|
31
31
|
strategy:
|
|
32
32
|
fail-fast: false
|
|
33
33
|
matrix:
|
|
34
34
|
ruby: ['3.2', '3.3', '3.4', '4.0']
|
|
35
|
+
minitest: ['~> 5.0', '~> 6.0']
|
|
36
|
+
include:
|
|
37
|
+
- ruby: '3.2'
|
|
38
|
+
minitest: '= 5.22.3'
|
|
39
|
+
- ruby: '3.2'
|
|
40
|
+
minitest: '= 6.0.0'
|
|
41
|
+
env:
|
|
42
|
+
MINITEST_VERSION: ${{ matrix.minitest }}
|
|
43
|
+
BUNDLE_FROZEN: 'false'
|
|
44
|
+
BUNDLE_DEPLOYMENT: 'false'
|
|
35
45
|
runs-on: ubuntu-latest
|
|
36
46
|
steps:
|
|
37
47
|
- uses: actions/checkout@v4
|
|
@@ -40,10 +50,37 @@ jobs:
|
|
|
40
50
|
with:
|
|
41
51
|
ruby-version: ${{ matrix.ruby }}
|
|
42
52
|
bundler: '2.7.2'
|
|
43
|
-
bundler-cache:
|
|
53
|
+
bundler-cache: false
|
|
54
|
+
- name: Resolve selected Minitest
|
|
55
|
+
run: |
|
|
56
|
+
bundle lock --update minitest
|
|
57
|
+
bundle install
|
|
58
|
+
- name: Verify selected Minitest
|
|
59
|
+
run: |
|
|
60
|
+
bundle exec ruby -rminitest -e '
|
|
61
|
+
version = Gem.loaded_specs.fetch("minitest").version
|
|
62
|
+
abort "Wrong Minitest: #{version}" unless Gem::Requirement.new(ENV.fetch("MINITEST_VERSION")).satisfied_by?(version)
|
|
63
|
+
puts "Ruby #{RUBY_VERSION}, Minitest #{version}"
|
|
64
|
+
'
|
|
44
65
|
- name: Run tests
|
|
45
66
|
run: bundle exec rake test
|
|
46
67
|
|
|
68
|
+
required-tests:
|
|
69
|
+
# Keep the names required by the repository rules while gating on every
|
|
70
|
+
# supported Ruby/Minitest combination, including the version boundaries.
|
|
71
|
+
name: Test (Ruby ${{ matrix.ruby }})
|
|
72
|
+
needs: test
|
|
73
|
+
if: ${{ always() }}
|
|
74
|
+
strategy:
|
|
75
|
+
matrix:
|
|
76
|
+
ruby: ['3.2', '3.3', '3.4', '4.0']
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
env:
|
|
79
|
+
TEST_RESULT: ${{ needs.test.result }}
|
|
80
|
+
steps:
|
|
81
|
+
- name: Require the complete compatibility matrix to pass
|
|
82
|
+
run: test "$TEST_RESULT" = success
|
|
83
|
+
|
|
47
84
|
changelog:
|
|
48
85
|
name: Changelog
|
|
49
86
|
runs-on: ubuntu-latest
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
## [Unreleased]
|
|
2
2
|
|
|
3
|
+
## [2.2.1] - 2026-09-24
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- Display failures normally when a relevant source line contains non-ASCII text under a non-UTF-8 locale (such as `LC_ALL=C` or an unrecognized `LC_ALL`), or contains bytes that aren't valid UTF-8, instead of reporting that Heat couldn't display the failure. Source files are read as UTF-8 and invalid bytes are replaced, so a file that declares a non-UTF-8 encoding shows `�` for characters that aren't valid UTF-8.
|
|
7
|
+
- Under a non-UTF-8 locale, report failures whose messages include non-ASCII text read at runtime (such as command output or file contents) instead of losing them, and keep `--heat-json` output valid when they occur.
|
|
8
|
+
- Under a non-UTF-8 locale, report every failure in a project whose path contains non-ASCII characters, including errors that Minitest's own reporter can't display in that situation.
|
|
9
|
+
|
|
10
|
+
## [2.2.0] - 2026-09-16
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Support Minitest 6 with explicit plugin activation (`Minitest.load :heat`) and compatible test filtering, while retaining automatic discovery on Minitest 5.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
- Require Minitest `>= 5.22.3, < 7` and test both major versions in CI. Applications using older Minitest versions must upgrade Minitest before upgrading Heat.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- Install only one Heat reporter when the plugin is loaded repeatedly, preserving valid JSON output.
|
|
20
|
+
- Normalize relative result paths so test exceptions retain their classification and failure locations when invoked with relative filenames.
|
|
21
|
+
- Return an unsuccessful exit status when Heat cannot record a result, and keep JSON output valid by sending reporter diagnostics to stderr.
|
|
22
|
+
- Return an unsuccessful exit status when an explicit test filter matches no tests, consistent with Minitest; unfiltered empty runs remain successful.
|
|
23
|
+
- Preserve namespaced method names and handle current Ruby quoting in backtrace details.
|
|
24
|
+
- Tests classified as broken now cause an unsuccessful process exit instead of incorrectly reporting success to test runners and CI.
|
|
25
|
+
- JSON output explicitly loads the time library so timestamp formatting works on Ruby 3.2 and 3.3 without relying on another dependency to load it.
|
|
26
|
+
- Updated locked development dependencies for security advisories affecting concurrent-ruby, erb, and json.
|
|
27
|
+
|
|
3
28
|
## [2.1.1] - 2026-02-01
|
|
4
29
|
|
|
5
30
|
### Changed
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
minitest-heat (2.
|
|
5
|
-
minitest
|
|
4
|
+
minitest-heat (2.2.1)
|
|
5
|
+
minitest (>= 5.22.3, < 7)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
@@ -12,7 +12,7 @@ GEM
|
|
|
12
12
|
bundler-audit (0.9.3)
|
|
13
13
|
bundler (>= 1.2.0)
|
|
14
14
|
thor (~> 1.0)
|
|
15
|
-
concurrent-ruby (1.3.
|
|
15
|
+
concurrent-ruby (1.3.8)
|
|
16
16
|
date (3.5.1)
|
|
17
17
|
debug (1.11.1)
|
|
18
18
|
irb (~> 1.10)
|
|
@@ -47,7 +47,7 @@ GEM
|
|
|
47
47
|
dry-inflector (~> 1.0)
|
|
48
48
|
dry-logic (~> 1.4)
|
|
49
49
|
zeitwerk (~> 2.6)
|
|
50
|
-
erb (6.0.
|
|
50
|
+
erb (6.0.7)
|
|
51
51
|
erubi (1.13.1)
|
|
52
52
|
flay (2.14.2)
|
|
53
53
|
erubi (~> 1.10)
|
|
@@ -63,7 +63,7 @@ GEM
|
|
|
63
63
|
pp (>= 0.6.0)
|
|
64
64
|
rdoc (>= 4.0.0)
|
|
65
65
|
reline (>= 0.4.2)
|
|
66
|
-
json (2.
|
|
66
|
+
json (2.21.2)
|
|
67
67
|
language_server-protocol (3.17.0.5)
|
|
68
68
|
lint_roller (1.1.0)
|
|
69
69
|
logger (1.7.0)
|
data/README.md
CHANGED
|
@@ -20,12 +20,22 @@ Or install it yourself as:
|
|
|
20
20
|
|
|
21
21
|
$ gem install minitest-heat
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
Heat supports Ruby 3.2 and newer with Minitest `>= 5.22.3, < 7`.
|
|
24
|
+
|
|
25
|
+
Minitest 5 discovers Heat automatically when the gem is available and plugin loading
|
|
26
|
+
is enabled. Existing Minitest 5 setups do not need to change.
|
|
27
|
+
|
|
28
|
+
Minitest 6 requires explicit plugin activation. Add this to your `test_helper.rb`:
|
|
24
29
|
|
|
25
30
|
```ruby
|
|
26
|
-
require 'minitest/
|
|
31
|
+
require 'minitest/autorun'
|
|
32
|
+
Minitest.load :heat
|
|
27
33
|
```
|
|
28
34
|
|
|
35
|
+
`require 'minitest/heat'` loads Heat's library and configuration API; it does not
|
|
36
|
+
activate the reporter on Minitest 6. Loading the Heat plugin more than once installs
|
|
37
|
+
only one reporter.
|
|
38
|
+
|
|
29
39
|
## Prioritizing Your Work
|
|
30
40
|
|
|
31
41
|
Minitest Heat surfaces the most impactful problems first so you can fix what matters without scrolling through noise.
|
|
@@ -145,6 +155,24 @@ FORCE_SLOWS=true # No errors or skipped tests, just slow tests
|
|
|
145
155
|
|
|
146
156
|
So to see the full context of a test suite, `IMPLODE=true bundle exec rake` will work its magic.
|
|
147
157
|
|
|
158
|
+
### Testing Minitest compatibility
|
|
159
|
+
|
|
160
|
+
The development lockfile retains Minitest 5.27.0. To select another supported version
|
|
161
|
+
in a disposable checkout, use the same runner as CI:
|
|
162
|
+
|
|
163
|
+
```sh
|
|
164
|
+
export MINITEST_VERSION='~> 6.0'
|
|
165
|
+
export BUNDLE_FROZEN=false BUNDLE_DEPLOYMENT=false
|
|
166
|
+
bundle lock --update minitest
|
|
167
|
+
bundle install
|
|
168
|
+
CI=true bundle exec rake test
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Use `~> 5.0` for the latest Minitest 5, or `= 5.22.3` / `= 6.0.0` for the supported
|
|
172
|
+
boundaries. These commands update that checkout's lockfile; do not commit those
|
|
173
|
+
version-selection changes. CI tests the latest 5.x and 6.x on Ruby 3.2–4.0 and both
|
|
174
|
+
Minitest boundaries on Ruby 3.2. All compatibility jobs must pass before release.
|
|
175
|
+
|
|
148
176
|
## Contributing
|
|
149
177
|
Bug reports and pull requests are welcome on GitHub at https://github.com/garrettdimon/minitest-heat. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/minitest-heat/blob/master/CODE_OF_CONDUCT.md).
|
|
150
178
|
|
data/favicon.svg
ADDED
|
@@ -12,8 +12,8 @@ module Minitest
|
|
|
12
12
|
def self.read(raw_text)
|
|
13
13
|
return nil if raw_text.nil? || raw_text.empty?
|
|
14
14
|
|
|
15
|
-
raw_pathname, raw_line_number, raw_container = raw_text.to_s.split(':')
|
|
16
|
-
raw_container = raw_container&.
|
|
15
|
+
raw_pathname, raw_line_number, raw_container = raw_text.to_s.split(':', 3)
|
|
16
|
+
raw_container = raw_container&.sub(/\Ain [`']/, '')&.delete_suffix("'")
|
|
17
17
|
|
|
18
18
|
::Minitest::Heat::Location.new(
|
|
19
19
|
pathname: raw_pathname,
|
data/lib/minitest/heat/hit.rb
CHANGED
data/lib/minitest/heat/issue.rb
CHANGED
|
@@ -35,7 +35,9 @@ module Minitest
|
|
|
35
35
|
# @return [Issue] the instance of the issue to use for examining the result
|
|
36
36
|
def self.from_result(result)
|
|
37
37
|
# Not all results are failures, so we use the safe navigation operator
|
|
38
|
-
|
|
38
|
+
failure = result.failure
|
|
39
|
+
unexpected = failure.is_a?(Minitest::UnexpectedError)
|
|
40
|
+
exception = unexpected ? failure.error : failure&.exception
|
|
39
41
|
|
|
40
42
|
new(
|
|
41
43
|
assertions: result.assertions,
|
|
@@ -46,11 +48,33 @@ module Minitest
|
|
|
46
48
|
passed: result.passed?,
|
|
47
49
|
error: result.error?,
|
|
48
50
|
skipped: result.skipped?,
|
|
49
|
-
message: exception&.message,
|
|
51
|
+
message: unexpected ? unexpected_error_message(exception) : exception&.message,
|
|
50
52
|
backtrace: exception&.backtrace
|
|
51
53
|
)
|
|
52
54
|
end
|
|
53
55
|
|
|
56
|
+
# Matches the format of `Minitest::UnexpectedError#message` without calling it. Minitest
|
|
57
|
+
# builds that message with a binary regular expression, which raises when the project path
|
|
58
|
+
# and the backtrace contain non-ASCII characters under a non-UTF-8 locale.
|
|
59
|
+
# @param error [Exception] the exception wrapped by the unexpected error
|
|
60
|
+
#
|
|
61
|
+
# @return [String] the exception class, message, and filtered backtrace
|
|
62
|
+
def self.unexpected_error_message(error)
|
|
63
|
+
lines = (error.backtrace || []).map { |line| Heat.utf8(line) }
|
|
64
|
+
backtrace = Minitest.filter_backtrace(lines).map { |line| line.gsub(minitest_base_pattern, '') }
|
|
65
|
+
|
|
66
|
+
"#{error.class}: #{Heat.utf8(error.message)}\n #{backtrace.join("\n ")}"
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Minitest's pattern for the directory it loaded from, rebuilt as UTF-8 so it can match
|
|
70
|
+
# UTF-8 backtraces. Reusing it strips the same prefix as Minitest even if a test changes
|
|
71
|
+
# the working directory.
|
|
72
|
+
#
|
|
73
|
+
# @return [Regexp] the UTF-8 equivalent of `Minitest::UnexpectedError::BASE_RE`
|
|
74
|
+
def self.minitest_base_pattern
|
|
75
|
+
@minitest_base_pattern ||= Regexp.new(Heat.utf8(Minitest::UnexpectedError::BASE_RE.source))
|
|
76
|
+
end
|
|
77
|
+
|
|
54
78
|
# Creates an instance of Issue. In general, the `from_result` approach will be more convenient
|
|
55
79
|
# for standard usage, but for lower-level purposes like testing, the initializer provides3
|
|
56
80
|
# more fine-grained control
|
|
@@ -67,10 +91,10 @@ module Minitest
|
|
|
67
91
|
#
|
|
68
92
|
# @return [type] [description]
|
|
69
93
|
def initialize(assertions: 1, test_location: ['Unrecognized Test File', 1], backtrace: [], execution_time: 0.0, message: nil, test_class: nil, test_identifier: nil, passed: false, error: false, skipped: false)
|
|
70
|
-
@message = message
|
|
94
|
+
@message = Heat.utf8(message)
|
|
71
95
|
|
|
72
96
|
@assertions = Integer(assertions)
|
|
73
|
-
@locations = Locations.new(test_location, backtrace)
|
|
97
|
+
@locations = Locations.new(test_location, backtrace&.map { |line| Heat.utf8(line) })
|
|
74
98
|
|
|
75
99
|
@test_class = test_class
|
|
76
100
|
@test_identifier = test_identifier
|
|
@@ -68,9 +68,9 @@ module Minitest
|
|
|
68
68
|
#
|
|
69
69
|
# @return [Pathname] a pathname instance for the relevant file
|
|
70
70
|
def pathname
|
|
71
|
-
Pathname(raw_pathname)
|
|
71
|
+
Pathname(Heat.utf8(File.expand_path(raw_pathname)))
|
|
72
72
|
rescue ArgumentError
|
|
73
|
-
Pathname(
|
|
73
|
+
Pathname(Heat.project_root)
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
# A safe interface to getting a string representing the path portion of the file
|
|
@@ -163,7 +163,7 @@ module Minitest
|
|
|
163
163
|
|
|
164
164
|
private
|
|
165
165
|
|
|
166
|
-
def project_root_dir =
|
|
166
|
+
def project_root_dir = Heat.project_root
|
|
167
167
|
|
|
168
168
|
def seconds_ago = (Time.now - mtime).to_i
|
|
169
169
|
end
|
|
@@ -102,7 +102,7 @@ module Minitest
|
|
|
102
102
|
end
|
|
103
103
|
|
|
104
104
|
def file_and_line_number_tokens(location)
|
|
105
|
-
style = location.to_s.include?(
|
|
105
|
+
style = location.to_s.include?(Heat.project_root) ? :bold : :muted
|
|
106
106
|
[
|
|
107
107
|
[style, location.filename],
|
|
108
108
|
[:muted, ':'],
|
|
@@ -118,7 +118,7 @@ module Minitest
|
|
|
118
118
|
end
|
|
119
119
|
|
|
120
120
|
def pathname(hit)
|
|
121
|
-
directory = hit.pathname.dirname.to_s.delete_prefix("#{
|
|
121
|
+
directory = hit.pathname.dirname.to_s.delete_prefix("#{Heat.project_root}/")
|
|
122
122
|
filename = hit.pathname.basename.to_s
|
|
123
123
|
|
|
124
124
|
[
|
data/lib/minitest/heat/source.rb
CHANGED
|
@@ -44,14 +44,19 @@ module Minitest
|
|
|
44
44
|
|
|
45
45
|
# Reads (and chomps) the lines of the target file
|
|
46
46
|
#
|
|
47
|
-
#
|
|
47
|
+
# Ruby labels file contents with the locale's encoding, which is US-ASCII under `LC_ALL=C` or
|
|
48
|
+
# an unrecognized locale. Ruby source is UTF-8 by default, so lines are read as UTF-8
|
|
49
|
+
# regardless of locale, and bytes that aren't valid UTF-8 are replaced so that displaying
|
|
50
|
+
# them can't raise.
|
|
51
|
+
#
|
|
52
|
+
# @return [Array<String>] the chomped lines of the file as valid UTF-8
|
|
48
53
|
def file_lines
|
|
49
|
-
@raw_lines ||= File.readlines(filename, chomp: true)
|
|
54
|
+
@raw_lines ||= File.readlines(filename, chomp: true, mode: 'rb').map { |line| Heat.utf8(line) }
|
|
50
55
|
# Remove trailing empty lines, checking for nil/empty safely
|
|
51
56
|
@raw_lines.pop while @raw_lines.any? && @raw_lines.last&.strip.to_s.empty?
|
|
52
57
|
|
|
53
58
|
@raw_lines
|
|
54
|
-
rescue Errno::ENOENT, Errno::EACCES, Errno::EISDIR, IOError
|
|
59
|
+
rescue Errno::ENOENT, Errno::EACCES, Errno::EISDIR, IOError
|
|
55
60
|
# Occasionally, for a variety of reasons, a file can't be read. In those cases, it's best to
|
|
56
61
|
# return no source code lines rather than have the test suite raise an error unrelated to
|
|
57
62
|
# the code being tested because that gets confusing.
|
data/lib/minitest/heat.rb
CHANGED
|
@@ -48,5 +48,30 @@ module Minitest
|
|
|
48
48
|
def self.configure
|
|
49
49
|
yield(configuration)
|
|
50
50
|
end
|
|
51
|
+
|
|
52
|
+
# Ruby labels text from outside Ruby source (paths, file contents, command output) with the
|
|
53
|
+
# locale's encoding, which is US-ASCII or binary under `LC_ALL=C` or an unrecognized locale.
|
|
54
|
+
# That text is overwhelmingly UTF-8, so unlabeled bytes are read as UTF-8 and text in any other
|
|
55
|
+
# encoding is converted. Anything that isn't valid UTF-8 is replaced so that comparing,
|
|
56
|
+
# displaying or serializing the text can't raise.
|
|
57
|
+
#
|
|
58
|
+
# @param text [String, nil] text from outside Ruby source
|
|
59
|
+
#
|
|
60
|
+
# @return [String, nil] valid UTF-8 text
|
|
61
|
+
def self.utf8(text)
|
|
62
|
+
return text unless text.is_a?(String)
|
|
63
|
+
|
|
64
|
+
case text.encoding
|
|
65
|
+
when Encoding::UTF_8, Encoding::US_ASCII, Encoding::BINARY
|
|
66
|
+
String.new(text, encoding: Encoding::UTF_8).scrub
|
|
67
|
+
else
|
|
68
|
+
text.encode(Encoding::UTF_8, invalid: :replace, undef: :replace)
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# The directory the tests run from, which identifies project files
|
|
73
|
+
#
|
|
74
|
+
# @return [String] the current working directory as UTF-8
|
|
75
|
+
def self.project_root = utf8(Dir.pwd)
|
|
51
76
|
end
|
|
52
77
|
end
|
data/lib/minitest/heat_plugin.rb
CHANGED
|
@@ -38,6 +38,7 @@ module Minitest
|
|
|
38
38
|
super()
|
|
39
39
|
|
|
40
40
|
@options = options
|
|
41
|
+
@recording_error = false
|
|
41
42
|
|
|
42
43
|
@timer = Heat::Timer.new
|
|
43
44
|
@results = Heat::Results.new
|
|
@@ -77,23 +78,25 @@ module Minitest
|
|
|
77
78
|
# Show the marker (skip for JSON output)
|
|
78
79
|
output.marker(issue.type) unless json_output?
|
|
79
80
|
rescue StandardError => e
|
|
81
|
+
@recording_error = true
|
|
80
82
|
display_exception_guidance(e)
|
|
81
83
|
end
|
|
82
84
|
|
|
83
85
|
def display_exception_guidance(exception)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
86
|
+
warn ''
|
|
87
|
+
warn 'Sorry, but Minitest Heat encountered an exception recording an issue. Disabling Minitest Heat will get you back on track.'
|
|
88
|
+
warn 'Please use the following exception details to submit an issue at https://github.com/garrettdimon/minitest-heat/issues'
|
|
89
|
+
warn "#{exception.message}:"
|
|
88
90
|
exception.backtrace.each do |line|
|
|
89
|
-
|
|
91
|
+
warn " #{line}"
|
|
90
92
|
end
|
|
91
|
-
|
|
93
|
+
warn ''
|
|
92
94
|
end
|
|
93
95
|
|
|
94
96
|
# Outputs the summary of the run.
|
|
95
97
|
def report
|
|
96
98
|
timer.stop!
|
|
99
|
+
warn "Nothing ran for filter: #{test_filter}" if empty_filtered_run?
|
|
97
100
|
|
|
98
101
|
if json_output?
|
|
99
102
|
output_json
|
|
@@ -108,19 +111,24 @@ module Minitest
|
|
|
108
111
|
def json_output? = options[:heat_json]
|
|
109
112
|
|
|
110
113
|
# Did this run pass?
|
|
111
|
-
def passed? = results.
|
|
114
|
+
def passed? = !@recording_error && !results.problems? && !empty_filtered_run?
|
|
112
115
|
|
|
113
116
|
private
|
|
114
117
|
|
|
118
|
+
def test_filter = options[:include] || options[:filter]
|
|
119
|
+
|
|
120
|
+
def empty_filtered_run? = test_filter && timer.test_count.zero?
|
|
121
|
+
|
|
115
122
|
def output_json
|
|
116
123
|
require 'json'
|
|
124
|
+
require 'time'
|
|
117
125
|
output.stream.puts JSON.pretty_generate(json_results)
|
|
118
126
|
end
|
|
119
127
|
|
|
120
128
|
def json_results
|
|
121
129
|
{
|
|
122
130
|
version: '1.0',
|
|
123
|
-
status:
|
|
131
|
+
status: passed? ? 'passed' : 'failed',
|
|
124
132
|
timestamp: Time.now.iso8601,
|
|
125
133
|
statistics: results.statistics,
|
|
126
134
|
timing: timer.to_h,
|
data/minitest-heat.gemspec
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: minitest-heat
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Garrett Dimon
|
|
@@ -15,14 +15,20 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - ">="
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version:
|
|
18
|
+
version: 5.22.3
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '7'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
26
|
- - ">="
|
|
24
27
|
- !ruby/object:Gem::Version
|
|
25
|
-
version:
|
|
28
|
+
version: 5.22.3
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '7'
|
|
26
32
|
description: Presents test results in a visual manner to guide you to where to look
|
|
27
33
|
first.
|
|
28
34
|
email:
|
|
@@ -50,6 +56,7 @@ files:
|
|
|
50
56
|
- Rakefile
|
|
51
57
|
- bin/console
|
|
52
58
|
- bin/setup
|
|
59
|
+
- favicon.svg
|
|
53
60
|
- lib/minitest/heat.rb
|
|
54
61
|
- lib/minitest/heat/backtrace.rb
|
|
55
62
|
- lib/minitest/heat/backtrace/line_count.rb
|