minitest-heat 0.0.10 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
@@ -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.