diff options
Diffstat (limited to 'spec/ruby/core/integer')
56 files changed, 1153 insertions, 666 deletions
diff --git a/spec/ruby/core/integer/allbits_spec.rb b/spec/ruby/core/integer/allbits_spec.rb index d7bd58d638..edce4b15e7 100644 --- a/spec/ruby/core/integer/allbits_spec.rb +++ b/spec/ruby/core/integer/allbits_spec.rb @@ -1,39 +1,37 @@ require_relative '../../spec_helper' -ruby_version_is '2.5' do - describe "Integer#allbits?" do - it "returns true iff all the bits of the argument are set in the receiver" do - 42.allbits?(42).should == true - 0b1010_1010.allbits?(0b1000_0010).should == true - 0b1010_1010.allbits?(0b1000_0001).should == false - 0b1000_0010.allbits?(0b1010_1010).should == false - (0b1010_1010 | bignum_value).allbits?(0b1000_0010 | bignum_value).should == true - (0b1010_1010 | bignum_value).allbits?(0b1000_0001 | bignum_value).should == false - (0b1000_0010 | bignum_value).allbits?(0b1010_1010 | bignum_value).should == false - end +describe "Integer#allbits?" do + it "returns true if and only if all the bits of the argument are set in the receiver" do + 42.allbits?(42).should == true + 0b1010_1010.allbits?(0b1000_0010).should == true + 0b1010_1010.allbits?(0b1000_0001).should == false + 0b1000_0010.allbits?(0b1010_1010).should == false + (0b1010_1010 | bignum_value).allbits?(0b1000_0010 | bignum_value).should == true + (0b1010_1010 | bignum_value).allbits?(0b1000_0001 | bignum_value).should == false + (0b1000_0010 | bignum_value).allbits?(0b1010_1010 | bignum_value).should == false + end - it "handles negative values using two's complement notation" do - (~0b1).allbits?(42).should == true - (-42).allbits?(-42).should == true - (~0b1010_1010).allbits?(~0b1110_1011).should == true - (~0b1010_1010).allbits?(~0b1000_0010).should == false - (~(0b1010_1010 | bignum_value)).allbits?(~(0b1110_1011 | bignum_value)).should == true - (~(0b1010_1010 | bignum_value)).allbits?(~(0b1000_0010 | bignum_value)).should == false - end + it "handles negative values using two's complement notation" do + (~0b1).allbits?(42).should == true + (-42).allbits?(-42).should == true + (~0b1010_1010).allbits?(~0b1110_1011).should == true + (~0b1010_1010).allbits?(~0b1000_0010).should == false + (~(0b1010_1010 | bignum_value)).allbits?(~(0b1110_1011 | bignum_value)).should == true + (~(0b1010_1010 | bignum_value)).allbits?(~(0b1000_0010 | bignum_value)).should == false + end - it "coerces the rhs using to_int" do - obj = mock("the int 0b10") - obj.should_receive(:to_int).and_return(0b10) - 0b110.allbits?(obj).should == true - end + it "coerces the rhs using to_int" do + obj = mock("the int 0b10") + obj.should_receive(:to_int).and_return(0b10) + 0b110.allbits?(obj).should == true + end - it "raises a TypeError when given a non-Integer" do - lambda { - (obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10]) - 13.allbits?(obj) - }.should raise_error(TypeError) - lambda { 13.allbits?("10") }.should raise_error(TypeError) - lambda { 13.allbits?(:symbol) }.should raise_error(TypeError) - end + it "raises a TypeError when given a non-Integer" do + -> { + (obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10]) + 13.allbits?(obj) + }.should raise_error(TypeError) + -> { 13.allbits?("10") }.should raise_error(TypeError) + -> { 13.allbits?(:symbol) }.should raise_error(TypeError) end end diff --git a/spec/ruby/core/integer/anybits_spec.rb b/spec/ruby/core/integer/anybits_spec.rb index 36803694aa..e0449074a2 100644 --- a/spec/ruby/core/integer/anybits_spec.rb +++ b/spec/ruby/core/integer/anybits_spec.rb @@ -1,38 +1,36 @@ require_relative '../../spec_helper' -ruby_version_is '2.5' do - describe "Integer#anybits?" do - it "returns true iff all the bits of the argument are set in the receiver" do - 42.anybits?(42).should == true - 0b1010_1010.anybits?(0b1000_0010).should == true - 0b1010_1010.anybits?(0b1000_0001).should == true - 0b1000_0010.anybits?(0b0010_1100).should == false - different_bignum = (2 * bignum_value) & (~bignum_value) - (0b1010_1010 | different_bignum).anybits?(0b1000_0010 | bignum_value).should == true - (0b1010_1010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == true - (0b1000_0010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == false - end +describe "Integer#anybits?" do + it "returns true if and only if all the bits of the argument are set in the receiver" do + 42.anybits?(42).should == true + 0b1010_1010.anybits?(0b1000_0010).should == true + 0b1010_1010.anybits?(0b1000_0001).should == true + 0b1000_0010.anybits?(0b0010_1100).should == false + different_bignum = (2 * bignum_value) & (~bignum_value) + (0b1010_1010 | different_bignum).anybits?(0b1000_0010 | bignum_value).should == true + (0b1010_1010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == true + (0b1000_0010 | different_bignum).anybits?(0b0010_1100 | bignum_value).should == false + end - it "handles negative values using two's complement notation" do - (~42).anybits?(42).should == false - (-42).anybits?(-42).should == true - (~0b100).anybits?(~0b1).should == true - (~(0b100 | bignum_value)).anybits?(~(0b1 | bignum_value)).should == true - end + it "handles negative values using two's complement notation" do + (~42).anybits?(42).should == false + (-42).anybits?(-42).should == true + (~0b100).anybits?(~0b1).should == true + (~(0b100 | bignum_value)).anybits?(~(0b1 | bignum_value)).should == true + end - it "coerces the rhs using to_int" do - obj = mock("the int 0b10") - obj.should_receive(:to_int).and_return(0b10) - 0b110.anybits?(obj).should == true - end + it "coerces the rhs using to_int" do + obj = mock("the int 0b10") + obj.should_receive(:to_int).and_return(0b10) + 0b110.anybits?(obj).should == true + end - it "raises a TypeError when given a non-Integer" do - lambda { - (obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10]) - 13.anybits?(obj) - }.should raise_error(TypeError) - lambda { 13.anybits?("10") }.should raise_error(TypeError) - lambda { 13.anybits?(:symbol) }.should raise_error(TypeError) - end + it "raises a TypeError when given a non-Integer" do + -> { + (obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10]) + 13.anybits?(obj) + }.should raise_error(TypeError) + -> { 13.anybits?("10") }.should raise_error(TypeError) + -> { 13.anybits?(:symbol) }.should raise_error(TypeError) end end diff --git a/spec/ruby/core/integer/bit_and_spec.rb b/spec/ruby/core/integer/bit_and_spec.rb index 8565f82397..e7face39ac 100644 --- a/spec/ruby/core/integer/bit_and_spec.rb +++ b/spec/ruby/core/integer/bit_and_spec.rb @@ -30,19 +30,19 @@ describe "Integer#&" do it "coerces the rhs and calls #coerce" do obj = mock("fixnum bit and") - obj.should_receive(:coerce).with(6).and_return([3, 6]) + obj.should_receive(:coerce).with(6).and_return([6, 3]) (6 & obj).should == 2 end it "raises a TypeError when passed a Float" do - lambda { (3 & 3.4) }.should raise_error(TypeError) + -> { (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) + -> { 3 & obj }.should raise_error(TypeError) end end @@ -55,24 +55,24 @@ describe "Integer#&" do @bignum = bignum_value(5) (@bignum & 3).should == 1 (@bignum & 52).should == 4 - (@bignum & bignum_value(9921)).should == 9223372036854775809 + (@bignum & bignum_value(9921)).should == 18446744073709551617 ((2*bignum_value) & 1).should == 0 - ((2*bignum_value) & (2*bignum_value)).should == 18446744073709551616 + ((2*bignum_value) & (2*bignum_value)).should == 36893488147419103232 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 & -0xffffffffffffff5).should == 18446744073709551617 (@bignum & -@bignum).should == 1 - (@bignum & -0x8000000000000000).should == 9223372036854775808 + (@bignum & -0x8000000000000000).should == 18446744073709551616 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 + (-@bignum & -0x4000000000000005).should == -23058430092136939525 + (-@bignum & -@bignum).should == -18446744073709551621 + (-@bignum & -0x4000000000000000).should == -23058430092136939520 end it "returns self bitwise AND other when both are negative and a multiple in bitsize of Fixnum::MIN" do @@ -84,14 +84,14 @@ describe "Integer#&" do end it "raises a TypeError when passed a Float" do - lambda { (@bignum & 3.4) }.should raise_error(TypeError) + -> { (@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) + -> { @bignum & obj }.should raise_error(TypeError) end end end diff --git a/spec/ruby/core/integer/bit_or_spec.rb b/spec/ruby/core/integer/bit_or_spec.rb index 16ab430f8b..fdf8a191e5 100644 --- a/spec/ruby/core/integer/bit_or_spec.rb +++ b/spec/ruby/core/integer/bit_or_spec.rb @@ -7,22 +7,43 @@ describe "Integer#|" do (5 | 4).should == 5 (5 | 6).should == 7 (248 | 4096).should == 4344 - (0xffff | bignum_value + 0xf0f0).should == 0x8000_0000_0000_ffff + (0xffff | bignum_value + 0xf0f0).should == 0x1_0000_0000_0000_ffff + end + + it "returns self bitwise OR other when one operand is negative" do + ((1 << 33) | -1).should == -1 + (-1 | (1 << 33)).should == -1 + + ((-(1<<33)-1) | 5).should == -8589934593 + (5 | (-(1<<33)-1)).should == -8589934593 + end + + it "returns self bitwise OR other when both operands are negative" do + (-5 | -1).should == -1 + (-3 | -4).should == -3 + (-12 | -13).should == -9 + (-13 | -12).should == -9 end it "returns self bitwise OR a bignum" do (-1 | 2**64).should == -1 end + it "coerces the rhs and calls #coerce" do + obj = mock("fixnum bit or") + obj.should_receive(:coerce).with(6).and_return([6, 3]) + (6 | obj).should == 7 + end + it "raises a TypeError when passed a Float" do - lambda { (3 | 3.4) }.should raise_error(TypeError) + -> { (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) + -> { 3 | obj }.should raise_error(TypeError) end end @@ -32,37 +53,37 @@ describe "Integer#|" do end it "returns self bitwise OR other" do - (@bignum | 2).should == 9223372036854775819 - (@bignum | 9).should == 9223372036854775819 - (@bignum | bignum_value).should == 9223372036854775819 + (@bignum | 2).should == 18446744073709551627 + (@bignum | 9).should == 18446744073709551627 + (@bignum | bignum_value).should == 18446744073709551627 end it "returns self bitwise OR other when one operand is negative" do - (@bignum | -0x40000000000000000).should == -64563604257983430645 + (@bignum | -0x40000000000000000).should == -55340232221128654837 (@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 | -@bignum).should == -18446744073709551627 (-@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) + -> { @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) + -> { @bignum | obj }.should raise_error(TypeError) end end end diff --git a/spec/ruby/core/integer/bit_xor_spec.rb b/spec/ruby/core/integer/bit_xor_spec.rb index 65f88341e0..1f46bc52f3 100644 --- a/spec/ruby/core/integer/bit_xor_spec.rb +++ b/spec/ruby/core/integer/bit_xor_spec.rb @@ -5,22 +5,43 @@ describe "Integer#^" 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 + (5 ^ bignum_value + 0xffff_ffff).should == 0x1_0000_0000_ffff_fffa + end + + it "returns self bitwise XOR other when one operand is negative" do + ((1 << 33) ^ -1).should == -8589934593 + (-1 ^ (1 << 33)).should == -8589934593 + + ((-(1<<33)-1) ^ 5).should == -8589934598 + (5 ^ (-(1<<33)-1)).should == -8589934598 + end + + it "returns self bitwise XOR other when both operands are negative" do + (-5 ^ -1).should == 4 + (-3 ^ -4).should == 1 + (-12 ^ -13).should == 7 + (-13 ^ -12).should == 7 end it "returns self bitwise EXCLUSIVE OR a bignum" do (-1 ^ 2**64).should == -18446744073709551617 end + it "coerces the rhs and calls #coerce" do + obj = mock("fixnum bit xor") + obj.should_receive(:coerce).with(6).and_return([6, 3]) + (6 ^ obj).should == 5 + end + it "raises a TypeError when passed a Float" do - lambda { (3 ^ 3.4) }.should raise_error(TypeError) + -> { (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) + -> { 3 ^ obj }.should raise_error(TypeError) end end @@ -30,21 +51,21 @@ describe "Integer#^" do end it "returns self bitwise EXCLUSIVE OR other" do - (@bignum ^ 2).should == 9223372036854775824 + (@bignum ^ 2).should == 18446744073709551632 (@bignum ^ @bignum).should == 0 - (@bignum ^ 14).should == 9223372036854775836 + (@bignum ^ 14).should == 18446744073709551644 end it "returns self bitwise EXCLUSIVE OR other when one operand is negative" do - (@bignum ^ -0x40000000000000000).should == -64563604257983430638 + (@bignum ^ -0x40000000000000000).should == -55340232221128654830 (@bignum ^ -@bignum).should == -4 - (@bignum ^ -0x8000000000000000).should == -18446744073709551598 + (@bignum ^ -0x8000000000000000).should == -27670116110564327406 end it "returns self bitwise EXCLUSIVE OR other when both operands are negative" do - (-@bignum ^ -0x40000000000000000).should == 64563604257983430638 + (-@bignum ^ -0x40000000000000000).should == 55340232221128654830 (-@bignum ^ -@bignum).should == 0 - (-@bignum ^ -0x4000000000000000).should == 13835058055282163694 + (-@bignum ^ -0x4000000000000000).should == 23058430092136939502 end it "returns self bitwise EXCLUSIVE OR other when all bits are 1 and other value is negative" do @@ -55,18 +76,18 @@ describe "Integer#^" do 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) + -> { @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) + -> { @bignum ^ obj }.should raise_error(TypeError) end end end diff --git a/spec/ruby/core/integer/ceil_spec.rb b/spec/ruby/core/integer/ceil_spec.rb index 13bdaf838d..eb633fba78 100644 --- a/spec/ruby/core/integer/ceil_spec.rb +++ b/spec/ruby/core/integer/ceil_spec.rb @@ -1,11 +1,16 @@ require_relative '../../spec_helper' require_relative 'shared/to_i' require_relative 'shared/integer_rounding' +require_relative 'shared/integer_ceil_precision' describe "Integer#ceil" do it_behaves_like :integer_to_i, :ceil it_behaves_like :integer_rounding_positive_precision, :ceil + context "with precision" do + it_behaves_like :integer_ceil_precision, :Integer + end + context "precision argument specified as part of the ceil method is negative" do it "returns the smallest integer greater than self with at least precision.abs trailing zeros" do 18.ceil(-1).should eql(20) diff --git a/spec/ruby/core/integer/ceildiv_spec.rb b/spec/ruby/core/integer/ceildiv_spec.rb new file mode 100644 index 0000000000..c6e22a457d --- /dev/null +++ b/spec/ruby/core/integer/ceildiv_spec.rb @@ -0,0 +1,20 @@ +require_relative '../../spec_helper' + +describe "Integer#ceildiv" do + it "returns a quotient of division which is rounded up to the nearest integer" do + 0.ceildiv(3).should eql(0) + 1.ceildiv(3).should eql(1) + 3.ceildiv(3).should eql(1) + 4.ceildiv(3).should eql(2) + + 4.ceildiv(-3).should eql(-1) + -4.ceildiv(3).should eql(-1) + -4.ceildiv(-3).should eql(2) + + 3.ceildiv(1.2).should eql(3) + 3.ceildiv(6/5r).should eql(3) + + (10**100-11).ceildiv(10**99-1).should eql(10) + (10**100-9).ceildiv(10**99-1).should eql(11) + end +end diff --git a/spec/ruby/core/integer/chr_spec.rb b/spec/ruby/core/integer/chr_spec.rb index 02d0283182..39cafe2874 100644 --- a/spec/ruby/core/integer/chr_spec.rb +++ b/spec/ruby/core/integer/chr_spec.rb @@ -10,8 +10,12 @@ describe "Integer#chr without argument" do end it "raises a RangeError is self is less than 0" do - lambda { -1.chr }.should raise_error(RangeError) - lambda { -bignum_value.chr }.should raise_error(RangeError) + -> { -1.chr }.should raise_error(RangeError, /-1 out of char range/) + -> { (-bignum_value).chr }.should raise_error(RangeError, /bignum out of char range/) + end + + it "raises a RangeError if self is too large" do + -> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError, /2206368128 out of char range/) end describe "when Encoding.default_internal is nil" do @@ -44,8 +48,8 @@ describe "Integer#chr without argument" do end it "raises a RangeError is self is greater than 255" do - lambda { 256.chr }.should raise_error(RangeError) - lambda { bignum_value.chr }.should raise_error(RangeError) + -> { 256.chr }.should raise_error(RangeError, /256 out of char range/) + -> { bignum_value.chr }.should raise_error(RangeError, /bignum out of char range/) end end @@ -133,7 +137,7 @@ describe "Integer#chr without argument" do [620, "TIS-620"] ].each do |integer, encoding_name| Encoding.default_internal = Encoding.find(encoding_name) - lambda { integer.chr }.should raise_error(RangeError) + -> { integer.chr }.should raise_error(RangeError, /(invalid codepoint|out of char range)/) end end end @@ -150,7 +154,7 @@ describe "Integer#chr with an encoding argument" do end it "accepts a String as an argument" do - lambda { 0xA4A2.chr('euc-jp') }.should_not raise_error + -> { 0xA4A2.chr('euc-jp') }.should_not raise_error end it "converts a String to an Encoding as Encoding.find does" do @@ -161,12 +165,12 @@ describe "Integer#chr with an encoding argument" do # http://redmine.ruby-lang.org/issues/4869 it "raises a RangeError is self is less than 0" do - lambda { -1.chr(Encoding::UTF_8) }.should raise_error(RangeError) - lambda { -bignum_value.chr(Encoding::EUC_JP) }.should raise_error(RangeError) + -> { -1.chr(Encoding::UTF_8) }.should raise_error(RangeError, /-1 out of char range/) + -> { (-bignum_value).chr(Encoding::EUC_JP) }.should raise_error(RangeError, /bignum out of char range/) end it "raises a RangeError if self is too large" do - lambda { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError) + -> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError, /2206368128 out of char range/) end it "returns a String with the specified encoding" do @@ -219,25 +223,35 @@ describe "Integer#chr with an encoding argument" do # #5864 it "raises RangeError if self is invalid as a codepoint in the specified encoding" do - [ [0x80, "US-ASCII"], - [0x0100, "BINARY"], - [0x0100, "EUC-JP"], - [0xA1A0, "EUC-JP"], - [0xA1, "EUC-JP"], - [0x80, "SHIFT_JIS"], - [0xE0, "SHIFT_JIS"], - [0x0100, "ISO-8859-9"], - [620, "TIS-620"], - [0xD800, "UTF-8"], - [0xDBFF, "UTF-8"], - [0xDC00, "UTF-8"], - [0xDFFF, "UTF-8"], - [0xD800, "UTF-16"], - [0xDBFF, "UTF-16"], - [0xDC00, "UTF-16"], - [0xDFFF, "UTF-16"], - ].each do |integer, encoding_name| - lambda { integer.chr(encoding_name) }.should raise_error(RangeError) - end + -> { 0x80.chr("US-ASCII") }.should raise_error(RangeError) + -> { 0x0100.chr("BINARY") }.should raise_error(RangeError) + -> { 0x0100.chr("EUC-JP") }.should raise_error(RangeError) + -> { 0xA1A0.chr("EUC-JP") }.should raise_error(RangeError) + -> { 0xA1.chr("EUC-JP") }.should raise_error(RangeError) + -> { 0x80.chr("SHIFT_JIS") }.should raise_error(RangeError) + -> { 0xE0.chr("SHIFT_JIS") }.should raise_error(RangeError) + -> { 0x0100.chr("ISO-8859-9") }.should raise_error(RangeError) + -> { 620.chr("TIS-620") }.should raise_error(RangeError) + # UTF-16 surrogate range + -> { 0xD800.chr("UTF-8") }.should raise_error(RangeError) + -> { 0xDBFF.chr("UTF-8") }.should raise_error(RangeError) + -> { 0xDC00.chr("UTF-8") }.should raise_error(RangeError) + -> { 0xDFFF.chr("UTF-8") }.should raise_error(RangeError) + # UTF-16 surrogate range + -> { 0xD800.chr("UTF-16") }.should raise_error(RangeError) + -> { 0xDBFF.chr("UTF-16") }.should raise_error(RangeError) + -> { 0xDC00.chr("UTF-16") }.should raise_error(RangeError) + -> { 0xDFFF.chr("UTF-16") }.should raise_error(RangeError) + end + + it 'returns a String encoding self interpreted as a codepoint in the CESU-8 encoding' do + # see more details here https://en.wikipedia.org/wiki/CESU-8 + # code points from U+0000 to U+FFFF is encoded in the same way as in UTF-8 + 0x0045.chr(Encoding::CESU_8).bytes.should == 0x0045.chr(Encoding::UTF_8).bytes + + # code points in range from U+10000 to U+10FFFF is CESU-8 data containing a 6-byte surrogate pair, + # which decodes to a 4-byte UTF-8 string + 0x10400.chr(Encoding::CESU_8).bytes.should != 0x10400.chr(Encoding::UTF_8).bytes + 0x10400.chr(Encoding::CESU_8).bytes.to_a.should == [0xED, 0xA0, 0x81, 0xED, 0xB0, 0x80] end end diff --git a/spec/ruby/core/integer/coerce_spec.rb b/spec/ruby/core/integer/coerce_spec.rb index 8db15bbaed..1d6dc9713f 100644 --- a/spec/ruby/core/integer/coerce_spec.rb +++ b/spec/ruby/core/integer/coerce_spec.rb @@ -5,13 +5,13 @@ describe "Integer#coerce" 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] + 1.coerce(2).map { |i| i.class }.should == [Integer, Integer] 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) + -> { 1.coerce(":)") }.should raise_error(ArgumentError) end it "returns an array containing two Floats" do @@ -21,7 +21,7 @@ describe "Integer#coerce" do end it "raises a TypeError when trying to coerce with nil" do - lambda { 1.coerce(nil) }.should raise_error(TypeError) + -> { 1.coerce(nil) }.should raise_error(TypeError) end it "tries to convert the given Object into a Float by using #to_f" do @@ -29,13 +29,13 @@ describe "Integer#coerce" do 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) + -> { 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) + -> { 1.coerce(mock('x')) }.should raise_error(TypeError) + -> { 1.coerce(1..4) }.should raise_error(TypeError) + -> { 1.coerce(:test) }.should raise_error(TypeError) end end @@ -44,8 +44,8 @@ describe "Integer#coerce" do a = bignum_value ary = a.coerce(2) - ary[0].should be_kind_of(Bignum) - ary[1].should be_kind_of(Bignum) + ary[0].should be_kind_of(Integer) + ary[1].should be_kind_of(Integer) ary.should == [2, a] end @@ -54,18 +54,18 @@ describe "Integer#coerce" do b = bignum_value ary = a.coerce(b) - ary[0].should be_kind_of(Bignum) - ary[1].should be_kind_of(Bignum) + ary[0].should be_kind_of(Integer) + ary[1].should be_kind_of(Integer) 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) + -> { a.coerce(nil) }.should raise_error(TypeError) + -> { a.coerce(mock('str')) }.should raise_error(TypeError) + -> { a.coerce(1..4) }.should raise_error(TypeError) + -> { a.coerce(:test) }.should raise_error(TypeError) end it "coerces both values to Floats and returns [other, self] when passed a Float" do diff --git a/spec/ruby/core/integer/comparison_spec.rb b/spec/ruby/core/integer/comparison_spec.rb index 4cf1d7cdc7..408c8e52ce 100644 --- a/spec/ruby/core/integer/comparison_spec.rb +++ b/spec/ruby/core/integer/comparison_spec.rb @@ -116,7 +116,7 @@ describe "Integer#<=>" do describe "with an Object" do before :each do @big = bignum_value - @num = mock("value for Bignum#<=>") + @num = mock("value for Integer#<=>") end it "calls #coerce on other" do @@ -124,28 +124,16 @@ describe "Integer#<=>" do @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 + it "lets the exception go through if #coerce raises an exception" do + @num.should_receive(:coerce).with(@big).and_raise(RuntimeError.new("my error")) + -> { + @big <=> @num + }.should raise_error(RuntimeError, "my error") 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) + -> { @big <=> @num }.should raise_error(Exception) end it "returns nil if #coerce does not return an Array" do @@ -174,7 +162,7 @@ describe "Integer#<=>" do (infinity_value <=> Float::MAX.to_i*2).should == 1 end - it "returns -1 when self is negative and other is Infinty" do + it "returns -1 when self is negative and other is Infinity" do (-Float::MAX.to_i*2 <=> infinity_value).should == -1 end diff --git a/spec/ruby/core/integer/complement_spec.rb b/spec/ruby/core/integer/complement_spec.rb index eafa5c263f..baf5e6c457 100644 --- a/spec/ruby/core/integer/complement_spec.rb +++ b/spec/ruby/core/integer/complement_spec.rb @@ -12,9 +12,9 @@ describe "Integer#~" do 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 + (~bignum_value(48)).should == -18446744073709551665 + (~(-bignum_value(21))).should == 18446744073709551636 + (~bignum_value(1)).should == -18446744073709551618 end end end diff --git a/spec/ruby/core/integer/constants_spec.rb b/spec/ruby/core/integer/constants_spec.rb new file mode 100644 index 0000000000..937806c72f --- /dev/null +++ b/spec/ruby/core/integer/constants_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' + +describe "Fixnum" do + it "is no longer defined" do + Object.should_not.const_defined?(:Fixnum) + end +end + +describe "Bignum" do + it "is no longer defined" do + Object.should_not.const_defined?(:Bignum) + end +end diff --git a/spec/ruby/core/integer/digits_spec.rb b/spec/ruby/core/integer/digits_spec.rb index 85afb6f50f..3d0a64c25f 100644 --- a/spec/ruby/core/integer/digits_spec.rb +++ b/spec/ruby/core/integer/digits_spec.rb @@ -19,14 +19,23 @@ describe "Integer#digits" do end it "raises ArgumentError when calling with a radix less than 2" do - lambda { 12345.digits(1) }.should raise_error(ArgumentError) + -> { 12345.digits(1) }.should raise_error(ArgumentError) end it "raises ArgumentError when calling with a negative radix" do - lambda { 12345.digits(-2) }.should raise_error(ArgumentError) + -> { 12345.digits(-2) }.should raise_error(ArgumentError) end it "raises Math::DomainError when calling digits on a negative number" do - lambda { -12345.digits(7) }.should raise_error(Math::DomainError) + -> { -12345.digits(7) }.should raise_error(Math::DomainError) + end + + it "returns integer values > 9 when base is above 10" do + 1234.digits(16).should == [2, 13, 4] + end + + it "can be used with base > 37" do + 1234.digits(100).should == [34, 12] + 980099.digits(100).should == [99, 0, 98] end end diff --git a/spec/ruby/core/integer/div_spec.rb b/spec/ruby/core/integer/div_spec.rb index ca69ff4681..2eb9c0623b 100644 --- a/spec/ruby/core/integer/div_spec.rb +++ b/spec/ruby/core/integer/div_spec.rb @@ -36,7 +36,7 @@ describe "Integer#div" do 10.div(y).should == result end - it "coerces self and the given argument to Floats and returns self divided by other as Fixnum" do + it "coerces self and the given argument to Floats and returns self divided by other as Integer" do 1.div(0.2).should == 5 1.div(0.16).should == 6 1.div(0.169).should == 5 @@ -46,21 +46,21 @@ describe "Integer#div" do 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) + -> { 0.div(0.0) }.should raise_error(ZeroDivisionError) + -> { 10.div(0.0) }.should raise_error(ZeroDivisionError) + -> { -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) + -> { 13.div(0) }.should raise_error(ZeroDivisionError) + -> { 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) + -> { 13.div(mock('10')) }.should raise_error(TypeError) + -> { 5.div("2") }.should raise_error(TypeError) + -> { 5.div(:"2") }.should raise_error(TypeError) + -> { 5.div([]) }.should raise_error(TypeError) end end @@ -70,8 +70,8 @@ describe "Integer#div" do end it "returns self divided by other" do - @bignum.div(4).should == 2305843009213693974 - @bignum.div(Rational(4, 1)).should == 2305843009213693974 + @bignum.div(4).should == 4611686018427387926 + @bignum.div(Rational(4, 1)).should == 4611686018427387926 @bignum.div(bignum_value(2)).should == 1 (-(10**50)).div(-(10**40 + 1)).should == 9999999999 @@ -118,29 +118,37 @@ describe "Integer#div" do 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) + -> { @bignum.div(mock("10")) }.should raise_error(TypeError) + -> { @bignum.div("2") }.should raise_error(TypeError) + -> { @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) + @bignum.div(4294967295.5).should eql(4294967296) not_supported_on :opal do - @bignum.div(4294967295.0).should eql(2147483648) + @bignum.div(4294967295.0).should eql(4294967297) @bignum.div(bignum_value(88).to_f).should eql(1) - @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) + -> { @bignum.div(0.0) }.should raise_error(ZeroDivisionError) + -> { @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) + -> { @bignum.div(0) }.should raise_error(ZeroDivisionError) + -> { @bignum.div(-0) }.should raise_error(ZeroDivisionError) + end + end + + context "rational" do + it "returns self divided by the given argument as an Integer" do + 2.div(6/5r).should == 1 + 1.div(6/5r).should == 0 + 5.div(6/5r).should == 4 end end end diff --git a/spec/ruby/core/integer/divide_spec.rb b/spec/ruby/core/integer/divide_spec.rb index 2d49307628..0d5e16e986 100644 --- a/spec/ruby/core/integer/divide_spec.rb +++ b/spec/ruby/core/integer/divide_spec.rb @@ -2,13 +2,7 @@ require_relative '../../spec_helper' require_relative 'shared/arithmetic_coerce' describe "Integer#/" do - 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 + it_behaves_like :integer_arithmetic_coerce_not_rescue, :/ context "fixnum" do it "returns self divided by the given argument" do @@ -18,6 +12,17 @@ describe "Integer#/" do it "supports dividing negative numbers" do (-1 / 10).should == -1 + (-1 / 10**10).should == -1 + (-1 / 10**20).should == -1 + end + + it "preservers sign correctly" do + (4 / 3).should == 1 + (4 / -3).should == -2 + (-4 / 3).should == -2 + (-4 / -3).should == 1 + (0 / -3).should == 0 + (0 / 3).should == 0 end it "returns result the same class as the argument" do @@ -27,7 +32,7 @@ describe "Integer#/" do end it "raises a ZeroDivisionError if the given argument is zero and not a Float" do - lambda { 1 / 0 }.should raise_error(ZeroDivisionError) + -> { 1 / 0 }.should raise_error(ZeroDivisionError) end it "does NOT raise ZeroDivisionError if the given argument is zero and is a Float" do @@ -41,9 +46,9 @@ describe "Integer#/" do 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) + -> { 13 / mock('10') }.should raise_error(TypeError) + -> { 13 / "10" }.should raise_error(TypeError) + -> { 13 / :symbol }.should raise_error(TypeError) end end @@ -53,7 +58,7 @@ describe "Integer#/" do end it "returns self divided by other" do - (@bignum / 4).should == 2305843009213693974 + (@bignum / 4).should == 4611686018427387926 (@bignum / bignum_value(2)).should == 1 @@ -64,17 +69,26 @@ describe "Integer#/" do ((10**50) / -(10**40 + 1)).should == -10000000000 end + it "preservers sign correctly" do + (4 / bignum_value).should == 0 + (4 / -bignum_value).should == -1 + (-4 / bignum_value).should == -1 + (-4 / -bignum_value).should == 0 + (0 / bignum_value).should == 0 + (0 / -bignum_value).should == 0 + end + it "returns self divided by Float" do not_supported_on :opal do - (bignum_value(88) / 4294967295.0).should be_close(2147483648.5, TOLERANCE) + (bignum_value(88) / 4294967295.0).should be_close(4294967297.0, TOLERANCE) end - (bignum_value(88) / 4294967295.5).should be_close(2147483648.25, TOLERANCE) + (bignum_value(88) / 4294967295.5).should be_close(4294967296.5, 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) + (@bignum / 4).should == 4611686018427387926 + (@bignum / 4.0).should be_close(4611686018427387926, TOLERANCE) + (@bignum / Rational(4, 1)).should == Rational(4611686018427387926, 1) end it "does NOT raise ZeroDivisionError if other is zero and is a Float" do @@ -83,13 +97,30 @@ describe "Integer#/" do end it "raises a ZeroDivisionError if other is zero and not a Float" do - lambda { @bignum / 0 }.should raise_error(ZeroDivisionError) + -> { @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) + -> { @bignum / mock('10') }.should raise_error(TypeError) + -> { @bignum / "2" }.should raise_error(TypeError) + -> { @bignum / :symbol }.should raise_error(TypeError) end end + + it "coerces the RHS and calls #coerce" do + obj = mock("integer plus") + obj.should_receive(:coerce).with(6).and_return([6, 3]) + (6 / obj).should == 2 + end + + it "coerces the RHS and calls #coerce even if it's private" do + obj = Object.new + class << obj + private def coerce(n) + [n, 3] + end + end + + (6 / obj).should == 2 + end end diff --git a/spec/ruby/core/integer/divmod_spec.rb b/spec/ruby/core/integer/divmod_spec.rb index 27fb34574c..7a489e9344 100644 --- a/spec/ruby/core/integer/divmod_spec.rb +++ b/spec/ruby/core/integer/divmod_spec.rb @@ -14,24 +14,24 @@ describe "Integer#divmod" do 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) + -> { 13.divmod(0) }.should raise_error(ZeroDivisionError) + -> { 0.divmod(0) }.should raise_error(ZeroDivisionError) + -> { -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) + -> { 0.divmod(0.0) }.should raise_error(ZeroDivisionError) + -> { 10.divmod(0.0) }.should raise_error(ZeroDivisionError) + -> { -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) + -> { 13.divmod("10") }.should raise_error(TypeError) + -> { 13.divmod(:symbol) }.should raise_error(TypeError) end end @@ -46,16 +46,16 @@ describe "Integer#divmod" do # 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).should == [4611686018427387917, 3] + @bignum.divmod(13).should == [1418980313362273205, 6] - @bignum.divmod(4.5).should == [2049638230412172288, 3.5] + @bignum.divmod(4.5).should == [4099276460824344576, 2.5] not_supported_on :opal do - @bignum.divmod(4.0).should == [2305843009213693952, 0.0] - @bignum.divmod(13.0).should == [709490156681136640, 8.0] + @bignum.divmod(4.0).should == [4611686018427387904, 0.0] + @bignum.divmod(13.0).should == [1418980313362273280, 3.0] - @bignum.divmod(2.0).should == [4611686018427387904, 0.0] + @bignum.divmod(2.0).should == [9223372036854775808, 0.0] end @bignum.divmod(bignum_value).should == [1, 55] @@ -94,24 +94,24 @@ describe "Integer#divmod" do 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) + -> { @bignum.divmod(0) }.should raise_error(ZeroDivisionError) + -> { (-@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) + -> { @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) + -> { @bignum.divmod(0.0) }.should raise_error(ZeroDivisionError) + -> { (-@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) + -> { @bignum.divmod(mock('10')) }.should raise_error(TypeError) + -> { @bignum.divmod("10") }.should raise_error(TypeError) + -> { @bignum.divmod(:symbol) }.should raise_error(TypeError) end end end diff --git a/spec/ruby/core/integer/downto_spec.rb b/spec/ruby/core/integer/downto_spec.rb index 92dee89fc9..987704b02e 100644 --- a/spec/ruby/core/integer/downto_spec.rb +++ b/spec/ruby/core/integer/downto_spec.rb @@ -1,6 +1,6 @@ require_relative '../../spec_helper' -describe "Integer#downto [stop] when self and stop are Fixnums" do +describe "Integer#downto [stop] when self and stop are Integers" do it "does not yield when stop is greater than self" do result = [] 5.downto(6) { |x| result << x } @@ -27,8 +27,8 @@ describe "Integer#downto [stop] when self and stop are Fixnums" do end it "raises an ArgumentError for invalid endpoints" do - lambda {1.downto("A") {|x| p x } }.should raise_error(ArgumentError) - lambda {1.downto(nil) {|x| p x } }.should raise_error(ArgumentError) + -> {1.downto("A") {|x| p x } }.should raise_error(ArgumentError) + -> {1.downto(nil) {|x| p x } }.should raise_error(ArgumentError) end describe "when no block is given" do @@ -45,9 +45,9 @@ describe "Integer#downto [stop] when self and stop are Fixnums" do describe "size" do it "raises an ArgumentError for invalid endpoints" do enum = 1.downto("A") - lambda { enum.size }.should raise_error(ArgumentError) + -> { enum.size }.should raise_error(ArgumentError) enum = 1.downto(nil) - lambda { enum.size }.should raise_error(ArgumentError) + -> { enum.size }.should raise_error(ArgumentError) end it "returns self - stop + 1" do diff --git a/spec/ruby/core/integer/element_reference_spec.rb b/spec/ruby/core/integer/element_reference_spec.rb index 6c72a717d6..cb7e0dc9b0 100644 --- a/spec/ruby/core/integer/element_reference_spec.rb +++ b/spec/ruby/core/integer/element_reference_spec.rb @@ -59,13 +59,13 @@ describe "Integer#[]" do end it "raises a TypeError when passed a String" do - lambda { 3["3"] }.should raise_error(TypeError) + -> { 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) + -> { 3[obj] }.should raise_error(TypeError) end it "calls #to_int to coerce a String to a Bignum and returns 0" do @@ -78,6 +78,83 @@ describe "Integer#[]" do it "returns 0 when passed a Float in the range of a Bignum" do 3[bignum_value.to_f].should == 0 end + + context "when index and length passed" do + it "returns specified number of bits from specified position" do + 0b101001101[2, 4].should == 0b0011 + 0b101001101[2, 5].should == 0b10011 + 0b101001101[2, 7].should == 0b1010011 + end + + it "ensures n[i, len] equals to (n >> i) & ((1 << len) - 1)" do + n = 0b101001101; i = 2; len = 4 + n[i, len].should == (n >> i) & ((1 << len) - 1) + end + + it "moves start position to the most significant bits when negative index passed" do + 0b000001[-1, 4].should == 0b10 + 0b000001[-2, 4].should == 0b100 + 0b000001[-3, 4].should == 0b1000 + end + + it "ignores negative length" do + 0b101001101[1, -1].should == 0b10100110 + 0b101001101[2, -1].should == 0b1010011 + 0b101001101[3, -1].should == 0b101001 + + 0b101001101[3, -5].should == 0b101001 + 0b101001101[3, -15].should == 0b101001 + 0b101001101[3, -125].should == 0b101001 + end + end + + context "when range passed" do + it "returns bits specified by range" do + 0b101001101[2..5].should == 0b0011 + 0b101001101[2..6].should == 0b10011 + 0b101001101[2..8].should == 0b1010011 + end + + it "ensures n[i..j] equals to (n >> i) & ((1 << (j - i + 1)) - 1)" do + n = 0b101001101; i = 2; j = 5 + n[i..j].should == (n >> i) & ((1 << (j - i + 1)) - 1) + end + + it "ensures n[i..] equals to (n >> i)" do + eval("0b101001101[3..]").should == 0b101001101 >> 3 + end + + it "moves lower boundary to the most significant bits when negative value passed" do + 0b000001[-1, 4].should == 0b10 + 0b000001[-2, 4].should == 0b100 + 0b000001[-3, 4].should == 0b1000 + end + + it "ignores upper boundary smaller than lower boundary" do + 0b101001101[4..1].should == 0b10100 + 0b101001101[4..2].should == 0b10100 + 0b101001101[-4..-5].should == 0b1010011010000 + end + + it "raises FloatDomainError if any boundary is infinity" do + -> { 0x0001[3..Float::INFINITY] }.should raise_error(FloatDomainError, /Infinity/) + -> { 0x0001[-Float::INFINITY..3] }.should raise_error(FloatDomainError, /-Infinity/) + end + + context "when passed (..i)" do + it "returns 0 if all i bits equal 0" do + eval("0b10000[..1]").should == 0 + eval("0b10000[..2]").should == 0 + eval("0b10000[..3]").should == 0 + end + + it "raises ArgumentError if any of i bit equals 1" do + -> { + eval("0b111110[..3]") + }.should raise_error(ArgumentError, /The beginless range for Integer#\[\] results in infinity/) + end + end + end end context "bignum" do @@ -102,10 +179,10 @@ describe "Integer#[]" do 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) + -> { @bignum[obj] }.should raise_error(TypeError) obj.should_receive(:to_int).and_return("asdf") - lambda { @bignum[obj] }.should raise_error(TypeError) + -> { @bignum[obj] }.should raise_error(TypeError) end end end diff --git a/spec/ruby/core/integer/fdiv_spec.rb b/spec/ruby/core/integer/fdiv_spec.rb index b27e6f1389..d9ea2fdf8d 100644 --- a/spec/ruby/core/integer/fdiv_spec.rb +++ b/spec/ruby/core/integer/fdiv_spec.rb @@ -9,6 +9,57 @@ describe "Integer#fdiv" do 8.fdiv(bignum_value).should be_close(8.673617379884035e-19, TOLERANCE) end + it "performs floating-point division between self bignum and a bignum" do + num = 1000000000000000000000000000000000048148248609680896326399448564623182963452541226153892315137780403285956264146010000000000000000000000000000000000048148248609680896326399448564623182963452541226153892315137780403285956264146010000000000000000000000000000000000048148248609680896326399448564623182963452541226153892315137780403285956264146009 + den = 2000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 + num.fdiv(den).should == 500.0 + end + + it "rounds to the correct value for bignums" do + den = 9 * 10**342 + + num = 1 * 10**344 + num.fdiv(den).should == 11.11111111111111 + + num = 1 * 10**343 + num.fdiv(den).should == 1.1111111111111112 + + num = 1 * 10**342 + num.fdiv(den).should == 0.1111111111111111 + + num = 2 * 10**342 + num.fdiv(den).should == 0.2222222222222222 + + num = 3 * 10**342 + num.fdiv(den).should == 0.3333333333333333 + + num = 4 * 10**342 + num.fdiv(den).should == 0.4444444444444444 + + num = 5 * 10**342 + num.fdiv(den).should == 0.5555555555555556 + + num = 6 * 10**342 + num.fdiv(den).should == 0.6666666666666666 + + num = 7 * 10**342 + num.fdiv(den).should == 0.7777777777777778 + + num = 8 * 10**342 + num.fdiv(den).should == 0.8888888888888888 + + num = 9 * 10**342 + num.fdiv(den).should == 1.0 + + num = -5 * 10**342 + num.fdiv(den).should == -0.5555555555555556 + end + + it "rounds to the correct float for bignum denominators" do + 1.fdiv(10**324).should == 0.0 + 1.fdiv(10**323).should == 1.0e-323 + end + it "performs floating-point division between self and a Float" do 8.fdiv(9.0).should be_close(0.888888888888889, TOLERANCE) end @@ -35,11 +86,11 @@ describe "Integer#fdiv" do end it "raises a TypeError when argument isn't numeric" do - lambda { 1.fdiv(mock('non-numeric')) }.should raise_error(TypeError) + -> { 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) + -> { 1.fdiv(6,0.2) }.should raise_error(ArgumentError) end it "follows the coercion protocol" do diff --git a/spec/ruby/core/integer/floor_spec.rb b/spec/ruby/core/integer/floor_spec.rb index aaa816fdc5..8fb84d58cb 100644 --- a/spec/ruby/core/integer/floor_spec.rb +++ b/spec/ruby/core/integer/floor_spec.rb @@ -1,19 +1,13 @@ require_relative '../../spec_helper' require_relative 'shared/to_i' require_relative 'shared/integer_rounding' +require_relative 'shared/integer_floor_precision' describe "Integer#floor" do it_behaves_like :integer_to_i, :floor it_behaves_like :integer_rounding_positive_precision, :floor - context "precision argument specified as part of the floor method is negative" do - it "returns the largest integer less than self with at least precision.abs trailing zeros" do - 1832.floor(-1).should eql(1830) - 1832.floor(-2).should eql(1800) - 1832.floor(-3).should eql(1000) - -1832.floor(-1).should eql(-1840) - -1832.floor(-2).should eql(-1900) - -1832.floor(-3).should eql(-2000) - end + context "with precision" do + it_behaves_like :integer_floor_precision, :Integer end end diff --git a/spec/ruby/core/integer/gcd_spec.rb b/spec/ruby/core/integer/gcd_spec.rb index 238bf66cc0..961f1c5c2e 100644 --- a/spec/ruby/core/integer/gcd_spec.rb +++ b/spec/ruby/core/integer/gcd_spec.rb @@ -33,13 +33,13 @@ describe "Integer#gcd" do it "accepts a Bignum argument" do bignum = 9999**99 - bignum.should be_kind_of(Bignum) + bignum.should be_kind_of(Integer) 99.gcd(bignum).should == 99 end it "works if self is a Bignum" do bignum = 9999**99 - bignum.should be_kind_of(Bignum) + bignum.should be_kind_of(Integer) bignum.gcd(99).should == 99 end @@ -55,15 +55,15 @@ describe "Integer#gcd" do end it "raises an ArgumentError if not given an argument" do - lambda { 12.gcd }.should raise_error(ArgumentError) + -> { 12.gcd }.should raise_error(ArgumentError) end it "raises an ArgumentError if given more than one argument" do - lambda { 12.gcd(30, 20) }.should raise_error(ArgumentError) + -> { 12.gcd(30, 20) }.should raise_error(ArgumentError) end it "raises a TypeError unless the argument is an Integer" do - lambda { 39.gcd(3.8) }.should raise_error(TypeError) - lambda { 45872.gcd([]) }.should raise_error(TypeError) + -> { 39.gcd(3.8) }.should raise_error(TypeError) + -> { 45872.gcd([]) }.should raise_error(TypeError) end end diff --git a/spec/ruby/core/integer/gcdlcm_spec.rb b/spec/ruby/core/integer/gcdlcm_spec.rb index 362f8a51bd..ebf45e55a1 100644 --- a/spec/ruby/core/integer/gcdlcm_spec.rb +++ b/spec/ruby/core/integer/gcdlcm_spec.rb @@ -28,26 +28,26 @@ describe "Integer#gcdlcm" do it "accepts a Bignum argument" do bignum = 91999**99 - bignum.should be_kind_of(Bignum) + bignum.should be_kind_of(Integer) 99.gcdlcm(bignum).should == [99.gcd(bignum), 99.lcm(bignum)] end it "works if self is a Bignum" do bignum = 9999**89 - bignum.should be_kind_of(Bignum) + bignum.should be_kind_of(Integer) bignum.gcdlcm(99).should == [bignum.gcd(99), bignum.lcm(99)] end it "raises an ArgumentError if not given an argument" do - lambda { 12.gcdlcm }.should raise_error(ArgumentError) + -> { 12.gcdlcm }.should raise_error(ArgumentError) end it "raises an ArgumentError if given more than one argument" do - lambda { 12.gcdlcm(30, 20) }.should raise_error(ArgumentError) + -> { 12.gcdlcm(30, 20) }.should raise_error(ArgumentError) end it "raises a TypeError unless the argument is an Integer" do - lambda { 39.gcdlcm(3.8) }.should raise_error(TypeError) - lambda { 45872.gcdlcm([]) }.should raise_error(TypeError) + -> { 39.gcdlcm(3.8) }.should raise_error(TypeError) + -> { 45872.gcdlcm([]) }.should raise_error(TypeError) end end diff --git a/spec/ruby/core/integer/gt_spec.rb b/spec/ruby/core/integer/gt_spec.rb index 14c51c9acc..f0179e566d 100644 --- a/spec/ruby/core/integer/gt_spec.rb +++ b/spec/ruby/core/integer/gt_spec.rb @@ -2,13 +2,7 @@ require_relative '../../spec_helper' require_relative 'shared/comparison_coerce' describe "Integer#>" do - 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 + it_behaves_like :integer_comparison_coerce_not_rescue, :> context "fixnum" do it "returns true if self is greater than the given argument" do @@ -23,8 +17,8 @@ describe "Integer#>" do 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) + -> { 5 > "4" }.should raise_error(ArgumentError) + -> { 5 > mock('x') }.should raise_error(ArgumentError) end end @@ -42,8 +36,8 @@ describe "Integer#>" do 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) + -> { @bignum > "4" }.should raise_error(ArgumentError) + -> { @bignum > mock('str') }.should raise_error(ArgumentError) end end end diff --git a/spec/ruby/core/integer/gte_spec.rb b/spec/ruby/core/integer/gte_spec.rb index 3d5c48faa5..6237fc2c51 100644 --- a/spec/ruby/core/integer/gte_spec.rb +++ b/spec/ruby/core/integer/gte_spec.rb @@ -2,13 +2,7 @@ require_relative '../../spec_helper' require_relative 'shared/comparison_coerce' describe "Integer#>=" do - 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 + it_behaves_like :integer_comparison_coerce_not_rescue, :>= context "fixnum" do it "returns true if self is greater than or equal to the given argument" do @@ -24,8 +18,8 @@ describe "Integer#>=" do 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) + -> { 5 >= "4" }.should raise_error(ArgumentError) + -> { 5 >= mock('x') }.should raise_error(ArgumentError) end end @@ -42,8 +36,8 @@ describe "Integer#>=" do 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) + -> { @bignum >= "4" }.should raise_error(ArgumentError) + -> { @bignum >= mock('str') }.should raise_error(ArgumentError) end end end diff --git a/spec/ruby/core/integer/integer_spec.rb b/spec/ruby/core/integer/integer_spec.rb index f8067cda06..2d5d2e3e92 100644 --- a/spec/ruby/core/integer/integer_spec.rb +++ b/spec/ruby/core/integer/integer_spec.rb @@ -13,8 +13,8 @@ end describe "Integer#integer?" do it "returns true for Integers" do - 0.integer?.should == true - -1.integer?.should == true - bignum_value.integer?.should == true + 0.should.integer? + -1.should.integer? + bignum_value.should.integer? end end diff --git a/spec/ruby/core/integer/lcm_spec.rb b/spec/ruby/core/integer/lcm_spec.rb index 6d608bdf41..296a001c8c 100644 --- a/spec/ruby/core/integer/lcm_spec.rb +++ b/spec/ruby/core/integer/lcm_spec.rb @@ -33,26 +33,26 @@ describe "Integer#lcm" do it "accepts a Bignum argument" do bignum = 9999**99 - bignum.should be_kind_of(Bignum) + bignum.should be_kind_of(Integer) 99.lcm(bignum).should == bignum end it "works if self is a Bignum" do bignum = 9999**99 - bignum.should be_kind_of(Bignum) + bignum.should be_kind_of(Integer) bignum.lcm(99).should == bignum end it "raises an ArgumentError if not given an argument" do - lambda { 12.lcm }.should raise_error(ArgumentError) + -> { 12.lcm }.should raise_error(ArgumentError) end it "raises an ArgumentError if given more than one argument" do - lambda { 12.lcm(30, 20) }.should raise_error(ArgumentError) + -> { 12.lcm(30, 20) }.should raise_error(ArgumentError) end it "raises a TypeError unless the argument is an Integer" do - lambda { 39.lcm(3.8) }.should raise_error(TypeError) - lambda { 45872.lcm([]) }.should raise_error(TypeError) + -> { 39.lcm(3.8) }.should raise_error(TypeError) + -> { 45872.lcm([]) }.should raise_error(TypeError) end end diff --git a/spec/ruby/core/integer/left_shift_spec.rb b/spec/ruby/core/integer/left_shift_spec.rb index a240c541c5..86c2b18ae2 100644 --- a/spec/ruby/core/integer/left_shift_spec.rb +++ b/spec/ruby/core/integer/left_shift_spec.rb @@ -56,44 +56,47 @@ describe "Integer#<< (with n << m)" do (3 << -bignum_value).should == 0 end - it "returns an Bignum == fixnum_max * 2 when fixnum_max << 1 and n > 0" do + it "returns a 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 be_an_instance_of(Integer) result.should == fixnum_max * 2 end - it "returns an Bignum == fixnum_min * 2 when fixnum_min << 1 and n < 0" do + it "returns a 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 be_an_instance_of(Integer) 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 + + obj = mock("to_int_neg_bignum") + obj.should_receive(:to_int).and_return(-bignum_value) + (3 << obj).should == 0 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) + -> { 3 << obj }.should raise_error(TypeError) end it "raises a TypeError when passed nil" do - lambda { 3 << nil }.should raise_error(TypeError) + -> { 3 << nil }.should raise_error(TypeError) end it "raises a TypeError when passed a String" do - lambda { 3 << "4" }.should raise_error(TypeError) + -> { 3 << "4" }.should raise_error(TypeError) end end context "bignum" do before :each do - @bignum = bignum_value * 16 + @bignum = bignum_value * 8 # 2 ** 67 end it "returns n shifted left m bits when n > 0, m > 0" do @@ -124,19 +127,15 @@ describe "Integer#<< (with n << m)" 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 be_an_instance_of(Integer) 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 be_an_instance_of(Integer) result.should == fixnum_min end @@ -151,15 +150,62 @@ describe "Integer#<< (with n << m)" do obj = mock("a string") obj.should_receive(:to_int).and_return("asdf") - lambda { @bignum << obj }.should raise_error(TypeError) + -> { @bignum << obj }.should raise_error(TypeError) end it "raises a TypeError when passed nil" do - lambda { @bignum << nil }.should raise_error(TypeError) + -> { @bignum << nil }.should raise_error(TypeError) end it "raises a TypeError when passed a String" do - lambda { @bignum << "4" }.should raise_error(TypeError) + -> { @bignum << "4" }.should raise_error(TypeError) + end + end + + context "when m is a bignum or larger than int" do + it "returns -1 when m < 0 and n < 0" do + (-1 << -bignum_value).should == -1 + (-1 << -(2**40)).should == -1 + + (-bignum_value << -bignum_value).should == -1 + (-bignum_value << -(2**40)).should == -1 + end + + it "returns 0 when m < 0 and n >= 0" do + (0 << -bignum_value).should == 0 + (1 << -bignum_value).should == 0 + (bignum_value << -bignum_value).should == 0 + + (0 << -(2**40)).should == 0 + (1 << -(2**40)).should == 0 + (bignum_value << -(2**40)).should == 0 + end + + it "returns 0 when m > 0 long and n == 0" do + (0 << (2**40)).should == 0 + end + + it "returns 0 when m > 0 bignum and n == 0" do + (0 << bignum_value).should == 0 + end + + it "raises RangeError when m > 0 and n != 0" do + # https://bugs.ruby-lang.org/issues/18518#note-9 + limit = RUBY_ENGINE == 'ruby' ? 2**67 : 2**32 + + coerce_long = mock("long") + coerce_long.stub!(:to_int).and_return(limit) + coerce_bignum = mock("bignum") + coerce_bignum.stub!(:to_int).and_return(bignum_value) + exps = [limit, coerce_long] + exps << bignum_value << coerce_bignum if bignum_value >= limit + + exps.each { |exp| + -> { (1 << exp) }.should raise_error(RangeError, 'shift width too big') + -> { (-1 << exp) }.should raise_error(RangeError, 'shift width too big') + -> { (bignum_value << exp) }.should raise_error(RangeError, 'shift width too big') + -> { (-bignum_value << exp) }.should raise_error(RangeError, 'shift width too big') + } end end end diff --git a/spec/ruby/core/integer/lt_spec.rb b/spec/ruby/core/integer/lt_spec.rb index a33a297d8b..c182f82555 100644 --- a/spec/ruby/core/integer/lt_spec.rb +++ b/spec/ruby/core/integer/lt_spec.rb @@ -2,13 +2,7 @@ require_relative '../../spec_helper' require_relative 'shared/comparison_coerce' describe "Integer#<" do - 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 + it_behaves_like :integer_comparison_coerce_not_rescue, :< context "fixnum" do it "returns true if self is less than the given argument" do @@ -23,8 +17,8 @@ describe "Integer#<" do 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) + -> { 5 < "4" }.should raise_error(ArgumentError) + -> { 5 < mock('x') }.should raise_error(ArgumentError) end end @@ -44,8 +38,8 @@ describe "Integer#<" do 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) + -> { @bignum < "4" }.should raise_error(ArgumentError) + -> { @bignum < mock('str') }.should raise_error(ArgumentError) end end end diff --git a/spec/ruby/core/integer/lte_spec.rb b/spec/ruby/core/integer/lte_spec.rb index 1d3ecea2ac..65b71d77f2 100644 --- a/spec/ruby/core/integer/lte_spec.rb +++ b/spec/ruby/core/integer/lte_spec.rb @@ -2,13 +2,7 @@ require_relative '../../spec_helper' require_relative 'shared/comparison_coerce' describe "Integer#<=" do - 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 + it_behaves_like :integer_comparison_coerce_not_rescue, :<= context "fixnum" do it "returns true if self is less than or equal to other" do @@ -24,8 +18,8 @@ describe "Integer#<=" do 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) + -> { 5 <= "4" }.should raise_error(ArgumentError) + -> { 5 <= mock('x') }.should raise_error(ArgumentError) end end @@ -46,9 +40,14 @@ describe "Integer#<=" do (@bignum <= (@bignum + 0.5)).should == false end + it "returns true for bignums compare to a bigger float" do + (18446744073709551616 <= 1.8446744073709552e+19).should == true + (@bignum <= (@bignum + 9999.0)).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) + -> { @bignum <= "4" }.should raise_error(ArgumentError) + -> { @bignum <= mock('str') }.should raise_error(ArgumentError) end end end diff --git a/spec/ruby/core/integer/minus_spec.rb b/spec/ruby/core/integer/minus_spec.rb index 84db427172..6072ba7c8b 100644 --- a/spec/ruby/core/integer/minus_spec.rb +++ b/spec/ruby/core/integer/minus_spec.rb @@ -2,13 +2,7 @@ require_relative '../../spec_helper' require_relative 'shared/arithmetic_coerce' describe "Integer#-" do - 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 + it_behaves_like :integer_arithmetic_coerce_not_rescue, :- context "fixnum" do it "returns self minus the given Integer" do @@ -16,16 +10,16 @@ describe "Integer#-" do (9237212 - 5_280).should == 9231932 (781 - 0.5).should == 780.5 - (2_560_496 - bignum_value).should == -9223372036852215312 + (2_560_496 - bignum_value).should == -18446744073706991120 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) + -> { 13 - "10" }.should raise_error(TypeError) + -> { 13 - :symbol }.should raise_error(TypeError) end end @@ -35,15 +29,32 @@ describe "Integer#-" do end it "returns self minus the given Integer" do - (@bignum - 9).should == 9223372036854776113 - (@bignum - 12.57).should be_close(9223372036854776109.43, TOLERANCE) + (@bignum - 9).should == 18446744073709551921 + (@bignum - 12.57).should be_close(18446744073709551917.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) + -> { @bignum - mock('10') }.should raise_error(TypeError) + -> { @bignum - "10" }.should raise_error(TypeError) + -> { @bignum - :symbol }.should raise_error(TypeError) end end + + it "coerces the RHS and calls #coerce" do + obj = mock("integer plus") + obj.should_receive(:coerce).with(5).and_return([5, 10]) + (5 - obj).should == -5 + end + + it "coerces the RHS and calls #coerce even if it's private" do + obj = Object.new + class << obj + private def coerce(n) + [n, 10] + end + end + + (5 - obj).should == -5 + end end diff --git a/spec/ruby/core/integer/multiply_spec.rb b/spec/ruby/core/integer/multiply_spec.rb index 1683b0c96e..5037d27458 100644 --- a/spec/ruby/core/integer/multiply_spec.rb +++ b/spec/ruby/core/integer/multiply_spec.rb @@ -2,13 +2,7 @@ require_relative '../../spec_helper' require_relative 'shared/arithmetic_coerce' describe "Integer#*" do - 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 + it_behaves_like :integer_arithmetic_coerce_not_rescue, :* context "fixnum" do it "returns self multiplied by the given Integer" do @@ -16,17 +10,17 @@ describe "Integer#*" do (1342177 * 800).should == 1073741600 (65536 * 65536).should == 4294967296 - (256 * bignum_value).should == 2361183241434822606848 + (256 * bignum_value).should == 4722366482869645213696 (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) + -> { 13 * "10" }.should raise_error(TypeError) + -> { 13 * :symbol }.should raise_error(TypeError) end end @@ -38,14 +32,14 @@ describe "Integer#*" do 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 + (@bignum * 10).should == 184467440737095523880 + (@bignum * (@bignum - 40)).should == 340282366920938491207277694290934407024 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) + -> { @bignum * mock('10') }.should raise_error(TypeError) + -> { @bignum * "10" }.should raise_error(TypeError) + -> { @bignum * :symbol }.should raise_error(TypeError) end end end diff --git a/spec/ruby/core/integer/nobits_spec.rb b/spec/ruby/core/integer/nobits_spec.rb index da689de5df..685759ffa3 100644 --- a/spec/ruby/core/integer/nobits_spec.rb +++ b/spec/ruby/core/integer/nobits_spec.rb @@ -1,38 +1,36 @@ require_relative '../../spec_helper' -ruby_version_is '2.5' do - describe "Integer#nobits?" do - it "returns true iff all no bits of the argument are set in the receiver" do - 42.nobits?(42).should == false - 0b1010_1010.nobits?(0b1000_0010).should == false - 0b1010_1010.nobits?(0b1000_0001).should == false - 0b0100_0101.nobits?(0b1010_1010).should == true - different_bignum = (2 * bignum_value) & (~bignum_value) - (0b1010_1010 | different_bignum).nobits?(0b1000_0010 | bignum_value).should == false - (0b1010_1010 | different_bignum).nobits?(0b1000_0001 | bignum_value).should == false - (0b0100_0101 | different_bignum).nobits?(0b1010_1010 | bignum_value).should == true - end +describe "Integer#nobits?" do + it "returns true if and only if all no bits of the argument are set in the receiver" do + 42.nobits?(42).should == false + 0b1010_1010.nobits?(0b1000_0010).should == false + 0b1010_1010.nobits?(0b1000_0001).should == false + 0b0100_0101.nobits?(0b1010_1010).should == true + different_bignum = (2 * bignum_value) & (~bignum_value) + (0b1010_1010 | different_bignum).nobits?(0b1000_0010 | bignum_value).should == false + (0b1010_1010 | different_bignum).nobits?(0b1000_0001 | bignum_value).should == false + (0b0100_0101 | different_bignum).nobits?(0b1010_1010 | bignum_value).should == true + end - it "handles negative values using two's complement notation" do - (~0b1101).nobits?(0b1101).should == true - (-42).nobits?(-42).should == false - (~0b1101).nobits?(~0b10).should == false - (~(0b1101 | bignum_value)).nobits?(~(0b10 | bignum_value)).should == false - end + it "handles negative values using two's complement notation" do + (~0b1101).nobits?(0b1101).should == true + (-42).nobits?(-42).should == false + (~0b1101).nobits?(~0b10).should == false + (~(0b1101 | bignum_value)).nobits?(~(0b10 | bignum_value)).should == false + end - it "coerces the rhs using to_int" do - obj = mock("the int 0b10") - obj.should_receive(:to_int).and_return(0b10) - 0b110.nobits?(obj).should == false - end + it "coerces the rhs using to_int" do + obj = mock("the int 0b10") + obj.should_receive(:to_int).and_return(0b10) + 0b110.nobits?(obj).should == false + end - it "raises a TypeError when given a non-Integer" do - lambda { - (obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10]) - 13.nobits?(obj) - }.should raise_error(TypeError) - lambda { 13.nobits?("10") }.should raise_error(TypeError) - lambda { 13.nobits?(:symbol) }.should raise_error(TypeError) - end + it "raises a TypeError when given a non-Integer" do + -> { + (obj = mock('10')).should_receive(:coerce).any_number_of_times.and_return([42,10]) + 13.nobits?(obj) + }.should raise_error(TypeError) + -> { 13.nobits?("10") }.should raise_error(TypeError) + -> { 13.nobits?(:symbol) }.should raise_error(TypeError) end end diff --git a/spec/ruby/core/integer/plus_spec.rb b/spec/ruby/core/integer/plus_spec.rb index 2880840bc1..38428e56c5 100644 --- a/spec/ruby/core/integer/plus_spec.rb +++ b/spec/ruby/core/integer/plus_spec.rb @@ -2,30 +2,24 @@ require_relative '../../spec_helper' require_relative 'shared/arithmetic_coerce' describe "Integer#+" do - 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 + it_behaves_like :integer_arithmetic_coerce_not_rescue, :+ context "fixnum" do it "returns self plus the given Integer" do (491 + 2).should == 493 (90210 + 10).should == 90220 - (9 + bignum_value).should == 9223372036854775817 + (9 + bignum_value).should == 18446744073709551625 (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) + -> { 13 + "10" }.should raise_error(TypeError) + -> { 13 + :symbol }.should raise_error(TypeError) end end @@ -35,15 +29,47 @@ describe "Integer#+" do 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 + (@bignum + 4).should == 18446744073709551696 + (@bignum + 4.2).should be_close(18446744073709551696.2, TOLERANCE) + (@bignum + bignum_value(3)).should == 36893488147419103311 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) + -> { @bignum + mock('10') }.should raise_error(TypeError) + -> { @bignum + "10" }.should raise_error(TypeError) + -> { @bignum + :symbol}.should raise_error(TypeError) end end + + it "can be redefined" do + code = <<~RUBY + class Integer + alias_method :old_plus, :+ + def +(other) + self - other + end + end + result = 1 + 2 + Integer.alias_method :+, :old_plus + print result + RUBY + ruby_exe(code).should == "-1" + end + + it "coerces the RHS and calls #coerce" do + obj = mock("integer plus") + obj.should_receive(:coerce).with(6).and_return([6, 3]) + (6 + obj).should == 9 + end + + it "coerces the RHS and calls #coerce even if it's private" do + obj = Object.new + class << obj + private def coerce(n) + [n, 3] + end + end + + (6 + obj).should == 9 + end end diff --git a/spec/ruby/core/integer/pow_spec.rb b/spec/ruby/core/integer/pow_spec.rb index ed14c40a27..ecaca01eff 100644 --- a/spec/ruby/core/integer/pow_spec.rb +++ b/spec/ruby/core/integer/pow_spec.rb @@ -2,48 +2,50 @@ require_relative '../../spec_helper' require_relative 'fixtures/classes' require_relative 'shared/exponent' -ruby_version_is "2.5" do - describe "Integer#pow" do - context "one argument is passed" do - it_behaves_like :integer_exponent, :pow +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 + + 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 + + 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 - 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 - - 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 - - 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 + it "raises a RangeError when the first argument is negative and the second argument is present" do + -> { 2.pow(-5, 1) }.should raise_error(RangeError) end end end diff --git a/spec/ruby/core/integer/rationalize_spec.rb b/spec/ruby/core/integer/rationalize_spec.rb index 590ab40cb2..09d741af33 100644 --- a/spec/ruby/core/integer/rationalize_spec.rb +++ b/spec/ruby/core/integer/rationalize_spec.rb @@ -33,7 +33,7 @@ describe "Integer#rationalize" do end it "raises ArgumentError when passed more than one argument" do - lambda { 1.rationalize(0.1, 0.1) }.should raise_error(ArgumentError) - lambda { 1.rationalize(0.1, 0.1, 2) }.should raise_error(ArgumentError) + -> { 1.rationalize(0.1, 0.1) }.should raise_error(ArgumentError) + -> { 1.rationalize(0.1, 0.1, 2) }.should raise_error(ArgumentError) end end diff --git a/spec/ruby/core/integer/remainder_spec.rb b/spec/ruby/core/integer/remainder_spec.rb index 473c59a2f0..757e42fbe8 100644 --- a/spec/ruby/core/integer/remainder_spec.rb +++ b/spec/ruby/core/integer/remainder_spec.rb @@ -15,8 +15,8 @@ describe "Integer#remainder" do 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 -5.remainder( 3).should == -2 -5.remainder(-3).should == -2 end @@ -33,19 +33,19 @@ describe "Integer#remainder" 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(97.345).should be_close(93.1349992295444, 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) + -> { 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) + -> { a.remainder(0.0) }.should raise_error(ZeroDivisionError) + -> { b.remainder(-0.0) }.should raise_error(ZeroDivisionError) end end end diff --git a/spec/ruby/core/integer/right_shift_spec.rb b/spec/ruby/core/integer/right_shift_spec.rb index 641d4da662..c902674e2f 100644 --- a/spec/ruby/core/integer/right_shift_spec.rb +++ b/spec/ruby/core/integer/right_shift_spec.rb @@ -52,48 +52,47 @@ describe "Integer#>> (with n >> m)" do (-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 + it "returns a 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 be_an_instance_of(Integer) result.should == fixnum_max * 2 end - it "returns an Bignum == fixnum_min * 2 when fixnum_min >> -1 and n < 0" do + it "returns a 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 be_an_instance_of(Integer) 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 + + obj = mock("to_int_bignum") + obj.should_receive(:to_int).and_return(bignum_value) + (8 >> obj).should == 0 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) + -> { 3 >> obj }.should raise_error(TypeError) end it "raises a TypeError when passed nil" do - lambda { 3 >> nil }.should raise_error(TypeError) + -> { 3 >> nil }.should raise_error(TypeError) end it "raises a TypeError when passed a String" do - lambda { 3 >> "4" }.should raise_error(TypeError) + -> { 3 >> "4" }.should raise_error(TypeError) end end context "bignum" do before :each do - @bignum = bignum_value * 16 + @bignum = bignum_value * 8 # 2 ** 67 end it "returns n shifted right m bits when n > 0, m > 0" do @@ -150,19 +149,15 @@ describe "Integer#>> (with n >> m)" 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 be_an_instance_of(Integer) 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 be_an_instance_of(Integer) result.should == fixnum_min end @@ -177,15 +172,62 @@ describe "Integer#>> (with n >> m)" do obj = mock("a string") obj.should_receive(:to_int).and_return("asdf") - lambda { @bignum >> obj }.should raise_error(TypeError) + -> { @bignum >> obj }.should raise_error(TypeError) end it "raises a TypeError when passed nil" do - lambda { @bignum >> nil }.should raise_error(TypeError) + -> { @bignum >> nil }.should raise_error(TypeError) end it "raises a TypeError when passed a String" do - lambda { @bignum >> "4" }.should raise_error(TypeError) + -> { @bignum >> "4" }.should raise_error(TypeError) + end + end + + context "when m is a bignum or larger than int" do + it "returns -1 when m > 0 and n < 0" do + (-1 >> bignum_value).should == -1 + (-1 >> (2**40)).should == -1 + + (-bignum_value >> bignum_value).should == -1 + (-bignum_value >> (2**40)).should == -1 + end + + it "returns 0 when m > 0 and n >= 0" do + (0 >> bignum_value).should == 0 + (1 >> bignum_value).should == 0 + (bignum_value >> bignum_value).should == 0 + + (0 >> (2**40)).should == 0 + (1 >> (2**40)).should == 0 + (bignum_value >> (2**40)).should == 0 + end + + it "returns 0 when m < 0 long and n == 0" do + (0 >> -(2**40)).should == 0 + end + + it "returns 0 when m < 0 bignum and n == 0" do + (0 >> -bignum_value).should == 0 + end + + it "raises RangeError when m < 0 and n != 0" do + # https://bugs.ruby-lang.org/issues/18518#note-9 + limit = RUBY_ENGINE == 'ruby' ? 2**67 : 2**32 + + coerce_long = mock("long") + coerce_long.stub!(:to_int).and_return(-limit) + coerce_bignum = mock("bignum") + coerce_bignum.stub!(:to_int).and_return(-bignum_value) + exps = [-limit, coerce_long] + exps << -bignum_value << coerce_bignum if bignum_value >= limit + + exps.each { |exp| + -> { (1 >> exp) }.should raise_error(RangeError, 'shift width too big') + -> { (-1 >> exp) }.should raise_error(RangeError, 'shift width too big') + -> { (bignum_value >> exp) }.should raise_error(RangeError, 'shift width too big') + -> { (-bignum_value >> exp) }.should raise_error(RangeError, 'shift width too big') + } end end end diff --git a/spec/ruby/core/integer/round_spec.rb b/spec/ruby/core/integer/round_spec.rb index a45a7b5fb3..189384f11a 100644 --- a/spec/ruby/core/integer/round_spec.rb +++ b/spec/ruby/core/integer/round_spec.rb @@ -6,14 +6,6 @@ describe "Integer#round" do 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 - [2, -4, 10**70, -10**100].each do |v| - v.round(42).should eql(v.to_f) - end - end - end - # redmine:5228 it "returns itself rounded if passed a negative value" do +249.round(-2).should eql(+200) @@ -29,26 +21,24 @@ describe "Integer#round" do (-25 * 10**70).round(-71).should eql(-30 * 10**70) end - platform_is_not wordsize: 32 do - it "raises a RangeError when passed a big negative value" do - lambda { 42.round(fixnum_min) }.should raise_error(RangeError) - end + it "raises a RangeError when passed a big negative value" do + -> { 42.round(min_long - 1) }.should raise_error(RangeError) end it "raises a RangeError when passed Float::INFINITY" do - lambda { 42.round(Float::INFINITY) }.should raise_error(RangeError) + -> { 42.round(Float::INFINITY) }.should raise_error(RangeError) end it "raises a RangeError when passed a beyond signed int" do - lambda { 42.round(1<<31) }.should raise_error(RangeError) + -> { 42.round(1<<31) }.should raise_error(RangeError) end it "raises a TypeError when passed a String" do - lambda { 42.round("4") }.should raise_error(TypeError) + -> { 42.round("4") }.should raise_error(TypeError) end it "raises a TypeError when its argument cannot be converted to an Integer" do - lambda { 42.round(nil) }.should raise_error(TypeError) + -> { 42.round(nil) }.should raise_error(TypeError) end it "calls #to_int on the argument to convert it to an Integer" do @@ -60,7 +50,7 @@ describe "Integer#round" do it "raises a TypeError when #to_int does not return an Integer" do obj = mock("Object") obj.stub!(:to_int).and_return([]) - lambda { 42.round(obj) }.should raise_error(TypeError) + -> { 42.round(obj) }.should raise_error(TypeError) end it "returns different rounded values depending on the half option" do @@ -78,24 +68,14 @@ describe "Integer#round" do (-25).round(-1, half: nil).should eql(-30) end - ruby_version_is "2.4"..."2.5" do - it "returns itself as a float if passed a positive precision and the half option" do - 35.round(1, half: :up).should eql(35.0) - 35.round(1, half: :down).should eql(35.0) - 35.round(1, half: :even).should eql(35.0) - end - end - - ruby_version_is "2.5" do - it "returns itself if passed a positive precision and the half option" do - 35.round(1, half: :up).should eql(35) - 35.round(1, half: :down).should eql(35) - 35.round(1, half: :even).should eql(35) - end + it "returns itself if passed a positive precision and the half option" do + 35.round(1, half: :up).should eql(35) + 35.round(1, half: :down).should eql(35) + 35.round(1, half: :even).should eql(35) end it "raises ArgumentError for an unknown rounding mode" do - lambda { 42.round(-1, half: :foo) }.should raise_error(ArgumentError, /invalid rounding mode: foo/) - lambda { 42.round(1, half: :foo) }.should raise_error(ArgumentError, /invalid rounding mode: foo/) + -> { 42.round(-1, half: :foo) }.should raise_error(ArgumentError, /invalid rounding mode: foo/) + -> { 42.round(1, half: :foo) }.should raise_error(ArgumentError, /invalid rounding mode: foo/) end end diff --git a/spec/ruby/core/integer/shared/abs.rb b/spec/ruby/core/integer/shared/abs.rb index 946aa21864..43844c9065 100644 --- a/spec/ruby/core/integer/shared/abs.rb +++ b/spec/ruby/core/integer/shared/abs.rb @@ -11,8 +11,8 @@ describe :integer_abs, shared: true do context "bignum" do it "returns the absolute bignum value" do - bignum_value(39).send(@method).should == 9223372036854775847 - (-bignum_value(18)).send(@method).should == 9223372036854775826 + bignum_value(39).send(@method).should == 18446744073709551655 + (-bignum_value(18)).send(@method).should == 18446744073709551634 end end end diff --git a/spec/ruby/core/integer/shared/arithmetic_coerce.rb b/spec/ruby/core/integer/shared/arithmetic_coerce.rb index 4c0cbcb999..1260192df1 100644 --- a/spec/ruby/core/integer/shared/arithmetic_coerce.rb +++ b/spec/ruby/core/integer/shared/arithmetic_coerce.rb @@ -1,25 +1,5 @@ require_relative '../fixtures/classes' -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") diff --git a/spec/ruby/core/integer/shared/comparison_coerce.rb b/spec/ruby/core/integer/shared/comparison_coerce.rb index 50437f77f5..af52f5e99b 100644 --- a/spec/ruby/core/integer/shared/comparison_coerce.rb +++ b/spec/ruby/core/integer/shared/comparison_coerce.rb @@ -1,27 +1,5 @@ require_relative '../fixtures/classes' -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") diff --git a/spec/ruby/core/integer/shared/equal.rb b/spec/ruby/core/integer/shared/equal.rb index 03416b60f5..ecee17831c 100644 --- a/spec/ruby/core/integer/shared/equal.rb +++ b/spec/ruby/core/integer/shared/equal.rb @@ -4,14 +4,14 @@ describe :integer_equal, shared: true do 1.send(@method, 1).should == true 9.send(@method, 5).should == false - # Actually, these call Float#==, Bignum#== etc. + # Actually, these call Float#==, Integer#== 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 + it "calls 'other == self' if the given argument is not an Integer" do 1.send(@method, '*').should == false obj = mock('one other') diff --git a/spec/ruby/core/integer/shared/exponent.rb b/spec/ruby/core/integer/shared/exponent.rb index 810e2a7101..5ef6d686d8 100644 --- a/spec/ruby/core/integer/shared/exponent.rb +++ b/spec/ruby/core/integer/shared/exponent.rb @@ -30,11 +30,13 @@ describe :integer_exponent, shared: true do (-2).send(@method, 30).should eql(1073741824) (-2).send(@method, 31).should eql(-2147483648) (-2).send(@method, 32).should eql(4294967296) + (-2).send(@method, 33).should eql(-8589934592) (-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) + (-2).send(@method, 65).should eql(-36893488147419103232) end it "can raise 1 to a bignum safely" do @@ -46,8 +48,18 @@ describe :integer_exponent, shared: true do (-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 + ruby_version_is ""..."3.4" do + it "returns Float::INFINITY when the number is too big" do + -> { + 2.send(@method, 427387904).should == Float::INFINITY + }.should complain(/warning: in a\*\*b, b may be too big/) + end + end + + ruby_version_is "3.4" do + it "raises an ArgumentError when the number is too big" do + -> { 100000000.send(@method, 1000000000) }.should raise_error(ArgumentError) + end end it "raises a ZeroDivisionError for 0 ** -1" do @@ -94,25 +106,39 @@ describe :integer_exponent, shared: true do 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) + (@bignum.send(@method, 4)).should == 115792089237316196603666111261383895964500887398800252671052694326794607293761 + (@bignum.send(@method, 1.3)).should be_close(11109528802438156839288832.0, 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) + -> { @bignum.send(@method, mock('10')) }.should raise_error(TypeError) + -> { @bignum.send(@method, "10") }.should raise_error(TypeError) + -> { @bignum.send(@method, :symbol) }.should raise_error(TypeError) + end + + ruby_version_is ""..."3.4" do + it "switch to a Float when the values is too big" do + flt = nil + -> { + flt = @bignum.send(@method, @bignum) + }.should complain(/warning: in a\*\*b, b may be too big/) + flt.should be_kind_of(Float) + flt.infinite?.should == 1 + end 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 + ruby_version_is "3.4" do + it "does not switch to a Float when the values is too big" do + -> { + @bignum.send(@method, @bignum) + }.should raise_error(ArgumentError) + end 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) + (-bignum_value).send(@method, (1.0/2)).should be_close(Complex(0.0, 4294967296.0), TOLERANCE) + (-@bignum).send(@method, (1.0/3)) .should be_close(Complex(1321122.9748145656, 2288252.1154253655), TOLERANCE) + (-@bignum).send(@method, Rational(1,3)).should be_close(Complex(1321122.9748145656, 2288252.1154253655), TOLERANCE) end end end diff --git a/spec/ruby/core/integer/shared/integer_ceil_precision.rb b/spec/ruby/core/integer/shared/integer_ceil_precision.rb new file mode 100644 index 0000000000..9f31c2cf61 --- /dev/null +++ b/spec/ruby/core/integer/shared/integer_ceil_precision.rb @@ -0,0 +1,43 @@ +describe :integer_ceil_precision, shared: true do + context "precision is zero" do + it "returns integer self" do + send(@method, 0).ceil(0).should.eql?(0) + send(@method, 123).ceil(0).should.eql?(123) + send(@method, -123).ceil(0).should.eql?(-123) + end + end + + context "precision is positive" do + it "returns self" do + send(@method, 0).ceil(1).should.eql?(send(@method, 0)) + send(@method, 0).ceil(10).should.eql?(send(@method, 0)) + + send(@method, 123).ceil(10).should.eql?(send(@method, 123)) + send(@method, -123).ceil(10).should.eql?(send(@method, -123)) + end + end + + context "precision is negative" do + it "always returns 0 when self is 0" do + send(@method, 0).ceil(-1).should.eql?(0) + send(@method, 0).ceil(-10).should.eql?(0) + end + + it "returns largest integer less than self with at least precision.abs trailing zeros" do + send(@method, 123).ceil(-1).should.eql?(130) + send(@method, 123).ceil(-2).should.eql?(200) + send(@method, 123).ceil(-3).should.eql?(1000) + + send(@method, -123).ceil(-1).should.eql?(-120) + send(@method, -123).ceil(-2).should.eql?(-100) + send(@method, -123).ceil(-3).should.eql?(0) + end + + ruby_bug "#20654", ""..."3.4" do + it "returns 10**precision.abs when precision.abs is larger than the number digits of self" do + send(@method, 123).ceil(-20).should.eql?(100000000000000000000) + send(@method, 123).ceil(-50).should.eql?(100000000000000000000000000000000000000000000000000) + end + end + end +end diff --git a/spec/ruby/core/integer/shared/integer_floor_precision.rb b/spec/ruby/core/integer/shared/integer_floor_precision.rb new file mode 100644 index 0000000000..4c5888c6c4 --- /dev/null +++ b/spec/ruby/core/integer/shared/integer_floor_precision.rb @@ -0,0 +1,43 @@ +describe :integer_floor_precision, shared: true do + context "precision is zero" do + it "returns integer self" do + send(@method, 0).floor(0).should.eql?(0) + send(@method, 123).floor(0).should.eql?(123) + send(@method, -123).floor(0).should.eql?(-123) + end + end + + context "precision is positive" do + it "returns self" do + send(@method, 0).floor(1).should.eql?(send(@method, 0)) + send(@method, 0).floor(10).should.eql?(send(@method, 0)) + + send(@method, 123).floor(10).should.eql?(send(@method, 123)) + send(@method, -123).floor(10).should.eql?(send(@method, -123)) + end + end + + context "precision is negative" do + it "always returns 0 when self is 0" do + send(@method, 0).floor(-1).should.eql?(0) + send(@method, 0).floor(-10).should.eql?(0) + end + + it "returns largest integer less than self with at least precision.abs trailing zeros" do + send(@method, 123).floor(-1).should.eql?(120) + send(@method, 123).floor(-2).should.eql?(100) + send(@method, 123).floor(-3).should.eql?(0) + + send(@method, -123).floor(-1).should.eql?(-130) + send(@method, -123).floor(-2).should.eql?(-200) + send(@method, -123).floor(-3).should.eql?(-1000) + end + + ruby_bug "#20654", ""..."3.4" do + it "returns -(10**precision.abs) when self is negative and precision.abs is larger than the number digits of self" do + send(@method, -123).floor(-20).should.eql?(-100000000000000000000) + send(@method, -123).floor(-50).should.eql?(-100000000000000000000000000000000000000000000000000) + end + end + end +end diff --git a/spec/ruby/core/integer/shared/integer_rounding.rb b/spec/ruby/core/integer/shared/integer_rounding.rb index 3fb6e830ef..56d1819f84 100644 --- a/spec/ruby/core/integer/shared/integer_rounding.rb +++ b/spec/ruby/core/integer/shared/integer_rounding.rb @@ -11,19 +11,9 @@ describe :integer_rounding_positive_precision, shared: true do end end - ruby_version_is "2.4"..."2.5" do - it "returns itself as a float if passed a positive precision" do - [2, -4, 10**70, -10**100].each do |v| - v.send(@method, 42).should eql(v.to_f) - end - end - end - - ruby_version_is "2.5" do - it "returns itself if passed a positive precision" do - [2, -4, 10**70, -10**100].each do |v| - v.send(@method, 42).should eql(v) - end + it "returns itself if passed a positive precision" do + [2, -4, 10**70, -10**100].each do |v| + v.send(@method, 42).should eql(v) end end end diff --git a/spec/ruby/core/integer/shared/modulo.rb b/spec/ruby/core/integer/shared/modulo.rb index d545a9af55..d91af1e924 100644 --- a/spec/ruby/core/integer/shared/modulo.rb +++ b/spec/ruby/core/integer/shared/modulo.rb @@ -1,6 +1,12 @@ describe :integer_modulo, shared: true do context "fixnum" do it "returns the modulus obtained from dividing self by the given argument" do + # test all possible combinations: + # - integer/double/bignum argument + # - positive/negative argument + # - positive/negative self + # - self greater/smaller than argument + 13.send(@method, 4).should == 1 4.send(@method, 13).should == 4 @@ -16,59 +22,93 @@ describe :integer_modulo, shared: true do (200).send(@method, -256).should == -56 (1000).send(@method, -512).should == -24 + 13.send(@method, -4.0).should == -3.0 + 4.send(@method, -13.0).should == -9.0 + + -13.send(@method, -4.0).should == -1.0 + -4.send(@method, -13.0).should == -4.0 + + -13.send(@method, 4.0).should == 3.0 + -4.send(@method, 13.0).should == 9.0 + 1.send(@method, 2.0).should == 1.0 200.send(@method, bignum_value).should == 200 + + 4.send(@method, bignum_value(10)).should == 4 + 4.send(@method, -bignum_value(10)).should == -18446744073709551622 + -4.send(@method, bignum_value(10)).should == 18446744073709551622 + -4.send(@method, -bignum_value(10)).should == -4 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) + -> { 13.send(@method, 0) }.should raise_error(ZeroDivisionError) + -> { 0.send(@method, 0) }.should raise_error(ZeroDivisionError) + -> { -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) + -> { 0.send(@method, 0.0) }.should raise_error(ZeroDivisionError) + -> { 10.send(@method, 0.0) }.should raise_error(ZeroDivisionError) + -> { -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) + -> { 13.send(@method, "10") }.should raise_error(TypeError) + -> { 13.send(@method, :symbol) }.should raise_error(TypeError) end end context "bignum" do before :each do - @bignum = bignum_value + @bignum = bignum_value(10) 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 + # test all possible combinations: + # - integer/double/bignum argument + # - positive/negative argument + # - positive/negative self + # - self greater/smaller than argument + + @bignum.send(@method, 5).should == 1 + @bignum.send(@method, -5).should == -4 + (-@bignum).send(@method, 5).should == 4 + (-@bignum).send(@method, -5).should == -1 + + @bignum.send(@method, 2.22).should be_close(1.5603603603605034, TOLERANCE) + @bignum.send(@method, -2.22).should be_close(-0.6596396396394968, TOLERANCE) + (-@bignum).send(@method, 2.22).should be_close(0.6596396396394968, TOLERANCE) + (-@bignum).send(@method, -2.22).should be_close(-1.5603603603605034, TOLERANCE) + + @bignum.send(@method, @bignum + 10).should == 18446744073709551626 + @bignum.send(@method, -(@bignum + 10)).should == -10 + (-@bignum).send(@method, @bignum + 10).should == 10 + (-@bignum).send(@method, -(@bignum + 10)).should == -18446744073709551626 + + (@bignum + 10).send(@method, @bignum).should == 10 + (@bignum + 10).send(@method, -@bignum).should == -18446744073709551616 + (-(@bignum + 10)).send(@method, @bignum).should == 18446744073709551616 + (-(@bignum + 10)).send(@method, -@bignum).should == -10 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) + -> { @bignum.send(@method, 0) }.should raise_error(ZeroDivisionError) + -> { (-@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) + -> { @bignum.send(@method, 0.0) }.should raise_error(ZeroDivisionError) + -> { -@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) + -> { @bignum.send(@method, mock('10')) }.should raise_error(TypeError) + -> { @bignum.send(@method, "10") }.should raise_error(TypeError) + -> { @bignum.send(@method, :symbol) }.should raise_error(TypeError) end end end diff --git a/spec/ruby/core/integer/size_spec.rb b/spec/ruby/core/integer/size_spec.rb index a134e82384..725e9eb062 100644 --- a/spec/ruby/core/integer/size_spec.rb +++ b/spec/ruby/core/integer/size_spec.rb @@ -1,7 +1,7 @@ require_relative '../../spec_helper' describe "Integer#size" do - platform_is wordsize: 32 do + platform_is c_long_size: 32 do it "returns the number of bytes in the machine representation of self" do -1.size.should == 4 0.size.should == 4 @@ -9,7 +9,7 @@ describe "Integer#size" do end end - platform_is wordsize: 64 do + platform_is c_long_size: 64 do it "returns the number of bytes in the machine representation of self" do -1.size.should == 8 0.size.should == 8 diff --git a/spec/ruby/core/integer/sqrt_spec.rb b/spec/ruby/core/integer/sqrt_spec.rb index e40bd12b19..4149ca2cc9 100644 --- a/spec/ruby/core/integer/sqrt_spec.rb +++ b/spec/ruby/core/integer/sqrt_spec.rb @@ -1,33 +1,31 @@ require_relative '../../spec_helper' -ruby_version_is "2.5" do - describe "Integer.sqrt" do - it "returns an integer" do - Integer.sqrt(10).should be_kind_of(Integer) - end +describe "Integer.sqrt" do + it "returns an integer" do + Integer.sqrt(10).should be_kind_of(Integer) + end - it "returns the integer square root of the argument" do - Integer.sqrt(0).should == 0 - Integer.sqrt(1).should == 1 - Integer.sqrt(24).should == 4 - Integer.sqrt(25).should == 5 - Integer.sqrt(10**400).should == 10**200 - end + it "returns the integer square root of the argument" do + Integer.sqrt(0).should == 0 + Integer.sqrt(1).should == 1 + Integer.sqrt(24).should == 4 + Integer.sqrt(25).should == 5 + Integer.sqrt(10**400).should == 10**200 + end - it "raises a Math::DomainError if the argument is negative" do - lambda { Integer.sqrt(-4) }.should raise_error(Math::DomainError) - end + it "raises a Math::DomainError if the argument is negative" do + -> { Integer.sqrt(-4) }.should raise_error(Math::DomainError) + end - it "accepts any argument that can be coerced to Integer" do - Integer.sqrt(10.0).should == 3 - end + it "accepts any argument that can be coerced to Integer" do + Integer.sqrt(10.0).should == 3 + end - it "converts the argument with #to_int" do - Integer.sqrt(mock_int(10)).should == 3 - end + it "converts the argument with #to_int" do + Integer.sqrt(mock_int(10)).should == 3 + end - it "raises a TypeError if the argument cannot be coerced to Integer" do - lambda { Integer.sqrt("test") }.should raise_error(TypeError) - end + it "raises a TypeError if the argument cannot be coerced to Integer" do + -> { Integer.sqrt("test") }.should raise_error(TypeError) end end diff --git a/spec/ruby/core/integer/to_f_spec.rb b/spec/ruby/core/integer/to_f_spec.rb index 06092eaa92..9f1df9ada9 100644 --- a/spec/ruby/core/integer/to_f_spec.rb +++ b/spec/ruby/core/integer/to_f_spec.rb @@ -11,9 +11,9 @@ describe "Integer#to_f" do 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) + bignum_value(0x4000_0aa0_0bb0_0000).to_f.should eql(23_058_441_774_644_068_352.0) + bignum_value(0x8000_0000_0000_0ccc).to_f.should eql(27_670_116_110_564_330_700.0) + (-bignum_value(99)).to_f.should eql(-18_446_744_073_709_551_715.0) end it "converts number close to Float::MAX without exceeding MAX or producing NaN" do diff --git a/spec/ruby/core/integer/to_r_spec.rb b/spec/ruby/core/integer/to_r_spec.rb index dbb12166f1..7732bedca1 100644 --- a/spec/ruby/core/integer/to_r_spec.rb +++ b/spec/ruby/core/integer/to_r_spec.rb @@ -15,12 +15,12 @@ describe "Integer#to_r" do it "works even if self is a Bignum" do bignum = 99999**999 - bignum.should be_an_instance_of(Bignum) + bignum.should be_an_instance_of(Integer) bignum.to_r.should == Rational(bignum, 1) end it "raises an ArgumentError if given any arguments" do - lambda { 287.to_r(2) }.should raise_error(ArgumentError) - lambda { 9102826.to_r(309, [], 71) }.should raise_error(ArgumentError) + -> { 287.to_r(2) }.should raise_error(ArgumentError) + -> { 9102826.to_r(309, [], 71) }.should raise_error(ArgumentError) end end diff --git a/spec/ruby/core/integer/to_s_spec.rb b/spec/ruby/core/integer/to_s_spec.rb index 687dc9d18f..ca08dad95c 100644 --- a/spec/ruby/core/integer/to_s_spec.rb +++ b/spec/ruby/core/integer/to_s_spec.rb @@ -13,10 +13,10 @@ describe "Integer#to_s" do 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) + -> { 123.to_s(-1) }.should raise_error(ArgumentError) + -> { 123.to_s(0) }.should raise_error(ArgumentError) + -> { 123.to_s(1) }.should raise_error(ArgumentError) + -> { 123.to_s(37) }.should raise_error(ArgumentError) end end @@ -59,18 +59,18 @@ describe "Integer#to_s" do 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) + -> { 123.to_s(-1) }.should raise_error(ArgumentError) + -> { 123.to_s(0) }.should raise_error(ArgumentError) + -> { 123.to_s(1) }.should raise_error(ArgumentError) + -> { 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" + bignum_value(9).to_s.should == "18446744073709551625" + bignum_value.to_s.should == "18446744073709551616" + (-bignum_value(675)).to_s.should == "-18446744073709552291" end end diff --git a/spec/ruby/core/integer/try_convert_spec.rb b/spec/ruby/core/integer/try_convert_spec.rb new file mode 100644 index 0000000000..8a0ca671a9 --- /dev/null +++ b/spec/ruby/core/integer/try_convert_spec.rb @@ -0,0 +1,48 @@ +require_relative '../../spec_helper' +require_relative 'fixtures/classes' + +describe "Integer.try_convert" do + it "returns the argument if it's an Integer" do + x = 42 + Integer.try_convert(x).should equal(x) + end + + it "returns nil when the argument does not respond to #to_int" do + Integer.try_convert(Object.new).should be_nil + end + + it "sends #to_int to the argument and returns the result if it's nil" do + obj = mock("to_int") + obj.should_receive(:to_int).and_return(nil) + Integer.try_convert(obj).should be_nil + end + + it "sends #to_int to the argument and returns the result if it's an Integer" do + x = 234 + obj = mock("to_int") + obj.should_receive(:to_int).and_return(x) + Integer.try_convert(obj).should equal(x) + end + + it "sends #to_int to the argument and raises TypeError if it's not a kind of Integer" do + obj = mock("to_int") + obj.should_receive(:to_int).and_return(Object.new) + -> { + Integer.try_convert obj + }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives Object)") + end + + it "responds with a different error message when it raises a TypeError, depending on the type of the non-Integer object :to_int returns" do + obj = mock("to_int") + obj.should_receive(:to_int).and_return("A String") + -> { + Integer.try_convert obj + }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives String)") + end + + it "does not rescue exceptions raised by #to_int" do + obj = mock("to_int") + obj.should_receive(:to_int).and_raise(RuntimeError) + -> { Integer.try_convert obj }.should raise_error(RuntimeError) + end +end diff --git a/spec/ruby/core/integer/uminus_spec.rb b/spec/ruby/core/integer/uminus_spec.rb index b6b110dec4..7a9cfe89bf 100644 --- a/spec/ruby/core/integer/uminus_spec.rb +++ b/spec/ruby/core/integer/uminus_spec.rb @@ -20,11 +20,11 @@ describe "Integer#-@" do context "bignum" do it "returns self as a negative value" do - bignum_value.send(:-@).should == -9223372036854775808 - (-bignum_value).send(:-@).should == 9223372036854775808 + bignum_value.send(:-@).should == -18446744073709551616 + (-bignum_value).send(:-@).should == 18446744073709551616 - bignum_value(921).send(:-@).should == -9223372036854776729 - (-bignum_value(921).send(:-@)).should == 9223372036854776729 + bignum_value(921).send(:-@).should == -18446744073709552537 + (-bignum_value(921).send(:-@)).should == 18446744073709552537 end end end diff --git a/spec/ruby/core/integer/upto_spec.rb b/spec/ruby/core/integer/upto_spec.rb index 7cab834ad4..dd6995e94b 100644 --- a/spec/ruby/core/integer/upto_spec.rb +++ b/spec/ruby/core/integer/upto_spec.rb @@ -1,6 +1,6 @@ require_relative '../../spec_helper' -describe "Integer#upto [stop] when self and stop are Fixnums" do +describe "Integer#upto [stop] when self and stop are Integers" do it "does not yield when stop is less than self" do result = [] 5.upto(4) { |x| result << x } @@ -27,8 +27,8 @@ describe "Integer#upto [stop] when self and stop are Fixnums" do end it "raises an ArgumentError for non-numeric endpoints" do - lambda { 1.upto("A") {|x| p x} }.should raise_error(ArgumentError) - lambda { 1.upto(nil) {|x| p x} }.should raise_error(ArgumentError) + -> { 1.upto("A") {|x| p x} }.should raise_error(ArgumentError) + -> { 1.upto(nil) {|x| p x} }.should raise_error(ArgumentError) end describe "when no block is given" do @@ -45,9 +45,9 @@ describe "Integer#upto [stop] when self and stop are Fixnums" do describe "size" do it "raises an ArgumentError for non-numeric endpoints" do enum = 1.upto("A") - lambda { enum.size }.should raise_error(ArgumentError) + -> { enum.size }.should raise_error(ArgumentError) enum = 1.upto(nil) - lambda { enum.size }.should raise_error(ArgumentError) + -> { enum.size }.should raise_error(ArgumentError) end it "returns stop - self + 1" do diff --git a/spec/ruby/core/integer/zero_spec.rb b/spec/ruby/core/integer/zero_spec.rb new file mode 100644 index 0000000000..bd362c4181 --- /dev/null +++ b/spec/ruby/core/integer/zero_spec.rb @@ -0,0 +1,13 @@ +require_relative '../../spec_helper' + +describe "Integer#zero?" do + it "returns true if self is 0" do + 0.should.zero? + 1.should_not.zero? + -1.should_not.zero? + end + + it "Integer#zero? overrides Numeric#zero?" do + 42.method(:zero?).owner.should == Integer + end +end |
