From a4912078c7d345a347f023ef28c0986458bdebf5 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Tue, 22 Nov 2011 15:37:16 -0500 Subject: [PATCH] Fix inconsistencies with Time{WithZone}#{hash,eql?} --- .../lib/active_support/core_ext/time/calculations.rb | 10 ++++++++++ activesupport/lib/active_support/time_with_zone.rb | 7 +++++-- activesupport/test/core_ext/time_ext_test.rb | 6 ++++++ activesupport/test/core_ext/time_with_zone_test.rb | 11 +++++++++-- 4 files changed, 30 insertions(+), 4 deletions(-) diff --git a/activesupport/lib/active_support/core_ext/time/calculations.rb b/activesupport/lib/active_support/core_ext/time/calculations.rb index 372dd692126..7a550864529 100644 --- a/activesupport/lib/active_support/core_ext/time/calculations.rb +++ b/activesupport/lib/active_support/core_ext/time/calculations.rb @@ -312,4 +312,14 @@ class Time end alias_method :compare_without_coercion, :<=> alias_method :<=>, :compare_with_coercion + + # Layers additional behavior on Time#eql? so that ActiveSupport::TimeWithZone instances + # can be eql? to an equivalent Time + def eql_with_coercion(other) + # if other is an ActiveSupport::TimeWithZone, coerce a Time instance from it so we can do eql? comparison + other = other.comparable_time if other.respond_to?(:comparable_time) + eql_without_coercion(other) + end + alias_method :eql_without_coercion, :eql? + alias_method :eql?, :eql_with_coercion end diff --git a/activesupport/lib/active_support/time_with_zone.rb b/activesupport/lib/active_support/time_with_zone.rb index 63279d0e6d0..d3adf671a03 100644 --- a/activesupport/lib/active_support/time_with_zone.rb +++ b/activesupport/lib/active_support/time_with_zone.rb @@ -203,7 +203,11 @@ module ActiveSupport end def eql?(other) - utc == other + utc.eql?(other) + end + + def hash + utc.hash end def +(other) @@ -277,7 +281,6 @@ module ActiveSupport def to_i utc.to_i end - alias_method :hash, :to_i alias_method :tv_sec, :to_i # A TimeWithZone acts like a Time, so just return +self+. diff --git a/activesupport/test/core_ext/time_ext_test.rb b/activesupport/test/core_ext/time_ext_test.rb index ab9be4b18b0..e7090eed085 100644 --- a/activesupport/test/core_ext/time_ext_test.rb +++ b/activesupport/test/core_ext/time_ext_test.rb @@ -744,6 +744,12 @@ class TimeExtCalculationsTest < ActiveSupport::TestCase assert_equal(-1, Time.utc(2000) <=> ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1, 0, 0, 1), ActiveSupport::TimeZone['UTC'] )) end + def test_eql? + assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) ) + assert_equal true, Time.utc(2000).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) ) + assert_equal false,Time.utc(2000, 1, 1, 0, 0, 1).eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone['UTC']) ) + end + def test_minus_with_time_with_zone assert_equal 86_400.0, Time.utc(2000, 1, 2) - ActiveSupport::TimeWithZone.new( Time.utc(2000, 1, 1), ActiveSupport::TimeZone['UTC'] ) end diff --git a/activesupport/test/core_ext/time_with_zone_test.rb b/activesupport/test/core_ext/time_with_zone_test.rb index b2309ae806b..9d9e411c280 100644 --- a/activesupport/test/core_ext/time_with_zone_test.rb +++ b/activesupport/test/core_ext/time_with_zone_test.rb @@ -200,8 +200,15 @@ class TimeWithZoneTest < Test::Unit::TestCase end def test_eql? - assert @twz.eql?(Time.utc(2000)) - assert @twz.eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) ) + assert_equal true, @twz.eql?(Time.utc(2000)) + assert_equal true, @twz.eql?( ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]) ) + assert_equal false, @twz.eql?( Time.utc(2000, 1, 1, 0, 0, 1) ) + assert_equal false, @twz.eql?( DateTime.civil(1999, 12, 31, 23, 59, 59) ) + end + + def test_hash + assert_equal Time.utc(2000).hash, @twz.hash + assert_equal Time.utc(2000).hash, ActiveSupport::TimeWithZone.new(Time.utc(2000), ActiveSupport::TimeZone["Hawaii"]).hash end def test_plus_with_integer