free_mutant/lib/mutant/reporter/cli.rb
2014-07-17 15:26:42 +00:00

144 lines
2.7 KiB
Ruby

module Mutant
class Reporter
# Reporter that reports in human readable format
class CLI < self
include Concord.new(:output)
NL = "\n".freeze
CLEAR_PREV_LINE = "\e[1A\e[2K".freeze
# Output abstraction to decouple tty? from buffer
class Output
include Concord.new(:tty, :buffer)
# Test if output is a tty
#
# @return [Boolean]
#
# @api private
#
def tty?
@tty
end
[:puts, :write].each do |name|
define_method(name) do |*args, &block|
buffer.public_send(name, *args, &block)
end
end
end # Output
# Rate per second progress report fires
OUTPUT_RATE = 1.0 / 20
# Initialize object
#
# @return [undefined]
#
# @api private
#
def initialize(*)
super
@last_frame = nil
@last_length = 0
@tty = output.respond_to?(:tty?) && output.tty?
end
# Report progress object
#
# @param [Runner::Collector] collector
#
# @return [self]
#
# @api private
#
def progress(collector)
throttle do
swap(frame(Printer::Collector, collector))
end
self
end
# Report warning
#
# @param [String] message
#
# @return [self]
#
# @api private
#
def warn(message)
output.puts(message)
self
end
# Report env
#
# @param [Result::Env] env
#
# @return [self]
#
# @api private
#
def report(env)
swap(frame(Printer::EnvResult, env))
self
end
private
# Compute progress frame
#
# @return [String]
#
# @api private
#
def frame(reporter, object)
buffer = StringIO.new
buffer.write(clear_command) if @tty
reporter.run(Output.new(@tty, buffer), object)
buffer.rewind
buffer.read
end
# Swap output frame
#
# @param [String] frame
#
# @return [undefined]
#
# @api private
#
def swap(frame)
output.write(frame)
@last_length = frame.split(NL).length
end
# Call block throttled
#
# @return [undefined]
#
# @api private
#
def throttle
now = Time.now
return if @last_frame && (now - @last_frame) < OUTPUT_RATE
yield
@last_frame = now
end
# Return clear command for last frame length
#
# @return [String]
#
# @api private
#
def clear_command
CLEAR_PREV_LINE * @last_length
end
end # CLI
end # Reporter
end # Mutant