Unverified Commit e60891e4 authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto Committed by GitHub

Merge pull request #4454 from shuujii/fix-Rational-cmp-Numeric

Fix `Rational#<=>(Numeric)`
parents 3e8b19b0 a6eb0183
......@@ -58,11 +58,12 @@ class Rational < Numeric
when Float
return to_f <=> rhs
end
case rhs
when Rational
(numerator * rhs.denominator - denominator * rhs.numerator) <=> 0
when Numeric
return rhs <=> self
(rhs <=> self)&.-@
else
nil
end
......
......@@ -3,13 +3,21 @@ def assert_rational(real, exp)
assert_float real.denominator, exp.denominator
end
def assert_equal_rational(exp, r1, r2)
def assert_equal_rational(exp, o1, o2)
if exp
assert_operator(r1, :==, r2)
assert_not_operator(r1, :!=, r2)
assert_operator(o1, :==, o2)
assert_not_operator(o1, :!=, o2)
else
assert_not_operator(r1, :==, r2)
assert_operator(r1, :!=, r2)
assert_not_operator(o1, :==, o2)
assert_operator(o1, :!=, o2)
end
end
def assert_cmp(exp, o1, o2)
if exp == (o1 <=> o2)
pass
else
flunk "", " Expected #{o1.inspect} <=> #{o2.inspect} to be #{exp}"
end
end
......@@ -101,6 +109,156 @@ assert 'Float#==(Rational), Float#!=(Rational)' do
assert_equal_rational(false, 3.3, Rational(13,4))
end
assert 'Rational#<=>' do
num = Class.new(Numeric) do
def initialize(n)
@n = n
end
def <=>(rhs)
rhs = rhs.to_i
rhs < 0 ? nil : @n <=> rhs
end
def inspect
"num(#{@n})"
end
end
assert_cmp(-1, Rational(-1), Rational(0))
assert_cmp(0, Rational(0), Rational(0))
assert_cmp(1, Rational(1), Rational(0))
assert_cmp(-1, Rational(-1), 0)
assert_cmp(0, Rational(0), 0)
assert_cmp(1, Rational(1), 0)
assert_cmp(-1, Rational(-1), 0.0)
assert_cmp(0, Rational(0), 0.0)
assert_cmp(1, Rational(1), 0.0)
assert_cmp(-1, Rational(1,2), Rational(2,3))
assert_cmp(0, Rational(2,3), Rational(2,3))
assert_cmp(1, Rational(2,3), Rational(1,2))
assert_cmp(1, Rational(2,3), Rational(1,2))
assert_cmp(1, Rational(0), Rational(-1))
assert_cmp(-1, Rational(0), Rational(1))
assert_cmp(1, Rational(2,3), Rational(1,2))
assert_cmp(0, Rational(2,3), Rational(2,3))
assert_cmp(-1, Rational(1,2), Rational(2,3))
assert_cmp(-1, Rational(1,2), Rational(2,3))
assert_cmp(nil, 3r, "3")
assert_cmp(1, 3r, num.new(2))
assert_cmp(0, 3r, num.new(3))
assert_cmp(-1, 3r, num.new(4))
assert_cmp(nil, Rational(-3), num.new(5))
end
assert 'Fixnum#<=>(Rational)' do
assert_cmp(-1, -2, Rational(-9,5))
assert_cmp(0, 5, 5r)
assert_cmp(1, 3, Rational(8,3))
end
assert 'Float#<=>(Rational)' do
assert_cmp(-1, -2.1, Rational(-9,5))
assert_cmp(0, 5.0, 5r)
assert_cmp(1, 2.7, Rational(8,3))
end
assert 'Rational#<' do
assert_operator(Rational(1,2), :<, Rational(2,3))
assert_not_operator(Rational(2,3), :<, Rational(2,3))
assert_operator(Rational(2,3), :<, 1)
assert_not_operator(2r, :<, 2)
assert_not_operator(Rational(2,3), :<, -3)
assert_operator(Rational(-4,3), :<, -0.3)
assert_not_operator(Rational(13,4), :<, 3.25)
assert_not_operator(Rational(2,3), :<, 0.6)
assert_raise(ArgumentError) { 1r < "2" }
end
assert 'Fixnum#<(Rational)' do
assert_not_operator(1, :<, Rational(2,3))
assert_not_operator(2, :<, 2r)
assert_operator(-3, :<, Rational(2,3))
end
assert 'Float#<(Rational)' do
assert_not_operator(-0.3, :<, Rational(-4,3))
assert_not_operator(3.25, :<, Rational(13,4))
assert_operator(0.6, :<, Rational(2,3))
end
assert 'Rational#<=' do
assert_operator(Rational(1,2), :<=, Rational(2,3))
assert_operator(Rational(2,3), :<=, Rational(2,3))
assert_operator(Rational(2,3), :<=, 1)
assert_operator(2r, :<=, 2)
assert_not_operator(Rational(2,3), :<=, -3)
assert_operator(Rational(-4,3), :<=, -0.3)
assert_operator(Rational(13,4), :<=, 3.25)
assert_not_operator(Rational(2,3), :<=, 0.6)
assert_raise(ArgumentError) { 1r <= "2" }
end
assert 'Fixnum#<=(Rational)' do
assert_not_operator(1, :<=, Rational(2,3))
assert_operator(2, :<=, 2r)
assert_operator(-3, :<=, Rational(2,3))
end
assert 'Float#<=(Rational)' do
assert_not_operator(-0.3, :<=, Rational(-4,3))
assert_operator(3.25, :<=, Rational(13,4))
assert_operator(0.6, :<=, Rational(2,3))
end
assert 'Rational#>' do
assert_not_operator(Rational(1,2), :>, Rational(2,3))
assert_not_operator(Rational(2,3), :>, Rational(2,3))
assert_not_operator(Rational(2,3), :>, 1)
assert_not_operator(2r, :>, 2)
assert_operator(Rational(2,3), :>, -3)
assert_not_operator(Rational(-4,3), :>, -0.3)
assert_not_operator(Rational(13,4), :>, 3.25)
assert_operator(Rational(2,3), :>, 0.6)
assert_raise(ArgumentError) { 1r > "2" }
end
assert 'Fixnum#>(Rational)' do
assert_operator(1, :>, Rational(2,3))
assert_not_operator(2, :>, 2r)
assert_not_operator(-3, :>, Rational(2,3))
end
assert 'Float#>(Rational)' do
assert_operator(-0.3, :>, Rational(-4,3))
assert_not_operator(3.25, :>, Rational(13,4))
assert_not_operator(0.6, :>, Rational(2,3))
end
assert 'Rational#>=' do
assert_not_operator(Rational(1,2), :>=, Rational(2,3))
assert_operator(Rational(2,3), :>=, Rational(2,3))
assert_not_operator(Rational(2,3), :>=, 1)
assert_operator(2r, :>=, 2)
assert_operator(Rational(2,3), :>=, -3)
assert_not_operator(Rational(-4,3), :>=, -0.3)
assert_operator(Rational(13,4), :>=, 3.25)
assert_operator(Rational(2,3), :>=, 0.6)
assert_raise(ArgumentError) { 1r >= "2" }
end
assert 'Fixnum#>=(Rational)' do
assert_operator(1, :>=, Rational(2,3))
assert_operator(2, :>=, 2r)
assert_not_operator(-3, :>=, Rational(2,3))
end
assert 'Float#>=(Rational)' do
assert_operator(-0.3, :>=, Rational(-4,3))
assert_operator(3.25, :>=, Rational(13,4))
assert_not_operator(0.6, :>=, Rational(2,3))
end
assert 'Rational#negative?' do
assert_predicate(Rational(-2,3), :negative?)
assert_predicate(Rational(2,-3), :negative?)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment