minitest-heat 2.1.0 → 2.2.0

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.
@@ -7,6 +7,7 @@ module Minitest
7
7
  # Kind of like an issue, but instead of focusing on a failing test, it covers all issues for a
8
8
  # given file to build a heat map of the affected files and line numbers
9
9
  class Hit
10
+ # Represents a single occurrence of an issue at a specific line
10
11
  Trace = Struct.new(:type, :line_number, :locations)
11
12
 
12
13
  # So we can sort hot spots by liklihood of being the most important spot to check out before
@@ -62,23 +63,17 @@ module Minitest
62
63
  # the most problematic across the various issue types
63
64
  #
64
65
  # @return [Integer] the problem weight for the file
65
- def weight
66
- issues.sum { |type, values| values.size * WEIGHTS.fetch(type, 0) }
67
- end
66
+ def weight = issues.sum { |type, values| values.size * WEIGHTS.fetch(type, 0) }
68
67
 
69
68
  # The total issue count for the file across all issue types. Includes duplicates if they exist
70
69
  #
71
70
  # @return [Integer] the sum of the counts for all line numbers for all issue types
72
- def count
73
- issues.sum { |_type, values| values.size }
74
- end
71
+ def count = issues.sum { |_type, values| values.size }
75
72
 
76
73
  # The full set of unique line numbers across all issue types
77
74
  #
78
75
  # @return [Array<Integer>] the full set of unique offending line numbers for the hit
79
- def line_numbers
80
- issues.values.flatten.uniq.sort
81
- end
76
+ def line_numbers = issues.values.flatten.uniq.sort
82
77
 
83
78
  # Generates a hash representation for JSON serialization
84
79
  #
@@ -93,9 +88,7 @@ module Minitest
93
88
 
94
89
  private
95
90
 
96
- def relative_path
97
- pathname.to_s.delete_prefix("#{Dir.pwd}/")
98
- end
91
+ def relative_path = pathname.to_s.delete_prefix("#{Dir.pwd}/")
99
92
 
100
93
  def lines_summary
101
94
  line_numbers.map do |line_num|
@@ -90,7 +90,7 @@ module Minitest
90
90
  # painfully slow and should get more attention.
91
91
  #
92
92
  # @return [Symbol] issue type for classifying issues and reporting
93
- def type # rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
93
+ def type # rubocop:disable Metrics/PerceivedComplexity
94
94
  if error? && in_test?
95
95
  :broken
96
96
  elsif error?
@@ -112,88 +112,66 @@ module Minitest
112
112
  # (Because slow tests still pass and wouldn't otherwise be considered an issue.)
113
113
  #
114
114
  # @return [Boolean] true if the test did not pass or if it was slow
115
- def hit?
116
- !passed? || slow? || painful?
117
- end
115
+ def hit? = !passed? || slow? || painful?
118
116
 
119
117
  # The number, in seconds, for a test to be considered "slow"
120
118
  #
121
119
  # @return [Float] number of seconds after which a test is considered slow
122
- def slow_threshold
123
- Minitest::Heat.configuration.slow_threshold
124
- end
120
+ def slow_threshold = Minitest::Heat.configuration.slow_threshold
125
121
 
126
122
  # The number, in seconds, for a test to be considered "painfully slow"
127
123
  #
128
124
  # @return [Float] number of seconds after which a test is considered painfully slow
129
- def painfully_slow_threshold
130
- Minitest::Heat.configuration.painfully_slow_threshold
131
- end
125
+ def painfully_slow_threshold = Minitest::Heat.configuration.painfully_slow_threshold
132
126
 
133
127
  # Determines if a test should be considered slow by comparing it to the low end definition of
134
128
  # what is considered slow.
135
129
  #
136
130
  # @return [Boolean] true if the test took longer to run than `slow_threshold`
137
- def slow?
138
- execution_time >= slow_threshold && execution_time < painfully_slow_threshold
139
- end
131
+ def slow? = execution_time >= slow_threshold && execution_time < painfully_slow_threshold
140
132
 
141
133
  # Determines if a test should be considered painfully slow by comparing it to the high end
142
134
  # definition of what is considered slow.
143
135
  #
144
136
  # @return [Boolean] true if the test took longer to run than `painfully_slow_threshold`
145
- def painful?
146
- execution_time >= painfully_slow_threshold
147
- end
137
+ def painful? = execution_time >= painfully_slow_threshold
148
138
 
