Skip to content

Commit

Permalink
Merge pull request #29 from waterlink/extract-time-formatting-logic
Browse files Browse the repository at this point in the history
Refactor and improve elapsed time logic
  • Loading branch information
waterlink committed Feb 21, 2016
2 parents 7379434 + ed08d0a commit 78307c3
Show file tree
Hide file tree
Showing 6 changed files with 231 additions and 17 deletions.
148 changes: 148 additions & 0 deletions spec/elapsed_time_spec.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
require "./spec_helper"
require "../src/elapsed_time"

module Spec2
Spec2.describe ElapsedTime do
let(:started_at) { Time.new(2014, 4, 21, 13, 27, 33, 57) }

describe "#to_s" do
context "when seconds < 1" do
it "returns in milliseconds" do
expect(ElapsedTime.new(
started_at, started_at + 1.milliseconds,
).to_s).to eq("1 milliseconds")

expect(ElapsedTime.new(
started_at, started_at + 50.milliseconds,
).to_s).to eq("50 milliseconds")

expect(ElapsedTime.new(
started_at, started_at + 999.milliseconds,
).to_s).to eq("999 milliseconds")
end

it "returns in milliseconds rounded to .2" do
expect(ElapsedTime.new(
started_at,
started_at + Time::Span.new(36 * 10000)
).to_s).to eq("36 milliseconds")

expect(ElapsedTime.new(
started_at,
started_at + Time::Span.new(36.5 * 10000)
).to_s).to eq("36.5 milliseconds")

expect(ElapsedTime.new(
started_at,
started_at + Time::Span.new(36.57 * 10000)
).to_s).to eq("36.57 milliseconds")

expect(ElapsedTime.new(
started_at,
started_at + Time::Span.new(36.573 * 10000)
).to_s).to eq("36.57 milliseconds")
end
end

context "when 1 <= total seconds < 60" do
it "returns in seconds" do
expect(ElapsedTime.new(
started_at, started_at + 1.seconds,
).to_s).to eq("1 seconds")

expect(ElapsedTime.new(
started_at, started_at + 34.seconds,
).to_s).to eq("34 seconds")

expect(ElapsedTime.new(
started_at, started_at + 59.seconds,
).to_s).to eq("59 seconds")

expect(ElapsedTime.new(
started_at, started_at + 60.seconds,
).to_s).not_to eq("60 seconds")
end

it "returns in seconds rounded to .2" do
expect(ElapsedTime.new(
started_at, started_at + 7.seconds,
).to_s).to eq("7 seconds")

expect(ElapsedTime.new(
started_at, started_at + 7.3.seconds,
).to_s).to eq("7.3 seconds")

expect(ElapsedTime.new(
started_at, started_at + 7.34.seconds,
).to_s).to eq("7.34 seconds")

expect(ElapsedTime.new(
started_at, started_at + 7.348.seconds,
).to_s).to eq("7.35 seconds")
end
end

context "when 1 minute <= elapsed < 1 hour" do
it "returns minutes:seconds" do
expect(ElapsedTime.new(
started_at, started_at + 60.seconds,
).to_s).to eq("1:00 minutes")

expect(ElapsedTime.new(
started_at, started_at + 1.3.minutes,
).to_s).to eq("1:18 minutes")

expect(ElapsedTime.new(
started_at, started_at + 25.7.minutes,
).to_s).to eq("25:42 minutes")

expect(ElapsedTime.new(
started_at, started_at + 59.99.minutes,
).to_s).to eq("59:59 minutes")
end

it "formats seconds part as 2 digit 0-padded" do
expect(ElapsedTime.new(
started_at, started_at + 1.1.minutes,
).to_s).to eq("1:06 minutes")

expect(ElapsedTime.new(
started_at, started_at + 69.seconds,
).to_s).to eq("1:09 minutes")

expect(ElapsedTime.new(
started_at, started_at + 70.seconds,
).to_s).to eq("1:10 minutes")
end
end

