From 9f6e82ee4783e491c20f5244a613fdeb4024beb5 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Sun, 17 Aug 2014 12:52:54 -0700 Subject: Fix rounding errors with #travel_to by resetting the usec on any passed time to zero, so we only travel with per-second precision, not anything deeper than that. --- activesupport/CHANGELOG.md | 5 +++++ activesupport/lib/active_support/testing/time_helpers.rb | 6 +++++- activesupport/test/test_test.rb | 13 ++++++++++--- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/activesupport/CHANGELOG.md b/activesupport/CHANGELOG.md index b961b373cb..96bce53999 100644 --- a/activesupport/CHANGELOG.md +++ b/activesupport/CHANGELOG.md @@ -1,3 +1,8 @@ +* Fix rounding errors with #travel_to by resetting the usec on any passed time to zero, so we only travel + with per-second precision, not anything deeper than that. + + *DHH* + * Fix ActiveSupport::TestCase not to order users' test cases by default. If this change breaks your tests because your tests are order dependent, you need to explicitly call ActiveSupport::TestCase.my_tests_are_order_dependent! at the top of your tests. diff --git a/activesupport/lib/active_support/testing/time_helpers.rb b/activesupport/lib/active_support/testing/time_helpers.rb index eefa84262e..1112c6e0b1 100644 --- a/activesupport/lib/active_support/testing/time_helpers.rb +++ b/activesupport/lib/active_support/testing/time_helpers.rb @@ -78,6 +78,10 @@ module ActiveSupport # or Date.today, in order to honor the application time zone # please always use Time.current and Date.current.) # + # 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). + # # This method also accepts a block, which will return the current time back to its original # state at the end of the block: # @@ -90,7 +94,7 @@ module ActiveSupport if date_or_time.is_a?(Date) && !date_or_time.is_a?(DateTime) now = date_or_time.midnight.to_time else - now = date_or_time.to_time + now = date_or_time.to_time.change(usec: 0) end simple_stubs.stub_object(Time, :now, now) diff --git a/activesupport/test/test_test.rb b/activesupport/test/test_test.rb index 6f63a8a725..b74bc9bf20 100644 --- a/activesupport/test/test_test.rb +++ b/activesupport/test/test_test.rb @@ -188,7 +188,7 @@ class TimeHelperTest < ActiveSupport::TestCase expected_time = Time.now + 1.day travel 1.day - assert_equal expected_time, Time.now + assert_equal expected_time.to_s(:db), Time.now.to_s(:db) assert_equal expected_time.to_date, Date.today end @@ -196,11 +196,11 @@ class TimeHelperTest < ActiveSupport::TestCase expected_time = Time.now + 1.day travel 1.day do - assert_equal expected_time, Time.now + assert_equal expected_time.to_s(:db), Time.now.to_s(:db) assert_equal expected_time.to_date, Date.today end - assert_not_equal expected_time, Time.now + assert_not_equal expected_time.to_s(:db), Time.now.to_s(:db) assert_not_equal expected_time.to_date, Date.today end @@ -235,4 +235,11 @@ class TimeHelperTest < ActiveSupport::TestCase assert_not_equal expected_time, Time.now assert_not_equal Date.new(2004, 11, 24), Date.today end + + def test_travel_to_will_reset_the_usec_to_avoid_mysql_rouding + travel_to Time.utc(2014, 10, 10, 10, 10, 50, 999999) do + assert_equal 50, Time.now.sec + assert_equal 0, Time.now.usec + end + end end -- cgit v1.2.3