From ca2a3bcaad04b522a08b89aafaf0ecb6db7d05ca Mon Sep 17 00:00:00 2001 From: Owen Stephens Date: Thu, 28 Mar 2019 00:57:05 +0000 Subject: Fix bug in Range comparisons when comparing to excluded-end Range Before: ```ruby (1..10).cover?(1...11) => false ``` After: ```ruby (1..10).cover?(1...11) => true ``` See https://git.io/fjTtz for the commit against Ruby core that added support for Range arguments, with similar handling of this case. --- .../active_support/core_ext/range/compare_range.rb | 33 ++++++++++++++-------- 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'activesupport/lib/active_support/core_ext') diff --git a/activesupport/lib/active_support/core_ext/range/compare_range.rb b/activesupport/lib/active_support/core_ext/range/compare_range.rb index 6f6d2a27bb..ea1dc29a76 100644 --- a/activesupport/lib/active_support/core_ext/range/compare_range.rb +++ b/activesupport/lib/active_support/core_ext/range/compare_range.rb @@ -3,9 +3,10 @@ module ActiveSupport module CompareWithRange # Extends the default Range#=== to support range comparisons. - # (1..5) === (1..5) # => true - # (1..5) === (2..3) # => true - # (1..5) === (2..6) # => false + # (1..5) === (1..5) # => true + # (1..5) === (2..3) # => true + # (1..5) === (1...6) # => true + # (1..5) === (2..6) # => false # # The native Range#=== behavior is untouched. # ('a'..'f') === ('c') # => true @@ -13,17 +14,20 @@ module ActiveSupport 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? ? :< : :<= - super(value.first) && value.last.send(operator, last) + value_max = !exclude_end? && value.exclude_end? ? value.max : value.last + super(value.first) && value_max.send(operator, last) else super end end # Extends the default Range#include? to support range comparisons. - # (1..5).include?(1..5) # => true - # (1..5).include?(2..3) # => true - # (1..5).include?(2..6) # => false + # (1..5).include?(1..5) # => true + # (1..5).include?(2..3) # => true + # (1..5).include?(1...6) # => true + # (1..5).include?(2..6) # => false # # The native Range#include? behavior is untouched. # ('a'..'f').include?('c') # => true @@ -31,17 +35,20 @@ module ActiveSupport 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? ? :< : :<= - super(value.first) && value.last.send(operator, last) + value_max = !exclude_end? && value.exclude_end? ? value.max : value.last + super(value.first) && value_max.send(operator, last) else super end end # Extends the default Range#cover? to support range comparisons. - # (1..5).cover?(1..5) # => true - # (1..5).cover?(2..3) # => true - # (1..5).cover?(2..6) # => false + # (1..5).cover?(1..5) # => true + # (1..5).cover?(2..3) # => true + # (1..5).cover?(1...6) # => true + # (1..5).cover?(2..6) # => false # # The native Range#cover? behavior is untouched. # ('a'..'f').cover?('c') # => true @@ -49,8 +56,10 @@ module ActiveSupport 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? ? :< : :<= - super(value.first) && value.last.send(operator, last) + value_max = !exclude_end? && value.exclude_end? ? value.max : value.last + super(value.first) && value_max.send(operator, last) else super end -- cgit v1.2.3