149
139
  # Determines if the issue is an exception that was raised from directly within a test
150
140
  # definition. In these cases, it's more likely to be a quick fix.
151
141
  #
152
142
  # @return [Boolean] true if the final locations of the stacktrace was a test file
153
- def in_test?
154
- locations.broken_test?
155
- end
143
+ def in_test? = locations.broken_test?
156
144
 
157
145
  # Determines if the issue is an exception that was raised from directly within the project
158
146
  # codebase.
159
147
  #
160
148
  # @return [Boolean] true if the final locations of the stacktrace was a file from the project
161
149
  # (as opposed to a dependency or Ruby library)
162
- def in_source?
163
- locations.proper_failure?
164
- end
150
+ def in_source? = locations.proper_failure?
165
151
 
166
152
  # Was the result a pass? i.e. Skips aren't passes or failures. Slows are still passes. So this
167
153
  # is purely a measure of whether the test explicitly passed all assertions
168
154
  #
169
155
  # @return [Boolean] false for errors, failures, or skips, true for passes (including slows)
170
- def passed?
171
- passed
172
- end
156
+ def passed? = passed
173
157
 
174
158
  # Was there an exception that triggered a failure?
175
159
  #
176
160
  # @return [Boolean] true if there's an exception
177
- def error?
178
- error
179
- end
161
+ def error? = error
180
162
 
181
163
  # Was the test skipped?
182
164
  #
183
165
  # @return [Boolean] true if the test was explicitly skipped, false otherwise
184
- def skipped?
185
- skipped
186
- end
166
+ def skipped? = skipped
187
167
 
188
168
  # The more nuanced detail of the failure. If it's an error, digs into the exception. Otherwise
189
169
  # uses the message from the result
190
170
  #
191
171
  # @return [String] a more detailed explanation of the issue
192
- def summary
193
- # When there's an exception, use the first line from the exception message. Otherwise, the
194
- # message represents explanation for a test failure, and should be used in full
195
- error? ? first_line_of_exception_message : message
196
- end
172
+ # When there's an exception, use the first line from the exception message. Otherwise, the
173
+ # message represents explanation for a test failure, and should be used in full
174
+ def summary = error? ? first_line_of_exception_message : message
197
175
 
198
176
  # Returns the first line of an exception message when the issue is from a proper exception
199
177
  # failure since exception messages can be long and cumbersome.
@@ -207,9 +185,7 @@ module Minitest
207
185
  text.size > exception_message_limit ? "#{text[0..exception_message_limit]}..." : text
208
186
  end
209
187
 
210
- def exception_message_limit
211
- 200
212
- end
188
+ def exception_message_limit = 200
213
189
 
214
190
  # Generates a hash representation for JSON serialization
215
191
  #
@@ -30,19 +30,12 @@ module Minitest
30
30
  # Generates a formatted string describing the line of code similar to the original backtrace
31
31
  #
32
32
  # @return [String] a consistently-formatted, human-readable string about the line of code
33
- def to_s
34
- "#{absolute_path}#{filename}:#{line_number} in `#{container}`"
35
- end
33
+ def to_s = "#{absolute_path}#{filename}:#{line_number} in `#{container}`"
36
34
 
37
35
  # Generates a simplified location array with the pathname and line number
38
36
  #
39
37
  # @return [Array<Pathname, Integer>] a no-frills location pair
40
- def to_a
41
- [
42
- pathname,
43
- line_number
44
- ]
45
- end
38
+ def to_a = [pathname, line_number]
46
39
 
47
40
  # Generates a hash representation for JSON serialization
48
41
  #
@@ -58,23 +51,24 @@ module Minitest
58
51
  # A short relative pathname and line number pair
59
52
  #
60
53
  # @return [String] the short filename/line number combo. ex. `dir/file.rb:23`
61
- def short
62
- "#{relative_filename}:#{line_number}"
63
- end
54
+ def short = "#{relative_filename}:#{line_number}"
55
+
56
+ # Determine if the file exists on disk
57
+ #
58
+ # @return [Boolean] true if the file exists
59
+ def file_exists? = pathname.exist?
64
60
 
65
61
  # Determine if there is a file and text at the given line number
66
62
  #
67
63
  # @return [Boolean] true if the file exists and has text at the given line number
68
- def exists?
69
- pathname.exist? && source_code.lines.any?
70
- end
64
+ def exists? = file_exists? && source_code.lines.any?
71
65
 