context "when total_seconds >= 1 hour" do
it "returns in hours" do
expect(ElapsedTime.new(
started_at, started_at + 60.minutes,
).to_s).to eq("1:00:00 hours")

expect(ElapsedTime.new(
started_at, started_at + 7.37.hours,
).to_s).to eq("7:22:12 hours")

expect(ElapsedTime.new(
started_at, started_at + 7832.26.hours,
).to_s).to eq("7832:15:36 hours")
end

it "formats seconds part as 2-digits 0-padded" do
expect(ElapsedTime.new(
started_at, started_at + 60.1.minutes,
).to_s).to eq("1:00:06 hours")
end

it "formats minutes part as 2-digits 0-padded" do
expect(ElapsedTime.new(
started_at, started_at + 61.minutes,
).to_s).to eq("1:01:00 hours")
end
end
end
end
end
80 changes: 80 additions & 0 deletions src/elapsed_time.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
module Spec2
class ElapsedTime
FORMATTERS = {
# seconds range => formatter class
(0...1) => InMilliseconds,
(1...60) => InSeconds,
(60...3600) => InMinutes,
(3600..Float32::INFINITY) => InHours,
}

private getter time_now, started_at
def initialize(@started_at = Spec2.started_at, @time_now = Time.now)
end

def to_s
formatter_class.new(elapsed).to_s
end

private def formatter_class
FORMATTERS
.to_a
.find(&.first.includes?(total_seconds))
.not_nil!
.last
end

private def elapsed
time_now - started_at
end

private def total_seconds
@_total_seconds ||= elapsed.total_seconds
end

record Format2DigitNumber, value do
def to_s
"%02d" % value
end

macro delegate(name, target)
def {{name.id}}
Format2DigitNumber.new({{target.id}}.{{name.id}}).to_s
end
end
end

record InSeconds, elapsed do
def to_s
"#{elapsed.total_seconds.round(2)} seconds"
end
end

record InMilliseconds, elapsed do
def to_s
"#{elapsed.total_milliseconds.round(2)} milliseconds"
end
end

record InMinutes, elapsed do
def to_s
"#{elapsed.minutes}:#{seconds} minutes"
end

Format2DigitNumber.delegate seconds, elapsed
end

record InHours, elapsed do
def to_s
"#{hours}:#{minutes}:#{seconds} hours"
end

private def hours
elapsed.total_hours.to_i
end

Format2DigitNumber.delegate minutes, elapsed
Format2DigitNumber.delegate seconds, elapsed
end
end
end
15 changes: 0 additions & 15 deletions src/reporter.cr
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,5 @@ module Spec2
abstract def example_failed(example, exception)
abstract def example_errored(example, exception)
abstract def report

private def elapsed_time
elapsed_time = Time.now - Spec2.started_at
total_seconds = elapsed_time.total_seconds

if total_seconds < 1
"#{elapsed_time.total_milliseconds.round(2)} milliseconds"
elsif total_seconds < 60
"#{total_seconds.round(2)} seconds"
else
minutes = elapsed_time.minutes
seconds = elapsed_time.seconds
"#{minutes}:#{seconds < 10 ? "0" : ""}#{seconds} minutes"
end
end
end
end
2 changes: 1 addition & 1 deletion src/reporters/default.cr
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ module Spec2

output.puts
status = @errors.size > 0 ? :failure : :success
output.puts "Finished in #{elapsed_time}"
output.puts "Finished in #{ElapsedTime.new.to_s}"
output.puts status, "Examples: #{@count}, failures: #{@errors.size}"
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/reporters/doc.cr
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module Spec2

output.puts
status = @errors.size > 0 ? :failure : :success
output.puts "Finished in #{elapsed_time}"
output.puts "Finished in #{ElapsedTime.new.to_s}"
output.puts status, "Examples: #{@count}, failures: #{@errors.size}"
end

Expand Down
1 change: 1 addition & 0 deletions src/spec2.cr
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ require "./output"
require "./outputs/*"
require "./should"
require "./global_dsl"
require "./elapsed_time"

module Spec2
extend self
Expand Down

0 comments on commit 78307c3

Please sign in to comment.