1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@62094 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
eregon 2018-01-29 16:08:16 +00:00
parent 1e658d45e1
commit 3fa5bd38af
494 changed files with 4133 additions and 3109 deletions

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/abs', __FILE__)
describe "Integer#abs" do
it_behaves_like :integer_abs, :abs
end

View file

@ -0,0 +1,97 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#&" do
context "fixnum" do
it "returns self bitwise AND other" do
(256 & 16).should == 0
(2010 & 5).should == 0
(65535 & 1).should == 1
(0xffff & bignum_value + 0xffff_ffff).should == 65535
end
it "returns self bitwise AND other when one operand is negative" do
((1 << 33) & -1).should == (1 << 33)
(-1 & (1 << 33)).should == (1 << 33)
((-(1<<33)-1) & 5).should == 5
(5 & (-(1<<33)-1)).should == 5
end
it "returns self bitwise AND other when both operands are negative" do
(-5 & -1).should == -5
(-3 & -4).should == -4
(-12 & -13).should == -16
(-13 & -12).should == -16
end
it "returns self bitwise AND a bignum" do
(-1 & 2**64).should == 18446744073709551616
end
it "coerces the rhs and calls #coerce" do
obj = mock("fixnum bit and")
obj.should_receive(:coerce).with(6).and_return([3, 6])
(6 & obj).should == 2
end
it "raises a TypeError when passed a Float" do
lambda { (3 & 3.4) }.should raise_error(TypeError)
end
it "raises a TypeError and does not call #to_int when defined on an object" do
obj = mock("fixnum bit and")
obj.should_not_receive(:to_int)
lambda { 3 & obj }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(5)
end
it "returns self bitwise AND other" do
@bignum = bignum_value(5)
(@bignum & 3).should == 1
(@bignum & 52).should == 4
(@bignum & bignum_value(9921)).should == 9223372036854775809
((2*bignum_value) & 1).should == 0
((2*bignum_value) & (2*bignum_value)).should == 18446744073709551616
end
it "returns self bitwise AND other when one operand is negative" do
((2*bignum_value) & -1).should == (2*bignum_value)
((4*bignum_value) & -1).should == (4*bignum_value)
(@bignum & -0xffffffffffffff5).should == 9223372036854775809
(@bignum & -@bignum).should == 1
(@bignum & -0x8000000000000000).should == 9223372036854775808
end
it "returns self bitwise AND other when both operands are negative" do
(-@bignum & -0x4000000000000005).should == -13835058055282163717
(-@bignum & -@bignum).should == -9223372036854775813
(-@bignum & -0x4000000000000000).should == -13835058055282163712
end
it "returns self bitwise AND other when both are negative and a multiple in bitsize of Fixnum::MIN" do
val = - ((1 << 93) - 1)
(val & val).should == val
val = - ((1 << 126) - 1)
(val & val).should == val
end
it "raises a TypeError when passed a Float" do
lambda { (@bignum & 3.4) }.should raise_error(TypeError)
end
it "raises a TypeError and does not call #to_int when defined on an object" do
obj = mock("bignum bit and")
obj.should_not_receive(:to_int)
lambda { @bignum & obj }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,76 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#bit_length" do
context "fixnum" do
it "returns the position of the leftmost bit of a positive number" do
0.bit_length.should == 0
1.bit_length.should == 1
2.bit_length.should == 2
3.bit_length.should == 2
4.bit_length.should == 3
n = fixnum_max.bit_length
fixnum_max[n].should == 0
fixnum_max[n - 1].should == 1
0.bit_length.should == 0
1.bit_length.should == 1
0xff.bit_length.should == 8
0x100.bit_length.should == 9
(2**12 - 1).bit_length.should == 12
(2**12).bit_length.should == 13
(2**12 + 1).bit_length.should == 13
end
it "returns the position of the leftmost 0 bit of a negative number" do
-1.bit_length.should == 0
-2.bit_length.should == 1
-3.bit_length.should == 2
-4.bit_length.should == 2
-5.bit_length.should == 3
n = fixnum_min.bit_length
fixnum_min[n].should == 1
fixnum_min[n - 1].should == 0
(-2**12 - 1).bit_length.should == 13
(-2**12).bit_length.should == 12
(-2**12 + 1).bit_length.should == 12
-0x101.bit_length.should == 9
-0x100.bit_length.should == 8
-0xff.bit_length.should == 8
-2.bit_length.should == 1
-1.bit_length.should == 0
end
end
context "bignum" do
it "returns the position of the leftmost bit of a positive number" do
(2**1000-1).bit_length.should == 1000
(2**1000).bit_length.should == 1001
(2**1000+1).bit_length.should == 1001
(2**10000-1).bit_length.should == 10000
(2**10000).bit_length.should == 10001
(2**10000+1).bit_length.should == 10001
(1 << 100).bit_length.should == 101
(1 << 100).succ.bit_length.should == 101
(1 << 100).pred.bit_length.should == 100
(1 << 10000).bit_length.should == 10001
end
it "returns the position of the leftmost 0 bit of a negative number" do
(-2**10000-1).bit_length.should == 10001
(-2**10000).bit_length.should == 10000
(-2**10000+1).bit_length.should == 10000
(-2**1000-1).bit_length.should == 1001
(-2**1000).bit_length.should == 1000
(-2**1000+1).bit_length.should == 1000
((-1 << 100)-1).bit_length.should == 101
((-1 << 100)-1).succ.bit_length.should == 100
((-1 << 100)-1).pred.bit_length.should == 101
((-1 << 10000)-1).bit_length.should == 10001
end
end
end

View file

@ -0,0 +1,68 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#|" do
context "fixnum" do
it "returns self bitwise OR other" do
(1 | 0).should == 1
(5 | 4).should == 5
(5 | 6).should == 7
(248 | 4096).should == 4344
(0xffff | bignum_value + 0xf0f0).should == 0x8000_0000_0000_ffff
end
it "returns self bitwise OR a bignum" do
(-1 | 2**64).should == -1
end
it "raises a TypeError when passed a Float" do
lambda { (3 | 3.4) }.should raise_error(TypeError)
end
it "raises a TypeError and does not call #to_int when defined on an object" do
obj = mock("integer bit or")
obj.should_not_receive(:to_int)
lambda { 3 | obj }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(11)
end
it "returns self bitwise OR other" do
(@bignum | 2).should == 9223372036854775819
(@bignum | 9).should == 9223372036854775819
(@bignum | bignum_value).should == 9223372036854775819
end
it "returns self bitwise OR other when one operand is negative" do
(@bignum | -0x40000000000000000).should == -64563604257983430645
(@bignum | -@bignum).should == -1
(@bignum | -0x8000000000000000).should == -9223372036854775797
end
it "returns self bitwise OR other when both operands are negative" do
(-@bignum | -0x4000000000000005).should == -1
(-@bignum | -@bignum).should == -9223372036854775819
(-@bignum | -0x4000000000000000).should == -11
end
it "raises a TypeError when passed a Float" do
not_supported_on :opal do
lambda {
bignum_value | bignum_value(0xffff).to_f
}.should raise_error(TypeError)
end
lambda { @bignum | 9.9 }.should raise_error(TypeError)
end
it "raises a TypeError and does not call #to_int when defined on an object" do
obj = mock("bignum bit or")
obj.should_not_receive(:to_int)
lambda { @bignum | obj }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,72 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#^" do
context "fixnum" do
it "returns self bitwise EXCLUSIVE OR other" do
(3 ^ 5).should == 6
(-2 ^ -255).should == 255
(5 ^ bignum_value + 0xffff_ffff).should == 0x8000_0000_ffff_fffa
end
it "returns self bitwise EXCLUSIVE OR a bignum" do
(-1 ^ 2**64).should == -18446744073709551617
end
it "raises a TypeError when passed a Float" do
lambda { (3 ^ 3.4) }.should raise_error(TypeError)
end
it "raises a TypeError and does not call #to_int when defined on an object" do
obj = mock("integer bit xor")
obj.should_not_receive(:to_int)
lambda { 3 ^ obj }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(18)
end
it "returns self bitwise EXCLUSIVE OR other" do
(@bignum ^ 2).should == 9223372036854775824
(@bignum ^ @bignum).should == 0
(@bignum ^ 14).should == 9223372036854775836
end
it "returns self bitwise EXCLUSIVE OR other when one operand is negative" do
(@bignum ^ -0x40000000000000000).should == -64563604257983430638
(@bignum ^ -@bignum).should == -4
(@bignum ^ -0x8000000000000000).should == -18446744073709551598
end
it "returns self bitwise EXCLUSIVE OR other when both operands are negative" do
(-@bignum ^ -0x40000000000000000).should == 64563604257983430638
(-@bignum ^ -@bignum).should == 0
(-@bignum ^ -0x4000000000000000).should == 13835058055282163694
end
it "returns self bitwise EXCLUSIVE OR other when all bits are 1 and other value is negative" do
(9903520314283042199192993791 ^ -1).should == -9903520314283042199192993792
(784637716923335095479473677900958302012794430558004314111 ^ -1).should ==
-784637716923335095479473677900958302012794430558004314112
end
it "raises a TypeError when passed a Float" do
not_supported_on :opal do
lambda {
bignum_value ^ bignum_value(0xffff).to_f
}.should raise_error(TypeError)
end
lambda { @bignum ^ 14.5 }.should raise_error(TypeError)
end
it "raises a TypeError and does not call #to_int when defined on an object" do
obj = mock("bignum bit xor")
obj.should_not_receive(:to_int)
lambda { @bignum ^ obj }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,6 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/equal', __FILE__)
describe "Integer#===" do
it_behaves_like :integer_equal, :===
end

View file

@ -3,8 +3,8 @@ require File.expand_path('../shared/to_i', __FILE__)
require File.expand_path('../shared/integer_rounding', __FILE__)
describe "Integer#ceil" do
it_behaves_like(:integer_to_i, :ceil)
it_behaves_like(:integer_rounding_positive_precision, :ceil)
it_behaves_like :integer_to_i, :ceil
it_behaves_like :integer_rounding_positive_precision, :ceil
ruby_version_is "2.4" do
context "precision argument specified as part of the ceil method is negative" do

View file

