minitest-bender 0.0.3 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -1
  3. data/Gemfile +1 -1
  4. data/README.md +37 -6
  5. data/lib/minitest-bender/colorizer.rb +61 -0
  6. data/lib/minitest-bender/configuration.rb +174 -0
  7. data/lib/minitest-bender/printers/plain.rb +29 -0
  8. data/lib/minitest-bender/printers/with_progress_bar.rb +115 -0
  9. data/lib/minitest-bender/recorders/grouped_icons.rb +36 -0
  10. data/lib/minitest-bender/recorders/icons.rb +26 -0
  11. data/lib/minitest-bender/recorders/none.rb +17 -0
  12. data/lib/minitest-bender/recorders/progress.rb +25 -0
  13. data/lib/minitest-bender/recorders/progress_groups.rb +48 -0
  14. data/lib/minitest-bender/recorders/progress_groups_and_issues.rb +55 -0
  15. data/lib/minitest-bender/recorders/progress_issues.rb +32 -0
  16. data/lib/minitest-bender/recorders/progress_verbose.rb +34 -0
  17. data/lib/minitest-bender/result_context.rb +39 -0
  18. data/lib/minitest-bender/result_factory.rb +5 -0
  19. data/lib/minitest-bender/results/base.rb +94 -38
  20. data/lib/minitest-bender/results/expectation.rb +10 -8
  21. data/lib/minitest-bender/results/test.rb +21 -8
  22. data/lib/minitest-bender/sections/activity.rb +95 -0
  23. data/lib/minitest-bender/sections/issues.rb +22 -0
  24. data/lib/minitest-bender/sections/sorted_overview.rb +115 -0
  25. data/lib/minitest-bender/sections/suite_status.rb +72 -0
  26. data/lib/minitest-bender/sections/time_ranking.rb +49 -0
  27. data/lib/minitest-bender/states/base.rb +76 -19
  28. data/lib/minitest-bender/states/failing.rb +11 -8
  29. data/lib/minitest-bender/states/passing.rb +19 -8
  30. data/lib/minitest-bender/states/raising.rb +42 -20
  31. data/lib/minitest-bender/states/skipped.rb +12 -9
  32. data/lib/minitest-bender/utils.rb +26 -0
  33. data/lib/minitest-bender/version.rb +1 -1
  34. data/lib/minitest/bender.rb +166 -77
  35. data/lib/minitest/bender_plugin.rb +49 -3
  36. data/lib/minitest_bender.rb +23 -5
  37. data/minitest-bender.gemspec +6 -6
  38. metadata +39 -22
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 07494f6c231ff2de7a071fd6927d4e4084593d5db749d9f29eab51274e536322
4
- data.tar.gz: 6e0a7fdc255cd9a6effbbe701739ebd850ae50d003aac8aaafdab7d154cddcae
3
+ metadata.gz: 49e6e3621dfce3e4fea0607c005dba7865a7619e62d7391b715ac883cf2a43a5
4
+ data.tar.gz: 7566d1731c3ad37d5124ba48f87300fb1875b63108681c06f34966fa36e06100
5
5
  SHA512:
6
- metadata.gz: 7391d8c06ad48f013e43ecad0bc5504973a447d4668b9e23cffb45cb19820895226b1c1db38af78ecf8fb5e97d91cfd47c753e363f86bd035f0cd3d7b1be0e8a
7
- data.tar.gz: 6a0b1d44d864fe758e15ffce2182e9b579285cafcd72c11800856ef2fab08d159cd76dc221abf80fa71c88e0a8f4e6268e6170507541dc66ff08fee9b96d8518
6
+ metadata.gz: 511ca6879fa694f7195a86bdea865c213796a8e5bf2d3d05c438b6a1bb028fd9a57c7d5c103bee7572c1515603b279d71cc8018f28fe28067c46c516f2629549
7
+ data.tar.gz: b2c7a9517be2b69455620ba1c4a871d921d53dc09c37a9d27a11009035a7112ff528e1fe4bb2be147774114320235839eebd53034391e6f31ee4813739fe8dd9
@@ -6,6 +6,19 @@ All notable changes to this project will be documented in this file. This projec
6
6
 
7
7
  * Your contribution here!
8
8
 