72
66
  # The pathanme for the location. Written to be safe and fallbackto the project directory if
73
67
  # an exception is raised ocnverting the value to a pathname
74
68
  #
75
69
  # @return [Pathname] a pathname instance for the relevant file
76
70
  def pathname
77
- Pathname(raw_pathname)
71
+ Pathname(raw_pathname).expand_path
78
72
  rescue ArgumentError
79
73
  Pathname(Dir.pwd)
80
74
  end
@@ -83,33 +77,21 @@ module Minitest
83
77
  #
84
78
  # @return [String] either the path/directory portion of the file name or '(Unrecognized File)'
85
79
  # if the offending file can't be found for some reason
86
- def path
87
- pathname.exist? ? pathname.dirname.to_s : UNRECOGNIZED
88
- end
80
+ def path = file_exists? ? pathname.dirname.to_s : UNRECOGNIZED
89
81
 
90
- def absolute_path
91
- pathname.exist? ? "#{path}/" : UNRECOGNIZED
92
- end
82
+ def absolute_path = file_exists? ? "#{path}/" : UNRECOGNIZED
93
83
 
94
- def relative_path
95
- pathname.exist? ? absolute_path.delete_prefix("#{project_root_dir}/") : UNRECOGNIZED
96
- end
84
+ def relative_path = file_exists? ? absolute_path.delete_prefix("#{project_root_dir}/") : UNRECOGNIZED
97
85
 
98
86
  # A safe interface for getting a string representing the filename portion of the file
99
87
  #
100
88
  # @return [String] either the filename portion of the file or '(Unrecognized File)'
101
89
  # if the offending file can't be found for some reason
102
- def filename
103
- pathname.exist? ? pathname.basename.to_s : UNRECOGNIZED
104
- end
90
+ def filename = file_exists? ? pathname.basename.to_s : UNRECOGNIZED
105
91
 
106
- def absolute_filename
107
- pathname.exist? ? pathname.to_s : UNRECOGNIZED
108
- end
92
+ def absolute_filename = file_exists? ? pathname.to_s : UNRECOGNIZED
109
93
 
110
- def relative_filename
111
- pathname.exist? ? pathname.to_s.delete_prefix("#{project_root_dir}/") : UNRECOGNIZED
112
- end
94
+ def relative_filename = file_exists? ? pathname.to_s.delete_prefix("#{project_root_dir}/") : UNRECOGNIZED
113
95
 
114
96
  # Line number identifying the specific line in the file
115
97
  #
@@ -124,9 +106,7 @@ module Minitest
124
106
  # The containing method or block details for the location
125
107
  #
126
108
  # @return [String] the containing method of the line of code
127
- def container
128
- raw_container.nil? ? '(Unknown Container)' : String(raw_container)
129
- end
109
+ def container = raw_container.nil? ? '(Unknown Container)' : String(raw_container)
130
110
 
131
111
  # Looks up the source code for the location. Can return multiple lines of source code from
132
112
  # the surrounding lines of code for the primary line
@@ -145,65 +125,47 @@ module Minitest
145
125
  # Determines if a given file is from the project directory
146
126
  #
147
127
  # @return [Boolean] true if the file is in the project (source code or test) but not vendored
148
- def project_file?
149
- path.include?(project_root_dir) && !bundled_file? && !binstub_file?
150
- end
128
+ def project_file? = path.include?(project_root_dir) && !bundled_file? && !binstub_file?
151
129
 
152
130
  # Determines if the file is in the project `vendor/bundle` directory.
153
131
  #
154
132
  # @return [Boolean] true if the file is in `<project_root>/vendor/bundle
155
- def bundled_file?
156
- path.include?("#{project_root_dir}/vendor/bundle")
157
- end
133
+ def bundled_file? = path.include?("#{project_root_dir}/vendor/bundle")
158
134
 
159
135
  # Determines if the file is in the project `bin` directory. With binstub'd gems, they'll
160
136
  # appear to be source code because the code is located in the project directory. This helps
161
137
  # make sure the backtraces don't think that's the case
162
138
  #
163
139
  # @return [Boolean] true if the file is in `<project_root>/bin
164
- def binstub_file?
165
- path.include?("#{project_root_dir}/bin")
166
- end
140
+ def binstub_file? = path.include?("#{project_root_dir}/bin")
167
141
 
