Class: Mutante::Reporter

Inherits:
Object
  • Object
show all
Defined in:
lib/mutante/reporter.rb

Constant Summary collapse

SPINNER_FRAMES =
%w[         ].freeze
COLORS =
{
  reset:   "\e[0m",
  bold:    "\e[1m",
  dim:     "\e[2m",
  red:     "\e[31m",
  green:   "\e[32m",
  yellow:  "\e[33m",
  blue:    "\e[34m",
  magenta: "\e[35m",
  cyan:    "\e[36m",
  gray:    "\e[90m"
}.freeze
CLEAR_LINE =
"\e[2K\r".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(io: $stdout, force_plain: false) ⇒ Reporter

Returns a new instance of Reporter.



20
21
22
23
24
25
26
27
28
29
30
31
# File 'lib/mutante/reporter.rb', line 20

def initialize(io: $stdout, force_plain: false)
  @io            = io
  @flagged       = []
  @tty           = !force_plain && io.respond_to?(:tty?) && io.tty?
  @total_files   = 0
  @file_index    = 0
  @current_file  = nil
  @counts        = nil
  @file_started  = nil
  @started_at    = nil
  @spinner_index = 0
end

Instance Attribute Details

#flaggedObject (readonly)

Returns the value of attribute flagged.



160
161
162
# File 'lib/mutante/reporter.rb', line 160

def flagged
  @flagged
end

Instance Method Details

#baseline_result(ok) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/mutante/reporter.rb', line 57

def baseline_result(ok)
  if @tty
    @io.print CLEAR_LINE
    if ok
      @io.puts "  #{color(:green)}#{color(:reset)} baseline #{color(:green)}green#{color(:reset)}"
    else
      @io.puts "  #{color(:red)}#{color(:reset)} baseline #{color(:red)}RED#{color(:reset)} — fix the suite before running mutante."
    end
  else
    @io.puts(ok ? "  baseline green." : "  baseline RED.")
    @io.puts
  end
end

#baseline_startingObject



47
48
49
50
51
52
53
54
55
# File 'lib/mutante/reporter.rb', line 47

def baseline_starting
  if @tty
    @io.puts
    @io.print "  #{color(:cyan)}#{color(:reset)} running baseline test suite..."
    @io.flush
  else
    @io.puts "mutante: running baseline test suite..."
  end
end

#file_finishedObject



126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/mutante/reporter.rb', line 126

def file_finished
  if @tty
    @io.print CLEAR_LINE
    elapsed = format_duration(monotonic_now - (@file_started || monotonic_now))
    icon    = @counts && @counts[:flagged].positive? ? "#{color(:yellow)}#{color(:reset)}" : "#{color(:green)}#{color(:reset)}"
    parts   = []
    parts << "#{@counts[:tested]} tested" if @counts
    parts << "#{color(:red)}#{@counts[:flagged]} flagged#{color(:reset)}" if @counts && @counts[:flagged].positive?
    parts << "#{@counts[:skipped]} skipped" if @counts && @counts[:skipped].positive?
    parts << "#{color(:gray)}#{elapsed}#{color(:reset)}"
    @io.puts "  #{icon} #{parts.join(color(:gray) + ' · ' + color(:reset))}"
  else
    @io.puts
  end
end

#file_starting(path) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/mutante/reporter.rb', line 71

def file_starting(path)
  @file_index  += 1
  @current_file = path
  @counts       = { tested: 0, flagged: 0, skipped: 0 }
  @file_started = monotonic_now

  if @tty
    @io.puts
    @io.puts "#{color(:cyan)}#{color(:reset)} " \
             "#{color(:bold)}#{path}#{color(:reset)} " \
             "#{color(:gray)}[#{@file_index}/#{@total_files}]#{color(:reset)}"
    redraw_status
  else
    @io.puts path
  end
end

#finishedObject



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/mutante/reporter.rb', line 142

def finished
  if @tty
    draw_summary
  else
    @io.puts
    @io.puts "=" * 60
    if @flagged.empty?
      @io.puts "mutante: no dead-code candidates found."
    else
      plural = @flagged.size == 1 ? "candidate line" : "candidate lines"
      @io.puts "mutante: #{@flagged.size} #{plural} flagged:"
      @flagged.each do |entry|
        @io.puts "  #{entry[:path]}:#{entry[:line]}  #{entry[:text].strip}"
      end
    end
  end
end

#line_flagged(path, line_number, line_text) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/mutante/reporter.rb', line 88

def line_flagged(path, line_number, line_text)
  @flagged << { path: path, line: line_number, text: line_text }
  @counts[:flagged] += 1 if @counts
  @counts[:tested]  += 1 if @counts

  if @tty
    @io.print CLEAR_LINE
    @io.puts "  #{color(:red)}#{color(:reset)} " \
             "#{color(:red)}#{path}:#{line_number}#{color(:reset)}  " \
             "#{color(:dim)}#{line_text.strip}#{color(:reset)}"
    redraw_status
  else
    @io.puts "  flagged #{path}:#{line_number}  #{line_text.strip}"
  end
end

#line_safe(_path, _line_number) ⇒ Object



104
105
106
107
108
109
110
111
112
113
# File 'lib/mutante/reporter.rb', line 104

def line_safe(_path, _line_number)
  @counts[:tested] += 1 if @counts

  if @tty
    redraw_status
  else
    @io.print "."
    @io.flush
  end
end

#line_skipped(_path, _line_number, _reason) ⇒ Object



115
116
117
118
119
120
121
122
123
124
# File 'lib/mutante/reporter.rb', line 115

def line_skipped(_path, _line_number, _reason)
  @counts[:skipped] += 1 if @counts

  if @tty
    redraw_status
  else
    @io.print "-"
    @io.flush
  end
end

#starting(files) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/mutante/reporter.rb', line 33

def starting(files)
  @total_files = files.size
  @started_at  = monotonic_now
  plural       = files.size == 1 ? "file" : "files"
  subtitle     = "analyzing #{files.size} #{plural} · reverse mutation testing"

  if @tty
    draw_header("mutante v#{Mutante::VERSION}", subtitle)
  else
    @io.puts "mutante: #{subtitle}"
    @io.puts
  end
end