9
+ ## [1.0.0][] (2020-07-19)
10
+
11
+ Thanks to [cboos](https://github.com/cboos) for contributing some of these enhancements!
12
+
13
+ * Two-step activation for better interoperability with other reporters
14
+ * Seven different recorders to choose from, five of which display a progress bar
15
+ * New "overview" section with sorted test results, enabled by default
16
+ * Skips, failures and errors are consistently sorted
17
+ * Irrelevant portions of backtraces are hidden by default
18
+ * Many configurable options such as visible sections and custom colors
19
+ * Graceful degradation of colors in console environments with poor support for them
20
+ * Smarter rerun command generation
21
+
9
22
  ## [0.0.3][] (2019-06-09)
10
23
 
11
24
  * Fixed running time format of slow tests
@@ -20,6 +33,7 @@ All notable changes to this project will be documented in this file. This projec
20
33
  * Initial release
21
34
 
22
35
  [Semver]: http://semver.org
23
- [Unreleased]: https://github.com/eugeniobruno/minitest-bender/compare/v0.0.2...HEAD
36
+ [Unreleased]: https://github.com/eugeniobruno/minitest-bender/compare/v1.0.0...HEAD
37
+ [1.0.0]: https://github.com/eugeniobruno/minitest-bender/compare/v0.0.3...v1.0.0
24
38
  [0.0.3]: https://github.com/eugeniobruno/minitest-bender/compare/v0.0.2...v0.0.3
25
39
  [0.0.2]: https://github.com/eugeniobruno/minitest-bender/compare/v0.0.1...v0.0.2
data/Gemfile CHANGED
@@ -1,4 +1,4 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in openhouse.gemspec
3
+ # Specify your gem's dependencies in minitest-bender.gemspec
4
4
  gemspec
data/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![Gem Version](https://badge.fury.io/rb/minitest-bender.svg)](https://badge.fury.io/rb/minitest-bender)
4
4
  [![Code Climate](https://codeclimate.com/github/eugeniobruno/minitest-bender.svg)](https://codeclimate.com/github/eugeniobruno/minitest-bender)
5
5
 
6
- My own Minitest reporter, without blackjack but with a hook.
6
+ A comprehensive Minitest reporter.
7
7
 
8
8
  ## Installation
9
9
 
@@ -23,24 +23,55 @@ Or install it yourself as:
23
23
 
24
24
  ## Usage
25
25
 
26
- Require this plugin right after Minitest:
26
+ Require this plugin right after Minitest, and then enable it explicitly:
27
27
 
28
28
  ```ruby
29
29
  require 'minitest/autorun'
30
30
  require 'minitest/bender'
31
+ Minitest::Bender.enable!
31
32
  ```
32
33
 
33
34
  That's it! The next time you run your tests, a new report format will be used instead of the default one.
34
35
 
36
+ Instead of calling the `enable!` method, you can also specify the `--bender` test option, e.g.
37
+
38
+ $ rake test TESTOPTS="--bender"
39
+
40
+ In both of these cases, Bender is activated with its default configuration. You can refer to [bender_plugin.rb](https://github.com/eugeniobruno/minitest-bender/blob/master/lib/minitest/bender_plugin.rb) or [configuration.rb](https://github.com/eugeniobruno/minitest-bender/blob/master/lib/minitest-bender/configuration.rb) to explore the multitude of options available to customize the output.
41
+
42
+ As an example, let's say your test suite takes several minutes to run, so you want to see detailed output in realtime. This behaviour is provided by a particular recorder called "progress_verbose", which is not the default one. In order to select this recorder for your app/gem, you can activate Bender like this instead:
43
+
44
+ ```ruby
45
+ Minitest::Bender.enable!({ recorder: :progress_verbose })
46
+ ```
47
+
48
+ You can also set configuration options via environment variables:
49
+
50
+ $ BENDER_RECORDER=progress_verbose rake test
51
+
52
+ Finally, command-line options also work:
53
+
54
+ $ rake test TESTOPTS="--bender-recorder=progress_verbose"
55
+
56
+ Bear in mind that setting a configuration option does not automatically enable the reporter, so remember to either call the `enable!` method, or to include the `--bender` argument.
57
+
58
+ If you use [minitest-reporters](https://github.com/kern/minitest-reporters) and have it installed and activated, you can select the `BenderReporter` as (one of the) reporters:
59
+
60
+ $ MINITEST_REPORTER=BenderReporter,HtmlReporter rake test
61
+
62
+
35
63
  ## Features
36
64
 
37
- Based on [minitest-colorin](https://github.com/gabynaiman/minitest-colorin/), the minitest-bender reporter offers you colored output including:
65
+ Originally based on [minitest-colorin](https://github.com/gabynaiman/minitest-colorin/), the minitest-bender reporter offers you, out of the box, colored output including:
38
66
 
39
- * Status, running time, name and message for each test/expectation, grouped by class/context
40
- * Details of skips, failures and errors in three different sections, with diffs, backtraces and commands to rerun each single test
41
- * Details of the top 3 slowest tests, if they may be relevant
67
+ * A progress bar, mostly useful for long-running suites, as the default of many different recorders
68
+ * Status, running time, name and message for each test/expectation, grouped by class/context and sorted by name
69
+ * Details of skips, failures and errors, with diffs, backtraces and commands to rerun each single test
70
+ * Details of the slowest tests, if they may be relevant
42
71
  * The same basic statistics of the default reporter
43
72
 
73
+ If the NO_COLOR environment variable is set, Bender will output non-colored text honoring [this standard](https://no-color.org/), thanks to the [paint gem](https://github.com/janlelis/paint/) dependency.
74
+
44
75
 
45
76
  ## Development
46
77
 
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV['ANSICON'] ||= 'Y' if ENV['ConEmuANSI'] != 'ON'
4
+ require 'paint'
5
+
6
+ module MinitestBender
7
+ class Colorizer
8
+ COLORS = { # Xterm No. - Xterm Name
9
+ pass: '87ff87', # 120 - LightGreen
10
+ skip: '5fd7ff', # 81 - SteelBlue1
11
+ fail: 'ff5f5f', # 203 - IndianRed1
12
+ error: 'ffd75f', # 221 - LightGoldenrod2
13
+ tests: '5fafaf', # 73 - CadetBlue
14
+ assertions: 'd75fd7', # 170 - Orchid
15
+ time: '878787', # 102 - Grey53
16
+ number: '5fafaf', # 73 - CadetBlue
17
+ backtrace: 'af8787' # 138 - RosyBrown
18
+ }
19
+
20
+ # In compatibility modes, colors that are mapped to black are avoided.
21
+ SAFE_COLORS = {
22
+ pass: '00ff5f', # 47 - SpringGreen2
23
+ tests: 'blue',
24
+ time: 'gray',
25
+ number: 'gray',
26
+ backtrace: 'gray'
27
+ }
28
+ COLORS.merge!(SAFE_COLORS) if Paint.mode < 256
29
+
30
+ COLORS.freeze
31
+
32
+ class << self
33
+ def custom_colors=(custom_colors)
34
+ @custom_colors = custom_colors
35
+ end
36
+
37
+ def colorize(string, color, *args)
38
+ if color == :normal
39
+ Paint[string, *args]
40
+ else
41
+ color_value = colors.fetch(color)
42
+ Paint[string, color_value, *args]
43
+ end
44
+ end
45
+
46
+ def color_keys
47
+ COLORS.keys
48
+ end
49
+
50
+ private
51
+
52
+ def colors
53
+ @colors ||= COLORS.merge(custom_colors)
54
+ end
55
+
56
+ def custom_colors
57
+ @custom_colors || {}
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,174 @@
1
+ module MinitestBender
2
+ class Configuration
3
+ DEFAULT_CONFIG = {
4
+ mode: :oblivious,
5
+ recorder: :progress,
6
+ sections: [:overview, :time_ranking, :issues, :activity, :suite_status],
7
+ sections_blacklist: [],
8
+ overview_sort_key: :name,
9
+ time_ranking_size: 5,
10
+ backtrace_view: :user,
11
+ rerun_command_stem: defined?(Rake) ? 'rake' : 'ruby',
12
+ custom_colors: {}
13
+ }.freeze
14
+
15
+ def initialize
16
+ @client_config = {}
17
+ @options_config = {}
18
+ end
19
+
20
+ def add_client_config(config)
21
+ validate_config(config)
22
+ client_config.merge!(config)
23
+ end
24
+
25
+ def mode=(mode)
26
+ options_config[:mode] = mode
27
+ end
28
+
29
+ def recorder=(recorder)
30
+ options_config[:recorder] = recorder
31
+ end
32
+
33
+ def sections=(sections)
34
+ options_config[:sections] = sections
35
+ end
36
+
37
+ def sections_blacklist=(sections_blacklist)
38
+ options_config[:sections_blacklist] = sections_blacklist
39
+ end
40
+
41
+ def overview_sort_key=(overview_sort_key)
42
+ options_config[:overview_sort_key] = overview_sort_key
43
+ end
44
+
45
+ def time_ranking_size=(time_ranking_size)
46
+ options_config[:time_ranking_size] = time_ranking_size
47
+ end
48
+
49
+ def backtrace_view=(backtrace_view)
50
+ options_config[:backtrace_view] = backtrace_view
51
+ end
52
+
53
+ def rerun_command_stem=(rerun_command_stem)
54
+ options_config[:rerun_command_stem] = rerun_command_stem
55
+ end
56
+
57
+ def set_custom_color(color_key, color)
58
+ options_config[:custom_colors] ||= {}
59
+ options_config[:custom_colors][color_key] = color
60
+ end
61
+
62
+ def cooperative?
63
+ final_config.fetch(:mode) == :cooperative
64
+ end
65
+
66
+ def recorder
67
+ final_config.fetch(:recorder)
68
+ end
69
+
70
+ def sections
71
+ sections_whitelist - sections_blacklist
72
+ end
73
+
74
+ def overview_sort_key
75
+ final_config.fetch(:overview_sort_key)
76
+ end
77
+
78
+ def time_ranking_size
79
+ final_config.fetch(:time_ranking_size)
80
+ end
81
+
82
+ def backtrace_view
83
+ final_config.fetch(:backtrace_view)
84
+ end
85
+
86
+ def rerun_command_stem
87
+ final_config.fetch(:rerun_command_stem)
88
+ end
89
+
90
+ def custom_colors
91
+ final_config.fetch(:custom_colors)
92
+ end
93
+
94
+ private
95
+
96
+ attr_reader :client_config, :options_config
97
+
98
+ def validate_config(config)
99
+ invalid_options = config.keys.map(&:to_sym) - valid_options
100
+ unless invalid_options.empty?
101
+ first_invalid_option = invalid_options.first
102
+ message = "invalid option: '#{first_invalid_option}'"
103
+ raise ArgumentError, message
104
+ end
105
+ end
106
+
107
+ def valid_options
108
+ default_config.keys
109
+ end
110
+
111
+ def parsed_list(list)
112
+ strings = list.is_a?(Array) ? list.map(&:to_s) : list.split(',')
113
+ strings.map { |s| s.strip.to_sym }
114
+ end
115
+
116
+ def default_config
117
+ DEFAULT_CONFIG
118
+ end
119
+
120
+ def env_config
121
+ {
122
+ mode: ENV['BENDER_MODE'],
123
+ recorder: ENV['BENDER_RECORDER'],
124
+ sections: ENV['BENDER_SECTIONS'],
125
+ sections_blacklist: ENV['BENDER_SECTIONS_BLACKLIST'],
126
+ overview_sort_key: ENV['BENDER_OVERVIEW_SORT_KEY'],
127
+ time_ranking_size: ENV['BENDER_TIME_RANKING_SIZE'],
128
+ backtrace_view: ENV['BENDER_BACKTRACE_VIEW'],
129
+ rerun_command_stem: ENV['BENDER_RERUN_COMMAND_STEM'],
130
+ custom_colors: custom_colors_env_config
131
+ }
132
+ end
133
+
134
+ def custom_colors_env_config
135
+ Colorizer.color_keys.each_with_object({}) do |color_key, h|
136
+ h[color_key] = ENV["BENDER_#{color_key.upcase}_COLOR"]
137
+ end
138
+ end
139
+
140
+ def merged_config
141
+ [default_config, client_config, env_config, options_config].reduce do |acum, config|
142
+ proper_config = Utils.with_symbolized_keys(Utils.without_nil_values(config))
143
+ acum.merge(proper_config) do |key, old_val, new_val|
144
+ if key == :custom_colors
145
+ old_val.merge(Utils.with_symbolized_keys(Utils.without_nil_values(new_val)))
146
+ else
147
+ new_val
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ def final_config
154
+ merged_config.tap do |config|
155
+ config[:mode] = config[:mode].to_sym
156
+ config[:recorder] = config[:recorder].to_sym
157
+ config[:sections] = parsed_list(config[:sections])
158
+ config[:sections_blacklist] = parsed_list(config[:sections_blacklist])
159
+ config[:overview_sort_key] = config[:overview_sort_key].to_sym
160
+ config[:time_ranking_size] = config[:time_ranking_size].to_i
161
+ config[:rerun_command_stem] = config[:rerun_command_stem].to_s
162
+ config[:backtrace_view] = config[:backtrace_view].to_sym
163
+ end
164
+ end
165
+
166
+ def sections_whitelist
167
+ final_config.fetch(:sections)
168
+ end
169
+
170
+ def sections_blacklist
171
+ final_config.fetch(:sections_blacklist)
172
+ end
173
+ end
174
+ end
@@ -0,0 +1,29 @@
1
+ module MinitestBender
2
+ module Printers
3
+ class Plain
4
+ def initialize(io)
5
+ @io = io
6
+ end
7
+
8
+ def print(string)
9
+ io.print(string)
10
+ end
11
+
12
+ def print_line(line = '')
13
+ io.puts(line)
14
+ end
15
+
16
+ def print_lines(lines)
17
+ lines.each { |line| print_line(line) }
18
+ end
19
+
20
+ def advance
21
+ # do nothing
22
+ end
23
+
24
+ private
25
+
26
+ attr_reader :io
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,115 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
4
+ require 'tty-progressbar'
5
+
6
+ module MinitestBender
7
+ module Printers
8
+ class WithProgressBar
9
+ COMPLETE_ICON = ' '
10
+ HEAD_ICON = 'ᗧ'
11
+ INCOMPLETE_ICON = '•'
12
+ ELAPSED_ICON = '⏱'
13
+ ETA_ICON = '⌛'
14
+
15
+ def initialize(io, total)
16
+ @io = io
17
+ @total = total
18
+ @bar = new_bar
19
+ end
20
+
21
+ def print(string)
22
+ io.print(string)
23
+ end
24
+
25
+ def print_line(line = '')
26
+ if io.tty?
27
+ bar.log(line)
28
+ else
29
+ io.puts(line)
30
+ end
31
+ end
32
+
33
+ def print_lines(lines)
34
+ lines.each { |line| print_line(line) }
35
+ end
36
+
37
+ def advance
38
+ bar.update({ head: head })
39
+ bar.advance(1, { counters_sym => counters })
40
+ end
41
+
42
+ private
43
+
44
+ attr_reader :io, :bar, :total
45
+
46
+ def new_bar
47
+ TTY::ProgressBar.new(bar_format_string, {
48
+ total: total,
49
+ width: [total, TTY::ProgressBar.max_columns].max,
50
+ complete: complete_icon,
51
+ head: head_icon,
52
+ incomplete: incomplete_icon
53
+ })
54
+ end
55
+
56
+ def bar_format_string
57
+ ":bar #{Colorizer.colorize(':current/:total', :tests)} :#{counters_sym} #{Colorizer.colorize(elapsed_icon + ' :elapsed', :time)} #{Colorizer.colorize(eta_icon + ':eta', :time)} #{Colorizer.colorize(':percent', :normal, :bold)}"
58
+ end
59
+
60
+ def counters
61
+ states.map do |state|
62
+ state.colored_icon_with_count(counters_padding_right)
63
+ end.join(' ')
64
+ end
65
+
66
+ def counters_sym
67
+ ('c' * counters_sym_length).to_sym
68
+ end
69
+
70
+ def counters_sym_length
71
+ ( 4 * (total.to_s.size + 1) ) + 6
72
+ end
73
+
74
+ def head
75
+ Colorizer.colorize(head_icon, head_color)
76
+ end
77
+
78
+ def complete_icon
79
+ COMPLETE_ICON
80
+ end
81
+
82
+ def head_icon
83
+ HEAD_ICON
84
+ end
85
+
86
+ def incomplete_icon
87
+ INCOMPLETE_ICON
88
+ end
89
+
90
+ def elapsed_icon
91
+ ELAPSED_ICON
92
+ end
93
+
94
+ def eta_icon
95
+ ETA_ICON
96
+ end
97
+
98
+ def head_color
99
+ reverse_states.find { |s| !s.results.empty? }.color
100
+ end
101
+
102
+ def states
103
+ @states ||= MinitestBender.states.values
104
+ end
105
+
106
+ def reverse_states
107
+ @reverse_states ||= states.reverse
108
+ end
109
+
110
+ def counters_padding_right
111
+ @counters_padding_right ||= total.to_s.size + 1
112
+ end
113
+ end
114
+ end
115
+ end