提交 a7d09164 编写于 作者: A Andrew Hodgkinson

Fix issues with ActiveSupport Range extensions on boundless Ranges

Address complaints by CodeClimate

Address review feedback
上级 6bf2e59b
* 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. * Fix `Range#include?` to work with beginless and endless ranges.
*Allen Hsu* *Allen Hsu*
......
...@@ -11,13 +11,15 @@ module CompareWithRange ...@@ -11,13 +11,15 @@ module CompareWithRange
# The native Range#=== behavior is untouched. # The native Range#=== behavior is untouched.
# ('a'..'f') === ('c') # => true # ('a'..'f') === ('c') # => true
# (5..9) === (11) # => false # (5..9) === (11) # => false
#
# The given range must be fully bounded, with both start and end.
def ===(value) def ===(value)
if value.is_a?(::Range) if value.is_a?(::Range)
# 1...10 includes 1..9 but it does not include 1..10. # 1...10 includes 1..9 but it does not include 1..10.
# 1..10 includes 1...11 but it does not include 1...12. # 1..10 includes 1...11 but it does not include 1...12.
operator = exclude_end? && !value.exclude_end? ? :< : :<= operator = exclude_end? && !value.exclude_end? ? :< : :<=
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last 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 else
super super
end end
...@@ -32,13 +34,15 @@ def ===(value) ...@@ -32,13 +34,15 @@ def ===(value)
# The native Range#include? behavior is untouched. # The native Range#include? behavior is untouched.
# ('a'..'f').include?('c') # => true # ('a'..'f').include?('c') # => true
# (5..9).include?(11) # => false # (5..9).include?(11) # => false
#
# The given range must be fully bounded, with both start and end.
def include?(value) def include?(value)
if value.is_a?(::Range) if value.is_a?(::Range)
# 1...10 includes 1..9 but it does not include 1..10. # 1...10 includes 1..9 but it does not include 1..10.
# 1..10 includes 1...11 but it does not include 1...12. # 1..10 includes 1...11 but it does not include 1...12.
operator = exclude_end? && !value.exclude_end? ? :< : :<= operator = exclude_end? && !value.exclude_end? ? :< : :<=
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last 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 else
super super
end end
...@@ -53,13 +57,15 @@ def include?(value) ...@@ -53,13 +57,15 @@ def include?(value)
# The native Range#cover? behavior is untouched. # The native Range#cover? behavior is untouched.
# ('a'..'f').cover?('c') # => true # ('a'..'f').cover?('c') # => true
# (5..9).cover?(11) # => false # (5..9).cover?(11) # => false
#
# The given range must be fully bounded, with both start and end.
def cover?(value) def cover?(value)
if value.is_a?(::Range) if value.is_a?(::Range)
# 1...10 covers 1..9 but it does not cover 1..10. # 1...10 covers 1..9 but it does not cover 1..10.
# 1..10 covers 1...11 but it does not cover 1...12. # 1..10 covers 1...11 but it does not cover 1...12.
operator = exclude_end? && !value.exclude_end? ? :< : :<= operator = exclude_end? && !value.exclude_end? ? :< : :<=
value_max = !exclude_end? && value.exclude_end? ? value.max : value.last 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 else
super super
end end
......
...@@ -64,12 +64,28 @@ def test_should_include_other_with_exclusive_end ...@@ -64,12 +64,28 @@ def test_should_include_other_with_exclusive_end
def test_include_with_endless_range def test_include_with_endless_range
assert(eval("1..").include?(2)) assert(eval("1..").include?(2))
end 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 end
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0") if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new("2.7.0")
def test_include_with_beginless_range def test_include_with_beginless_range
assert(eval("..2").include?(1)) assert(eval("..2").include?(1))
end 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 end
def test_should_compare_identical_inclusive def test_should_compare_identical_inclusive
...@@ -84,6 +100,26 @@ def test_should_compare_other_with_exclusive_end ...@@ -84,6 +100,26 @@ def test_should_compare_other_with_exclusive_end
assert((1..10) === (1...11)) assert((1..10) === (1...11))
end 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 def test_exclusive_end_should_not_include_identical_with_inclusive_end
assert_not_includes (1...10), 1..10 assert_not_includes (1...10), 1..10
end end
...@@ -109,6 +145,26 @@ def test_should_cover_other_with_exclusive_end ...@@ -109,6 +145,26 @@ def test_should_cover_other_with_exclusive_end
assert((1..10).cover?(1...11)) assert((1..10).cover?(1...11))
end 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 def test_overlaps_on_time
time_range_1 = Time.utc(2005, 12, 10, 15, 30)..Time.utc(2005, 12, 10, 17, 30) 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) 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.
先完成此消息的编辑!
想要评论请 注册