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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc5068c6b1be1b2c9b8c7022da1df9ec2e03aa6c1aac37f579925973d55f8efb
4
- data.tar.gz: f492675d598fd4cd51aeb04af25db4a12d3bc3d5b4c2bfbfc0c53e7f0dc44c61
3
+ metadata.gz: 5002a70b8781d74165f357718b769508a49fdb1f0de8c5321c7d2001c0e5a35c
4
+ data.tar.gz: 964154c41295fbbdf2ddd3d1111b917649d6e27ed9e741dabecab3701d81f3b6
5
5
  SHA512:
6
- metadata.gz: 51f03b1d83f8ab6cd0b2ee95bb3e5308750cfe44ac2aa6095101e2e61dcae3a1f4176cd5c5d7d23ab844011ac162bf08ac3b2c79edeae2e310dba13b83cdf35d
7
- data.tar.gz: 0b3e98d2e537e1b2df31f0800fab55bf72030be73f70eb823f7cd6799a8dd8c83daebc2692cfcd653017b3a21542a4de5215398456658f89131f7d132052b038
6
+ metadata.gz: de8d4e9468a3cd311517cb4c618d60c0b619f456df3f0f04a1184fd9c6f5aaa5bbb27b7790ad789f917d5f76e3f8dfb23bef247ec9010ced9b417f0c01476dc2
7
+ data.tar.gz: c3deb15724cf7f10656fb9ca5f2ad76079cd4c4ec3aa3a1a9eb907c246bad9197232ea43f78466456b47fa4d3414644613175390946678051f28247c92e33f69
@@ -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: true
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
@@ -5,6 +5,8 @@ source 'https://rubygems.org'
5
5
  # Runtime dependencies in minitest-heat.gemspec
6
6
  gemspec
7
7
 
8
+ gem 'minitest', ENV.fetch('MINITEST_VERSION') if ENV['MINITEST_VERSION']
9
+
8
10
  # Development dependencies
9
11
  gem 'bundler-audit', '>= 0.9'
10
12
  gem 'debug'
data/Gemfile.lock CHANGED
@@ -1,8 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- minitest-heat (2.1.1)
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.6)
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.1)
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.18.0)
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
- And depending on your usage, you may need to require Minitest Heat in your test suite:
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/heat'
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
@@ -0,0 +1,3 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
2
+ <text y="0.9em" font-size="90">🔥</text>
3
+ </svg>
@@ -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&.delete_prefix('in `')&.delete_suffix("'")
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,
@@ -88,7 +88,7 @@ module Minitest
88
88
 
89
89
  private
90
90
 
91
- def relative_path = pathname.to_s.delete_prefix("#{Dir.pwd}/")
91
+ def relative_path = pathname.to_s.delete_prefix("#{Heat.project_root}/")
92
92
 
93
93
  def lines_summary
94
94
  line_numbers.map do |line_num|
@@ -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
- exception = result.failure&.exception
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(Dir.pwd)
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 = Dir.pwd
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?(Dir.pwd) ? :bold : :muted
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("#{Dir.pwd}/")
121
+ directory = hit.pathname.dirname.to_s.delete_prefix("#{Heat.project_root}/")
122
122
  filename = hit.pathname.basename.to_s
123
123
 
124
124
  [
@@ -44,14 +44,19 @@ module Minitest
44
44
 
45
45
  # Reads (and chomps) the lines of the target file
46
46
  #
47
- # @return [type] [description]
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, Encoding::UndefinedConversionError
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.
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Minitest
4
4
  module Heat
5
- VERSION = '2.1.1'
5
+ VERSION = '2.2.1'
6
6
  end
7
7
  end
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
@@ -11,6 +11,8 @@ module Minitest
11
11
  end
12
12
 
13
13
  def self.plugin_heat_init(options)
14
+ return if reporter.reporters.any? { |existing| existing.is_a?(HeatReporter) }
15
+
14
16
  io = options.fetch(:io, $stdout)
15
17
 
16
18
  reporter.reporters.reject! do |reporter|
@@ -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
- output.newline
85
- puts 'Sorry, but Minitest Heat encountered an exception recording an issue. Disabling Minitest Heat will get you back on track.'
86
- puts 'Please use the following exception details to submit an issue at https://github.com/garrettdimon/minitest-heat/issues'
87
- puts "#{exception.message}:"
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
- puts " #{line}"
91
+ warn " #{line}"
90
92
  end
91
- output.newline
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.errors.empty? && results.failures.empty?
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: results.problems? ? 'failed' : 'passed',
131
+ status: passed? ? 'passed' : 'failed',
124
132
  timestamp: Time.now.iso8601,
125
133
  statistics: results.statistics,
126
134
  timing: timer.to_h,
@@ -31,5 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
32
32
  spec.require_paths = ['lib']
33
33
 
34
- spec.add_dependency 'minitest'
34
+ spec.add_dependency 'minitest', '>= 5.22.3', '< 7'
35
35
  end
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.1.1
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: '0'
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: '0'
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