168
142
  # Determines if a given file follows the standard approaching to naming test files.
169
143
  #
170
144
  # @return [Boolean] true if the file name starts with `test_` or ends with `_test.rb`
171
- def test_file?
172
- filename.to_s.start_with?('test_') || filename.to_s.end_with?('_test.rb')
173
- end
145
+ def test_file? = filename.to_s.start_with?('test_') || filename.to_s.end_with?('_test.rb')
174
146
 
175
147
  # Determines if a given file is a non-test file from the project directory
176
148
  #
177
149
  # @return [Boolean] true if the file is in the project but not a test file or vendored file
178
- def source_code_file?
179
- project_file? && !test_file?
180
- end
150
+ def source_code_file? = project_file? && !test_file?
181
151
 
182
152
  # A safe interface to getting the last modified time for the file in question
183
153
  #
184
154
  # @return [Time] the timestamp for when the file in question was last modified or `Time.at(0)`
185
155
  # if the offending file can't be found for some reason
186
- def mtime
187
- pathname.exist? ? pathname.mtime : UNKNOWN_MODIFICATION_TIME
188
- end
156
+ def mtime = file_exists? ? pathname.mtime : UNKNOWN_MODIFICATION_TIME
189
157
 
190
158
  # A safe interface to getting the number of seconds since the file was modified
191
159
  #
192
160
  # @return [Integer] the number of seconds since the file was modified or `-1` if the offending
193
161
  # file can't be found for some reason
194
- def age_in_seconds
195
- pathname.exist? ? seconds_ago : UNKNOWN_MODIFICATION_SECONDS
196
- end
162
+ def age_in_seconds = file_exists? ? seconds_ago : UNKNOWN_MODIFICATION_SECONDS
197
163
 
198
164
  private
199
165
 
200
- def project_root_dir
201
- Dir.pwd
202
- end
166
+ def project_root_dir = Dir.pwd
203
167
 
204
- def seconds_ago
205
- (Time.now - mtime).to_i
206
- end
168
+ def seconds_ago = (Time.now - mtime).to_i
207
169
  end
208
170
  end
209
171
  end
@@ -28,27 +28,21 @@ module Minitest
28
28
  # test failure
29
29
  #
30
30
  # @return [String] ex. 'path/to/file.rb:12'
31
- def to_s
32
- "#{most_relevant.absolute_filename}:#{most_relevant.line_number}"
33
- end
31
+ def to_s = "#{most_relevant.absolute_filename}:#{most_relevant.line_number}"
34
32
 
35
33
  # Knows if the failure is contained within the test. For example, if there's bad code in a
36
34
  # test, and it raises an exception, then it's really a broken test rather than a proper
37
35
  # faiure.
38
36
  #
39
37
  # @return [Boolean] true if final file in the backtrace is the same as the test location file
40
- def broken_test?
41
- !test_failure.nil? && test_failure == final
42
- end
38
+ def broken_test? = !test_failure.nil? && test_failure == final
43
39
 
44
40
  # Knows if the failure occurred in the actual project source code—as opposed to the test or
45
41
  # an external piece of code like a gem.
46
42
  #
47
43
  # @return [Boolean] true if there's a non-test project file in the stacktrace but it's not
48
44
  # a result of a broken test
49
- def proper_failure?
50
- !source_code.nil? && !broken_test?
51
- end
45
+ def proper_failure? = !source_code.nil? && !broken_test?
52
46
 
53
47
  # The file most likely to be the source of the underlying problem. Often, the most recent
54
48
  # backtrace files will be a gem or external library that's failing indirectly as a result
@@ -64,9 +58,7 @@ module Minitest
64
58
  ].compact.first
65
59
  end
66
60
 
67
- def freshest
68
- backtrace.recently_modified_locations.first
69
- end
61
+ def freshest = backtrace.recently_modified_locations.first
70
62
 
71
63
  # Returns the final test location based on the backtrace if present. Otherwise falls back to
72
64
  # the test location which represents the test definition. The `test_definition` attribute
@@ -74,32 +66,24 @@ module Minitest
74
66
  # line from within the test where the problem occurred
75
67
  #
76
68
  # @return [Location] the final location from the test files
77
- def test_failure
78
- backtrace.test_locations.any? ? backtrace.test_locations.first : test_definition
79
- end
69
+ def test_failure = backtrace.test_locations.any? ? backtrace.test_locations.first : test_definition
80
70
 
