Module: Ace::Test::EndToEndRunner::Atoms::DisplayHelpers

Defined in:
lib/ace/test/end_to_end_runner/atoms/display_helpers.rb

Overview

Pure formatting functions for E2E test display output. No I/O, no side effects — all methods return strings.

Constant Summary collapse

ANSI_COLORS =
{
  green: "\033[32m",
  red: "\033[31m",
  yellow: "\033[33m",
  cyan: "\033[36m",
  gray: "\033[90m",
  reset: "\033[0m"
}.freeze
SEPARATOR =
"=" * 65
DOUBLE_SEPARATOR =
"\u2550" * 65
UNICODE_ICONS =

Unicode and ASCII fallback icons for progress display

{
  waiting: "\u00b7",    # · (middle dot)
  running: "\u22ef",    # ⋯ (midline horizontal ellipsis)
  check: "\u2713",      # ✓ (check mark)
  cross: "\u2717"       # ✗ (ballot x)
}.freeze
ASCII_ICONS =
{
  waiting: ".",
  running: "...",
  check: "OK",
  cross: "XX"
}.freeze

Class Method Summary collapse

Class Method Details

.color(text, color_name, use_color: true) ⇒ String

Wrap text in ANSI color codes (or return plain text)

Parameters:

  • text (String)
  • color_name (Symbol)

    one of :green, :red, :yellow, :cyan, :gray

  • use_color (Boolean) (defaults to: true)

Returns:

  • (String)


108
109
110
111
112
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 108

def color(text, color_name, use_color: true)
  return text unless use_color

  "#{ANSI_COLORS[color_name]}#{text}#{ANSI_COLORS[:reset]}"
end

.double_separatorString

Returns 65-char double-line separator (═ or =).

Returns:

  • (String)

    65-char double-line separator (═ or =)



48
49
50
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 48

def double_separator
  unicode_terminal? ? DOUBLE_SEPARATOR : SEPARATOR
end

.format_duration(seconds) ⇒ String

Human-readable duration for summary lines

Parameters:

  • seconds (Numeric)

Returns:

  • (String)

    e.g. “1m 50s” or “10.70s”



81
82
83
84
85
86
87
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 81

def format_duration(seconds)
  if seconds >= 60
    "#{(seconds / 60).floor}m #{(seconds % 60).round(0)}s"
  else
    sprintf("%.2fs", seconds)
  end
end

.format_elapsed(seconds) ⇒ String

Right-aligned elapsed seconds for columnar output

Parameters:

  • seconds (Numeric)

Returns:

  • (String)

    e.g. “ 10.7s”



74
75
76
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 74

def format_elapsed(seconds)
  sprintf("%5.1fs", seconds)
end

.format_single_result(result, use_color: false) ⇒ String

Format a single-test result line

Parameters:

Returns:

  • (String)


224
225
226
227
228
229
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 224

def format_single_result(result, use_color: false)
  icon = color(status_icon(result.success?), result.success? ? :green : :red, use_color: use_color)
  tc = tc_count_display(result)

  "Result: #{icon} #{result.status.upcase}#{tc}"
end

.format_suite_duration(seconds) ⇒ String

Duration formatted for suite-level display (minute-range values)

Parameters:

  • seconds (Numeric)

Returns:

  • (String)

    e.g. “4m 25s” or “45.3s”



117
118
119
120
121
122
123
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 117

def format_suite_duration(seconds)
  if seconds >= 60
    "#{(seconds / 60).floor}m %02ds" % (seconds % 60).round(0)
  else
    sprintf("%.1fs", seconds)
  end
end

.format_suite_elapsed(seconds) ⇒ String

Right-aligned elapsed for suite columnar output (wider field)

Parameters:

  • seconds (Numeric)

Returns:

  • (String)

    e.g. “ 4m 25s” (7 chars wide)



128
129
130
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 128

def format_suite_elapsed(seconds)
  sprintf("%7s", format_suite_duration(seconds))
end

.format_suite_summary(results_data, use_color: false) ⇒ Array<String>

Build the full suite summary block

Parameters:

  • results_data (Hash)

    with keys :total, :passed, :failed, :errors, :packages, :duration, :failed_details

  • use_color (Boolean) (defaults to: false)

Returns:

  • (Array<String>)

    lines to print



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 152

