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.
- checksums.yaml +4 -4
- data/Gemfile.lock +6 -6
- data/README.md +48 -13
- data/examples/exceptions.png +0 -0
- data/examples/failures.png +0 -0
- data/examples/map.png +0 -0
- data/examples/markers.png +0 -0
- data/examples/skips.png +0 -0
- data/examples/slows.png +0 -0
- data/lib/minitest/heat/backtrace/line_parser.rb +25 -0
- data/lib/minitest/heat/backtrace.rb +21 -59
- data/lib/minitest/heat/hit.rb +18 -6
- data/lib/minitest/heat/issue.rb +35 -17
- data/lib/minitest/heat/location.rb +113 -132
- data/lib/minitest/heat/locations.rb +105 -0
- data/lib/minitest/heat/map.rb +3 -4
- data/lib/minitest/heat/output/backtrace.rb +88 -70
- data/lib/minitest/heat/output/issue.rb +56 -83
- data/lib/minitest/heat/output/map.rb +116 -28
- data/lib/minitest/heat/output.rb +27 -13
- data/lib/minitest/heat/results.rb +11 -6
- data/lib/minitest/heat/source.rb +1 -1
- data/lib/minitest/heat/version.rb +1 -1
- data/lib/minitest/heat.rb +1 -0
- data/lib/minitest/heat_plugin.rb +1 -1
- data/lib/minitest/heat_reporter.rb +13 -6
- metadata +11 -4
- data/lib/minitest/heat/backtrace/line.rb +0 -118
@@ -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
|
17
|
-
when :
|
18
|
-
when :
|
19
|
-
when :
|
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
|
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
|
-
[
|
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
|
96
|
-
|
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
|
-
[
|
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
|
-
[
|
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 =
|
136
|
-
line_number =
|
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,
|
125
|
+
[:default, locations.test_definition.relative_path],
|
126
|
+
[:default, locations.test_definition.filename],
|
151
127
|
[:muted, ':'],
|
152
|
-
[:default,
|
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
|
-
|
17
|
-
|
18
|
-
|
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
|
-
|
21
|
+
# Add a new line
|
22
|
+
@tokens << [[:muted, ""]]
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|
34
|
-
|
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
|
50
|
-
|
51
|
-
|
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
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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)
|
data/lib/minitest/heat/output.rb
CHANGED
@@ -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
|
-
#
|
52
|
-
#
|
53
|
-
#
|
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
|
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
|
-
|
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
|
23
|
-
|
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
|
-
#
|
28
|
-
pathname
|
29
|
-
|
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?
|
data/lib/minitest/heat/source.rb
CHANGED
data/lib/minitest/heat.rb
CHANGED
data/lib/minitest/heat_plugin.rb
CHANGED
@@ -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
|
-
|
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
|
80
|
-
puts
|
81
|
-
puts "#{
|
82
|
-
|
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
|
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.
|
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-
|
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/
|
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.
|
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.
|