minitest-heat 0.0.10 → 0.0.14

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.
@@ -5,36 +5,25 @@ module Minitest
5
5
  class Output
6
6
  # Formats issues to output based on the issue type
7
7
  class Issue # rubocop:disable Metrics/ClassLength
8
- attr_accessor :issue
8
+ attr_accessor :issue, :locations
9
9
 
10
10
  def initialize(issue)
11
11
  @issue = issue
12
+ @locations = issue.locations
12
13
  end
13
14
 
14
15
  def tokens
15
16
  case issue.type
16
- when :error then error_tokens
17
- when :broken then broken_tokens
18
- when :failure then failure_tokens
19
- when :skipped then skipped_tokens
20
- when :painful then painful_tokens
21
- when :slow then slow_tokens
17
+ when :error, :broken then exception_tokens
18
+ when :failure then failure_tokens
19
+ when :skipped then skipped_tokens
20
+ when :painful, :slow then slow_tokens
22
21
  end
23
22
  end
24
23
 
25
24
  private
26
25
 
27
- def error_tokens
28
- [
29
- headline_tokens,
30
- test_location_tokens,
31
- summary_tokens,
32
- *backtrace_tokens,
33
- newline_tokens
34
- ]
35
- end
36
-
37
- def broken_tokens
26
+ def exception_tokens
38
27
  [
39
28
  headline_tokens,
40
29
  test_location_tokens,
@@ -61,14 +50,6 @@ module Minitest
61
50
  ]
62
51
  end
63
52
 
64
- def painful_tokens
65
- [
66
- headline_tokens,
67
- slowness_summary_tokens,
68
- newline_tokens
69
- ]
70
- end
71
-
72
53
  def slow_tokens