81
71
  # Returns the final source code location based on the backtrace
82
72
  #
83
73
  # @return [Location] the final location from the source code files
84
- def source_code
85
- backtrace.source_code_locations.first
86
- end
74
+ def source_code = backtrace.source_code_locations.first
87
75
 
88
76
  # Returns the final project location based on the backtrace if present. Otherwise falls back
89
77
  # to the test location which represents the test definition.
90
78
  #
91
79
  # @return [Location] the final location from the project files
92
- def project
93
- backtrace.project_locations.any? ? backtrace.project_locations.first : test_definition
94
- end
80
+ def project = backtrace.project_locations.any? ? backtrace.project_locations.first : test_definition
95
81
 
96
82
  # The line number from within the `test_file` test definition where the failure occurred
97
83
  #
98
84
  # @return [Location] the last location from the backtrace or the test location if a backtrace
99
85
  # was not passed to the initializer
100
- def final
101
- backtrace.locations.any? ? backtrace.locations.first : test_definition
102
- end
86
+ def final = backtrace.locations.any? ? backtrace.locations.first : test_definition
103
87
  end
104
88
  end
105
89
  end
@@ -26,25 +26,19 @@ module Minitest
26
26
  # Returns a subset of affected files to keep the list from being overwhelming
27
27
  #
28
28
  # @return [Array] the list of files and the line numbers for each encountered issue type
29
- def file_hits
30
- hot_files.take(MAXIMUM_FILES_TO_SHOW)
31
- end
29
+ def file_hits = hot_files.take(MAXIMUM_FILES_TO_SHOW)
32
30
 
33
31
  # Generates a hash representation for JSON serialization
34
32
  #
35
33
  # @return [Array<Hash>] array of hit hashes sorted by weight (highest first)
36
- def to_h
37
- hot_files.map(&:to_h)
38
- end
34
+ def to_h = hot_files.map(&:to_h)
39
35
 
40
36
  private
41
37
 
42
38
  # Sorts the files by hit "weight" so that the most problematic files are at the beginning
43
39
  #
44
40
  # @return [Array] the collection of files that encountred issues
45
- def hot_files
46
- hits.values.sort_by(&:weight).reverse
47
- end
41
+ def hot_files = hits.values.sort_by(&:weight).reverse
48
42
  end
49
43
  end
50
44
  end
@@ -23,16 +23,14 @@ module Minitest
23
23
  # Determines the number of lines to display from the backtrace.
24
24
  #
25
25
  # @return [Integer] the number of lines to limit the backtrace to
26
- def line_count
27
- # Defined as a method instead of using the constant directly in order to easily support
28
- # adding options for controlling how many lines are displayed from a backtrace.
29
- #
30
- # For example, instead of a fixed number, the backtrace could dynamically calculate how
31
- # many lines it should displaye in order to get to the origination point. Or it could have
32
- # a default, but inteligently go back further if the backtrace meets some criteria for
33
- # displaying more lines.
34
- ::Minitest::Heat::Backtrace::LineCount.new(backtrace.locations).limit
35
- end
26
+ # Defined as a method instead of using the constant directly in order to easily support
27
+ # adding options for controlling how many lines are displayed from a backtrace.
28
+ #
29
+ # For example, instead of a fixed number, the backtrace could dynamically calculate how
30
+ # many lines it should displaye in order to get to the origination point. Or it could have
31
+ # a default, but inteligently go back further if the backtrace meets some criteria for
32
+ # displaying more lines.
33
+ def line_count = ::Minitest::Heat::Backtrace::LineCount.new(backtrace.locations).limit
36
34
 
37
35
  # A subset of parsed lines from the backtrace.
38
36
  #
@@ -69,16 +67,14 @@ module Minitest
69
67
  *file_and_line_number_tokens(location),
70
68
  containining_element_token(location),
71
69
  source_code_line_token(location),
72
- most_recently_modified_token(location),
70
+ most_recently_modified_token(location)
73
71
  ].compact
74
72
  end
75
73
 
76
74
  # Determines if all lines to be displayed are from within the project directory
77
75
  #
78
76
  # @return [Boolean] true if all lines of the backtrace being displayed are from the project
79
- def all_backtrace_from_project?
80
- backtrace_locations.all?(&:project_file?)
81
- end
77
+ def all_backtrace_from_project? = backtrace_locations.all?(&:project_file?)
82
78
 
