Permalink
Browse files

Add Timecop#lens where time can go FASTER

  • Loading branch information...
1 parent 5ec0f05 commit 6942d0eed940ea9a4e06d4dd9658f97bd7c14c8b David Holcomb & Ken Mayer committed Sep 19, 2012
Showing with 47 additions and 2 deletions.
  1. +14 −2 lib/timecop/time_stack_item.rb
  2. +14 −0 lib/timecop/timecop.rb
  3. +9 −0 test/time_stack_item_test.rb
  4. +10 −0 test/timecop_test.rb
@@ -6,9 +6,11 @@ class TimeStackItem #:nodoc:
attr_reader :mock_type
def initialize(mock_type, *args)
- raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel].include?(mock_type)
+ raise "Unknown mock_type #{mock_type}" unless [:freeze, :travel, :lens].include?(mock_type)
+ @scaling_factor = args.shift if mock_type == :lens
@mock_type = mock_type
@time = parse_time(*args)
+ @time_was = Time.now_without_mock_time
@travel_offset = compute_travel_offset
@dst_adjustment = compute_dst_adjustment(@time)
end
@@ -44,14 +46,24 @@ def utc_offset
def travel_offset
@travel_offset
end
+
+ def scaling_factor
+ @scaling_factor
+ end
def time(time_klass=Time) #:nodoc:
if travel_offset.nil?
time_klass.at( @time.to_f )
- else
+ elsif scaling_factor.nil?
time_klass.at( ( Time.now_without_mock_time + travel_offset ).to_f )
+ else
+ time_klass.at( scaled_time )
end
end
+
+ def scaled_time
+ (@time + (Time.now_without_mock_time - @time_was) * scaling_factor).to_f
+ end
def date(date_klass=Date)
date_klass.jd(time.__send__(:to_date).jd)
View
@@ -67,6 +67,20 @@ def travel(*args, &block)
block_given? ? val : nil
end
+ # Allows you to run a block of code and "lens" a time throughout the execution of that block.
+ # The first argument is a scaling factor, for example:
+ # Timecop.lens(2) do
+ # ... time will 'go' twice as fast here
+ # end
+ # See Timecop#freeze for exact usage of the other arguments
+ #
+ # Returns the value of the block or nil.
+ def lens(*args, &block)
+ val = instance().send(:travel, :lens, *args, &block)
+
+ block_given? ? val : nil
+ end
+
def baseline
instance().send(:baseline)
end
@@ -172,6 +172,15 @@ def test_set_travel_offset_for_freeze
assert_equal nil, tsi.send(:travel_offset)
end
+ def test_set_scaling_factor_for_lens
+ t_now = Time.now
+ t = Time.local(2009, 10, 1, 0, 0, 30)
+ expected_offset = t - t_now
+ tsi = Timecop::TimeStackItem.new(:lens, 4, t)
+ assert_times_effectively_equal expected_offset, tsi.send(:travel_offset), 1, "Offset not calculated correctly"
+ assert_equal tsi.send(:scaling_factor), 4, "Scaling factor not set"
+ end
+
def test_parse_string_date_with_active_support
date = '2012-01-02'
Time.expects(:parse).with(date).returns(Time.local(2012, 01, 02))
View
@@ -250,6 +250,16 @@ def test_mocked_date_time_now_is_local
end
end
+ def test_lensing_keeps_time_moving_at_an_accelerated_rate
+ t = Time.local(2008, 10, 10, 10, 10, 10)
+ Timecop.lens(4, t) do
+ start = Time.now
+ assert_times_effectively_equal start, t, 1, "Looks like we failed to actually travel time"
+ sleep(0.25)
+ assert_times_effectively_equal Time.at((start + 4*0.25).to_f), Time.now, 0.25, "Looks like time is not moving at 4x"
+ end
+ end
+
def test_freeze_with_utc_time
each_timezone do
t = Time.utc(2008, 10, 10, 10, 10, 10)

0 comments on commit 6942d0e

Please sign in to comment.