def format_suite_summary(results_data, use_color: false)
  lines = ["", double_separator]

  failed_details = results_data[:failed_details] || []
  if failed_details.any?
    lines << "Failed tests:"
    failed_details.each do |detail|
      lines << "  - #{detail[:package]}/#{detail[:test_name]}: #{detail[:cases]}"
    end
    lines << ""
  end

  lines << "Duration:    #{format_suite_duration(results_data[:duration])}"
  lines << "Tests:       #{results_data[:passed]} passed, #{results_data[:failed] + results_data[:errors]} failed"

  total_tc = results_data[:total_cases] || 0
  passed_tc = results_data[:passed_cases] || 0
  if total_tc > 0
    failed_tc = total_tc - passed_tc
    pct = (passed_tc * 100.0 / total_tc).round(0)
    lines << "Test cases:  #{passed_tc} passed, #{failed_tc} failed (#{pct}%)"
  end

  lines << ""
  lines << if results_data[:failed] + results_data[:errors] == 0
    color("\u2713 ALL TESTS PASSED", :green, use_color: use_color)
  else
    color("\u2717 SOME TESTS FAILED", :red, use_color: use_color)
  end
  lines << double_separator
  lines
end

.format_suite_test_line(icon, elapsed, package, test_name, cases_str, pkg_width:, name_width:) ⇒ String

Build a columnar test result line for suite display

Parameters:

  • icon (String)

    status icon (may include ANSI)

  • elapsed (Numeric)

    seconds

  • package (String)

    package name

  • test_name (String)

    test name

  • cases_str (String)

    e.g. “5/5 cases” or “”

  • pkg_width (Integer)

    column width for package

  • name_width (Integer)

    column width for test name

Returns:

  • (String)


141
142
143
144
145
146
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 141

def format_suite_test_line(icon, elapsed, package, test_name, cases_str, pkg_width:, name_width:)
  time_col = format_suite_elapsed(elapsed)
  pkg_col = package.ljust(pkg_width)
  name_col = test_name.ljust(name_width)
  "#{icon}  #{time_col}  #{pkg_col}  #{name_col}  #{cases_str}"
end

.format_summary_lines(results, duration, report_path, use_color: false) ⇒ Array<String>

Format summary lines for display after a test run

Parameters:

  • results (Array<Models::TestResult>)
  • duration (Numeric)

    total duration in seconds

  • report_path (String)
  • use_color (Boolean) (defaults to: false)

Returns:

  • (Array<String>)

    lines to print



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 191

def format_summary_lines(results, duration, report_path, use_color: false)
  passed = results.count(&:success?)
  failed = results.size - passed
  total_tc = results.sum(&:total_count)
  total_passed_tc = results.sum(&:passed_count)
  total_failed_tc = total_tc - total_passed_tc

  lines = [separator]
  lines << "Duration:     #{format_duration(duration)}"
  lines << "Tests:        #{passed} passed, #{failed} failed"

  if total_tc > 0
    pct = (total_passed_tc * 100.0 / total_tc).round(0)
    lines << "Test cases:   #{total_passed_tc} passed, #{total_failed_tc} failed (#{pct}%)"
  end

  lines << "Report:       #{report_path}"
  lines << ""

  lines << if failed == 0
    color("\u2713 ALL TESTS PASSED", :green, use_color: use_color)
  else
    color("\u2717 SOME TESTS FAILED", :red, use_color: use_color)
  end

  lines << separator
  lines
end

.running_iconString

Get the running icon for progress display

Returns:

  • (String)

    “⋯” or “…”



67
68
69
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 67

def running_icon
  unicode_terminal? ? UNICODE_ICONS[:running] : ASCII_ICONS[:running]
end

.separatorString

Returns 65-char separator line.

Returns:

  • (String)

    65-char separator line



99
100
101
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 99

def separator
  SEPARATOR
end

.status_icon(success) ⇒ String

Returns “✓” or “✗” (or ASCII fallback).

Parameters:

  • success (Boolean)

Returns:

  • (String)

    “✓” or “✗” (or ASCII fallback)



54
55
56
57
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 54

def status_icon(success)
  icons = unicode_terminal? ? UNICODE_ICONS : ASCII_ICONS
  success ? icons[:check] : icons[:cross]
end

.tc_count_display(result) ⇒ String

Test case count display suffix

Parameters:

Returns:

  • (String)

    e.g. “ 0/8 cases” or “”



92
93
94
95
96
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 92

def tc_count_display(result)
  return "" if result.total_count == 0

  "  #{result.passed_count}/#{result.total_count} cases"
end

.unicode_terminal?Boolean

Detect if the current terminal supports Unicode Checks LANG/LC_ALL environment variables for UTF-8 encoding

Returns:

  • (Boolean)

    true if terminal likely supports Unicode



42
43
44
45
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 42

def unicode_terminal?
  lang = ENV["LANG"] || ENV["LC_ALL"] || ""
  lang.include?("UTF-8") || lang.include?("utf-8")
end

.waiting_iconString

Get the waiting icon for progress display

Returns:

  • (String)

    “·” or “.”



61
62
63
# File 'lib/ace/test/end_to_end_runner/atoms/display_helpers.rb', line 61

def waiting_icon
  unicode_terminal? ? UNICODE_ICONS[:waiting] : ASCII_ICONS[:waiting]
end