@ -165,6 +165,10 @@ describe "Integer#chr with an encoding argument" do
lambda { -bignum_value.chr(Encoding::EUC_JP) }.should raise_error(RangeError)
end
it "raises a RangeError if self is too large" do
lambda { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError)
end
it "returns a String with the specified encoding" do
0x0000.chr(Encoding::US_ASCII).encoding.should == Encoding::US_ASCII
0x007F.chr(Encoding::US_ASCII).encoding.should == Encoding::US_ASCII

View file

@ -0,0 +1,105 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#coerce" do
context "fixnum" do
describe "when given a Fixnum" do
it "returns an array containing two Fixnums" do
1.coerce(2).should == [2, 1]
1.coerce(2).map { |i| i.class }.should == [Fixnum, Fixnum]
end
end
describe "when given a String" do
it "raises an ArgumentError when trying to coerce with a non-number String" do
lambda { 1.coerce(":)") }.should raise_error(ArgumentError)
end
it "returns an array containing two Floats" do
1.coerce("2").should == [2.0, 1.0]
1.coerce("-2").should == [-2.0, 1.0]
end
end
it "raises a TypeError when trying to coerce with nil" do
lambda { 1.coerce(nil) }.should raise_error(TypeError)
end
it "tries to convert the given Object into a Float by using #to_f" do
(obj = mock('1.0')).should_receive(:to_f).and_return(1.0)
2.coerce(obj).should == [1.0, 2.0]
(obj = mock('0')).should_receive(:to_f).and_return('0')
lambda { 2.coerce(obj).should == [1.0, 2.0] }.should raise_error(TypeError)
end
it "raises a TypeError when given an Object that does not respond to #to_f" do
lambda { 1.coerce(mock('x')) }.should raise_error(TypeError)
lambda { 1.coerce(1..4) }.should raise_error(TypeError)
lambda { 1.coerce(:test) }.should raise_error(TypeError)
end
end
context "bignum" do
it "coerces other to a Bignum and returns [other, self] when passed a Fixnum" do
a = bignum_value
ary = a.coerce(2)
ary[0].should be_kind_of(Bignum)
ary[1].should be_kind_of(Bignum)
ary.should == [2, a]
end
it "returns [other, self] when passed a Bignum" do
a = bignum_value
b = bignum_value
ary = a.coerce(b)
ary[0].should be_kind_of(Bignum)
ary[1].should be_kind_of(Bignum)
ary.should == [b, a]
end
it "raises a TypeError when not passed a Fixnum or Bignum" do
a = bignum_value
lambda { a.coerce(nil) }.should raise_error(TypeError)
lambda { a.coerce(mock('str')) }.should raise_error(TypeError)
lambda { a.coerce(1..4) }.should raise_error(TypeError)
lambda { a.coerce(:test) }.should raise_error(TypeError)
end
ruby_version_is ""..."2.4" do
it "raises a TypeError when passed a String" do
a = bignum_value
lambda { a.coerce("123") }.should raise_error(TypeError)
end
it "raises a TypeError when passed a Float" do
a = bignum_value
lambda { a.coerce(12.3) }.should raise_error(TypeError)
end
end
ruby_version_is "2.4" do
it "coerces both values to Floats and returns [other, self] when passed a Float" do
a = bignum_value
a.coerce(1.2).should == [1.2, a.to_f]
end
it "coerces both values to Floats and returns [other, self] when passed a String" do
a = bignum_value
a.coerce("123").should == [123.0, a.to_f]
end
it "calls #to_f to coerce other to a Float" do
b = mock("bignum value")
b.should_receive(:to_f).and_return(1.2)
a = bignum_value
ary = a.coerce(b)
ary.should == [1.2, a.to_f]
end
end
end
end

View file

@ -0,0 +1,189 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#<=>" do
context "fixnum" do
it "returns -1 when self is less than the given argument" do
(-3 <=> -1).should == -1
(-5 <=> 10).should == -1
(-5 <=> -4.5).should == -1
end
it "returns 0 when self is equal to the given argument" do
(0 <=> 0).should == 0
(954 <=> 954).should == 0
(954 <=> 954.0).should == 0
end
it "returns 1 when self is greater than the given argument" do
(496 <=> 5).should == 1
(200 <=> 100).should == 1
(51 <=> 50.5).should == 1
end
it "returns nil when the given argument is not an Integer" do
(3 <=> mock('x')).should == nil
(3 <=> 'test').should == nil
end
end
context "bignum" do
describe "with a Fixnum" do
it "returns -1 when other is larger" do
(-bignum_value <=> 2).should == -1
end
it "returns 1 when other is smaller" do
(bignum_value <=> 2).should == 1
end
end
describe "with a Bignum" do
describe "when other is negative" do
it "returns -1 when self is negative and other is larger" do
(-bignum_value(42) <=> -bignum_value).should == -1
end
it "returns 0 when other is equal" do
(-bignum_value <=> -bignum_value).should == 0
end
it "returns 1 when self is negative and other is smaller" do
(-bignum_value <=> -bignum_value(94)).should == 1
end
it "returns 1 when self is positive" do
(bignum_value <=> -bignum_value).should == 1
end
end
describe "when other is positive" do
it "returns -1 when self is negative" do
(-bignum_value <=> bignum_value).should == -1
end
it "returns -1 when self is positive and other is larger" do
(bignum_value <=> bignum_value(38)).should == -1
end
it "returns 0 when other is equal" do
(bignum_value <=> bignum_value).should == 0
end
it "returns 1 when other is smaller" do
(bignum_value(56) <=> bignum_value).should == 1
end
end
end
describe "with a Float" do
describe "when other is negative" do
it "returns -1 when self is negative and other is larger" do
(-bignum_value(0xffff) <=> -bignum_value.to_f).should == -1
end
it "returns 0 when other is equal" do
(-bignum_value <=> -bignum_value.to_f).should == 0
end
it "returns 1 when self is negative and other is smaller" do
(-bignum_value <=> -bignum_value(0xffef).to_f).should == 1
end
it "returns 1 when self is positive" do
(bignum_value <=> -bignum_value.to_f).should == 1
end
end
describe "when other is positive" do
it "returns -1 when self is negative" do
(-bignum_value <=> bignum_value.to_f).should == -1
end
it "returns -1 when self is positive and other is larger" do
(bignum_value <=> bignum_value(0xfffe).to_f).should == -1
end
it "returns 0 when other is equal" do
(bignum_value <=> bignum_value.to_f).should == 0
end
it "returns 1 when other is smaller" do
(bignum_value(0xfeff) <=> bignum_value.to_f).should == 1
end
end
end
describe "with an Object" do
before :each do
@big = bignum_value
@num = mock("value for Bignum#<=>")
end
it "calls #coerce on other" do
@num.should_receive(:coerce).with(@big).and_return([@big.to_f, 2.5])
@big <=> @num
end
ruby_version_is ""..."2.5" do
it "returns nil if #coerce raises an exception" do
@num.should_receive(:coerce).with(@big).and_raise(RuntimeError)
lambda {
@result = (@big <=> @num)
}.should complain(/Numerical comparison operators will no more rescue exceptions/)
@result.should be_nil
end
end
ruby_version_is "2.5" do
it "lets the exception go through if #coerce raises an exception" do
@num.should_receive(:coerce).with(@big).and_raise(RuntimeError.new("my error"))
lambda {
@big <=> @num
}.should raise_error(RuntimeError, "my error")
end
end
it "raises an exception if #coerce raises a non-StandardError exception" do
@num.should_receive(:coerce).with(@big).and_raise(Exception)
lambda { @big <=> @num }.should raise_error(Exception)
end
it "returns nil if #coerce does not return an Array" do
@num.should_receive(:coerce).with(@big).and_return(nil)
(@big <=> @num).should be_nil
end
it "returns -1 if the coerced value is larger" do
@num.should_receive(:coerce).with(@big).and_return([@big, bignum_value(10)])
(@big <=> @num).should == -1
end
it "returns 0 if the coerced value is equal" do
@num.should_receive(:coerce).with(@big).and_return([@big, bignum_value])
(@big <=> @num).should == 0
end
it "returns 1 if the coerced value is smaller" do
@num.should_receive(:coerce).with(@big).and_return([@big, 22])
(@big <=> @num).should == 1
end
end
# The tests below are taken from matz's revision 23730 for Ruby trunk
it "returns 1 when self is Infinity and other is a Bignum" do
(infinity_value <=> Float::MAX.to_i*2).should == 1
end
it "returns -1 when self is negative and other is Infinty" do
(-Float::MAX.to_i*2 <=> infinity_value).should == -1
end
it "returns 1 when self is negative and other is -Infinity" do
(-Float::MAX.to_i*2 <=> -infinity_value).should == 1
end
it "returns -1 when self is -Infinity and other is negative" do
(-infinity_value <=> -Float::MAX.to_i*2).should == -1
end
end
end

View file

@ -0,0 +1,20 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#~" do
context "fixnum" do
it "returns self with each bit flipped" do
(~0).should == -1
(~1221).should == -1222
(~-2).should == 1
(~-599).should == 598
end
end
context "bignum" do
it "returns self with each bit flipped" do
(~bignum_value(48)).should == -9223372036854775857
(~(-bignum_value(21))).should == 9223372036854775828
(~bignum_value(1)).should == -9223372036854775810
end
end
end

View file

