|
| 1 | +require 'rspec' |
| 2 | + |
| 3 | +# Regression test for RubyBignum.big_op coercion. |
| 4 | +# |
| 5 | +# When a Bignum is compared against a custom numeric type that |
| 6 | +# implements coerce, the coerced comparison must use the correct |
| 7 | +# operator (>, >=, <, <=). The bug was that all four operators |
| 8 | +# used > after coercion, so < and <= returned wrong results. |
| 9 | + |
| 10 | +describe "Bignum comparison with coerce" do |
| 11 | + before :all do |
| 12 | + @cls = Class.new do |
| 13 | + def initialize(v) @v = v end |
| 14 | + def coerce(other) [self.class.new(other), self] end |
| 15 | + def >(other) @v.to_i > other.to_i end |
| 16 | + def >=(other) @v.to_i >= other.to_i end |
| 17 | + def <(other) @v.to_i < other.to_i end |
| 18 | + def <=(other) @v.to_i <= other.to_i end |
| 19 | + def to_i() @v.to_i end |
| 20 | + end |
| 21 | + end |
| 22 | + |
| 23 | + it "uses > after coercion for >" do |
| 24 | + expect((2**100) > @cls.new(1)).to be true |
| 25 | + expect((2**100) > @cls.new(2**101)).to be false |
| 26 | + end |
| 27 | + |
| 28 | + it "uses >= after coercion for >=" do |
| 29 | + expect((2**100) >= @cls.new(1)).to be true |
| 30 | + expect((2**100) >= @cls.new(2**101)).to be false |
| 31 | + end |
| 32 | + |
| 33 | + it "uses < after coercion for <" do |
| 34 | + expect((2**100) < @cls.new(2**101)).to be true |
| 35 | + expect((2**100) < @cls.new(1)).to be false |
| 36 | + end |
| 37 | + |
| 38 | + it "uses <= after coercion for <=" do |
| 39 | + expect((2**100) <= @cls.new(2**101)).to be true |
| 40 | + expect((2**100) <= @cls.new(1)).to be false |
| 41 | + end |
| 42 | +end |
0 commit comments