minitest-heat 0.0.5 → 0.0.6
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/.gitignore +1 -0
- data/.rubocop.yml +23 -0
- data/Gemfile +5 -3
- data/Gemfile.lock +30 -1
- data/README.md +12 -3
- data/Rakefile +8 -6
- data/lib/minitest/heat/backtrace.rb +19 -74
- data/lib/minitest/heat/hit.rb +83 -0
- data/lib/minitest/heat/issue.rb +46 -31
- data/lib/minitest/heat/line.rb +74 -0
- data/lib/minitest/heat/location.rb +20 -14
- data/lib/minitest/heat/map.rb +10 -21
- data/lib/minitest/heat/output/backtrace.rb +19 -29
- data/lib/minitest/heat/output/issue.rb +110 -0
- data/lib/minitest/heat/output/map.rb +47 -0
- data/lib/minitest/heat/output/marker.rb +50 -0
- data/lib/minitest/heat/output/results.rb +17 -5
- data/lib/minitest/heat/output/source_code.rb +2 -2
- data/lib/minitest/heat/output/token.rb +15 -13
- data/lib/minitest/heat/output.rb +12 -121
- data/lib/minitest/heat/results.rb +16 -3
- data/lib/minitest/heat/version.rb +3 -1
- data/lib/minitest/heat.rb +2 -0
- data/lib/minitest/heat_plugin.rb +5 -5
- data/lib/minitest/heat_reporter.rb +25 -24
- data/minitest-heat.gemspec +4 -2
- metadata +63 -4
- data/lib/minitest/heat/output/location.rb +0 -20
@@ -14,10 +14,18 @@ module Minitest
|
|
14
14
|
# - 'most_relevant' represents the most specific file to investigate starting with the source
|
15
15
|
# code and then looking to the test code with final line of the backtrace as a fallback
|
16
16
|
class Location
|
17
|
+
TestDefinition = Struct.new(:pathname, :line_number) do
|
18
|
+
def initialize(pathname, line_number)
|
19
|
+
@pathname = Pathname(pathname)
|
20
|
+
@line_number = Integer(line_number)
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
17
25
|
attr_reader :test_location, :backtrace
|
18
26
|
|
19
27
|
def initialize(test_location, backtrace = [])
|
20
|
-
@test_location = test_location
|
28
|
+
@test_location = TestDefinition.new(*test_location)
|
21
29
|
@backtrace = Backtrace.new(backtrace)
|
22
30
|
end
|
23
31
|
|
@@ -58,28 +66,28 @@ module Minitest
|
|
58
66
|
#
|
59
67
|
# @return [String] the relative path to the file from the project root
|
60
68
|
def most_relevant_file
|
61
|
-
Pathname(most_relevant_location
|
69
|
+
Pathname(most_relevant_location.pathname)
|
62
70
|
end
|
63
71
|
|
64
72
|
# The line number of the `most_relevant_file` where the failure originated
|
65
73
|
#
|
66
74
|
# @return [Integer] line number
|
67
75
|
def most_relevant_failure_line
|
68
|
-
most_relevant_location
|
76
|
+
most_relevant_location.line_number
|
69
77
|
end
|
70
78
|
|
71
79
|
# The final location of the stacktrace regardless of whether it's from within the project
|
72
80
|
#
|
73
81
|
# @return [String] the relative path to the file from the project root
|
74
82
|
def final_file
|
75
|
-
Pathname(final_location
|
83
|
+
Pathname(final_location.pathname)
|
76
84
|
end
|
77
85
|
|
78
86
|
# The line number of the `final_file` where the failure originated
|
79
87
|
#
|
80
88
|
# @return [Integer] line number
|
81
89
|
def final_failure_line
|
82
|
-
final_location
|
90
|
+
final_location.line_number
|
83
91
|
end
|
84
92
|
|
85
93
|
# The final location of the stacktrace regardless of whether it's from within the project
|
@@ -100,7 +108,7 @@ module Minitest
|
|
100
108
|
#
|
101
109
|
# @return [String, nil] the relative path to the file from the project root
|
102
110
|
def source_code_file
|
103
|
-
return nil unless backtrace.
|
111
|
+
return nil unless backtrace.source_code_entries.any?
|
104
112
|
|
105
113
|
backtrace.final_source_code_location.pathname
|
106
114
|
end
|
@@ -109,30 +117,30 @@ module Minitest
|
|
109
117
|
#
|
110
118
|
# @return [Integer] line number
|
111
119
|
def source_code_failure_line
|
112
|
-
return nil unless backtrace.
|
120
|
+
return nil unless backtrace.source_code_entries.any?
|
113
121
|
|
114
|
-
backtrace.final_source_code_location.
|
122
|
+
backtrace.final_source_code_location.line_number
|
115
123
|
end
|
116
124
|
|
117
125
|
# The final location from the stacktrace that is within the project's test directory
|
118
126
|
#
|
119
127
|
# @return [String, nil] the relative path to the file from the project root
|
120
128
|
def test_file
|
121
|
-
Pathname(test_location
|
129
|
+
Pathname(test_location.pathname)
|
122
130
|
end
|
123
131
|
|
124
132
|
# The line number of the `test_file` where the test is defined
|
125
133
|
#
|
126
134
|
# @return [Integer] line number
|
127
135
|
def test_definition_line
|
128
|
-
test_location
|
136
|
+
test_location.line_number
|
129
137
|
end
|
130
138
|
|
131
139
|
# The line number from within the `test_file` test definition where the failure occurred
|
132
140
|
#
|
133
141
|
# @return [Integer] line number
|
134
142
|
def test_failure_line
|
135
|
-
backtrace.final_test_location&.
|
143
|
+
backtrace.final_test_location&.line_number || test_definition_line
|
136
144
|
end
|
137
145
|
|
138
146
|
# The line number from within the `test_file` test definition where the failure occurred
|
@@ -166,10 +174,8 @@ module Minitest
|
|
166
174
|
end
|
167
175
|
|
168
176
|
def backtrace?
|
169
|
-
backtrace.
|
177
|
+
backtrace.parsed_entries.any?
|
170
178
|
end
|
171
179
|
end
|
172
180
|
end
|
173
181
|
end
|
174
|
-
|
175
|
-
|
data/lib/minitest/heat/map.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
module Minitest
|
4
4
|
module Heat
|
5
5
|
class Map
|
6
|
+
MAXIMUM_FILES_TO_SHOW = 5
|
7
|
+
|
6
8
|
attr_reader :hits
|
7
9
|
|
8
10
|
# So we can sort hot spots by liklihood of being the most important spot to check out before
|
@@ -14,44 +16,31 @@ module Minitest
|
|
14
16
|
# misleading. It doesn't represent a proper failure, but rather a test that doesn't work.
|
15
17
|
WEIGHTS = {
|
16
18
|
error: 3, # exceptions from source code have the highest liklihood of a ripple effect
|
17
|
-
broken:
|
19
|
+
broken: 2, # broken tests won't have ripple effects but can't help if they can't run
|
18
20
|
failure: 1, # failures are kind of the whole point, and they could have ripple effects
|
19
21
|
skipped: 0, # skips aren't failures, but they shouldn't go ignored
|
20
22
|
painful: 0, # slow tests aren't failures, but they shouldn't be ignored
|
21
|
-
slow: 0
|
22
|
-
}
|
23
|
+
slow: 0
|
24
|
+
}.freeze
|
23
25
|
|
24
26
|
def initialize
|
25
27
|
@hits = {}
|
26
28
|
end
|
27
29
|
|
28
30
|
def add(filename, line_number, type)
|
29
|
-
@hits[filename] ||=
|
30
|
-
@hits[filename][:total] += 1
|
31
|
-
@hits[filename][:weight] += WEIGHTS[type]
|
31
|
+
@hits[filename] ||= Hit.new(filename)
|
32
32
|
|
33
|
-
@hits[filename]
|
34
|
-
@hits[filename][type] << line_number
|
33
|
+
@hits[filename].log(type, line_number)
|
35
34
|
end
|
36
35
|
|
37
|
-
def
|
38
|
-
hot_files
|
39
|
-
.sort_by { |filename, weight| weight }
|
40
|
-
.reverse
|
41
|
-
.take(5)
|
36
|
+
def file_hits
|
37
|
+
hot_files.take(MAXIMUM_FILES_TO_SHOW)
|
42
38
|
end
|
43
39
|
|
44
40
|
private
|
45
41
|
|
46
42
|
def hot_files
|
47
|
-
|
48
|
-
@hits.each_pair do |filename, details|
|
49
|
-
# Can't really be a "hot spot" with just a single issue
|
50
|
-
# next unless details[:weight] > 1
|
51
|
-
|
52
|
-
files[filename] = details[:weight]
|
53
|
-
end
|
54
|
-
files
|
43
|
+
hits.values.sort_by(&:weight).reverse
|
55
44
|
end
|
56
45
|
end
|
57
46
|
end
|
@@ -21,22 +21,18 @@ module Minitest
|
|
21
21
|
# final backtrace line if it might be relevant/helpful?
|
22
22
|
|
23
23
|
# Iterate over the selected lines from the backtrace
|
24
|
-
|
24
|
+
backtrace_entries.each do |backtrace_entry|
|
25
25
|
# Get the source code for the line from the backtrace
|
26
|
-
source_code = source_code_for(backtrace_line)
|
27
|
-
|
28
26
|
parts = [
|
29
27
|
indentation_token,
|
30
|
-
path_token(
|
31
|
-
file_and_line_number_token(
|
32
|
-
source_code_line_token(source_code)
|
28
|
+
path_token(backtrace_entry),
|
29
|
+
file_and_line_number_token(backtrace_entry),
|
30
|
+
source_code_line_token(backtrace_entry.source_code)
|
33
31
|
]
|
34
32
|
|
35
|
-
parts << file_freshness(
|
33
|
+
parts << file_freshness(backtrace_entry) if most_recently_modified?(backtrace_entry)
|
36
34
|
|
37
35
|
@tokens << parts
|
38
|
-
|
39
|
-
|
40
36
|
end
|
41
37
|
|
42
38
|
@tokens
|
@@ -55,37 +51,31 @@ module Minitest
|
|
55
51
|
# ...it could be influenced by a "compact" or "robust" reporter super-style?
|
56
52
|
# ...it's smart about exceptions that were raised outside of the project?
|
57
53
|
# ...it's smart about highlighting lines of code differently based on whether it's source code, test code, or external code?
|
58
|
-
def
|
59
|
-
|
54
|
+
def backtrace_entries
|
55
|
+
project_entries
|
60
56
|
end
|
61
57
|
|
62
58
|
private
|
63
59
|
|
64
|
-
def
|
65
|
-
|
60
|
+
def all_backtrace_entries_from_project?
|
61
|
+
backtrace_entries.all? { |line| line.path.to_s.include?(project_root_dir) }
|
66
62
|
end
|
67
63
|
|
68
64
|
def project_root_dir
|
69
65
|
Dir.pwd
|
70
66
|
end
|
71
67
|
|
72
|
-
def
|
73
|
-
backtrace.
|
68
|
+
def project_entries
|
69
|
+
backtrace.project_entries.take(line_count)
|
74
70
|
end
|
75
71
|
|
76
|
-
def
|
77
|
-
backtrace.
|
78
|
-
end
|
79
|
-
|
80
|
-
def source_code_for(line)
|
81
|
-
filename = "#{line.path}/#{line.file}"
|
82
|
-
|
83
|
-
Minitest::Heat::Source.new(filename, line_number: line.number, max_line_count: 1)
|
72
|
+
def all_entries
|
73
|
+
backtrace.parsed_entries.take(line_count)
|
84
74
|
end
|
85
75
|
|
86
76
|
def most_recently_modified?(line)
|
87
77
|
# If there's more than one line being displayed, and the current line is the freshest
|
88
|
-
|
78
|
+
backtrace_entries.size > 1 && line == backtrace.freshest_project_location
|
89
79
|
end
|
90
80
|
|
91
81
|
def indentation_token
|
@@ -97,21 +87,21 @@ module Minitest
|
|
97
87
|
|
98
88
|
# If all of the backtrace lines are from the project, no point in the added redundant
|
99
89
|
# noise of showing the project root directory over and over again
|
100
|
-
path = path.delete_prefix(project_root_dir) if
|
90
|
+
path = path.delete_prefix(project_root_dir) if all_backtrace_entries_from_project?
|
101
91
|
|
102
92
|
[:muted, path]
|
103
93
|
end
|
104
94
|
|
105
|
-
def file_and_line_number_token(
|
106
|
-
[:default, "#{
|
95
|
+
def file_and_line_number_token(backtrace_entry)
|
96
|
+
[:default, "#{backtrace_entry.file}:#{backtrace_entry.line_number}"]
|
107
97
|
end
|
108
98
|
|
109
99
|
def source_code_line_token(source_code)
|
110
100
|
[:muted, " `#{source_code.line.strip}`"]
|
111
101
|
end
|
112
102
|
|
113
|
-
def file_freshness(
|
114
|
-
[:bold,
|
103
|
+
def file_freshness(_line)
|
104
|
+
[:bold, ' < Most Recently Modified']
|
115
105
|
end
|
116
106
|
|
117
107
|
# The number of spaces each line of code should be indented. Currently defaults to 2 in
|
@@ -4,6 +4,11 @@ module Minitest
|
|
4
4
|
module Heat
|
5
5
|
class Output
|
6
6
|
class Issue
|
7
|
+
SHARED_SYMBOLS = {
|
8
|
+
spacer: ' · ',
|
9
|
+
arrow: ' > '
|
10
|
+
}.freeze
|
11
|
+
|
7
12
|
attr_accessor :issue
|
8
13
|
|
9
14
|
def initialize(issue)
|
@@ -11,6 +16,111 @@ module Minitest
|
|
11
16
|
end
|
12
17
|
|
13
18
|
def tokens
|
19
|
+
case issue.type
|
20
|
+
when :error then error_tokens
|
21
|
+
when :broken then broken_tokens
|
22
|
+
when :failure then failure_tokens
|
23
|
+
when :skipped then skipped_tokens
|
24
|
+
when :painful then painful_tokens
|
25
|
+
when :slow then slow_tokens
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def error_tokens
|
32
|
+
[
|
33
|
+
headline_tokens,
|
34
|
+
summary_tokens,
|
35
|
+
*backtrace_tokens,
|
36
|
+
newline_tokens
|
37
|
+
]
|
38
|
+
end
|
39
|
+
|
40
|
+
def broken_tokens
|
41
|
+
[
|
42
|
+
headline_tokens,
|
43
|
+
summary_tokens,
|
44
|
+
*backtrace_tokens,
|
45
|
+
newline_tokens
|
46
|
+
]
|
47
|
+
end
|
48
|
+
|
49
|
+
def failure_tokens
|
50
|
+
[
|
51
|
+
headline_tokens,
|
52
|
+
summary_tokens,
|
53
|
+
location_tokens,
|
54
|
+
*source_tokens,
|
55
|
+
newline_tokens
|
56
|
+
]
|
57
|
+
end
|
58
|
+
|
59
|
+
def skipped_tokens
|
60
|
+
[
|
61
|
+
headline_tokens,
|
62
|
+
summary_tokens,
|
63
|
+
newline_tokens
|
64
|
+
]
|
65
|
+
end
|
66
|
+
|
67
|
+
def painful_tokens
|
68
|
+
[
|
69
|
+
headline_tokens,
|
70
|
+
slowness_tokens,
|
71
|
+
newline_tokens
|
72
|
+
]
|
73
|
+
end
|
74
|
+
|
75
|
+
def slow_tokens
|
76
|
+
[
|
77
|
+
headline_tokens,
|
78
|
+
slowness_tokens,
|
79
|
+
newline_tokens
|
80
|
+
]
|
81
|
+
end
|
82
|
+
|
83
|
+
def headline_tokens
|
84
|
+
[[issue.type, issue.label], [:muted, spacer], [:default, issue.test_name], [:muted, spacer], [:muted, issue.test_class]]
|
85
|
+
end
|
86
|
+
|
87
|
+
def summary_tokens
|
88
|
+
[[:italicized, issue.summary]]
|
89
|
+
end
|
90
|
+
|
91
|
+
def backtrace_tokens
|
92
|
+
backtrace = ::Minitest::Heat::Output::Backtrace.new(issue.location)
|
93
|
+
|
94
|
+
backtrace.tokens
|
95
|
+
end
|
96
|
+
|
97
|
+
def location_tokens
|
98
|
+
[[:muted, issue.short_location]]
|
99
|
+
end
|
100
|
+
|
101
|
+
def source_tokens
|
102
|
+
filename = issue.location.project_file
|
103
|
+
line_number = issue.location.project_failure_line
|
104
|
+
|
105
|
+
source_code = ::Minitest::Heat::Output::SourceCode.new(filename, line_number)
|
106
|
+
|
107
|
+
source_code.tokens
|
108
|
+
end
|
109
|
+
|
110
|
+
def slowness_tokens
|
111
|
+
[[:bold, issue.slowness], [:muted, spacer], [:default, issue.short_location] ]
|
112
|
+
end
|
113
|
+
|
114
|
+
def newline_tokens
|
115
|
+
[]
|
116
|
+
end
|
117
|
+
|
118
|
+
def spacer
|
119
|
+
SHARED_SYMBOLS[:spacer]
|
120
|
+
end
|
121
|
+
|
122
|
+
def arrow
|
123
|
+
SHARED_SYMBOLS[:arrow]
|
14
124
|
end
|
15
125
|
end
|
16
126
|
end
|
@@ -4,16 +4,63 @@ module Minitest
|
|
4
4
|
module Heat
|
5
5
|
class Output
|
6
6
|
class Map
|
7
|
+
# extend Forwardable
|
8
|
+
|
7
9
|
attr_accessor :map
|
8
10
|
|
11
|
+
# def_delegators :@results, :errors, :brokens, :failures, :slows, :skips, :problems?, :slows?
|
12
|
+
|
9
13
|
def initialize(map)
|
10
14
|
@map = map
|
15
|
+
@tokens = []
|
11
16
|
end
|
12
17
|
|
13
18
|
def tokens
|
19
|
+
map.file_hits.each do |file|
|
20
|
+
@tokens << [
|
21
|
+
*pathname(file),
|
22
|
+
*line_numbers(file)
|
23
|
+
]
|
24
|
+
end
|
25
|
+
|
26
|
+
@tokens
|
14
27
|
end
|
15
28
|
|
16
29
|
private
|
30
|
+
|
31
|
+
def pathname(file)
|
32
|
+
directory = "#{file.pathname.dirname.to_s.delete_prefix(Dir.pwd)}/"
|
33
|
+
filename = file.pathname.basename.to_s
|
34
|
+
|
35
|
+
[
|
36
|
+
[:default, directory],
|
37
|
+
[:bold, filename],
|
38
|
+
[:default, ' · ']
|
39
|
+
]
|
40
|
+
end
|
41
|
+
|
42
|
+
def hit_line_numbers(file, issue_type)
|
43
|
+
line_numbers_for_issue_type = file.issues.fetch(issue_type) { [] }
|
44
|
+
|
45
|
+
return nil if line_numbers_for_issue_type.empty?
|
46
|
+
|
47
|
+
numbers = []
|
48
|
+
line_numbers_for_issue_type.sort.map do |line_number|
|
49
|
+
numbers << [issue_type, "#{line_number} "]
|
50
|
+
end
|
51
|
+
numbers
|
52
|
+
end
|
53
|
+
|
54
|
+
def line_numbers(file)
|
55
|
+
[
|
56
|
+
*hit_line_numbers(file, :error),
|
57
|
+
*hit_line_numbers(file, :broken),
|
58
|
+
*hit_line_numbers(file, :failure),
|
59
|
+
*hit_line_numbers(file, :skipped),
|
60
|
+
*hit_line_numbers(file, :painful),
|
61
|
+
*hit_line_numbers(file, :slow)
|
62
|
+
].compact.sort_by { |number_token| number_token[1] }
|
63
|
+
end
|
17
64
|
end
|
18
65
|
end
|
19
66
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Minitest
|
4
|
+
module Heat
|
5
|
+
# Friendly API for printing nicely-formatted output to the console
|
6
|
+
class Output
|
7
|
+
class Marker
|
8
|
+
SYMBOLS = {
|
9
|
+
success: '·',
|
10
|
+
slow: '♦',
|
11
|
+
painful: '♦',
|
12
|
+
broken: 'B',
|
13
|
+
error: 'E',
|
14
|
+
skipped: 'S',
|
15
|
+
failure: 'F'
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
STYLES = {
|
19
|
+
success: :success,
|
20
|
+
slow: :slow,
|
21
|
+
painful: :painful,
|
22
|
+
broken: :error,
|
23
|
+
error: :error,
|
24
|
+
skipped: :skipped,
|
25
|
+
failure: :failure
|
26
|
+
}.freeze
|
27
|
+
|
28
|
+
attr_accessor :issue_type
|
29
|
+
|
30
|
+
def initialize(issue_type)
|
31
|
+
@issue_type = issue_type
|
32
|
+
end
|
33
|
+
|
34
|
+
def token
|
35
|
+
[style, symbol]
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def style
|
41
|
+
STYLES.fetch(issue_type, :default)
|
42
|
+
end
|
43
|
+
|
44
|
+
def symbol
|
45
|
+
SYMBOLS.fetch(issue_type, '?')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -8,7 +8,7 @@ module Minitest
|
|
8
8
|
|
9
9
|
attr_accessor :results
|
10
10
|
|
11
|
-
def_delegators :@results, :errors, :brokens, :failures, :
|
11
|
+
def_delegators :@results, :errors, :brokens, :failures, :skips, :painfuls, :slows, :problems?, :slows?
|
12
12
|
|
13
13
|
def initialize(results)
|
14
14
|
@results = results
|
@@ -17,8 +17,8 @@ module Minitest
|
|
17
17
|
|
18
18
|
def tokens
|
19
19
|
@tokens << [*issue_counts_tokens] if issue_counts_tokens&.any?
|
20
|
-
@tokens << [assertions_count_token, test_count_token]
|
21
20
|
@tokens << [assertions_performance_token, tests_performance_token, timing_token]
|
21
|
+
@tokens << [assertions_count_token, test_count_token]
|
22
22
|
|
23
23
|
@tokens
|
24
24
|
end
|
@@ -35,14 +35,21 @@ module Minitest
|
|
35
35
|
def issue_counts_tokens
|
36
36
|
return unless problems? || slows?
|
37
37
|
|
38
|
-
counts = [
|
38
|
+
counts = [
|
39
|
+
error_count_token,
|
40
|
+
broken_count_token,
|
41
|
+
failure_count_token,
|
42
|
+
skip_count_token,
|
43
|
+
painful_count_token,
|
44
|
+
slow_count_token
|
45
|
+
].compact
|
39
46
|
|
40
47
|
# # Create an array of separator tokens one less than the total number of issue count tokens
|
41
48
|
separator_tokens = Array.new(counts.size, separator_token)
|
42
49
|
|
43
50
|
counts_with_separators = counts
|
44
|
-
|
45
|
-
|
51
|
+
.zip(separator_tokens) # Add separators between the counts
|
52
|
+
.flatten(1) # Flatten the zipped separators, but no more
|
46
53
|
|
47
54
|
counts_with_separators.pop # Remove the final trailing zipped separator that's not needed
|
48
55
|
|
@@ -66,6 +73,11 @@ module Minitest
|
|
66
73
|
issue_count_token(style, skips, name: 'Skip')
|
67
74
|
end
|
68
75
|
|
76
|
+
def painful_count_token
|
77
|
+
style = problems? ? :muted : :painful
|
78
|
+
issue_count_token(style, painfuls, name: 'Painfully Slow')
|
79
|
+
end
|
80
|
+
|
69
81
|
def slow_count_token
|
70
82
|
style = problems? ? :muted : :slow
|
71
83
|
issue_count_token(style, slows, name: 'Slow')
|
@@ -101,9 +101,9 @@ module Minitest
|
|
101
101
|
# @return [Array<Symbol>] the Token styles for the line number and line of code
|
102
102
|
def styles_for(line_of_code)
|
103
103
|
if line_of_code == source.line && highlight_key_line?
|
104
|
-
[
|
104
|
+
%i[default default]
|
105
105
|
else
|
106
|
-
[
|
106
|
+
%i[muted muted]
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Minitest
|
2
4
|
module Heat
|
3
5
|
# Friendly API for printing nicely-formatted output to the console
|
@@ -6,18 +8,18 @@ module Minitest
|
|
6
8
|
class InvalidStyle < ArgumentError; end
|
7
9
|
|
8
10
|
STYLES = {
|
9
|
-
success:
|
10
|
-
slow:
|
11
|
-
painful:
|
12
|
-
error:
|
13
|
-
broken:
|
14
|
-
failure:
|
15
|
-
skipped:
|
11
|
+
success: %i[default green],
|
12
|
+
slow: %i[default green],
|
13
|
+
painful: %i[bold green],
|
14
|
+
error: %i[bold red],
|
15
|
+
broken: %i[bold red],
|
16
|
+
failure: %i[default red],
|
17
|
+
skipped: %i[default yellow],
|
16
18
|
warning_light: %i[light yellow],
|
17
|
-
italicized:
|
18
|
-
bold:
|
19
|
-
default:
|
20
|
-
muted:
|
19
|
+
italicized: %i[italic gray],
|
20
|
+
bold: %i[bold default],
|
21
|
+
default: %i[default default],
|
22
|
+
muted: %i[light gray]
|
21
23
|
}.freeze
|
22
24
|
|
23
25
|
attr_accessor :style_key, :content
|
@@ -38,14 +40,14 @@ module Minitest
|
|
38
40
|
end
|
39
41
|
|
40
42
|
def eql?(other)
|
41
|
-
style_key == other.style_key &&
|
43
|
+
style_key == other.style_key && content == other.content
|
42
44
|
end
|
43
45
|
alias :== eql?
|
44
46
|
|
45
47
|
private
|
46
48
|
|
47
49
|
ESC_SEQUENCE = "\e["
|
48
|
-
END_SEQUENCE =
|
50
|
+
END_SEQUENCE = 'm'
|
49
51
|
|
50
52
|
WEIGHTS = {
|
51
53
|
default: 0,
|