@ -0,0 +1,138 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#div" do
context "fixnum" do
it "returns self divided by the given argument as an Integer" do
2.div(2).should == 1
1.div(2).should == 0
5.div(2).should == 2
end
it "rounds towards -inf" do
8192.div(10).should == 819
8192.div(-10).should == -820
(-8192).div(10).should == -820
(-8192).div(-10).should == 819
end
it "means (x / y).floor" do
5.div(2).should == (5 / 2).floor
5.div(2.0).should == (5 / 2.0).floor
5.div(-2).should == (5 / -2).floor
5.div(100).should == (5 / 100).floor
5.div(100.0).should == (5 / 100.0).floor
5.div(-100).should == (5 / -100).floor
end
it "calls #coerce and #div if argument responds to #coerce" do
x = mock("x")
y = mock("y")
result = mock("result")
y.should_receive(:coerce).and_return([x, y])
x.should_receive(:div).with(y).and_return(result)
10.div(y).should == result
end
it "coerces self and the given argument to Floats and returns self divided by other as Fixnum" do
1.div(0.2).should == 5
1.div(0.16).should == 6
1.div(0.169).should == 5
-1.div(50.4).should == -1
1.div(bignum_value).should == 0
1.div(Rational(1, 5)).should == 5
end
it "raises a ZeroDivisionError when the given argument is 0 and a Float" do
lambda { 0.div(0.0) }.should raise_error(ZeroDivisionError)
lambda { 10.div(0.0) }.should raise_error(ZeroDivisionError)
lambda { -10.div(0.0) }.should raise_error(ZeroDivisionError)
end
it "raises a ZeroDivisionError when the given argument is 0 and not a Float" do
lambda { 13.div(0) }.should raise_error(ZeroDivisionError)
lambda { 13.div(-0) }.should raise_error(ZeroDivisionError)
end
it "raises a TypeError when given a non-numeric argument" do
lambda { 13.div(mock('10')) }.should raise_error(TypeError)
lambda { 5.div("2") }.should raise_error(TypeError)
lambda { 5.div(:"2") }.should raise_error(TypeError)
lambda { 5.div([]) }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(88)
end
it "returns self divided by other" do
@bignum.div(4).should == 2305843009213693974
@bignum.div(Rational(4, 1)).should == 2305843009213693974
@bignum.div(bignum_value(2)).should == 1
(-(10**50)).div(-(10**40 + 1)).should == 9999999999
(10**50).div(10**40 + 1).should == 9999999999
(-10**50).div(10**40 + 1).should == -10000000000
(10**50).div(-(10**40 + 1)).should == -10000000000
end
it "calls #coerce and #div if argument responds to #coerce" do
x = mock("x")
y = mock("y")
result = mock("result")
y.should_receive(:coerce).and_return([x, y])
x.should_receive(:div).with(y).and_return(result)
@bignum.div(y).should == result
end
it "means (x / y).floor" do
@bignum.div(2).should == (@bignum / 2).floor
@bignum.div(-2).should == (@bignum / -2).floor
@bignum.div(@bignum+1).should == (@bignum / (@bignum+1)).floor
@bignum.div(-(@bignum+1)).should == (@bignum / -(@bignum+1)).floor
@bignum.div(2.0).should == (@bignum / 2.0).floor
@bignum.div(100.0).should == (@bignum / 100.0).floor
end
it "looses precision if passed Float argument" do
@bignum.div(1).should_not == @bignum.div(1.0)
@bignum.div(4).should_not == @bignum.div(4.0)
@bignum.div(21).should_not == @bignum.div(21.0)
end
it "raises a TypeError when given a non-numeric" do
lambda { @bignum.div(mock("10")) }.should raise_error(TypeError)
lambda { @bignum.div("2") }.should raise_error(TypeError)
lambda { @bignum.div(:symbol) }.should raise_error(TypeError)
end
it "returns a result of integer division of self by a float argument" do
@bignum.div(4294967295.5).should eql(2147483648)
not_supported_on :opal do
@bignum.div(4294967295.0).should eql(2147483648)
@bignum.div(bignum_value(88).to_f).should eql(1)
@bignum.div(-bignum_value(88).to_f).should eql(-1)
end
end
# #5490
it "raises ZeroDivisionError if the argument is 0 and is a Float" do
lambda { @bignum.div(0.0) }.should raise_error(ZeroDivisionError)
lambda { @bignum.div(-0.0) }.should raise_error(ZeroDivisionError)
end
it "raises ZeroDivisionError if the argument is 0 and is not a Float" do
lambda { @bignum.div(0) }.should raise_error(ZeroDivisionError)
lambda { @bignum.div(-0) }.should raise_error(ZeroDivisionError)
end
end
end

View file

@ -1,7 +1,96 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/arithmetic_exception_in_coerce', __FILE__)
require File.expand_path('../shared/arithmetic_coerce', __FILE__)
describe "Integer#/" do
it_behaves_like :integer_arithmetic_exception_in_coerce, :/
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :/
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :/
end
context "fixnum" do
it "returns self divided by the given argument" do
(2 / 2).should == 1
(3 / 2).should == 1
end
it "supports dividing negative numbers" do
(-1 / 10).should == -1
end
it "returns result the same class as the argument" do
(3 / 2).should == 1
(3 / 2.0).should == 1.5
(3 / Rational(2, 1)).should == Rational(3, 2)
end
it "raises a ZeroDivisionError if the given argument is zero and not a Float" do
lambda { 1 / 0 }.should raise_error(ZeroDivisionError)
end
it "does NOT raise ZeroDivisionError if the given argument is zero and is a Float" do
(1 / 0.0).to_s.should == 'Infinity'
(-1 / 0.0).to_s.should == '-Infinity'
end
it "coerces fixnum and return self divided by other" do
(-1 / 50.4).should be_close(-0.0198412698412698, TOLERANCE)
(1 / bignum_value).should == 0
end
it "raises a TypeError when given a non-Integer" do
lambda { 13 / mock('10') }.should raise_error(TypeError)
lambda { 13 / "10" }.should raise_error(TypeError)
lambda { 13 / :symbol }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(88)
end
it "returns self divided by other" do
(@bignum / 4).should == 2305843009213693974
(@bignum / bignum_value(2)).should == 1
(-(10**50) / -(10**40 + 1)).should == 9999999999
((10**50) / (10**40 + 1)).should == 9999999999
((-10**50) / (10**40 + 1)).should == -10000000000
((10**50) / -(10**40 + 1)).should == -10000000000
end
it "returns self divided by Float" do
not_supported_on :opal do
(bignum_value(88) / 4294967295.0).should be_close(2147483648.5, TOLERANCE)
end
(bignum_value(88) / 4294967295.5).should be_close(2147483648.25, TOLERANCE)
end
it "returns result the same class as the argument" do
(@bignum / 4).should == 2305843009213693974
(@bignum / 4.0).should be_close(2305843009213693974, TOLERANCE)
(@bignum / Rational(4, 1)).should == Rational(2305843009213693974, 1)
end
it "does NOT raise ZeroDivisionError if other is zero and is a Float" do
(bignum_value / 0.0).to_s.should == 'Infinity'
(bignum_value / -0.0).to_s.should == '-Infinity'
end
it "raises a ZeroDivisionError if other is zero and not a Float" do
lambda { @bignum / 0 }.should raise_error(ZeroDivisionError)
end
it "raises a TypeError when given a non-numeric" do
lambda { @bignum / mock('10') }.should raise_error(TypeError)
lambda { @bignum / "2" }.should raise_error(TypeError)
lambda { @bignum / :symbol }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,117 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#divmod" do
context "fixnum" do
it "returns an Array containing quotient and modulus obtained from dividing self by the given argument" do
13.divmod(4).should == [3, 1]
4.divmod(13).should == [0, 4]
13.divmod(4.0).should == [3, 1]
4.divmod(13.0).should == [0, 4]
1.divmod(2.0).should == [0, 1.0]
200.divmod(bignum_value).should == [0, 200]
end
it "raises a ZeroDivisionError when the given argument is 0" do
lambda { 13.divmod(0) }.should raise_error(ZeroDivisionError)
lambda { 0.divmod(0) }.should raise_error(ZeroDivisionError)
lambda { -10.divmod(0) }.should raise_error(ZeroDivisionError)
end
it "raises a ZeroDivisionError when the given argument is 0 and a Float" do
lambda { 0.divmod(0.0) }.should raise_error(ZeroDivisionError)
lambda { 10.divmod(0.0) }.should raise_error(ZeroDivisionError)
lambda { -10.divmod(0.0) }.should raise_error(ZeroDivisionError)
end
it "raises a TypeError when given a non-Integer" do
lambda {
(obj = mock('10')).should_receive(:to_int).any_number_of_times.and_return(10)
13.divmod(obj)
}.should raise_error(TypeError)
lambda { 13.divmod("10") }.should raise_error(TypeError)
lambda { 13.divmod(:symbol) }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(55)
end
# Based on MRI's test/test_integer.rb (test_divmod),
# MRI maintains the following property:
# if q, r = a.divmod(b) ==>
# assert(0 < b ? (0 <= r && r < b) : (b < r && r <= 0))
# So, r is always between 0 and b.
it "returns an Array containing quotient and modulus obtained from dividing self by the given argument" do
@bignum.divmod(4).should == [2305843009213693965, 3]
@bignum.divmod(13).should == [709490156681136604, 11]
@bignum.divmod(4.5).should == [2049638230412172288, 3.5]
not_supported_on :opal do
@bignum.divmod(4.0).should == [2305843009213693952, 0.0]
@bignum.divmod(13.0).should == [709490156681136640, 8.0]
@bignum.divmod(2.0).should == [4611686018427387904, 0.0]
end
@bignum.divmod(bignum_value).should == [1, 55]
(-(10**50)).divmod(-(10**40 + 1)).should == [9999999999, -9999999999999999999999999999990000000001]
(10**50).divmod(10**40 + 1).should == [9999999999, 9999999999999999999999999999990000000001]
(-10**50).divmod(10**40 + 1).should == [-10000000000, 10000000000]
(10**50).divmod(-(10**40 + 1)).should == [-10000000000, -10000000000]
end
describe "with q = floor(x/y), a = q*b + r," do
it "returns [q,r] when a < 0, b > 0 and |a| < b" do
a = -@bignum + 1
b = @bignum
a.divmod(b).should == [-1, 1]
end
it "returns [q,r] when a > 0, b < 0 and a > |b|" do
b = -@bignum + 1
a = @bignum
a.divmod(b).should == [-2, -@bignum + 2]
end
it "returns [q,r] when a > 0, b < 0 and a < |b|" do
a = @bignum - 1
b = -@bignum
a.divmod(b).should == [-1, -1]
end
it "returns [q,r] when a < 0, b < 0 and |a| < |b|" do
a = -@bignum + 1
b = -@bignum
a.divmod(b).should == [0, -@bignum + 1]
end
end
it "raises a ZeroDivisionError when the given argument is 0" do
lambda { @bignum.divmod(0) }.should raise_error(ZeroDivisionError)
lambda { (-@bignum).divmod(0) }.should raise_error(ZeroDivisionError)
end
# Behaviour established as correct in r23953
it "raises a FloatDomainError if other is NaN" do
lambda { @bignum.divmod(nan_value) }.should raise_error(FloatDomainError)
end
it "raises a ZeroDivisionError when the given argument is 0 and a Float" do
lambda { @bignum.divmod(0.0) }.should raise_error(ZeroDivisionError)
lambda { (-@bignum).divmod(0.0) }.should raise_error(ZeroDivisionError)
end
it "raises a TypeError when the given argument is not an Integer" do
lambda { @bignum.divmod(mock('10')) }.should raise_error(TypeError)
lambda { @bignum.divmod("10") }.should raise_error(TypeError)
lambda { @bignum.divmod(:symbol) }.should raise_error(TypeError)
end
end
end