83
79
  # Determines if the file referenced by a backtrace line is the most recently modified file
84
80
  # of all the files referenced in the visible backtrace locations.
@@ -87,16 +83,12 @@ module Minitest
87
83
  #
88
84
  # @return [<type>] <description>
89
85
  #
90
- def most_recently_modified?(location)
91
- # If there's more than one line being displayed (otherwise, with one line, of course it's
92
- # the most recently modified because there_aren't any others) and the current line is the
93
- # same as the freshest location in the backtrace
94
- backtrace_locations.size > 1 && location == locations.freshest
95
- end
86
+ # If there's more than one line being displayed (otherwise, with one line, of course it's
87
+ # the most recently modified because there_aren't any others) and the current line is the
88
+ # same as the freshest location in the backtrace
89
+ def most_recently_modified?(location) = backtrace_locations.size > 1 && location == locations.freshest
96
90
 
97
- def indentation_token
98
- [:default, ' ' * indentation]
99
- end
91
+ def indentation_token = [:default, ' ' * indentation]
100
92
 
101
93
  def path_token(location)
102
94
  # If the line is a project file, help it stand out from the backtrace noise
@@ -145,9 +137,7 @@ module Minitest
145
137
  # option that would reduce the space used.
146
138
  #
147
139
  # @return [type] [description]
148
- def indentation
149
- DEFAULT_INDENTATION_SPACES
150
- end
140
+ def indentation = DEFAULT_INDENTATION_SPACES
151
141
  end
152
142
  end
153
143
  end
@@ -4,7 +4,7 @@ module Minitest
4
4
  module Heat
5
5
  class Output
6
6
  # Formats issues to output based on the issue type
7
- class Issue # rubocop:disable Metrics/ClassLength
7
+ class Issue
8
8
  attr_accessor :issue, :locations
9
9
 
10
10
  def initialize(issue)
@@ -19,7 +19,7 @@ module Minitest
19
19
  next unless relevant_issue_types?(hit)
20
20
 
21
21
  # Add a new line
22
- @tokens << [[:muted, ""]]
22
+ @tokens << [[:muted, '']]
23
23
 
24
24
  # Build the summary line for the file
25
25
  @tokens << file_summary_tokens(hit)
@@ -54,10 +54,10 @@ module Minitest
54
54
  # 1. Only pull the traces that have proper locations
55
55
  # 2. Sort the traces by the most recent line number so they're displayed in numeric order
56
56
  # 3. Get the final relevant location from the trace
57
- traces.
58
- select { |trace| trace.locations.any? }.
59
- sort_by { |trace| trace.locations.last.line_number }.
60
- map { |trace| origination_location_token(trace) }
57
+ traces
58
+ .select { |trace| trace.locations.any? }
59
+ .sort_by { |trace| trace.locations.last.line_number }
60
+ .map { |trace| origination_location_token(trace) }
61
61
  end
62
62
 
63
63
  def file_summary_tokens(hit)
@@ -80,7 +80,7 @@ module Minitest
80
80
  [:muted, ':'],
81
81
  [:default, location.line_number],
82
82
  [:muted, " in #{location.container}"],
83
- [:muted, " #{Output::SYMBOLS[:arrow]} `#{location.source_code.line.strip}`"],
83
+ [:muted, " #{Output::SYMBOLS[:arrow]} `#{location.source_code.line.strip}`"]
84
84
  ]
85
85
  end
86
86
 
@@ -160,7 +160,7 @@ module Minitest
160
160
  def line_number_token(style, line_number, frequency)
161
161
  if frequency > 1
162
162
  [
163
- [style, "#{line_number}"],
163
+ [style, line_number.to_s],
164
164
  [:muted, "✕#{frequency} "]
165
165
  ]
166
166
  else
@@ -33,19 +33,13 @@ module Minitest
33
33
  @issue_type = issue_type
34
34
  end
35
35
 
36
- def token
37
- [style, symbol]
38
- end
36
+ def token = [style, symbol]
39
37
 
40
38
  private
41
39
 
42
- def style
43
- STYLES.fetch(issue_type, :default)
44
- end
40
+ def style = STYLES.fetch(issue_type, :default)
45
41
 
46
- def symbol
47
- SYMBOLS.fetch(issue_type, '?')
48
- end
42
+ def symbol = SYMBOLS.fetch(issue_type, '?')
49
43
  end
50
44
  end
51
45
  end