Skip to content

Commit 587af76

Browse files
committed
Make <=> methods return nil if passed a non-comparable argument.
Resolves test case failures on ruby 2.2.0 and later due to Comparable#== no longer catching exceptions (https://bugs.ruby-lang.org/issues/7688). (cherry picked from commit ae0e708)
1 parent f4f3c2e commit 587af76

File tree

6 files changed

+29
-1
lines changed

6 files changed

+29
-1
lines changed

lib/tzinfo/country.rb

+3
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,10 @@ def zone_info
137137

138138
# Compare two Countries based on their code. Returns -1 if c is less
139139
# than self, 0 if c is equal to self and +1 if c is greater than self.
140+
#
141+
# Returns nil if c is not comparable with Country instances.
140142
def <=>(c)
143+
return nil unless c.is_a?(Country)
141144
code <=> c.code
142145
end
143146

lib/tzinfo/time_or_datetime.rb

+8
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,15 @@ def sec
178178
# receiver is less than, equal to, or greater than timeOrDateTime.
179179
#
180180
# Milliseconds and smaller units are ignored in the comparison.
181+
#
182+
# Returns nil if the passed in timeOrDateTime is not comparable with
183+
# TimeOrDateTime instances.
181184
def <=>(timeOrDateTime)
185+
return nil unless timeOrDateTime.is_a?(TimeOrDateTime) ||
186+
timeOrDateTime.is_a?(Time) ||
187+
timeOrDateTime.is_a?(DateTime) ||
188+
timeOrDateTime.respond_to?(:to_i)
189+
182190
if timeOrDateTime.is_a?(TimeOrDateTime)
183191
orig = timeOrDateTime.to_orig
184192

lib/tzinfo/timezone.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -498,10 +498,13 @@ def strftime(format, utc = Time.now.utc)
498498

499499
# Compares two Timezones based on their identifier. Returns -1 if tz is less
500500
# than self, 0 if tz is equal to self and +1 if tz is greater than self.
501+
#
502+
# Returns nil if tz is not comparable with Timezone instances.
501503
def <=>(tz)
504+
return nil unless tz.is_a?(Timezone)
502505
identifier <=> tz.identifier
503506
end
504-
507+
505508
# Returns true if and only if the identifier of tz is equal to the
506509
# identifier of this Timezone.
507510
def eql?(tz)

test/tc_country.rb

+4
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ def test_compare
114114
assert_equal(1, Country.get('US') <=> Country.get('FR'))
115115
end
116116

117+
def test_compare_non_comparable
118+
assert_nil(Country.get('GB') <=> Object.new)
119+
end
120+
117121
def test_equality
118122
assert_equal(true, Country.get('GB') == Country.get('GB'))
119123
assert_equal(false, Country.get('GB') == Country.get('US'))

test/tc_time_or_datetime.rb

+6
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,12 @@ def test_compare_timestamp_str
276276
assert_equal(1, TimeOrDateTime.new(1143214323) <=> '1111678323')
277277
end
278278

279+
def test_compare_non_comparable
280+
assert_nil(TimeOrDateTime.new(Time.utc(2006, 3, 24, 15, 32, 3)) <=> Object.new)
281+
assert_nil(TimeOrDateTime.new(DateTime.new(2006, 3, 24, 15, 32, 3)) <=> Object.new)
282+
assert_nil(TimeOrDateTime.new(1143214323) <=> Object.new)
283+
end
284+
279285
def test_eql
280286
assert_equal(true, TimeOrDateTime.new(Time.utc(2006, 3, 24, 15, 32, 3)).eql?(TimeOrDateTime.new(Time.utc(2006, 3, 24, 15, 32, 3))))
281287
assert_equal(false, TimeOrDateTime.new(Time.utc(2006, 3, 24, 15, 32, 3)).eql?(TimeOrDateTime.new(DateTime.new(2006, 3, 24, 15, 32, 3))))

test/tc_timezone.rb

+4
Original file line numberDiff line numberDiff line change
@@ -907,6 +907,10 @@ def test_compare
907907
assert_equal(1, TestTimezone.new('Europe/Paris') <=> TestTimezone.new('America/New_York'))
908908
end
909909

910+
def test_compare_non_comparable
911+
assert_nil(TestTimezone.new('Europe/London') <=> Object.new)
912+
end
913+
910914
def test_equality
911915
assert_equal(true, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/London'))
912916
assert_equal(false, TestTimezone.new('Europe/London') == TestTimezone.new('Europe/london'))

0 commit comments

Comments
 (0)