View file

@ -1,10 +0,0 @@
require File.expand_path('../../../spec_helper', __FILE__)
ruby_version_is '2.4' do
describe "Integer#dup" do
it "returns self" do
int = 2
int.dup.should equal(int)
end
end
end

View file

@ -0,0 +1,111 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#[]" do
context "fixnum" do
it "behaves like (n >> b) & 1" do
0b101[1].should == 0
0b101[2].should == 1
end
it "returns 1 if the nth bit is set" do
15[1].should == 1
end
it "returns 1 if the nth bit is set (in two's-complement representation)" do
(-1)[1].should == 1
end
it "returns 0 if the nth bit is not set" do
8[2].should == 0
end
it "returns 0 if the nth bit is not set (in two's-complement representation)" do
(-2)[0].should == 0
end
it "returns 0 if the nth bit is greater than the most significant bit" do
2[3].should == 0
end
it "returns 1 if self is negative and the nth bit is greater than the most significant bit" do
(-1)[3].should == 1
end
it "returns 0 when passed a negative argument" do
3[-1].should == 0
(-1)[-1].should == 0
end
it "calls #to_int to convert the argument to an Integer and returns 1 if the nth bit is set" do
obj = mock('1')
obj.should_receive(:to_int).and_return(1)
2[obj].should == 1
end
it "calls #to_int to convert the argument to an Integer and returns 0 if the nth bit is set" do
obj = mock('0')
obj.should_receive(:to_int).and_return(0)
2[obj].should == 0
end
it "accepts a Float argument and returns 0 if the bit at the truncated value is not set" do
13[1.3].should == 0
end
it "accepts a Float argument and returns 1 if the bit at the truncated value is set" do
13[2.1].should == 1
end
it "raises a TypeError when passed a String" do
lambda { 3["3"] }.should raise_error(TypeError)
end
it "raises a TypeError when #to_int does not return an Integer" do
obj = mock('asdf')
obj.should_receive(:to_int).and_return("asdf")
lambda { 3[obj] }.should raise_error(TypeError)
end
it "calls #to_int to coerce a String to a Bignum and returns 0" do
obj = mock('bignum value')
obj.should_receive(:to_int).and_return(bignum_value)
3[obj].should == 0
end
it "returns 0 when passed a Float in the range of a Bignum" do
3[bignum_value.to_f].should == 0
end
end
context "bignum" do
before :each do
@bignum = bignum_value(4996)
end
it "returns the nth bit in the binary representation of self" do
@bignum[2].should == 1
@bignum[9.2].should == 1
@bignum[21].should == 0
@bignum[0xffffffff].should == 0
@bignum[-0xffffffff].should == 0
end
it "tries to convert the given argument to an Integer using #to_int" do
@bignum[1.3].should == @bignum[1]
(obj = mock('2')).should_receive(:to_int).at_least(1).and_return(2)
@bignum[obj].should == 1
end
it "raises a TypeError when the given argument can't be converted to Integer" do
obj = mock('asdf')
lambda { @bignum[obj] }.should raise_error(TypeError)
obj.should_receive(:to_int).and_return("asdf")
lambda { @bignum[obj] }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/equal', __FILE__)
describe "Integer#==" do
it_behaves_like :integer_equal, :==
end

View file

@ -1,20 +1,40 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#even?" do
it "returns true for a Fixnum when it is an even number" do
(-2).even?.should be_true
(-1).even?.should be_false
context "fixnum" do
it "returns true for a Fixnum when it is an even number" do
(-2).even?.should be_true
(-1).even?.should be_false
0.even?.should be_true
1.even?.should be_false
2.even?.should be_true
0.even?.should be_true
1.even?.should be_false
2.even?.should be_true
end
it "returns true for a Bignum when it is an even number" do
bignum_value(0).even?.should be_true
bignum_value(1).even?.should be_false
(-bignum_value(0)).even?.should be_true
(-bignum_value(1)).even?.should be_false
end
end
it "returns true for a Bignum when it is an even number" do
bignum_value(0).even?.should be_true
bignum_value(1).even?.should be_false
context "bignum" do
it "returns true if self is even and positive" do
(10000**10).even?.should be_true
end
(-bignum_value(0)).even?.should be_true
(-bignum_value(1)).even?.should be_false
it "returns true if self is even and negative" do
(-10000**10).even?.should be_true
end
it "returns false if self is odd and positive" do
(9879**976).even?.should be_false
end
it "returns false if self is odd and negative" do
(-9879**976).even?.should be_false
end
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/exponent', __FILE__)
describe "Integer#**" do
it_behaves_like :integer_exponent, :**
end

View file

@ -0,0 +1,49 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#fdiv" do
it "performs floating-point division between self and a fixnum" do
8.fdiv(7).should be_close(1.14285714285714, TOLERANCE)
end
it "performs floating-point division between self and a bignum" do
8.fdiv(bignum_value).should be_close(8.673617379884035e-19, TOLERANCE)
end
it "performs floating-point division between self and a Float" do
8.fdiv(9.0).should be_close(0.888888888888889, TOLERANCE)
end
it "returns NaN when the argument is NaN" do
-1.fdiv(nan_value).nan?.should be_true
1.fdiv(nan_value).nan?.should be_true
end
it "returns Infinity when the argument is 0" do
1.fdiv(0).infinite?.should == 1
end
it "returns -Infinity when the argument is 0 and self is negative" do
-1.fdiv(0).infinite?.should == -1
end
it "returns Infinity when the argument is 0.0" do
1.fdiv(0.0).infinite?.should == 1
end
it "returns -Infinity when the argument is 0.0 and self is negative" do
-1.fdiv(0.0).infinite?.should == -1
end
it "raises a TypeError when argument isn't numeric" do
lambda { 1.fdiv(mock('non-numeric')) }.should raise_error(TypeError)
end
it "raises an ArgumentError when passed multiple arguments" do
lambda { 1.fdiv(6,0.2) }.should raise_error(ArgumentError)
end
it "follows the coercion protocol" do
(obj = mock('10')).should_receive(:coerce).with(1).and_return([1, 10])
1.fdiv(obj).should == 0.1
end
end

View file

@ -3,8 +3,8 @@ require File.expand_path('../shared/to_i', __FILE__)
require File.expand_path('../shared/integer_rounding', __FILE__)
describe "Integer#floor" do
it_behaves_like(:integer_to_i, :floor)
it_behaves_like(:integer_rounding_positive_precision, :floor)
it_behaves_like :integer_to_i, :floor
it_behaves_like :integer_rounding_positive_precision, :floor
ruby_version_is "2.4" do
context "precision argument specified as part of the floor method is negative" do

View file

@ -1,7 +1,50 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison_exception_in_coerce', __FILE__)
require File.expand_path('../shared/comparison_coerce', __FILE__)
describe "Integer#>" do
it_behaves_like :integer_comparison_exception_in_coerce, :>
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :>
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :>
end
context "fixnum" do
it "returns true if self is greater than the given argument" do
(13 > 2).should == true
(-500 > -600).should == true
(1 > 5).should == false
(5 > 5).should == false
(900 > bignum_value).should == false
(5 > 4.999).should == true
end
it "raises an ArgumentError when given a non-Integer" do
lambda { 5 > "4" }.should raise_error(ArgumentError)
lambda { 5 > mock('x') }.should raise_error(ArgumentError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(732)
end
it "returns true if self is greater than the given argument" do
(@bignum > (@bignum - 1)).should == true
(@bignum > 14.6).should == true
(@bignum > 10).should == true
(@bignum > (@bignum + 500)).should == false
end
it "raises an ArgumentError when given a non-Integer" do
lambda { @bignum > "4" }.should raise_error(ArgumentError)
lambda { @bignum > mock('str') }.should raise_error(ArgumentError)
end
end
end

View file

@ -1,7 +1,50 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison_exception_in_coerce', __FILE__)
require File.expand_path('../shared/comparison_coerce', __FILE__)
describe "Integer#>=" do
it_behaves_like :integer_comparison_exception_in_coerce, :>=
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :>=
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :>=
end
context "fixnum" do
it "returns true if self is greater than or equal to the given argument" do
(13 >= 2).should == true
(-500 >= -600).should == true
(1 >= 5).should == false
(2 >= 2).should == true
(5 >= 5).should == true
(900 >= bignum_value).should == false
(5 >= 4.999).should == true
end
it "raises an ArgumentError when given a non-Integer" do
lambda { 5 >= "4" }.should raise_error(ArgumentError)
lambda { 5 >= mock('x') }.should raise_error(ArgumentError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(14)
end
it "returns true if self is greater than or equal to other" do
(@bignum >= @bignum).should == true
(@bignum >= (@bignum + 2)).should == false
(@bignum >= 5664.2).should == true
(@bignum >= 4).should == true
end
it "raises an ArgumentError when given a non-Integer" do
lambda { @bignum >= "4" }.should raise_error(ArgumentError)
lambda { @bignum >= mock('str') }.should raise_error(ArgumentError)
end
end
end

View file

@ -0,0 +1,165 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#<< (with n << m)" do
context "fixnum" do
it "returns n shifted left m bits when n > 0, m > 0" do
(1 << 1).should == 2
end
it "returns n shifted left m bits when n < 0, m > 0" do
(-1 << 1).should == -2
(-7 << 1).should == -14
(-42 << 2).should == -168
end
it "returns n shifted right m bits when n > 0, m < 0" do
(2 << -1).should == 1
end
it "returns n shifted right m bits when n < 0, m < 0" do
(-2 << -1).should == -1
end
it "returns 0 when n == 0" do
(0 << 1).should == 0
end
it "returns n when n > 0, m == 0" do
(1 << 0).should == 1
end
it "returns n when n < 0, m == 0" do
(-1 << 0).should == -1
end
it "returns 0 when n > 0, m < 0 and n < 2**-m" do
(3 << -2).should == 0
(7 << -3).should == 0
(127 << -7).should == 0
# To make sure the exponent is not truncated
(7 << -32).should == 0
(7 << -64).should == 0
end
it "returns -1 when n < 0, m < 0 and n > -(2**-m)" do
(-3 << -2).should == -1
(-7 << -3).should == -1
(-127 << -7).should == -1
# To make sure the exponent is not truncated
(-7 << -32).should == -1
(-7 << -64).should == -1
end
it "returns 0 when m < 0 and m is a Bignum" do
(3 << -bignum_value).should == 0
end
it "returns an Bignum == fixnum_max * 2 when fixnum_max << 1 and n > 0" do
result = fixnum_max << 1
result.should be_an_instance_of(Bignum)
result.should == fixnum_max * 2
end
it "returns an Bignum == fixnum_min * 2 when fixnum_min << 1 and n < 0" do
result = fixnum_min << 1
result.should be_an_instance_of(Bignum)
result.should == fixnum_min * 2
end
it "calls #to_int to convert the argument to an Integer" do
obj = mock("4")
obj.should_receive(:to_int).and_return(4)
(3 << obj).should == 48
end
it "raises a TypeError when #to_int does not return an Integer" do
obj = mock("a string")
obj.should_receive(:to_int).and_return("asdf")
lambda { 3 << obj }.should raise_error(TypeError)
end
it "raises a TypeError when passed nil" do
lambda { 3 << nil }.should raise_error(TypeError)
end
it "raises a TypeError when passed a String" do
lambda { 3 << "4" }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value * 16
end
it "returns n shifted left m bits when n > 0, m > 0" do
(@bignum << 4).should == 2361183241434822606848
end
it "returns n shifted left m bits when n < 0, m > 0" do
(-@bignum << 9).should == -75557863725914323419136
end
it "returns n shifted right m bits when n > 0, m < 0" do
(@bignum << -1).should == 73786976294838206464
end
it "returns n shifted right m bits when n < 0, m < 0" do
(-@bignum << -2).should == -36893488147419103232
end
it "returns n when n > 0, m == 0" do
(@bignum << 0).should == @bignum
end
it "returns n when n < 0, m == 0" do
(-@bignum << 0).should == -@bignum
end
it "returns 0 when m < 0 and m == p where 2**p > n >= 2**(p-1)" do
(@bignum << -68).should == 0
end
it "returns 0 when m < 0 and m is a Bignum" do
(@bignum << -bignum_value).should == 0
end
it "returns a Fixnum == fixnum_max when (fixnum_max * 2) << -1 and n > 0" do
result = (fixnum_max * 2) << -1
result.should be_an_instance_of(Fixnum)
result.should == fixnum_max
end
it "returns a Fixnum == fixnum_min when (fixnum_min * 2) << -1 and n < 0" do
result = (fixnum_min * 2) << -1
result.should be_an_instance_of(Fixnum)
result.should == fixnum_min
end
it "calls #to_int to convert the argument to an Integer" do
obj = mock("4")
obj.should_receive(:to_int).and_return(4)
(@bignum << obj).should == 2361183241434822606848
end
it "raises a TypeError when #to_int does not return an Integer" do
obj = mock("a string")
obj.should_receive(:to_int).and_return("asdf")
lambda { @bignum << obj }.should raise_error(TypeError)
end
it "raises a TypeError when passed nil" do
lambda { @bignum << nil }.should raise_error(TypeError)
end
it "raises a TypeError when passed a String" do
lambda { @bignum << "4" }.should raise_error(TypeError)
end
end
end

View file

@ -1,6 +1,52 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison_exception_in_coerce', __FILE__)
require File.expand_path('../shared/comparison_coerce', __FILE__)
describe "Integer#<" do
it_behaves_like :integer_comparison_exception_in_coerce, :<
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :<
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :<
end
context "fixnum" do
it "returns true if self is less than the given argument" do
(2 < 13).should == true
(-600 < -500).should == true
(5 < 1).should == false
(5 < 5).should == false
(900 < bignum_value).should == true
(5 < 4.999).should == false
end
it "raises an ArgumentError when given a non-Integer" do
lambda { 5 < "4" }.should raise_error(ArgumentError)
lambda { 5 < mock('x') }.should raise_error(ArgumentError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(32)
end
it "returns true if self is less than the given argument" do
(@bignum < @bignum + 1).should == true
(-@bignum < -(@bignum - 1)).should == true
(@bignum < 1).should == false
(@bignum < 5).should == false
(@bignum < 4.999).should == false
end
it "raises an ArgumentError when given a non-Integer" do
lambda { @bignum < "4" }.should raise_error(ArgumentError)
lambda { @bignum < mock('str') }.should raise_error(ArgumentError)
end
end
end

View file

@ -1,6 +1,55 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/comparison_exception_in_coerce', __FILE__)
require File.expand_path('../shared/comparison_coerce', __FILE__)
describe "Integer#<=" do
it_behaves_like :integer_comparison_exception_in_coerce, :<=
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_comparison_coerce_rescue, :<=
end
ruby_version_is "2.5" do
it_behaves_like :integer_comparison_coerce_not_rescue, :<=
end
context "fixnum" do
it "returns true if self is less than or equal to other" do
(2 <= 13).should == true
(-600 <= -500).should == true
(5 <= 1).should == false
(5 <= 5).should == true
(-2 <= -2).should == true
(900 <= bignum_value).should == true
(5 <= 4.999).should == false
end
it "raises an ArgumentError when given a non-Integer" do
lambda { 5 <= "4" }.should raise_error(ArgumentError)
lambda { 5 <= mock('x') }.should raise_error(ArgumentError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(39)
end
it "returns true if self is less than or equal to other" do
(@bignum <= @bignum).should == true
(-@bignum <= -(@bignum - 1)).should == true
(@bignum <= 4.999).should == false
end
it "returns false if compares with near float" do
(@bignum <= (@bignum + 0.0)).should == false
(@bignum <= (@bignum + 0.5)).should == false
end
it "raises an ArgumentError when given a non-Integer" do
lambda { @bignum <= "4" }.should raise_error(ArgumentError)
lambda { @bignum <= mock('str') }.should raise_error(ArgumentError)
end
end
end

View file

@ -0,0 +1,7 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/abs', __FILE__)
describe "Integer#magnitude" do
it_behaves_like :integer_abs, :magnitude
end

View file

@ -1,7 +1,50 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/arithmetic_exception_in_coerce', __FILE__)
require File.expand_path('../shared/arithmetic_coerce', __FILE__)
describe "Integer#-" do
it_behaves_like :integer_arithmetic_exception_in_coerce, :-
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :-
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :-
end
context "fixnum" do
it "returns self minus the given Integer" do
(5 - 10).should == -5
(9237212 - 5_280).should == 9231932
(781 - 0.5).should == 780.5
(2_560_496 - bignum_value).should == -9223372036852215312
end
it "raises a TypeError when given a non-Integer" do
lambda {
(obj = mock('10')).should_receive(:to_int).any_number_of_times.and_return(10)
13 - obj
}.should raise_error(TypeError)
lambda { 13 - "10" }.should raise_error(TypeError)
lambda { 13 - :symbol }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(314)
end
it "returns self minus the given Integer" do
(@bignum - 9).should == 9223372036854776113
(@bignum - 12.57).should be_close(9223372036854776109.43, TOLERANCE)
(@bignum - bignum_value(42)).should == 272
end
it "raises a TypeError when given a non-Integer" do
lambda { @bignum - mock('10') }.should raise_error(TypeError)
lambda { @bignum - "10" }.should raise_error(TypeError)
lambda { @bignum - :symbol }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,10 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/modulo', __FILE__)
describe "Integer#%" do
it_behaves_like :integer_modulo, :%
end
describe "Integer#modulo" do
it_behaves_like :integer_modulo, :modulo
end

View file

@ -1,6 +1,52 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/arithmetic_exception_in_coerce', __FILE__)
require File.expand_path('../shared/arithmetic_coerce', __FILE__)
describe "Integer#*" do
it_behaves_like :integer_arithmetic_exception_in_coerce, :*
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :*
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :*
end
context "fixnum" do
it "returns self multiplied by the given Integer" do
(4923 * 2).should == 9846
(1342177 * 800).should == 1073741600
(65536 * 65536).should == 4294967296
(256 * bignum_value).should == 2361183241434822606848
(6712 * 0.25).should == 1678.0
end
it "raises a TypeError when given a non-Integer" do
lambda {
(obj = mock('10')).should_receive(:to_int).any_number_of_times.and_return(10)
13 * obj
}.should raise_error(TypeError)
lambda { 13 * "10" }.should raise_error(TypeError)
lambda { 13 * :symbol }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(772)
end
it "returns self multiplied by the given Integer" do
(@bignum * (1/bignum_value(0xffff).to_f)).should be_close(1.0, TOLERANCE)
(@bignum * (1/bignum_value(0xffff).to_f)).should be_close(1.0, TOLERANCE)
(@bignum * 10).should == 92233720368547765800
(@bignum * (@bignum - 40)).should == 85070591730234629737795195287525433200
end
it "raises a TypeError when given a non-Integer" do
lambda { @bignum * mock('10') }.should raise_error(TypeError)
lambda { @bignum * "10" }.should raise_error(TypeError)
lambda { @bignum * :symbol }.should raise_error(TypeError)
end
end
end

View file

@ -2,5 +2,5 @@ require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/next', __FILE__)
describe "Integer#next" do
it_behaves_like(:integer_next, :next)
it_behaves_like :integer_next, :next
end

View file

@ -1,18 +1,38 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#odd?" do
it "returns true when self is an odd number" do
(-2).odd?.should be_false
(-1).odd?.should be_true
context "fixnum" do
it "returns true when self is an odd number" do
(-2).odd?.should be_false
(-1).odd?.should be_true
0.odd?.should be_false
1.odd?.should be_true
2.odd?.should be_false
0.odd?.should be_false
1.odd?.should be_true
2.odd?.should be_false
bignum_value(0).odd?.should be_false
bignum_value(1).odd?.should be_true
bignum_value(0).odd?.should be_false
bignum_value(1).odd?.should be_true
(-bignum_value(0)).odd?.should be_false
(-bignum_value(1)).odd?.should be_true
(-bignum_value(0)).odd?.should be_false
(-bignum_value(1)).odd?.should be_true
end
end
context "bignum" do
it "returns true if self is odd and positive" do
(987279**19).odd?.should be_true
end
it "returns true if self is odd and negative" do
(-9873389**97).odd?.should be_true
end
it "returns false if self is even and positive" do
(10000000**10).odd?.should be_false
end
it "returns false if self is even and negative" do
(-1000000**100).odd?.should be_false
end
end
end

View file

@ -1,6 +1,50 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/arithmetic_exception_in_coerce', __FILE__)
require File.expand_path('../shared/arithmetic_coerce', __FILE__)
describe "Integer#+" do
it_behaves_like :integer_arithmetic_exception_in_coerce, :+
ruby_version_is "2.4"..."2.5" do
it_behaves_like :integer_arithmetic_coerce_rescue, :+
end
ruby_version_is "2.5" do
it_behaves_like :integer_arithmetic_coerce_not_rescue, :+
end
context "fixnum" do
it "returns self plus the given Integer" do
(491 + 2).should == 493
(90210 + 10).should == 90220
(9 + bignum_value).should == 9223372036854775817
(1001 + 5.219).should == 1006.219
end
it "raises a TypeError when given a non-Integer" do
lambda {
(obj = mock('10')).should_receive(:to_int).any_number_of_times.and_return(10)
13 + obj
}.should raise_error(TypeError)
lambda { 13 + "10" }.should raise_error(TypeError)
lambda { 13 + :symbol }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(76)
end
it "returns self plus the given Integer" do
(@bignum + 4).should == 9223372036854775888
(@bignum + 4.2).should be_close(9223372036854775888.2, TOLERANCE)
(@bignum + bignum_value(3)).should == 18446744073709551695
end
it "raises a TypeError when given a non-Integer" do
lambda { @bignum + mock('10') }.should raise_error(TypeError)
lambda { @bignum + "10" }.should raise_error(TypeError)
lambda { @bignum + :symbol}.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,51 @@
require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../fixtures/classes', __FILE__)
require File.expand_path('../shared/exponent', __FILE__)
ruby_version_is "2.5" do
describe "Integer#pow" do
context "one argument is passed" do
it_behaves_like :integer_exponent, :pow
end
context "two arguments are passed" do
it "returns modulo of self raised to the given power" do
2.pow(5, 12).should == 8
2.pow(6, 13).should == 12
2.pow(7, 14).should == 2
2.pow(8, 15).should == 1
end
ruby_bug '#13669', '2.5'...'2.5.1' do
it "works well with bignums" do
2.pow(61, 5843009213693951).should eql 3697379018277258
2.pow(62, 5843009213693952).should eql 1551748822859776
2.pow(63, 5843009213693953).should eql 3103497645717974
2.pow(64, 5843009213693954).should eql 363986077738838
end
end
it "handles sign like #divmod does" do
2.pow(5, 12).should == 8
2.pow(5, -12).should == -4
-2.pow(5, 12).should == 4
-2.pow(5, -12).should == -8
end
it "ensures all arguments are integers" do
-> { 2.pow(5, 12.0) }.should raise_error(TypeError, /2nd argument not allowed unless all arguments are integers/)
-> { 2.pow(5, Rational(12, 1)) }.should raise_error(TypeError, /2nd argument not allowed unless all arguments are integers/)
end
it "raises TypeError for non-numeric value" do
-> { 2.pow(5, "12") }.should raise_error(TypeError)
-> { 2.pow(5, []) }.should raise_error(TypeError)
-> { 2.pow(5, nil) }.should raise_error(TypeError)
end
it "raises a ZeroDivisionError when the given argument is 0" do
-> { 2.pow(5, 0) }.should raise_error(ZeroDivisionError)
end
end
end
end

View file

@ -0,0 +1,51 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#remainder" do
context "fixnum" do
it "returns the remainder of dividing self by other" do
5.remainder(3).should == 2
5.remainder(3.0).should == 2.0
5.remainder(Rational(3, 1)).should == Rational(2, 1)
end
it "means x-y*(x/y).truncate" do
5.remainder(3).should == 2
5.remainder(3.3).should be_close(1.7, TOLERANCE)
5.remainder(3.7).should be_close(1.3, TOLERANCE)
end
it "keeps sign of self" do
5.remainder( 3).should == 2
5.remainder(-3).should == 2
-5.remainder( 3).should == -2
-5.remainder(-3).should == -2
end
it "raises TypeError if passed non-numeric argument" do
-> { 5.remainder("3") }.should raise_error(TypeError)
-> { 5.remainder(:"3") }.should raise_error(TypeError)
-> { 5.remainder([]) }.should raise_error(TypeError)
-> { 5.remainder(nil) }.should raise_error(TypeError)
end
end
context "bignum" do
it "returns the remainder of dividing self by other" do
a = bignum_value(79)
a.remainder(2).should == 1
a.remainder(97.345).should be_close(46.5674996147722, TOLERANCE)
a.remainder(bignum_value).should == 79
end
it "raises a ZeroDivisionError if other is zero and not a Float" do
lambda { bignum_value(66).remainder(0) }.should raise_error(ZeroDivisionError)
end
it "does raises ZeroDivisionError if other is zero and a Float" do
a = bignum_value(7)
b = bignum_value(32)
lambda { a.remainder(0.0) }.should raise_error(ZeroDivisionError)
lambda { b.remainder(-0.0) }.should raise_error(ZeroDivisionError)
end
end
end

View file

@ -0,0 +1,191 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#>> (with n >> m)" do
context "fixnum" do
it "returns n shifted right m bits when n > 0, m > 0" do
(2 >> 1).should == 1
end
it "returns n shifted right m bits when n < 0, m > 0" do
(-2 >> 1).should == -1
(-7 >> 1).should == -4
(-42 >> 2).should == -11
end
it "returns n shifted left m bits when n > 0, m < 0" do
(1 >> -1).should == 2
end
it "returns n shifted left m bits when n < 0, m < 0" do
(-1 >> -1).should == -2
end
it "returns 0 when n == 0" do
(0 >> 1).should == 0
end
it "returns n when n > 0, m == 0" do
(1 >> 0).should == 1
end
it "returns n when n < 0, m == 0" do
(-1 >> 0).should == -1
end
it "returns 0 when n > 0, m > 0 and n < 2**m" do
(3 >> 2).should == 0
(7 >> 3).should == 0
(127 >> 7).should == 0
# To make sure the exponent is not truncated
(7 >> 32).should == 0
(7 >> 64).should == 0
end
it "returns -1 when n < 0, m > 0 and n > -(2**m)" do
(-3 >> 2).should == -1
(-7 >> 3).should == -1
(-127 >> 7).should == -1
# To make sure the exponent is not truncated
(-7 >> 32).should == -1
(-7 >> 64).should == -1
end
it "returns 0 when m is a bignum" do
(3 >> bignum_value).should == 0
end
it "returns an Bignum == fixnum_max * 2 when fixnum_max >> -1 and n > 0" do
result = fixnum_max >> -1
result.should be_an_instance_of(Bignum)
result.should == fixnum_max * 2
end
it "returns an Bignum == fixnum_min * 2 when fixnum_min >> -1 and n < 0" do
result = fixnum_min >> -1
result.should be_an_instance_of(Bignum)
result.should == fixnum_min * 2
end
it "calls #to_int to convert the argument to an Integer" do
obj = mock("2")
obj.should_receive(:to_int).and_return(2)
(8 >> obj).should == 2
end
it "raises a TypeError when #to_int does not return an Integer" do
obj = mock("a string")
obj.should_receive(:to_int).and_return("asdf")
lambda { 3 >> obj }.should raise_error(TypeError)
end
it "raises a TypeError when passed nil" do
lambda { 3 >> nil }.should raise_error(TypeError)
end
it "raises a TypeError when passed a String" do
lambda { 3 >> "4" }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value * 16
end
it "returns n shifted right m bits when n > 0, m > 0" do
(@bignum >> 1).should == 73786976294838206464
end
it "returns n shifted right m bits when n < 0, m > 0" do
(-@bignum >> 2).should == -36893488147419103232
end
it "respects twos complement signed shifting" do
# This explicit left hand value is important because it is the
# exact bit pattern that matters, so it's important it's right
# here to show the significance.
#
(-42949672980000000000000 >> 14).should == -2621440001220703125
(-42949672980000000000001 >> 14).should == -2621440001220703126
# Note the off by one -------------------- ^^^^^^^^^^^^^^^^^^^^
# This is because even though we discard the lowest bit, in twos
# complement it would influence the bits to the left of it.
(-42949672980000000000000 >> 15).should == -1310720000610351563
(-42949672980000000000001 >> 15).should == -1310720000610351563
(-0xfffffffffffffffff >> 32).should == -68719476736
end
it "respects twos complement signed shifting for very large values" do
giant = 42949672980000000000000000000000000000000000000000000000000000000000000000000000000000000000
neg = -giant
(giant >> 84).should == 2220446050284288846538547929770901490087453566957265138626098632812
(neg >> 84).should == -2220446050284288846538547929770901490087453566957265138626098632813
end
it "returns n shifted left m bits when n > 0, m < 0" do
(@bignum >> -2).should == 590295810358705651712
end
it "returns n shifted left m bits when n < 0, m < 0" do
(-@bignum >> -3).should == -1180591620717411303424
end
it "returns n when n > 0, m == 0" do
(@bignum >> 0).should == @bignum
end
it "returns n when n < 0, m == 0" do
(-@bignum >> 0).should == -@bignum
end
it "returns 0 when m > 0 and m == p where 2**p > n >= 2**(p-1)" do
(@bignum >> 68).should == 0
end
it "returns 0 when m is a Bignum" do
(@bignum >> bignum_value).should == 0
end
it "returns a Fixnum == fixnum_max when (fixnum_max * 2) >> 1 and n > 0" do
result = (fixnum_max * 2) >> 1
result.should be_an_instance_of(Fixnum)
result.should == fixnum_max
end
it "returns a Fixnum == fixnum_min when (fixnum_min * 2) >> 1 and n < 0" do
result = (fixnum_min * 2) >> 1
result.should be_an_instance_of(Fixnum)
result.should == fixnum_min
end
it "calls #to_int to convert the argument to an Integer" do
obj = mock("2")
obj.should_receive(:to_int).and_return(2)
(@bignum >> obj).should == 36893488147419103232
end
it "raises a TypeError when #to_int does not return an Integer" do
obj = mock("a string")
obj.should_receive(:to_int).and_return("asdf")
lambda { @bignum >> obj }.should raise_error(TypeError)
end
it "raises a TypeError when passed nil" do
lambda { @bignum >> nil }.should raise_error(TypeError)
end
it "raises a TypeError when passed a String" do
lambda { @bignum >> "4" }.should raise_error(TypeError)
end
end
end

View file

@ -3,8 +3,8 @@ require File.expand_path('../shared/to_i', __FILE__)
require File.expand_path('../shared/integer_rounding', __FILE__)
describe "Integer#round" do
it_behaves_like(:integer_to_i, :round)
it_behaves_like(:integer_rounding_positive_precision, :round)
it_behaves_like :integer_to_i, :round
it_behaves_like :integer_rounding_positive_precision, :round
ruby_version_is ""..."2.5" do # Not just since 2.4
it "rounds itself as a float if passed a positive precision" do

View file

@ -0,0 +1,18 @@
describe :integer_abs, shared: true do
context "fixnum" do
it "returns self's absolute fixnum value" do
{ 0 => [0, -0, +0], 2 => [2, -2, +2], 100 => [100, -100, +100] }.each do |key, values|
values.each do |value|
value.send(@method).should == key
end
end
end
end
context "bignum" do
it "returns the absolute bignum value" do
bignum_value(39).send(@method).should == 9223372036854775847
(-bignum_value(18)).send(@method).should == 9223372036854775826
end
end
end

View file

@ -0,0 +1,31 @@
require File.expand_path('../../fixtures/classes', __FILE__)
describe :integer_arithmetic_coerce_rescue, shared: true do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises TypeError" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(TypeError, /MockObject can't be coerced into Integer/)
end
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
[Exception, NoMemoryError].each do |exception|
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(exception)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(exception)
end
end
end
describe :integer_arithmetic_coerce_not_rescue, shared: true do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(IntegerSpecs::CoerceError)
end
end

View file

@ -1,33 +0,0 @@
require File.expand_path('../../fixtures/classes', __FILE__)
describe :integer_arithmetic_exception_in_coerce, shared: true do
ruby_version_is ""..."2.5" do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises TypeError" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(TypeError, /MockObject can't be coerced into #{1.class}/)
end
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
[Exception, NoMemoryError].each do |exception|
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(exception)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(exception)
end
end
end
ruby_version_is "2.5" do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 + b
-> { 1.send(@method, b) }.should raise_error(IntegerSpecs::CoerceError)
end
end
end

View file

@ -0,0 +1,33 @@
require File.expand_path('../../fixtures/classes', __FILE__)
describe :integer_comparison_coerce_rescue, shared: true do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises ArgumentError" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 > b
-> {
-> { 1.send(@method, b) }.should raise_error(ArgumentError, /comparison of Integer with MockObject failed/)
}.should complain(/Numerical comparison operators will no more rescue exceptions of #coerce/)
end
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
[Exception, NoMemoryError].each do |exception|
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(exception)
# e.g. 1 > b
-> { 1.send(@method, b) }.should raise_error(exception)
end
end
end
describe :integer_comparison_coerce_not_rescue, shared: true do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 > b
-> { 1.send(@method, b) }.should raise_error(IntegerSpecs::CoerceError)
end
end

View file

@ -1,35 +0,0 @@
require File.expand_path('../../fixtures/classes', __FILE__)
describe :integer_comparison_exception_in_coerce, shared: true do
ruby_version_is ""..."2.5" do
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises ArgumentError" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 > b
-> {
-> { 1.send(@method, b) }.should raise_error(ArgumentError, /comparison of #{1.class} with MockObject failed/)
}.should complain(/Numerical comparison operators will no more rescue exceptions of #coerce/)
end
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
[Exception, NoMemoryError].each do |exception|
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(exception)
# e.g. 1 > b
-> { 1.send(@method, b) }.should raise_error(exception)
end
end
end
ruby_version_is "2.5" do
it "does not rescue exception raised in other#coerce" do
b = mock("numeric with failed #coerce")
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
# e.g. 1 > b
-> { 1.send(@method, b) }.should raise_error(IntegerSpecs::CoerceError)
end
end
end

View file

@ -0,0 +1,58 @@
describe :integer_equal, shared: true do
context "fixnum" do
it "returns true if self has the same value as other" do
1.send(@method, 1).should == true
9.send(@method, 5).should == false
# Actually, these call Float#==, Bignum#== etc.
9.send(@method, 9.0).should == true
9.send(@method, 9.01).should == false
10.send(@method, bignum_value).should == false
end
it "calls 'other == self' if the given argument is not a Integer" do
1.send(@method, '*').should == false
obj = mock('one other')
obj.should_receive(:==).any_number_of_times.and_return(false)
1.send(@method, obj).should == false
obj = mock('another')
obj.should_receive(:==).any_number_of_times.and_return(true)
2.send(@method, obj).should == true
end
end
context "bignum" do
before :each do
@bignum = bignum_value
end
it "returns true if self has the same value as the given argument" do
@bignum.send(@method, @bignum).should == true
@bignum.send(@method, @bignum.to_f).should == true
@bignum.send(@method, @bignum + 1).should == false
(@bignum + 1).send(@method, @bignum).should == false
@bignum.send(@method, 9).should == false
@bignum.send(@method, 9.01).should == false
@bignum.send(@method, bignum_value(10)).should == false
end
it "calls 'other == self' if the given argument is not an Integer" do
obj = mock('not integer')
obj.should_receive(:==).and_return(true)
@bignum.send(@method, obj).should == true
end
it "returns the result of 'other == self' as a boolean" do
obj = mock('not integer')
obj.should_receive(:==).exactly(2).times.and_return("woot", nil)
@bignum.send(@method, obj).should == true
@bignum.send(@method, obj).should == false
end
end
end

View file

@ -0,0 +1,118 @@
describe :integer_exponent, shared: true do
context "fixnum" do
it "returns self raised to the given power" do
2.send(@method, 0).should eql 1
2.send(@method, 1).should eql 2
2.send(@method, 2).should eql 4
9.send(@method, 0.5).should eql 3.0
9.send(@method, Rational(1, 2)).should eql 3.0
5.send(@method, -1).to_f.to_s.should == '0.2'
2.send(@method, 40).should eql 1099511627776
end
it "overflows the answer to a bignum transparently" do
2.send(@method, 29).should eql 536870912
2.send(@method, 30).should eql 1073741824
2.send(@method, 31).should eql 2147483648
2.send(@method, 32).should eql 4294967296
2.send(@method, 61).should eql 2305843009213693952
2.send(@method, 62).should eql 4611686018427387904
2.send(@method, 63).should eql 9223372036854775808
2.send(@method, 64).should eql 18446744073709551616
8.send(@method, 23).should eql 590295810358705651712
end
it "raises negative numbers to the given power" do
(-2).send(@method, 29).should eql(-536870912)
(-2).send(@method, 30).should eql(1073741824)
(-2).send(@method, 31).should eql(-2147483648)
(-2).send(@method, 32).should eql(4294967296)
(-2).send(@method, 61).should eql(-2305843009213693952)
(-2).send(@method, 62).should eql(4611686018427387904)
(-2).send(@method, 63).should eql(-9223372036854775808)
(-2).send(@method, 64).should eql(18446744073709551616)
end
it "can raise 1 to a bignum safely" do
1.send(@method, 4611686018427387904).should eql 1
end
it "can raise -1 to a bignum safely" do
(-1).send(@method, 4611686018427387904).should eql(1)
(-1).send(@method, 4611686018427387905).should eql(-1)
end
it "returns Float::INFINITY when the number is too big" do
2.send(@method, 427387904).should == Float::INFINITY
end
it "raises a ZeroDivisionError for 0 ** -1" do
-> { 0.send(@method, -1) }.should raise_error(ZeroDivisionError)
-> { 0.send(@method, Rational(-1, 1)) }.should raise_error(ZeroDivisionError)
end
it "returns Float::INFINITY for 0 ** -1.0" do
0.send(@method, -1.0).should == Float::INFINITY
end
it "raises a TypeError when given a non-numeric power" do
-> { 13.send(@method, "10") }.should raise_error(TypeError)
-> { 13.send(@method, :symbol) }.should raise_error(TypeError)
-> { 13.send(@method, nil) }.should raise_error(TypeError)
end
it "coerces power and calls #**" do
num_2 = mock("2")
num_13 = mock("13")
num_2.should_receive(:coerce).with(13).and_return([num_13, num_2])
num_13.should_receive(:**).with(num_2).and_return(169)
13.send(@method, num_2).should == 169
end
it "returns Float when power is Float" do
2.send(@method, 2.0).should == 4.0
end
it "returns Rational when power is Rational" do
2.send(@method, Rational(2, 1)).should == Rational(4, 1)
end
it "returns a complex number when negative and raised to a fractional power" do
(-8).send(@method, 1.0/3) .should be_close(Complex(1, 1.73205), TOLERANCE)
(-8).send(@method, Rational(1, 3)).should be_close(Complex(1, 1.73205), TOLERANCE)
end
end
context "bignum" do
before :each do
@bignum = bignum_value(47)
end
it "returns self raised to other power" do
(@bignum.send(@method, 4)).should == 7237005577332262361485077344629993318496048279512298547155833600056910050625
(@bignum.send(@method, 1.2)).should be_close(57262152889751597425762.57804, TOLERANCE)
end
it "raises a TypeError when given a non-Integer" do
lambda { @bignum.send(@method, mock('10')) }.should raise_error(TypeError)
lambda { @bignum.send(@method, "10") }.should raise_error(TypeError)
lambda { @bignum.send(@method, :symbol) }.should raise_error(TypeError)
end
it "switch to a Float when the values is too big" do
flt = @bignum.send(@method, @bignum)
flt.should be_kind_of(Float)
flt.infinite?.should == 1
end
it "returns a complex number when negative and raised to a fractional power" do
((-@bignum).send(@method, (1.0/3))) .should be_close(Complex(1048576,1816186.907597341), TOLERANCE)
((-@bignum).send(@method, Rational(1,3))).should be_close(Complex(1048576,1816186.907597341), TOLERANCE)
end
end
end

View file

@ -0,0 +1,74 @@
describe :integer_modulo, shared: true do
context "fixnum" do
it "returns the modulus obtained from dividing self by the given argument" do
13.send(@method, 4).should == 1
4.send(@method, 13).should == 4
13.send(@method, 4.0).should == 1
4.send(@method, 13.0).should == 4
(-200).send(@method, 256).should == 56
(-1000).send(@method, 512).should == 24
(-200).send(@method, -256).should == -200
(-1000).send(@method, -512).should == -488
(200).send(@method, -256).should == -56
(1000).send(@method, -512).should == -24
1.send(@method, 2.0).should == 1.0
200.send(@method, bignum_value).should == 200
end
it "raises a ZeroDivisionError when the given argument is 0" do
lambda { 13.send(@method, 0) }.should raise_error(ZeroDivisionError)
lambda { 0.send(@method, 0) }.should raise_error(ZeroDivisionError)
lambda { -10.send(@method, 0) }.should raise_error(ZeroDivisionError)
end
it "raises a ZeroDivisionError when the given argument is 0 and a Float" do
lambda { 0.send(@method, 0.0) }.should raise_error(ZeroDivisionError)
lambda { 10.send(@method, 0.0) }.should raise_error(ZeroDivisionError)
lambda { -10.send(@method, 0.0) }.should raise_error(ZeroDivisionError)
end
it "raises a TypeError when given a non-Integer" do
lambda {
(obj = mock('10')).should_receive(:to_int).any_number_of_times.and_return(10)
13.send(@method, obj)
}.should raise_error(TypeError)
lambda { 13.send(@method, "10") }.should raise_error(TypeError)
lambda { 13.send(@method, :symbol) }.should raise_error(TypeError)
end
end
context "bignum" do
before :each do
@bignum = bignum_value
end
it "returns the modulus obtained from dividing self by the given argument" do
@bignum.send(@method, 5).should == 3
@bignum.send(@method, -5).should == -2
@bignum.send(@method, -100).should == -92
@bignum.send(@method, 2.22).should be_close(0.780180180180252, TOLERANCE)
@bignum.send(@method, bignum_value(10)).should == 9223372036854775808
end
it "raises a ZeroDivisionError when the given argument is 0" do
lambda { @bignum.send(@method, 0) }.should raise_error(ZeroDivisionError)
lambda { (-@bignum).send(@method, 0) }.should raise_error(ZeroDivisionError)
end
it "raises a ZeroDivisionError when the given argument is 0 and a Float" do
lambda { @bignum.send(@method, 0.0) }.should raise_error(ZeroDivisionError)
lambda { -@bignum.send(@method, 0.0) }.should raise_error(ZeroDivisionError)
end
it "raises a TypeError when given a non-Integer" do
lambda { @bignum.send(@method, mock('10')) }.should raise_error(TypeError)
lambda { @bignum.send(@method, "10") }.should raise_error(TypeError)
lambda { @bignum.send(@method, :symbol) }.should raise_error(TypeError)
end
end
end

View file

@ -0,0 +1,34 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#size" do
platform_is wordsize: 32 do
it "returns the number of bytes in the machine representation of self" do
-1.size.should == 4
0.size.should == 4
4091.size.should == 4
end
end
platform_is wordsize: 64 do
it "returns the number of bytes in the machine representation of self" do
-1.size.should == 8
0.size.should == 8
4091.size.should == 8
end
end
context "bignum" do
it "returns the number of bytes required to hold the unsigned bignum data" do
# that is, n such that 256 * n <= val.abs < 256 * (n+1)
(256**7).size.should == 8
(256**8).size.should == 9
(256**9).size.should == 10
(256**10).size.should == 11
(256**10-1).size.should == 10
(256**11).size.should == 12
(256**12).size.should == 13
(256**20-1).size.should == 20
(256**40-1).size.should == 40
end
end
end

View file

@ -2,5 +2,5 @@ require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/next', __FILE__)
describe "Integer#succ" do
it_behaves_like(:integer_next, :succ)
it_behaves_like :integer_next, :succ
end

View file

@ -0,0 +1,23 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#to_f" do
context "fixnum" do
it "returns self converted to a Float" do
0.to_f.should == 0.0
-500.to_f.should == -500.0
9_641_278.to_f.should == 9641278.0
end
end
context "bignum" do
it "returns self converted to a Float" do
bignum_value(0x4000_0aa0_0bb0_0000).to_f.should eql(13_835_069_737_789_292_544.00)
bignum_value(0x8000_0000_0000_0ccc).to_f.should eql(18_446_744_073_709_555_712.00)
(-bignum_value(99)).to_f.should eql(-9_223_372_036_854_775_808.00)
end
it "converts number close to Float::MAX without exceeding MAX or producing NaN" do
(10**308).to_f.should == 10.0 ** 308
end
end
end

View file

@ -2,5 +2,5 @@ require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/to_i', __FILE__)
describe "Integer#to_i" do
it_behaves_like(:integer_to_i, :to_i)
it_behaves_like :integer_to_i, :to_i
end

View file

@ -2,5 +2,5 @@ require File.expand_path('../../../spec_helper', __FILE__)
require File.expand_path('../shared/to_i', __FILE__)
describe "Integer#to_int" do
it_behaves_like(:integer_to_i, :to_int)
it_behaves_like :integer_to_i, :to_int
end

View file

@ -0,0 +1,99 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#to_s" do
context "fixnum" do
context "when given a base" do
it "returns self converted to a String in the given base" do
12345.to_s(2).should == "11000000111001"
12345.to_s(8).should == "30071"
12345.to_s(10).should == "12345"
12345.to_s(16).should == "3039"
95.to_s(16).should == "5f"
12345.to_s(36).should == "9ix"
end
it "raises an ArgumentError if the base is less than 2 or higher than 36" do
lambda { 123.to_s(-1) }.should raise_error(ArgumentError)
lambda { 123.to_s(0) }.should raise_error(ArgumentError)
lambda { 123.to_s(1) }.should raise_error(ArgumentError)
lambda { 123.to_s(37) }.should raise_error(ArgumentError)
end
end
context "when no base given" do
it "returns self converted to a String using base 10" do
255.to_s.should == '255'
3.to_s.should == '3'
0.to_s.should == '0'
-9002.to_s.should == '-9002'
end
end
with_feature :encoding do
before :each do
@internal = Encoding.default_internal
end
after :each do
Encoding.default_internal = @internal
end
it "returns a String in US-ASCII encoding when Encoding.default_internal is nil" do
Encoding.default_internal = nil
1.to_s.encoding.should equal(Encoding::US_ASCII)
end
it "returns a String in US-ASCII encoding when Encoding.default_internal is not nil" do
Encoding.default_internal = Encoding::IBM437
1.to_s.encoding.should equal(Encoding::US_ASCII)
end
end
end
context "bignum" do
describe "when given a base" do
it "returns self converted to a String using the given base" do
a = 2**64
a.to_s(2).should == "10000000000000000000000000000000000000000000000000000000000000000"
a.to_s(8).should == "2000000000000000000000"
a.to_s(16).should == "10000000000000000"
a.to_s(32).should == "g000000000000"
end
it "raises an ArgumentError if the base is less than 2 or higher than 36" do
lambda { 123.to_s(-1) }.should raise_error(ArgumentError)
lambda { 123.to_s(0) }.should raise_error(ArgumentError)
lambda { 123.to_s(1) }.should raise_error(ArgumentError)
lambda { 123.to_s(37) }.should raise_error(ArgumentError)
end
end
describe "when given no base" do
it "returns self converted to a String using base 10" do
bignum_value(9).to_s.should == "9223372036854775817"
bignum_value.to_s.should == "9223372036854775808"
(-bignum_value(675)).to_s.should == "-9223372036854776483"
end
end
with_feature :encoding do
before :each do
@internal = Encoding.default_internal
end
after :each do
Encoding.default_internal = @internal
end
it "returns a String in US-ASCII encoding when Encoding.default_internal is nil" do
Encoding.default_internal = nil
bignum_value.to_s.encoding.should equal(Encoding::US_ASCII)
end
it "returns a String in US-ASCII encoding when Encoding.default_internal is not nil" do
Encoding.default_internal = Encoding::IBM437
bignum_value.to_s.encoding.should equal(Encoding::US_ASCII)
end
end
end
end

View file

@ -3,8 +3,8 @@ require File.expand_path('../shared/to_i', __FILE__)
require File.expand_path('../shared/integer_rounding', __FILE__)
describe "Integer#truncate" do
it_behaves_like(:integer_to_i, :truncate)
it_behaves_like(:integer_rounding_positive_precision, :truncate)
it_behaves_like :integer_to_i, :truncate
it_behaves_like :integer_rounding_positive_precision, :truncate
ruby_version_is "2.4" do
context "precision argument specified as part of the truncate method is negative" do

View file

@ -0,0 +1,28 @@
require File.expand_path('../../../spec_helper', __FILE__)
describe "Integer#-@" do
context "fixnum" do
it "returns self as a negative value" do
2.send(:-@).should == -2
-2.should == -2
-268435455.should == -268435455
(--5).should == 5
-8.send(:-@).should == 8
end
it "negates self at Fixnum/Bignum boundaries" do
fixnum_max.send(:-@).should == (0 - fixnum_max)
fixnum_min.send(:-@).should == (0 - fixnum_min)
end
end
context "bignum" do
it "returns self as a negative value" do
bignum_value.send(:-@).should == -9223372036854775808
(-bignum_value).send(:-@).should == 9223372036854775808
bignum_value(921).send(:-@).should == -9223372036854776729
(-bignum_value(921).send(:-@)).should == 9223372036854776729
end
end
end