Fix regression when testing inclusion in unbounded ranges

Caused by 04a92a6764bf678919cf4b68a27496a39d6b886a.  This treats
unbounded ranges of arbitrary objects the same as how unbounded
string ranges are treated:

  (..x)  === y  # (y <=> x) <= 0
  (...x) === y  # (y <=> x) <  0
  (x..)  === y  # (x <=> y) <= 0

Fixes [Bug #19864]
This commit is contained in:
Jeremy Evans 2023-09-15 16:58:26 -07:00
parent 8835ca23c1
commit 25711683e8
2 changed files with 32 additions and 0 deletions

View File

@ -1820,6 +1820,7 @@ range_string_cover_internal(VALUE range, VALUE val)
return r_cover_p(range, beg, end, val);
}
if (NIL_P(beg)) {
unbounded_begin:;
VALUE r = rb_funcall(val, id_cmp, 1, end);
if (NIL_P(r)) return Qfalse;
if (RANGE_EXCL(range)) {
@ -1828,12 +1829,20 @@ range_string_cover_internal(VALUE range, VALUE val)
return RBOOL(rb_cmpint(r, val, end) <= 0);
}
else if (NIL_P(end)) {
unbounded_end:;
VALUE r = rb_funcall(beg, id_cmp, 1, val);
if (NIL_P(r)) return Qfalse;
return RBOOL(rb_cmpint(r, beg, val) <= 0);
}
}
if (!NIL_P(beg) && NIL_P(end)) {
goto unbounded_end;
}
if (NIL_P(beg) && !NIL_P(end)) {
goto unbounded_begin;
}
return range_include_fallback(beg, end, val);
}

View File

@ -2,6 +2,7 @@
require 'test/unit'
require 'delegate'
require 'timeout'
require 'date'
require 'rbconfig/sizeof'
class TestRange < Test::Unit::TestCase
@ -624,6 +625,28 @@ class TestRange < Test::Unit::TestCase
assert_operator(c.new(0)..c.new(10), :===, c.new(5), bug12003)
end
def test_eqq_unbounded_ruby_bug_19864
t1 = Date.today
t2 = t1 + 1
assert_equal(true, (..t1) === t1)
assert_equal(false, (..t1) === t2)
assert_equal(true, (..t2) === t1)
assert_equal(true, (..t2) === t2)
assert_equal(false, (...t1) === t1)
assert_equal(false, (...t1) === t2)
assert_equal(true, (...t2) === t1)
assert_equal(false, (...t2) === t2)
assert_equal(true, (t1..) === t1)
assert_equal(true, (t1..) === t2)
assert_equal(false, (t2..) === t1)
assert_equal(true, (t2..) === t2)
assert_equal(true, (t1...) === t1)
assert_equal(true, (t1...) === t2)
assert_equal(false, (t2...) === t1)
assert_equal(true, (t2...) === t2)
end
def test_eqq_non_iteratable
k = Class.new do
include Comparable