diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb
index a1155bf770..fbab62b7b6 100644
--- a/activesupport/lib/active_support/testing/time_helpers.rb
+++ b/activesupport/lib/active_support/testing/time_helpers.rb
@@ -115,7 +115,8 @@ module ActiveSupport
#
# Note that the usec for the time passed will be set to 0 to prevent rounding
# errors with external services, like MySQL (which will round instead of floor,
- # leading to off-by-one-second errors).
+ # leading to off-by-one-second errors), unless the with_usec argument
+ # is set to true.
#
# This method also accepts a block, which will return the current time back to its original
# state at the end of the block:
@@ -125,7 +126,7 @@ module ActiveSupport
# Time.current # => Wed, 24 Nov 2004 01:04:44 EST -05:00
# end
# Time.current # => Sat, 09 Nov 2013 15:34:49 EST -05:00
- def travel_to(date_or_time)
+ def travel_to(date_or_time, with_usec: false)
if block_given? && in_block
travel_to_nested_block_call = <<~MSG
@@ -158,12 +159,14 @@ module ActiveSupport
now = date_or_time.midnight.to_time
elsif date_or_time.is_a?(String)
now = Time.zone.parse(date_or_time)
+ elsif with_usec
+ now = date_or_time.to_time
else
now = date_or_time.to_time.change(usec: 0)
end
stubbed_time = Time.now if simple_stubs.stubbing(Time, :now)
- simple_stubs.stub_object(Time, :now) { at(now.to_i) }
+ simple_stubs.stub_object(Time, :now) { at(now.to_f) }
simple_stubs.stub_object(Date, :today) { jd(now.to_date.jd) }
simple_stubs.stub_object(DateTime, :now) { jd(now.to_date.jd, now.hour, now.min, now.sec, Rational(now.utc_offset, 86400)) }
diff --git a/activesupport/test/time_travel_test.rb b/activesupport/test/time_travel_test.rb
index f9673516dd..c589ade975 100644
--- a/activesupport/test/time_travel_test.rb
+++ b/activesupport/test/time_travel_test.rb
@@ -186,6 +186,41 @@ class TimeTravelTest < ActiveSupport::TestCase
end
end
+ def test_time_helper_travel_to_with_usec
+ Time.stub(:now, Time.now) do
+ duration_usec = 0.1.seconds
+ traveled_time = Time.new(2004, 11, 24, 1, 4, 44) + duration_usec
+ expected_time = Time.new(2004, 11, 24, 1, 4, 44)
+
+ assert_nothing_raised do
+ travel_to traveled_time
+
+ assert_equal expected_time, Time.now
+
+ travel_back
+ end
+ ensure
+ travel_back
+ end
+ end
+
+ def test_time_helper_travel_to_with_usec_true
+ Time.stub(:now, Time.now) do
+ duration_usec = 0.1.seconds
+ expected_time = Time.new(2004, 11, 24, 1, 4, 44) + duration_usec
+
+ assert_nothing_raised do
+ travel_to expected_time, with_usec: true
+
+ assert_equal expected_time.to_f, Time.now.to_f
+
+ travel_back
+ end
+ ensure
+ travel_back
+ end
+ end
+
def test_time_helper_travel_with_subsequent_block
Time.stub(:now, Time.now) do
outer_expected_time = Time.new(2004, 11, 24, 1, 4, 44)