未验证 提交 3e907155 编写于 作者: C Carlos Antonio da Silva 提交者: Kasper Timm Hansen

Merge pull request #37178 from pond/fix-boundless-range-extensions

Fix issues with ActiveSupport Range extensions on boundless Ranges

Closes #37177
上级 11885f26
* Fix `Range#===`, `Range#include?`, and `Range#cover?` to work with beginless (startless)
and endless range targets. Builds on work by Allen Hsu.
*Andrew Hodgkinson*
* Fix `Range#include?` to work with beginless and endless ranges.
*Allen Hsu*
......
......@@ -11,13 +11,15 @@ module CompareWithRange
# The native Range#=== behavior is untouched.
# ('a'..'f') === ('c') # => true
# (5..9) === (11) # => false
#
# The given range must be fully bounded, with both start and end.
def ===(value)
if value.is_a?(::Range)
# 1...10 includes 1..9 but it does not include 1..10.
# 1..10 includes 1...11 but it does not include 1...12.
operator = exclude_end? && !value.exclude_end? ? :< : :<=
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
super(value.first) && value_max.send(operator, last)
super(value.first) && (self.end.nil? || value_max.send(operator, last))
else
super
end
......@@ -32,13 +34,15 @@ def ===(value)
# The native Range#include? behavior is untouched.
# ('a'..'f').include?('c') # => true
# (5..9).include?(11) # => false
#
# The given range must be fully bounded, with both start and end.
def include?(value)
if value.is_a?(::Range)
# 1...10 includes 1..9 but it does not include 1..10.
# 1..10 includes 1...11 but it does not include 1...12.
operator = exclude_end? && !value.exclude_end? ? :< : :<=
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
super(value.first) && value_max.send(operator, last)
super(value.first) && (self.end.nil? || value_max.send(operator, last))
else
super
end
......@@ -53,13 +57,15 @@ def include?(value)
# The native Range#cover? behavior is untouched.
# ('a'..'f').cover?('c') # => true
# (5..9).cover?(11) # => false
#
# The given range must be fully bounded, with both start and end.
def cover?(value)
if value.is_a?(::Range)
# 1...10 covers 1..9 but it does not cover 1..10.
# 1..10 covers 1...11 but it does not cover 1...12.
operator = exclude_end? && !value.exclude_end? ? :< : :<=
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last
super(value.first) && value_max.send(operator, last)
super(value.first) && (self.end.nil? || value_max.send(operator, last))
else
super
end
......
......@@ -64,12 +64,28 @@ def test_should_include_other_with_exclusive_end
def test_include_with_endless_range
assert(eval("1..").include?(2))
end
def test_should_include_range_with_endless_range
assert(eval("1..").include?(2..4))
end
def test_should_not_include_range_with_endless_range
assert_not(eval("1..").include?(0..4))
end
end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0")
def test_include_with_beginless_range
assert(eval("..2").include?(1))
end
def test_should_include_range_with_beginless_range
assert(eval("..2").include?(-1..1))
end
def test_should_not_include_range_with_beginless_range
assert_not(eval("..2").include?(-1..3))
end
end
def test_should_compare_identical_inclusive
......@@ -84,6 +100,26 @@ def test_should_compare_other_with_exclusive_end
assert((1..10) === (1...11))
end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0")
def test_should_compare_range_with_endless_range
assert(eval("1..") === (2..4))
end
def test_should_not_compare_range_with_endless_range
assert_not(eval("1..") === (0..4))
end
end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0")
def test_should_compare_range_with_beginless_range
assert(eval("..2") === (-1..1))
end
def test_should_not_compare_range_with_beginless_range
assert_not(eval("..2") === (-1..3))
end
end
def test_exclusive_end_should_not_include_identical_with_inclusive_end
assert_not_includes (1...10), 1..10
end
......@@ -109,6 +145,26 @@ def test_should_cover_other_with_exclusive_end
assert((1..10).cover?(1...11))
end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.6.0")
def test_should_cover_range_with_endless_range
assert(eval("1..").cover?(2..4))
end
def test_should_not_cover_range_with_endless_range
assert_not(eval("1..").cover?(0..4))
end
end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0")
def test_should_cover_range_with_beginless_range
assert(eval("..2").cover?(-1..1))
end
def test_should_not_cover_range_with_beginless_range
assert_not(eval("..2").cover?(-1..3))
end
end
def test_overlaps_on_time
time_range_1 = Time.utc(2005, 12, 10, 15, 30)..Time.utc(2005, 12, 10, 17, 30)
time_range_2 = Time.utc(2005, 12, 10, 17, 00)..Time.utc(2005, 12, 10, 18, 00)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册