Move stats to their own types

This commit is contained in:
Michael Miller 2019-02-22 13:47:57 -07:00
parent 48a1e61949
commit 5c2747efc0
3 changed files with 101 additions and 25 deletions

View file

@ -0,0 +1,49 @@
module Spectator::Formatters
# Produces a stringified time span for the runtime.
private struct Runtime
# Creates the runtime instance.
def initialize(@runtime : Time::Span)
end
# Appends the runtime to the output.
# The text will be formatted as follows,
# depending on the length of time:
# ```text
# Finished in ## microseconds
# Finished in ## milliseconds
# Finished in ## seconds
# Finished in #:##
# Finished in #:##:##
# Finished in # days #:##:##
# ```
def to_s(io)
io << "Finished in "
io << human_time(@runtime)
end
# Provides a more human-friendly formatting for a time span.
# This produces a string with the minimum of
# microseconds, milliseconds, seconds, minutes, hours, or days.
private def human_time(span)
millis = span.total_milliseconds
return "#{(millis * 1000).round.to_i} microseconds" if millis < 1
seconds = span.total_seconds
return "#{millis.round(2)} milliseconds" if seconds < 1
return "#{seconds.round(2)} seconds" if seconds < 60
int_seconds = seconds.to_i
minutes = int_seconds / 60
int_seconds %= 60
return sprintf("%i:%02i", minutes, int_seconds) if minutes < 60
hours = minutes / 60
minutes %= 60
return sprintf("%i:%02i:%02i", hours, minutes, int_seconds) if hours < 24
days = hours / 24
hours %= 24
return sprintf("%i days %i:%02i:%02i", days, hours, minutes, int_seconds)
end
end
end

View file

@ -0,0 +1,50 @@
module Spectator::Formatters
# Produces a stringified stats counter from result totals.
private struct StatsCounter
# Creates the instance with each of the counters.
private def initialize(@examples : Int32, @failures : Int32, @errors : Int32, @pending : Int32)
end
# Creates the instance from the counters in a report.
def initialize(report)
initialize(report.example_count, report.failed_count, report.error_count, report.pending_count)
end
# Produces a colorized formatting for the stats,
# depending on the number of each type of result.
def color
if @errors > 0
Color.error(self)
elsif @failures > 0
Color.failure(self)
elsif @pending > 0
Color.pending(self)
else
Color.success(self)
end
end
# Appends the counters to the output.
# The format will be:
# ```text
# # examples, # failures, # errors, # pending
# ```
def to_s(io)
stats.each_with_index do |stat, value, index|
io << ", " if index > 0
io << value
io << ' '
io << stat
end
end
private def stats
{
examples: @examples,
failures: @failures,
errors: @errors,
pending: @pending,
}
end
end
end

View file

@ -32,8 +32,8 @@ module Spectator::Formatters
# This contains how long the suite took to run
# and the counts for the results (total, failures, errors, and pending).
private def stats(report)
@io.puts "Finished in #{human_time(report.runtime)}"
@io.puts "#{report.example_count} examples, #{report.failed_count} failures, #{report.error_count} errors, #{report.pending_count} pending"
@io.puts Runtime.new(report.runtime)
@io.puts StatsCounter.new(report).color
end
# Produces the failure commands section of the summary.
@ -50,28 +50,5 @@ module Spectator::Formatters
@io.puts Comment.color("TODO")
end
end
# Provides a more human-friendly formatting for a time span.
private def human_time(span)
millis = span.total_milliseconds
return "#{(millis * 1000).round.to_i} microseconds" if millis < 1
seconds = span.total_seconds
return "#{millis.round(2)} milliseconds" if seconds < 1
return "#{seconds.round(2)} seconds" if seconds < 60
int_seconds = seconds.to_i
minutes = int_seconds / 60
int_seconds %= 60
return sprintf("%i:%02i", minutes, int_seconds) if minutes < 60
hours = minutes / 60
minutes %= 60
return sprintf("%i:%02i:%02i", hours, minutes, int_seconds) if hours < 24
days = hours / 24
hours %= 24
return sprintf("%i days %i:%02i:%02i", days, hours, minutes, int_seconds)
end
end
end