tryouts 2.4.1 → 3.0.0.pre2
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/LICENSE.txt +1 -1
- data/README.md +187 -73
- data/exe/try +53 -45
- data/exe/tryouts +2 -2
- data/lib/tryouts/cli/formatters/base.rb +108 -0
- data/lib/tryouts/cli/formatters/compact.rb +246 -0
- data/lib/tryouts/cli/formatters/factory.rb +52 -0
- data/lib/tryouts/cli/formatters/output_manager.rb +140 -0
- data/lib/tryouts/cli/formatters/quiet.rb +159 -0
- data/lib/tryouts/cli/formatters/verbose.rb +344 -0
- data/lib/tryouts/cli/formatters.rb +6 -0
- data/lib/tryouts/cli/modes/generate.rb +22 -0
- data/lib/tryouts/cli/modes/inspect.rb +42 -0
- data/lib/tryouts/cli/opts.rb +88 -0
- data/lib/tryouts/cli.rb +54 -0
- data/lib/tryouts/console.rb +55 -40
- data/lib/tryouts/file_processor.rb +66 -0
- data/lib/tryouts/prism_parser.rb +314 -0
- data/lib/tryouts/test_executor.rb +82 -0
- data/lib/tryouts/test_runner.rb +128 -0
- data/lib/tryouts/testbatch.rb +293 -53
- data/lib/tryouts/testcase.rb +32 -91
- data/lib/tryouts/translators/minitest_translator.rb +106 -0
- data/lib/tryouts/translators/rspec_translator.rb +88 -0
- data/lib/tryouts/version.rb +2 -12
- data/lib/tryouts.rb +16 -263
- metadata +60 -13
- data/VERSION.yml +0 -4
- data/lib/tryouts/section.rb +0 -27
@@ -0,0 +1,246 @@
|
|
1
|
+
# lib/tryouts/cli/formatters/compact.rb
|
2
|
+
|
3
|
+
class Tryouts
|
4
|
+
class CLI
|
5
|
+
# Compact single-line formatter focused on results
|
6
|
+
class CompactFormatter
|
7
|
+
include FormatterInterface
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@show_debug = options.fetch(:debug, false)
|
11
|
+
@show_trace = options.fetch(:trace, false)
|
12
|
+
@show_passed = options.fetch(:show_passed, true)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Phase-level output - minimal for compact mode
|
16
|
+
def phase_header(message, _file_count = nil, level = 0)
|
17
|
+
# Skip execution phase headers in compact mode - they create unwanted empty lines
|
18
|
+
return if level >= 1
|
19
|
+
|
20
|
+
text = "#{message}..."
|
21
|
+
puts indent_text(text, level)
|
22
|
+
end
|
23
|
+
|
24
|
+
# File-level operations - compact single lines
|
25
|
+
def file_start(file_path, context_info = {})
|
26
|
+
return unless @show_debug
|
27
|
+
|
28
|
+
framework = context_info[:framework] || :direct
|
29
|
+
context = context_info[:context] || :fresh
|
30
|
+
pretty_path = Console.pretty_path(file_path)
|
31
|
+
|
32
|
+
puts indent_text("Running: #{pretty_path} (#{framework}/#{context})", 1)
|
33
|
+
end
|
34
|
+
|
35
|
+
def file_parsed(_file_path, test_count, setup_present: false, teardown_present: false)
|
36
|
+
# Don't show parsing info in compact mode unless debug
|
37
|
+
return unless @show_debug
|
38
|
+
|
39
|
+
extras = []
|
40
|
+
extras << 'setup' if setup_present
|
41
|
+
extras << 'teardown' if teardown_present
|
42
|
+
suffix = extras.empty? ? '' : " +#{extras.join(',')}"
|
43
|
+
|
44
|
+
puts indent_text("Parsed #{test_count} tests#{suffix}", 1)
|
45
|
+
end
|
46
|
+
|
47
|
+
def file_execution_start(file_path, test_count, _context_mode)
|
48
|
+
pretty_path = Console.pretty_path(file_path)
|
49
|
+
puts
|
50
|
+
puts "#{pretty_path}: #{test_count} tests"
|
51
|
+
end
|
52
|
+
|
53
|
+
def file_result(_file_path, total_tests, failed_count, error_count, elapsed_time)
|
54
|
+
detail = []
|
55
|
+
if failed_count > 0
|
56
|
+
status = Console.color(:red, '✗')
|
57
|
+
detail << "#{failed_count}/#{total_tests} failed"
|
58
|
+
else
|
59
|
+
status = Console.color(:green, '✓')
|
60
|
+
detail << "#{total_tests} passed"
|
61
|
+
end
|
62
|
+
|
63
|
+
if error_count > 0
|
64
|
+
status = Console.color(:yellow, '⚠') if failed_count == 0
|
65
|
+
detail << "#{error_count} errors"
|
66
|
+
end
|
67
|
+
|
68
|
+
time_str = if elapsed_time
|
69
|
+
if elapsed_time < 2
|
70
|
+
" (#{(elapsed_time * 1000).to_i}ms)"
|
71
|
+
else
|
72
|
+
" (#{elapsed_time.round(2)}s)"
|
73
|
+
end
|
74
|
+
else
|
75
|
+
''
|
76
|
+
end
|
77
|
+
puts " #{status} #{detail.join(', ')}#{time_str}"
|
78
|
+
end
|
79
|
+
|
80
|
+
# Test-level operations - only show in debug mode for compact
|
81
|
+
def test_start(test_case, index, _total)
|
82
|
+
return unless @show_debug
|
83
|
+
|
84
|
+
desc = test_case.description.to_s
|
85
|
+
desc = "test #{index}" if desc.empty?
|
86
|
+
puts " Running: #{desc}"
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_result(test_case, result_status, actual_results = [], _elapsed_time = nil)
|
90
|
+
# Only show failed tests in compact mode unless show_passed is true
|
91
|
+
return if result_status == :passed && !@show_passed
|
92
|
+
|
93
|
+
desc = test_case.description.to_s
|
94
|
+
desc = 'unnamed test' if desc.empty?
|
95
|
+
|
96
|
+
case result_status
|
97
|
+
when :passed
|
98
|
+
status = Console.color(:green, '✓')
|
99
|
+
when :failed
|
100
|
+
status = Console.color(:red, '✗')
|
101
|
+
if actual_results.any?
|
102
|
+
failure_info = " (got: #{actual_results.first.inspect})"
|
103
|
+
desc += failure_info
|
104
|
+
end
|
105
|
+
when :skipped
|
106
|
+
status = Console.color(:yellow, '-')
|
107
|
+
else
|
108
|
+
status = '?'
|
109
|
+
end
|
110
|
+
|
111
|
+
puts indent_text("#{status} #{desc}", 1)
|
112
|
+
end
|
113
|
+
|
114
|
+
def test_output(test_case, output_text)
|
115
|
+
# In compact mode, only show output for failed tests and only if debug mode is enabled
|
116
|
+
return if output_text.nil? || output_text.strip.empty?
|
117
|
+
return unless @show_debug
|
118
|
+
|
119
|
+
puts " Output: #{output_text.lines.count} lines"
|
120
|
+
if output_text.lines.count <= 3
|
121
|
+
output_text.lines.each do |line|
|
122
|
+
puts " #{line.chomp}"
|
123
|
+
end
|
124
|
+
else
|
125
|
+
puts " #{output_text.lines.first.chomp}"
|
126
|
+
puts " ... (#{output_text.lines.count - 2} more lines)"
|
127
|
+
puts " #{output_text.lines.last.chomp}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
# Setup/teardown operations - minimal output
|
132
|
+
def setup_start(_line_range)
|
133
|
+
# No file setup start output for compact
|
134
|
+
end
|
135
|
+
|
136
|
+
def setup_output(output_text)
|
137
|
+
return if output_text.strip.empty?
|
138
|
+
return unless @show_debug
|
139
|
+
|
140
|
+
# In compact mode, just show that there was output
|
141
|
+
lines = output_text.lines.count
|
142
|
+
puts " Setup output (#{lines} lines)"
|
143
|
+
end
|
144
|
+
|
145
|
+
def teardown_start(_line_range)
|
146
|
+
return unless @show_debug
|
147
|
+
|
148
|
+
puts ' Teardown...'
|
149
|
+
end
|
150
|
+
|
151
|
+
def teardown_output(output_text)
|
152
|
+
return if output_text.strip.empty?
|
153
|
+
return unless @show_debug
|
154
|
+
|
155
|
+
# In compact mode, just show that there was output
|
156
|
+
lines = output_text.lines.count
|
157
|
+
puts " Teardown output (#{lines} lines)"
|
158
|
+
end
|
159
|
+
|
160
|
+
# Summary operations
|
161
|
+
def batch_summary(total_tests, failed_count, elapsed_time)
|
162
|
+
# Skip - file_result already shows this information with better alignment
|
163
|
+
end
|
164
|
+
|
165
|
+
def grand_total(total_tests, failed_count, error_count, successful_files, total_files, elapsed_time)
|
166
|
+
puts
|
167
|
+
puts '=' * 50
|
168
|
+
|
169
|
+
issues_count = failed_count + error_count
|
170
|
+
if issues_count > 0
|
171
|
+
passed = total_tests - issues_count
|
172
|
+
details = []
|
173
|
+
details << "#{failed_count} failed" if failed_count > 0
|
174
|
+
details << "#{error_count} errors" if error_count > 0
|
175
|
+
result = Console.color(:red, "#{details.join(', ')}, #{passed} passed")
|
176
|
+
else
|
177
|
+
result = Console.color(:green, "#{total_tests} tests passed")
|
178
|
+
end
|
179
|
+
|
180
|
+
time_str = if elapsed_time < 2
|
181
|
+
"#{(elapsed_time * 1000).to_i}ms"
|
182
|
+
else
|
183
|
+
"#{elapsed_time.round(2)}s"
|
184
|
+
end
|
185
|
+
|
186
|
+
puts "Total: #{result} (#{time_str})"
|
187
|
+
puts "Files: #{successful_files} of #{total_files} successful"
|
188
|
+
end
|
189
|
+
|
190
|
+
# Debug and diagnostic output - minimal in compact mode
|
191
|
+
def debug_info(message, level = 0)
|
192
|
+
return unless @show_debug
|
193
|
+
|
194
|
+
puts indent_text("DEBUG: #{message}", level)
|
195
|
+
end
|
196
|
+
|
197
|
+
def trace_info(message, level = 0)
|
198
|
+
return unless @show_trace
|
199
|
+
|
200
|
+
puts indent_text("TRACE: #{message}", level)
|
201
|
+
end
|
202
|
+
|
203
|
+
def error_message(message, backtrace = nil)
|
204
|
+
puts Console.color(:red, "ERROR: #{message}")
|
205
|
+
|
206
|
+
return unless backtrace && @show_debug
|
207
|
+
|
208
|
+
backtrace.first(3).each do |line|
|
209
|
+
puts indent_text(line.chomp, 1)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Utility methods
|
214
|
+
def raw_output(text)
|
215
|
+
puts text
|
216
|
+
end
|
217
|
+
|
218
|
+
def separator(style = :light)
|
219
|
+
case style
|
220
|
+
when :heavy
|
221
|
+
puts '=' * 50
|
222
|
+
when :light
|
223
|
+
puts '-' * 50
|
224
|
+
when :dotted
|
225
|
+
puts '.' * 50
|
226
|
+
else
|
227
|
+
puts '-' * 50
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
# Compact formatter that only shows failures and errors
|
233
|
+
class CompactFailsFormatter < CompactFormatter
|
234
|
+
def initialize(options = {})
|
235
|
+
super(options.merge(show_passed: false))
|
236
|
+
end
|
237
|
+
|
238
|
+
def test_result(test_case, result_status, actual_results = [], elapsed_time = nil)
|
239
|
+
# Only show failed/error tests
|
240
|
+
return if result_status == :passed
|
241
|
+
|
242
|
+
super
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# lib/tryouts/cli/formatters/factory.rb
|
2
|
+
|
3
|
+
class Tryouts
|
4
|
+
class CLI
|
5
|
+
# Factory for creating formatters and output managers
|
6
|
+
class FormatterFactory
|
7
|
+
def self.create_output_manager(options = {})
|
8
|
+
formatter = create_formatter(options)
|
9
|
+
OutputManager.new(formatter)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.create_formatter(options = {})
|
13
|
+
# Map boolean flags to format symbols if format not explicitly set
|
14
|
+
format = options[:format]&.to_sym || determine_format_from_flags(options)
|
15
|
+
|
16
|
+
case format
|
17
|
+
when :verbose
|
18
|
+
if options[:fails_only]
|
19
|
+
VerboseFailsFormatter.new(options)
|
20
|
+
else
|
21
|
+
VerboseFormatter.new(options)
|
22
|
+
end
|
23
|
+
when :compact
|
24
|
+
if options[:fails_only]
|
25
|
+
CompactFailsFormatter.new(options)
|
26
|
+
else
|
27
|
+
CompactFormatter.new(options)
|
28
|
+
end
|
29
|
+
when :quiet
|
30
|
+
if options[:fails_only]
|
31
|
+
QuietFailsFormatter.new(options)
|
32
|
+
else
|
33
|
+
QuietFormatter.new(options)
|
34
|
+
end
|
35
|
+
else
|
36
|
+
VerboseFormatter.new(options) # Default to verbose
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class << self
|
41
|
+
private
|
42
|
+
|
43
|
+
def determine_format_from_flags(options)
|
44
|
+
return :quiet if options[:quiet]
|
45
|
+
return :verbose if options[:verbose]
|
46
|
+
|
47
|
+
:compact # Default
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
# lib/tryouts/cli/formatters/output_manager.rb
|
2
|
+
|
3
|
+
class Tryouts
|
4
|
+
class CLI
|
5
|
+
# Output manager that coordinates all output through formatters
|
6
|
+
class OutputManager
|
7
|
+
attr_reader :formatter
|
8
|
+
|
9
|
+
def initialize(formatter)
|
10
|
+
@formatter = formatter
|
11
|
+
@indent_level = 0
|
12
|
+
end
|
13
|
+
|
14
|
+
# Phase-level methods
|
15
|
+
def processing_phase(file_count, level = 0)
|
16
|
+
@formatter.phase_header("PROCESSING #{file_count} FILES", file_count, level)
|
17
|
+
end
|
18
|
+
|
19
|
+
def execution_phase(test_count, level = 1)
|
20
|
+
@formatter.phase_header("EXECUTING #{test_count} TESTS", test_count, level)
|
21
|
+
end
|
22
|
+
|
23
|
+
def error_phase(level = 1)
|
24
|
+
@formatter.phase_header('ERROR DETAILS', level)
|
25
|
+
end
|
26
|
+
|
27
|
+
# File-level methods
|
28
|
+
def file_start(file_path, framework: :direct, context: :fresh)
|
29
|
+
context_info = { framework: framework, context: context }
|
30
|
+
@formatter.file_start(file_path, context_info)
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_parsed(file_path, test_count, setup_present: false, teardown_present: false)
|
34
|
+
with_indent(1) do
|
35
|
+
@formatter.file_parsed(file_path, test_count,
|
36
|
+
setup_present: setup_present,
|
37
|
+
teardown_present: teardown_present
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def file_execution_start(file_path, test_count, context_mode)
|
43
|
+
@formatter.file_execution_start(file_path, test_count, context_mode)
|
44
|
+
end
|
45
|
+
|
46
|
+
def file_success(file_path, total_tests, failed_count, error_count, elapsed_time)
|
47
|
+
with_indent(1) do
|
48
|
+
@formatter.file_result(file_path, total_tests, failed_count, error_count, elapsed_time)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def file_failure(file_path, error_message, backtrace = nil)
|
53
|
+
with_indent(1) do
|
54
|
+
@formatter.error_message("#{Console.pretty_path(file_path)}: #{error_message}", backtrace)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Test-level methods
|
59
|
+
def test_start(test_case, index, total)
|
60
|
+
with_indent(2) do
|
61
|
+
@formatter.test_start(test_case, index, total)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_result(test_case, result_status, actual_results = [], elapsed_time = nil)
|
66
|
+
@formatter.test_result(test_case, result_status, actual_results, elapsed_time)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_output(test_case, output_text)
|
70
|
+
@formatter.test_output(test_case, output_text)
|
71
|
+
end
|
72
|
+
|
73
|
+
# Setup/teardown methods
|
74
|
+
def setup_start(line_range)
|
75
|
+
with_indent(2) do
|
76
|
+
@formatter.setup_start(line_range)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def setup_output(output_text)
|
81
|
+
@formatter.setup_output(output_text)
|
82
|
+
end
|
83
|
+
|
84
|
+
def teardown_start(line_range)
|
85
|
+
with_indent(2) do
|
86
|
+
@formatter.teardown_start(line_range)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def teardown_output(output_text)
|
91
|
+
@formatter.teardown_output(output_text)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Summary methods
|
95
|
+
def batch_summary(total_tests, failed_count, elapsed_time)
|
96
|
+
@formatter.batch_summary(total_tests, failed_count, elapsed_time)
|
97
|
+
end
|
98
|
+
|
99
|
+
def grand_total(total_tests, failed_count, error_count, successful_files, total_files, elapsed_time)
|
100
|
+
@formatter.grand_total(total_tests, failed_count, error_count, successful_files, total_files, elapsed_time)
|
101
|
+
end
|
102
|
+
|
103
|
+
# Debug methods
|
104
|
+
def info(message, level = 0)
|
105
|
+
with_indent(level) do
|
106
|
+
@formatter.debug_info(message, level)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def trace(message, level = 0)
|
111
|
+
with_indent(level) do
|
112
|
+
@formatter.trace_info(message, level)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
def error(message, backtrace = nil)
|
117
|
+
@formatter.error_message(message, backtrace)
|
118
|
+
end
|
119
|
+
|
120
|
+
# Utility methods
|
121
|
+
def raw(text)
|
122
|
+
@formatter.raw_output(text)
|
123
|
+
end
|
124
|
+
|
125
|
+
def separator(style = :light)
|
126
|
+
@formatter.separator(style)
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
def with_indent(level)
|
132
|
+
old_level = @indent_level
|
133
|
+
@indent_level = level
|
134
|
+
yield
|
135
|
+
ensure
|
136
|
+
@indent_level = old_level
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
# lib/tryouts/cli/formatters/quiet.rb
|
2
|
+
|
3
|
+
class Tryouts
|
4
|
+
class CLI
|
5
|
+
# Minimal output formatter - only shows essential information
|
6
|
+
class QuietFormatter
|
7
|
+
include FormatterInterface
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@show_errors = options.fetch(:show_errors, true)
|
11
|
+
@show_final_summary = options.fetch(:show_final_summary, true)
|
12
|
+
@current_file = nil
|
13
|
+
end
|
14
|
+
|
15
|
+
# Phase-level output - silent
|
16
|
+
def phase_header(message, file_count = nil, level = nil)
|
17
|
+
# Silent in quiet mode
|
18
|
+
end
|
19
|
+
|
20
|
+
# File-level operations - minimal
|
21
|
+
def file_start(file_path, context_info = {})
|
22
|
+
# Silent in quiet mode
|
23
|
+
end
|
24
|
+
|
25
|
+
def file_parsed(file_path, test_count, setup_present: false, teardown_present: false)
|
26
|
+
# Silent in quiet mode
|
27
|
+
end
|
28
|
+
|
29
|
+
def file_execution_start(file_path, _test_count, _context_mode)
|
30
|
+
@current_file = file_path
|
31
|
+
end
|
32
|
+
|
33
|
+
def file_result(file_path, total_tests, failed_count, error_count, elapsed_time)
|
34
|
+
# Silent in quiet mode - results shown in batch_summary
|
35
|
+
end
|
36
|
+
|
37
|
+
# Test-level operations - dot notation
|
38
|
+
def test_start(test_case, index, total)
|
39
|
+
# Silent in quiet mode
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_result(_test_case, result_status, _actual_results = [], _elapsed_time = nil)
|
43
|
+
case result_status
|
44
|
+
when :passed
|
45
|
+
print Console.color(:green, '.')
|
46
|
+
when :failed
|
47
|
+
print Console.color(:red, 'F')
|
48
|
+
when :error
|
49
|
+
print Console.color(:red, 'E')
|
50
|
+
when :skipped
|
51
|
+
print Console.color(:yellow, 'S')
|
52
|
+
else
|
53
|
+
print '?'
|
54
|
+
end
|
55
|
+
$stdout.flush
|
56
|
+
end
|
57
|
+
|
58
|
+
def test_output(test_case, output_text)
|
59
|
+
# Silent in quiet mode - could optionally show output for failed tests only
|
60
|
+
# For now, keeping it completely silent
|
61
|
+
end
|
62
|
+
|
63
|
+
# Setup/teardown operations - silent
|
64
|
+
def setup_start(line_range)
|
65
|
+
# Silent in quiet mode
|
66
|
+
end
|
67
|
+
|
68
|
+
def setup_output(output_text)
|
69
|
+
# Silent in quiet mode
|
70
|
+
end
|
71
|
+
|
72
|
+
def teardown_start(line_range)
|
73
|
+
# Silent in quiet mode
|
74
|
+
end
|
75
|
+
|
76
|
+
def teardown_output(output_text)
|
77
|
+
# Silent in quiet mode
|
78
|
+
end
|
79
|
+
|
80
|
+
# Summary operations - show results
|
81
|
+
def batch_summary(total_tests, failed_count, elapsed_time)
|
82
|
+
return unless @show_final_summary
|
83
|
+
|
84
|
+
puts # New line after dots
|
85
|
+
|
86
|
+
if failed_count > 0
|
87
|
+
passed = total_tests - failed_count
|
88
|
+
time_str = elapsed_time ? " (#{elapsed_time.round(2)}s)" : ''
|
89
|
+
puts "#{failed_count} failed, #{passed} passed#{time_str}"
|
90
|
+
else
|
91
|
+
time_str = elapsed_time ? " (#{elapsed_time.round(2)}s)" : ''
|
92
|
+
puts "#{total_tests} passed#{time_str}"
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def grand_total(total_tests, failed_count, error_count, successful_files, total_files, elapsed_time)
|
97
|
+
return unless @show_final_summary
|
98
|
+
|
99
|
+
puts
|
100
|
+
|
101
|
+
time_str = if elapsed_time < 2
|
102
|
+
"#{(elapsed_time * 1000).to_i}ms"
|
103
|
+
else
|
104
|
+
"#{elapsed_time.round(2)}s"
|
105
|
+
end
|
106
|
+
|
107
|
+
issues_count = failed_count + error_count
|
108
|
+
if issues_count > 0
|
109
|
+
passed = total_tests - issues_count
|
110
|
+
details = []
|
111
|
+
details << "#{failed_count} failed" if failed_count > 0
|
112
|
+
details << "#{error_count} errors" if error_count > 0
|
113
|
+
puts Console.color(:red, "Total: #{details.join(', ')}, #{passed} passed (#{time_str})")
|
114
|
+
else
|
115
|
+
puts Console.color(:green, "Total: #{total_tests} passed (#{time_str})")
|
116
|
+
end
|
117
|
+
|
118
|
+
if total_files > 1
|
119
|
+
puts "Files: #{successful_files} of #{total_files} successful"
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
# Debug and diagnostic output - silent unless errors
|
124
|
+
def debug_info(message, level = 0)
|
125
|
+
# Silent in quiet mode
|
126
|
+
end
|
127
|
+
|
128
|
+
def trace_info(message, level = 0)
|
129
|
+
# Silent in quiet mode
|
130
|
+
end
|
131
|
+
|
132
|
+
def error_message(message, _details = nil)
|
133
|
+
return unless @show_errors
|
134
|
+
|
135
|
+
puts
|
136
|
+
puts Console.color(:red, "ERROR: #{message}")
|
137
|
+
end
|
138
|
+
|
139
|
+
# Utility methods
|
140
|
+
def raw_output(text)
|
141
|
+
puts text if @show_final_summary
|
142
|
+
end
|
143
|
+
|
144
|
+
def separator(style = :light)
|
145
|
+
# Silent in quiet mode
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# Quiet formatter that only shows dots for failures and errors
|
150
|
+
class QuietFailsFormatter < QuietFormatter
|
151
|
+
def test_result(test_case, result_status, actual_results = [], elapsed_time = nil)
|
152
|
+
# Only show non-pass dots in fails mode
|
153
|
+
return if result_status == :passed
|
154
|
+
|
155
|
+
super
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|