73
54
  [
74
55
  headline_tokens,
@@ -78,9 +59,14 @@ module Minitest
78
59
  end
79
60
 
80
61
  def headline_tokens
81
- [[issue.type, label(issue)], spacer_token, [:default, test_name(issue)]]
62
+ [label_token(issue), spacer_token, [:default, test_name(issue)]]
82
63
  end
83
64
 
65
+ # Creates a display-friendly version of the test name with underscores removed and the
66
+ # first letter capitalized regardless of the formatt used for the test definition
67
+ # @param issue [Issue] the issue to use to generate the test name
68
+ #
69
+ # @return [String] the cleaned up version of the test name
84
70
  def test_name(issue)
85
71
  test_prefix = 'test_'
86
72
  identifier = issue.test_identifier
@@ -92,50 +78,39 @@ module Minitest
92
78
  end
93
79
  end
94
80
 
95
- def label(issue)
96
- if issue.error? && issue.in_test?
97
- # When the exception came out of the test itself, that's a different kind of exception
98
- # that really only indicates there's a problem with the code in the test. It's kind of
99
- # between an error and a test.
100
- 'Broken Test'
101
- elsif issue.error?
102
- 'Error'
103
- elsif issue.skipped?
104
- 'Skipped'
105
- elsif issue.painful?
106
- 'Passed but Very Slow'
107
- elsif issue.slow?
108
- 'Passed but Slow'
109
- elsif !issue.passed?
110
- 'Failure'
111
- else
112
- 'Success'
113
- end
81
+ def label_token(issue)
82
+ [issue.type, issue_label(issue.type)]
114
83
  end
115
84
 
116
85
  def test_name_and_class_tokens
117
86
  [[:default, issue.test_class], *test_location_tokens]
118
87
  end
119
88
 
120
- def backtrace_tokens
121
- backtrace = ::Minitest::Heat::Output::Backtrace.new(issue.location)
122
-
123
- backtrace.tokens
124
- end
125
-
126
89
  def test_location_tokens
127
- [[:default, test_file_short_location], [:muted, ':'], [:default, issue.test_definition_line], arrow_token, [:default, issue.test_failure_line], [:muted, test_line_source]]
90
+ [
91
+ [:default, locations.test_definition.relative_filename],
92
+ [:muted, ':'],
93
+ [:default, locations.test_definition.line_number],
94
+ arrow_token,
95
+ [:default, locations.test_failure.line_number],
96
+ [:muted, "\n #{locations.test_failure.source_code.line.strip}"]
97
+ ]
128
98
  end
129
99
 
130
100
  def location_tokens
131
- [[:default, most_relevant_short_location], [:muted, ':'], [:default, issue.location.most_relevant_failure_line], [:muted, most_relevant_line_source]]
101
+ [
102
+ [:default, locations.most_relevant.relative_filename],
103
+ [:muted, ':'],
104
+ [:default, locations.most_relevant.line_number],
105
+ [:muted, "\n #{locations.most_relevant.source_code.line.strip}"]
106
+ ]
132
107
  end
133
108
 
134
109
  def source_tokens
135
- filename = issue.location.project_file
136
- line_number = issue.location.project_failure_line
137
-
110
+ filename = locations.project.filename
111
+ line_number = locations.project.line_number
138
112
  source = Minitest::Heat::Source.new(filename, line_number: line_number)
113
+
139
114
  [[:muted, " #{Output::SYMBOLS[:arrow]} `#{source.line.strip}`"]]
140
115
  end
141
116
 
@@ -147,9 +122,10 @@ module Minitest
147
122
  [
148
123
  [:bold, slowness(issue)],
149
124
  spacer_token,
150
- [:default, issue.location.test_file.to_s.delete_prefix(Dir.pwd)],
125
+ [:default, locations.test_definition.relative_path],
126
+ [:default, locations.test_definition.filename],
151
127
  [:muted, ':'],
152
- [:default, issue.location.test_definition_line]
128
+ [:default, locations.test_definition.line_number]
153
129
  ]
154
130
  end
155
131
 
@@ -161,30 +137,6 @@ module Minitest
161
137
  []
162
138
  end
163
139
 
164
- def most_relevant_short_location
165
- issue.location.most_relevant_file.to_s.delete_prefix("#{Dir.pwd}/")
166
- end
167
-
168
- def test_file_short_location
169
- issue.location.test_file.to_s.delete_prefix("#{Dir.pwd}/")
170
- end
171
-
172
- def most_relevant_line_source
173
- filename = issue.location.project_file
174
- line_number = issue.location.project_failure_line
175
-
176
- source = Minitest::Heat::Source.new(filename, line_number: line_number)
177
- "\n #{source.line.strip}"
178
- end
179
-
180
- def test_line_source
181
- filename = issue.location.test_file
182
- line_number = issue.location.test_failure_line
183
-
184
- source = Minitest::Heat::Source.new(filename, line_number: line_number)
185
- "\n #{source.line.strip}"
186
- end
187
-
188
140
  def spacer_token
189
141
  Output::TOKENS[:spacer]
190
142
  end
@@ -192,6 +144,27 @@ module Minitest
192
144
  def arrow_token
193
145
  Output::TOKENS[:muted_arrow]
194
146
  end
147
+
148
+ def backtrace_tokens
149
+ @backtrace_tokens ||= ::Minitest::Heat::Output::Backtrace.new(locations).tokens
150
+ end
151
+
152
+ # The string to use to describe the failure type when displaying results/
153
+ # @param issue_type [Symbol] the symbol representing the issue's failure type
154
+ #
155
+ # @return [String] the display-friendly string describing the failure reason
156
+ def issue_label(issue_type)
157
+ case issue_type
158
+ when :error then 'Error'
159
+ when :broken then 'Broken Test'
160
+ when :failure then 'Failure'
161
+ when :skipped then 'Skipped'
162
+ when :slow then 'Passed but Slow'
163
+ when :painful then 'Passed but Very Slow'
164
+ when :passed then 'Success'
165
+ else 'Unknown'
166
+ end
167
+ end
195
168
  end
196
169
  end
197
170
  end
@@ -13,16 +13,36 @@ module Minitest
13
13
  end
14
14
 
15
15
  def tokens
16
- map.file_hits.each do |hit|
17
- file_tokens = pathname(hit)
18
- line_number_tokens = line_numbers(hit)
16
+ results.heat_map.file_hits.each do |hit|
17
+ # Focus on the relevant issues based on most significant problems. i.e. If there are
18
+ # legitimate failures or errors, skips and slows aren't relevant
19
+ next unless relevant_issue_types?(hit)
19
20
 
20
- next if line_number_tokens.empty?
21
+ # Add a new line
22
+ @tokens << [[:muted, ""]]
21
23
 
22
- @tokens << [
23
- *file_tokens,
24
- *line_number_tokens
25
- ]
24
+ # Build the summary line for the file
25
+ @tokens << file_summary_tokens(hit)
26
+
27
+ # Get the set of line numbers that appear more than once
28
+ repeated_line_numbers = find_repeated_line_numbers_in(hit)
29
+
30
+ # Only display more details if the same line number shows up more than once
31
+ next unless repeated_line_numbers.any?
32
+
33
+ repeated_line_numbers.each do |line_number|
34
+ # Get the backtraces for the given line numbers
35
+ traces = hit.lines[line_number.to_s]
36
+
37
+ # If there aren't any traces there's no way to provide additional details
38
+ break unless traces.any?
39
+
40
+ # A short summary explaining the details that will follow
41
+ @tokens << [[:muted, " Issues on Line #{line_number} initially triggered from these locations:"]]
42
+
43
+ # The last relevant location for each error's backtrace
44
+ @tokens += origination_sources(traces)
45
+ end
26
46
  end
27
47
 
28
48
  @tokens
@@ -30,8 +50,34 @@ module Minitest
30
50
 
31
51
  private
32
52
 
33
- def map
34
- results.heat_map
53
+ def origination_sources(traces)
54
+ # 1. Sort the traces by the most recent line number so they're displayed in numeric order
55
+ # 2. Get the final relevant location from the trace
56
+ traces.
57
+ sort_by { |trace| trace.locations.last.line_number }.
58
+ map { |trace| origination_location_token(trace) }
59
+ end
60
+
61
+ def file_summary_tokens(hit)
62
+ pathname_tokens = pathname(hit)
63
+ line_number_list_tokens = sorted_line_number_list(hit)
64
+
65
+ [*pathname_tokens, *line_number_list_tokens]
66
+ end
67
+
68
+ def origination_location_token(trace)
69
+ # The earliest project line from the backtrace—this is probabyl wholly incorrect in terms
70
+ # of what would be the most helpful line to display, but it's a start.
71
+ location = trace.locations.last
72
+
73
+ [
74
+ [:muted, " #{Output::SYMBOLS[:arrow]} "],
75
+ [:default, location.relative_filename],
76
+ [:muted, ':'],
77
+ [:default, location.line_number],
78
+ [:muted, " in #{location.container}"],
79
+ [:muted, " #{Output::SYMBOLS[:arrow]} `#{location.source_code.line.strip}`"],
80
+ ]
35
81
  end
36
82
 
37
83
  def relevant_issue_types
@@ -46,37 +92,79 @@ module Minitest
46
92
  issue_types
47
93
  end
48
94
 
49
- def pathname(file)
50
- directory = "#{file.pathname.dirname.to_s.delete_prefix(Dir.pwd)}/".delete_prefix('/')
51
- filename = file.pathname.basename.to_s
95
+ def relevant_issue_types?(hit)
96
+ # The intersection of which issue types are relevant based on the context and which issues
97
+ # matc those issue types
98
+ intersection_issue_types = relevant_issue_types & hit.issues.keys
52
99
 
53
- [
54
- [:default, directory],
55
- [:bold, filename],
56
- [:default, ' · ']
57
- ]
100
+ intersection_issue_types.any?
58
101
  end
59
102
 
60
- def hit_line_numbers(file, issue_type)
61
- numbers = []
62
- line_numbers_for_issue_type = file.issues.fetch(issue_type) { [] }
63
- line_numbers_for_issue_type.map do |line_number|
64
- numbers << [issue_type, "#{line_number} "]
103
+ def find_repeated_line_numbers_in(hit)
104
+ repeated_line_numbers = []
105
+
106
+ hit.lines.each_pair do |line_number, traces|
107
+ # If there aren't multiple traces for a line number, it's not a repeat
108
+ next unless traces.size > 1
109
+
110
+ repeated_line_numbers << Integer(line_number)
65
111
  end
66
112
 
67
- numbers
113
+ repeated_line_numbers.sort
114
+ end
115
+
116
+ def pathname(hit)
117
+ directory = hit.pathname.dirname.to_s.delete_prefix("#{Dir.pwd}/")
118
+ filename = hit.pathname.basename.to_s
119
+
120
+ [
121
+ [:default, "#{directory}/"],
122
+ [:bold, filename],
123
+ [:default, ' · ']
124
+ ]
68
125
  end
69
126
 
70
- def line_numbers(file)
127
+ # Gets the list of line numbers for a given hit location (i.e. file) so they can be
128
+ # displayed after the file name to show which lines were problematic
129
+ # @param hit [Hit] the instance to extract line numbers from
130
+ #
131
+ # @return [Array<Symbol,String>] [description]
132
+ def line_number_tokens_for_hit(hit)
71
133
  line_number_tokens = []
72
134
 
73
- # Merge the hits for all issue types into one list
74
135
  relevant_issue_types.each do |issue_type|
75
- line_number_tokens += hit_line_numbers(file, issue_type)
136
+ # Retrieve any line numbers for the issue type
137
+ line_numbers_for_issue_type = hit.issues.fetch(issue_type) { [] }
138
+
139
+ # Build the list of tokens representing styled line numbers
140
+ line_numbers_for_issue_type.each do |line_number|
141
+ line_number_tokens << line_number_token(issue_type, line_number)
142
+ end
76
143
  end
77
144
 
145
+ line_number_tokens.compact
146
+ end
147
+
148
+ # Builds a token representing a styled line number
149
+ #
150
+ # @param style [Symbol] the relevant display style for the issue
151
+ # @param line_number [Integer] the affected line number
152
+ #
153
+ # @return [Array<Symbol,Integer>] array token representing the line number and issue type
154
+ def line_number_token(style, line_number)
155
+ [style, "#{line_number} "]
156
+ end
157
+
158
+ # Sorts line number tokens so that line numbers are displayed in order regardless of their
159
+ # underlying issue type
160
+ #
161
+ # @param hit [Hit] the instance of the hit file details to build the heat map entry
162
+ #
163
+ # @return [Array] the arrays representing the line number tokens to display next to a file
164
+ # name in the heat map. ex [[:error, 12], [:falure, 13]]
165
+ def sorted_line_number_list(hit)
78
166
  # Sort the collected group of line number hits so they're in order
79
- line_number_tokens.compact.sort do |a, b|
167
+ line_number_tokens_for_hit(hit).sort do |a, b|
80
168
  # Ensure the line numbers are integers for sorting (otherwise '100' comes before '12')
81
169
  first_line_number = Integer(a[1].strip)
82
170
  second_line_number = Integer(b[1].strip)
@@ -11,7 +11,7 @@ require_relative 'output/token'
11
11
  module Minitest
12
12
  module Heat
13
13
  # Friendly API for printing nicely-formatted output to the console
14
- class Output
14
+ class Output # rubocop:disable Metrics/ClassLength
15
15
  SYMBOLS = {
16
16
  middot: '·',
17
17
  arrow: '➜',
@@ -48,23 +48,26 @@ module Minitest
48
48
  newline
49
49
 
50
50
  # Issues start with the least critical and go up to the most critical so that the most
51
- # pressing issues are displayed at the bottom of the report in order to reduce scrolling.
52
- # This way, as you fix issues, the list gets shorter, and eventually the least critical
53
- # issues will be displayed without scrolling once more problematic issues are resolved.
51
+ # pressing issues are displayed at the bottom of the report in order to reduce scrolling.
52
+ #
53
+ # This way, as you fix issues, the list gets shorter, and eventually the least critical
54
+ # issues will be displayed without scrolling once more problematic issues are resolved.
54
55
  %i[slows painfuls skips failures brokens errors].each do |issue_category|
56
+ # Only show categories for the most pressing issues after the suite runs, otherwise,
57
+ # suppress them until the more critical issues are resolved.
55
58
  next unless show?(issue_category, results)
56
59
 
57
60
  results.send(issue_category).each { |issue| issue_details(issue) }
58
61
  end
59
- rescue => e
62
+ rescue StandardError => e
60
63
  message = "Sorry, but Minitest Heat couldn't display the details of any failures."
61
64
  exception_guidance(message, e)
62
65
  end
63
66
 
64
67
  def issue_details(issue)
65
68
  print_tokens Minitest::Heat::Output::Issue.new(issue).tokens
66
- rescue => e
67
- message = "Sorry, but Minitest Heat couldn't display output for a failure."
69
+ rescue StandardError => e
70
+ message = "Sorry, but Minitest Heat couldn't display output for a specific failure."
68
71
  exception_guidance(message, e)
69
72
  end
70
73
 
@@ -75,7 +78,7 @@ module Minitest
75
78
  def compact_summary(results, timer)
76
79
  newline
77
80
  print_tokens ::Minitest::Heat::Output::Results.new(results, timer).tokens
78
- rescue => e
81
+ rescue StandardError => e
79
82
  message = "Sorry, but Minitest Heat couldn't display the summary."
80
83
  exception_guidance(message, e)
81
84
  end
@@ -84,15 +87,24 @@ module Minitest
84
87
  newline
85
88
  print_tokens ::Minitest::Heat::Output::Map.new(map).tokens
86
89
  newline
87
- rescue => e
90
+ rescue StandardError => e
88
91
  message = "Sorry, but Minitest Heat couldn't display the heat map."
89
92
  exception_guidance(message, e)
90
93
  end
91
94
 
95
+ private
96
+
97
+ # Displays some guidance related to exceptions generated by Minitest Heat in order to help
98
+ # people get back on track (and ideally submit issues)
99
+ # @param message [String] a slightly more specific explanation of which part of minitest-heat
100
+ # caused the failure
101
+ # @param exception [Exception] the exception that caused the problem
102
+ #
103
+ # @return [void] displays the guidance to the console
92
104
  def exception_guidance(message, exception)
93
105
  newline
94
106
  puts "#{message} Disabling Minitest Heat can get you back on track until the problem can be fixed."
95
- puts "Please use the following exception details to submit an issue at https://github.com/garrettdimon/minitest-heat/issues"
107
+ puts 'Please use the following exception details to submit an issue at https://github.com/garrettdimon/minitest-heat/issues'
96
108
  puts "#{exception.message}:"
97
109
  exception.backtrace.each do |line|
98
110
  puts " #{line}"
@@ -100,8 +112,6 @@ module Minitest
100
112
  newline
101
113
  end
102
114
 
103
- private
104
-
105
115
  def no_problems?(results)
106
116
  !results.problems?
107
117
  end
@@ -138,7 +148,11 @@ module Minitest
138
148
  def print_tokens(lines_of_tokens)
139
149
  lines_of_tokens.each do |tokens|
140
150
  tokens.each do |token|
141
- print Token.new(*token).to_s(token_format)
151
+ begin
152
+ print Token.new(*token).to_s(token_format)
153
+ rescue
154
+ puts token.inspect
155
+ end
142
156
  end
143
157
  newline
144
158
  end
@@ -19,16 +19,21 @@ module Minitest
19
19
  # Record everything—even if it's a success
20
20
  @issues.push(issue)
21
21
 
22
- # If it's not a genuine problem, we're done here, otherwise update the heat map
23
- update_heat_map(issue) if issue.hit?
22
+ # If it's not a genuine problem, we're done here...
23
+ return unless issue.hit?
24
+
25
+ # ...otherwise update the heat map
26
+ update_heat_map(issue)
24
27
  end
25
28
 
26
29
  def update_heat_map(issue)
27
- # Get the elements we need to generate a heat map entry
28
- pathname = issue.location.project_file.to_s
29
- line_number = issue.location.project_failure_line.to_i
30
+ # For heat map purposes, only the project backtrace lines are interesting
31
+ pathname, line_number = issue.locations.project.to_a
32
+
33
+ # Backtrace is only relevant for exception-generating issues, not slows, skips, or failures
34
+ backtrace = issue.error? ? issue.locations.backtrace.project_locations : []
30
35
 
31
- @heat_map.add(pathname, line_number, issue.type)
36
+ @heat_map.add(pathname, line_number, issue.type, backtrace: backtrace)
32
37
  end
33
38
 
34
39
  def problems?
@@ -35,7 +35,7 @@ module Minitest
35
35
  #
36
36
  # @return [Array<String>] the range of lines of code around
37
37
  def lines
38
- return [line] if max_line_count == 1
38
+ return [line].compact if max_line_count == 1
39
39
 
40
40
  file_lines[(line_numbers.first - 1)..(line_numbers.last - 1)]
41
41
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Minitest
4
4
  module Heat
5
- VERSION = '0.0.10'
5
+ VERSION = '0.0.14'
6
6
  end
7
7
  end
data/lib/minitest/heat.rb CHANGED
@@ -4,6 +4,7 @@ require_relative 'heat/backtrace'
4
4
  require_relative 'heat/hit'
5
5
  require_relative 'heat/issue'
6
6
  require_relative 'heat/location'
7
+ require_relative 'heat/locations'
7
8
  require_relative 'heat/map'
8
9
  require_relative 'heat/output'
9
10
  require_relative 'heat/results'
@@ -6,7 +6,7 @@ module Minitest # rubocop:disable Style/Documentation
6
6
  def self.plugin_heat_init(options)
7
7
  io = options.fetch(:io, $stdout)
8
8
 
9
- self.reporter.reporters.reject! do |reporter|
9
+ reporter.reporters.reject! do |reporter|
10
10
  # Minitest Heat acts as a unified Progress *and* Summary reporter. Using other reporters of
11
11
  # those types in conjunction with it creates some overly-verbose output
12
12
  reporter.is_a?(ProgressReporter) || reporter.is_a?(SummaryReporter)
@@ -74,12 +74,16 @@ module Minitest
74
74
 
75
75
  # Show the marker
76
76
  output.marker(issue.type)
77
- rescue => e
77
+ rescue StandardError => e
78
+ display_exception_guidance(e)
79
+ end
80
+
81
+ def display_exception_guidance(exception)
78
82
  output.newline
79
- puts "Sorry, but Minitest Heat encountered an exception recording an issue. Disabling Minitest Heat will get you back on track."
80
- puts "Please use the following exception details to submit an issue at https://github.com/garrettdimon/minitest-heat/issues"
81
- puts "#{e.message}:"
82
- e.backtrace.each do |line|
83
+ puts 'Sorry, but Minitest Heat encountered an exception recording an issue. Disabling Minitest Heat will get you back on track.'
84
+ puts 'Please use the following exception details to submit an issue at https://github.com/garrettdimon/minitest-heat/issues'
85
+ puts "#{exception.message}:"
86
+ exception.backtrace.each do |line|
83
87
  puts " #{line}"
84
88
  end
85
89
  output.newline
@@ -92,13 +96,16 @@ module Minitest
92
96
  # The list of individual issues and their associated details
93
97
  output.issues_list(results)
94
98
 
95
- # Display a short summary of the total issue counts fore ach category as well as performance
99
+ # Display a short summary of the total issue counts for each category as well as performance
96
100
  # details for the test suite as a whole
97
101
  output.compact_summary(results, timer)
98
102
 
99
103
  # If there were issues, shows a short heat map summary of which files and lines were the most
100
104
  # common sources of issues
101
105
  output.heat_map(results)
106
+
107
+ output.newline
108
+ output.newline
102
109
  end
103
110
 
104
111
  # Did this run pass?
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: minitest-heat
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garrett Dimon
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-31 00:00:00.000000000 Z
11
+ date: 2021-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: minitest
@@ -141,12 +141,19 @@ files:
141
141
  - Rakefile
142
142
  - bin/console
143
143
  - bin/setup
144
+ - examples/exceptions.png
145
+ - examples/failures.png
146
+ - examples/map.png
147
+ - examples/markers.png
148
+ - examples/skips.png
149
+ - examples/slows.png
144
150
  - lib/minitest/heat.rb
145
151
  - lib/minitest/heat/backtrace.rb
146
- - lib/minitest/heat/backtrace/line.rb
152
+ - lib/minitest/heat/backtrace/line_parser.rb
147
153
  - lib/minitest/heat/hit.rb
148
154
  - lib/minitest/heat/issue.rb
149
155
  - lib/minitest/heat/location.rb
156
+ - lib/minitest/heat/locations.rb
150
157
  - lib/minitest/heat/map.rb
151
158
  - lib/minitest/heat/output.rb
152
159
  - lib/minitest/heat/output/backtrace.rb
@@ -188,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
188
195
  - !ruby/object:Gem::Version
189
196
  version: '0'
190
197
  requirements: []
191
- rubygems_version: 3.1.6
198
+ rubygems_version: 3.2.22
192
199
  signing_key:
193
200
  specification_version: 4
194
201
  summary: Presents test results in a visual manner to guide you to where to look first.