public
Created

  • Download Gist
time.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
class Time
class << self
attr_accessor :mock_time
def now_with_mock_time
@mock_time || now_without_mock_time
end
alias_method_chain :now, :mock_time
# Freeze Time.now, DateTime.now and Date.today to the given Time
# This method operates only in the context of a provided block.
#
# Example Usage:
#
# Time.be(:utc, 2007, 5, 2) do
# puts Time.now
# end
# # => 2007-05-02 00:00:00 UTC
#
# Time.be(:local, 2007, 5, 2, 17, 31, 2) do
# puts Time.now
# end
# # => 2007-05-02 17:31:02 +1000
#
# It works with DateTime.now too:
#
# Time.be(Time.utc(2012, 1, 1)) do
# puts DateTime.now
# end
# # => 2012-01-01T00:00:00+00:00
#
# And also with Date.today:
#
# Time.be(:utc, 2000, 2, 14) do
# puts Date.today
# end
# # => 2000-02-14
#
# Blocks can be nested together:
#
# Time.be(:utc, 2007, 5, 2) do
# Time.be(:local, 2007, 5, 2, 17, 31, 2) do
# puts Time.now
# end
# puts Time.now
# end
# # => 2007-05-02 17:31:02 +1000
# # => 2007-05-02 00:00:00 UTC
#
# And lastly, you can take advantage of ActiveSupport's Numeric helpers:
#
# Time.be(:utc, 2000, 1, 1) do
# Time.be(4.days.from_now.utc) do
# puts Time.now
# Time.be(3.minutes.ago.utc) do
# puts Time.now
# end
# end
# end
# # => 2000-01-05 00:00:00 UTC
# # => 2000-01-04 23:57:00 UTC
#
def be(a_time_or_type, *args)
raise ArgumentError, "Time.be requires a block, but none was given" unless block_given?
a_time = if a_time_or_type.kind_of?(Time)
a_time_or_type
else
unless [:utc, :local].include?(a_time_or_type)
raise ArgumentError, "First argument must either by a Time, :utc or :local"
end
Time.send(a_time_or_type, *args)
end
original_mock_time = @mock_time
@mock_time = a_time
yield
ensure
@mock_time = original_mock_time
end
end
end
time_spec.rb
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
require 'spec_helper'
 
describe "Time.be" do
it "sets the current time for the scope of a block" do
Time.be(Time.utc(2009, 3, 9)) { Time.now.should == Time.utc(2009, 3, 9) }
end
it "supports nesting blocks" do
Time.be(Time.utc(2009, 3, 9)) do
Time.be(Time.utc(2007, 1, 1)) { Time.now.should == Time.utc(2007, 1, 1) }
end
end
it "restores the time after the block has executed" do
Time.be(Time.utc(2009, 3, 9)) do
Time.be(Time.utc(2007, 1, 1)) { }
Time.now.should == Time.utc(2009, 3, 9)
end
end
it "supports passing time values as arguments" do
Time.be(:local, 2009, 3, 9, 17, 37, 59) do
Time.now.should == Time.local(2009, 3, 9, 17, 37, 59)
end
end
it "allows travelling through relative time" do
Time.be(:utc, 2009, 3, 9) do
Time.be(2.hours.from_now) do
Time.now.should == Time.utc(2009, 3, 9, 2, 0, 0)
Time.be(4.days.ago) do
Time.now.should == Time.utc(2009, 3, 5, 2, 0, 0)
end
end
end
end
it "affects DateTime" do
Time.be(:utc, 2009, 3, 9) do
date_time = DateTime.now
date_time.year.should == 2009
date_time.month.should == 3
date_time.day.should == 9
date_time.hour.should == 0
date_time.minute.should == 0
end
end
it "affects Date" do
Time.be(:utc, 2009, 3, 9) do
date = Date.today
date.year.should == 2009
date.month.should == 3
date.day.should == 9
end
end
end

Comment no longer makes sense. Should have really used a new gist. Meh.

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.