diff options
author | Benoit Daloze <[email protected]> | 2022-01-28 14:42:38 +0100 |
---|---|---|
committer | Benoit Daloze <[email protected]> | 2022-01-28 14:42:38 +0100 |
commit | e0c5488ff9308b1a16718c64bc9096caca88ed83 (patch) | |
tree | b0ede98f96c4477c470bef45547abff525215b21 /spec/ruby/core | |
parent | bb5f71088774b14c96fe11718e5e1b7ffb20fff2 (diff) |
Update to ruby/spec@902ab83
Diffstat (limited to 'spec/ruby/core')
41 files changed, 377 insertions, 101 deletions
diff --git a/spec/ruby/core/dir/fixtures/common.rb b/spec/ruby/core/dir/fixtures/common.rb index c32b056819..637fe93e2f 100644 --- a/spec/ruby/core/dir/fixtures/common.rb +++ b/spec/ruby/core/dir/fixtures/common.rb @@ -94,6 +94,7 @@ module DirSpecs special/こんにちは.txt special/\a ] + @mock_dir_files << "special/_\u{1f60e}.erb" end end diff --git a/spec/ruby/core/dir/read_spec.rb b/spec/ruby/core/dir/read_spec.rb index 59de2e81cf..2953aad72f 100644 --- a/spec/ruby/core/dir/read_spec.rb +++ b/spec/ruby/core/dir/read_spec.rb @@ -39,5 +39,38 @@ describe "Dir#read" do entries.sort.should == DirSpecs.expected_paths end + platform_is_not :windows do + it "returns all directory entries even when encoding conversion will fail" do + dir = Dir.open(File.join(DirSpecs.mock_dir, 'special')) + utf8_entries = [] + begin + while entry = dir.read + utf8_entries << entry + end + ensure + dir.close + end + old_internal_encoding = Encoding::default_internal + old_external_encoding = Encoding::default_external + Encoding.default_internal = Encoding::UTF_8 + Encoding.default_external = Encoding::SHIFT_JIS + dir = Dir.open(File.join(DirSpecs.mock_dir, 'special')) + shift_jis_entries = [] + begin + -> { + while entry = dir.read + shift_jis_entries << entry + end + }.should_not raise_error + ensure + dir.close + Encoding.default_internal = old_internal_encoding + Encoding.default_external = old_external_encoding + end + shift_jis_entries.size.should == utf8_entries.size + shift_jis_entries.filter { |f| f.encoding == Encoding::SHIFT_JIS }.size.should == 1 + end + end + it_behaves_like :dir_closed, :read end diff --git a/spec/ruby/core/enumerable/all_spec.rb b/spec/ruby/core/enumerable/all_spec.rb index b782f94a3e..0ded1e8eba 100644 --- a/spec/ruby/core/enumerable/all_spec.rb +++ b/spec/ruby/core/enumerable/all_spec.rb @@ -131,7 +131,6 @@ describe "Enumerable#all?" do pattern.yielded.should == [[0], [1], [2], [-1]] end - # may raise an exception in future versions it "always returns true on empty enumeration" do @empty.all?(Integer).should == true [].all?(Integer).should == true diff --git a/spec/ruby/core/enumerable/any_spec.rb b/spec/ruby/core/enumerable/any_spec.rb index 636b1fa450..355cd0c290 100644 --- a/spec/ruby/core/enumerable/any_spec.rb +++ b/spec/ruby/core/enumerable/any_spec.rb @@ -145,7 +145,6 @@ describe "Enumerable#any?" do pattern.yielded.should == [[0], [1], [2]] end - # may raise an exception in future versions it "always returns false on empty enumeration" do @empty.any?(Integer).should == false [].any?(Integer).should == false diff --git a/spec/ruby/core/enumerable/none_spec.rb b/spec/ruby/core/enumerable/none_spec.rb index b898d00063..99bb7f7a4e 100644 --- a/spec/ruby/core/enumerable/none_spec.rb +++ b/spec/ruby/core/enumerable/none_spec.rb @@ -100,7 +100,6 @@ describe "Enumerable#none?" do pattern.yielded.should == [[0], [1], [2], [-1]] end - # may raise an exception in future versions it "always returns true on empty enumeration" do @empty.none?(Integer).should == true [].none?(Integer).should == true diff --git a/spec/ruby/core/enumerable/one_spec.rb b/spec/ruby/core/enumerable/one_spec.rb index d54dd4a527..47bfd65a0f 100644 --- a/spec/ruby/core/enumerable/one_spec.rb +++ b/spec/ruby/core/enumerable/one_spec.rb @@ -91,7 +91,6 @@ describe "Enumerable#one?" do pattern.yielded.should == [[0], [1], [2], [-1]] end - # may raise an exception in future versions it "always returns false on empty enumeration" do @empty.one?(Integer).should == false [].one?(Integer).should == false diff --git a/spec/ruby/core/float/coerce_spec.rb b/spec/ruby/core/float/coerce_spec.rb index ea108f3303..baa831dcf6 100644 --- a/spec/ruby/core/float/coerce_spec.rb +++ b/spec/ruby/core/float/coerce_spec.rb @@ -9,10 +9,10 @@ describe "Float#coerce" do 1.0.coerce(3.14).should == [3.14, 1.0] a, b = -0.0.coerce(bignum_value) - a.should be_close(9223372036854775808.0, TOLERANCE) + a.should be_close(18446744073709551616.0, TOLERANCE) b.should be_close(-0.0, TOLERANCE) a, b = 1.0.coerce(bignum_value) - a.should be_close(9223372036854775808.0, TOLERANCE) + a.should be_close(18446744073709551616.0, TOLERANCE) b.should be_close(1.0, TOLERANCE) end end diff --git a/spec/ruby/core/float/divmod_spec.rb b/spec/ruby/core/float/divmod_spec.rb index ec55dd3681..523217ac1f 100644 --- a/spec/ruby/core/float/divmod_spec.rb +++ b/spec/ruby/core/float/divmod_spec.rb @@ -10,7 +10,7 @@ describe "Float#divmod" do values[1].should be_close(2.8284, TOLERANCE) values = -1.0.divmod(bignum_value) values[0].should eql(-1) - values[1].should be_close(9223372036854775808.000, TOLERANCE) + values[1].should be_close(18446744073709551616.0, TOLERANCE) values = -1.0.divmod(1) values[0].should eql(-1) values[1].should eql(0.0) diff --git a/spec/ruby/core/float/minus_spec.rb b/spec/ruby/core/float/minus_spec.rb index 5626cbdac2..a4281a397b 100644 --- a/spec/ruby/core/float/minus_spec.rb +++ b/spec/ruby/core/float/minus_spec.rb @@ -6,7 +6,7 @@ describe "Float#-" do it "returns self minus other" do (9_237_212.5280 - 5_280).should be_close(9231932.528, TOLERANCE) - (2_560_496.1691 - bignum_value).should be_close(-9223372036852215808.000, TOLERANCE) + (2_560_496.1691 - bignum_value).should be_close(-18446744073706991616.0, TOLERANCE) (5.5 - 5.5).should be_close(0.0,TOLERANCE) end end diff --git a/spec/ruby/core/float/multiply_spec.rb b/spec/ruby/core/float/multiply_spec.rb index eca0b52c4f..2adb8796cd 100644 --- a/spec/ruby/core/float/multiply_spec.rb +++ b/spec/ruby/core/float/multiply_spec.rb @@ -7,7 +7,7 @@ describe "Float#*" do it "returns self multiplied by other" do (4923.98221 * 2).should be_close(9847.96442, TOLERANCE) (6712.5 * 0.25).should be_close(1678.125, TOLERANCE) - (256.4096 * bignum_value).should be_close(2364961134621118431232.000, TOLERANCE) + (256.4096 * bignum_value).should be_close(4729922269242236862464.0, TOLERANCE) end it "raises a TypeError when given a non-Numeric" do diff --git a/spec/ruby/core/float/plus_spec.rb b/spec/ruby/core/float/plus_spec.rb index 06b136a06b..e3e19d7f39 100644 --- a/spec/ruby/core/float/plus_spec.rb +++ b/spec/ruby/core/float/plus_spec.rb @@ -6,7 +6,7 @@ describe "Float#+" do it "returns self plus other" do (491.213 + 2).should be_close(493.213, TOLERANCE) - (9.99 + bignum_value).should be_close(9223372036854775808.000, TOLERANCE) + (9.99 + bignum_value).should be_close(18446744073709551616.0, TOLERANCE) (1001.99 + 5.219).should be_close(1007.209, TOLERANCE) end end diff --git a/spec/ruby/core/hash/transform_keys_spec.rb b/spec/ruby/core/hash/transform_keys_spec.rb index 1e82ff6547..361089ca97 100644 --- a/spec/ruby/core/hash/transform_keys_spec.rb +++ b/spec/ruby/core/hash/transform_keys_spec.rb @@ -73,7 +73,6 @@ describe "Hash#transform_keys!" do @hash.should == { 'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4 } end - # https://bugs.ruby-lang.org/issues/14380 it "prevents conflicts between new keys and old ones" do @hash.transform_keys!(&:succ) @hash.should == { b: 1, c: 2, d: 3, e: 4 } diff --git a/spec/ruby/core/integer/bit_and_spec.rb b/spec/ruby/core/integer/bit_and_spec.rb index 15a8026855..8de5a14aaa 100644 --- a/spec/ruby/core/integer/bit_and_spec.rb +++ b/spec/ruby/core/integer/bit_and_spec.rb @@ -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 diff --git a/spec/ruby/core/integer/bit_or_spec.rb b/spec/ruby/core/integer/bit_or_spec.rb index e486eeec10..6f4279c170 100644 --- a/spec/ruby/core/integer/bit_or_spec.rb +++ b/spec/ruby/core/integer/bit_or_spec.rb @@ -7,13 +7,34 @@ 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 and") + obj.should_receive(:coerce).with(6).and_return([3, 6]) + (6 & obj).should == 2 + end + it "raises a TypeError when passed a Float" do -> { (3 | 3.4) }.should raise_error(TypeError) end @@ -32,20 +53,20 @@ 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 diff --git a/spec/ruby/core/integer/bit_xor_spec.rb b/spec/ruby/core/integer/bit_xor_spec.rb index ac8826a52f..f1150a20d5 100644 --- a/spec/ruby/core/integer/bit_xor_spec.rb +++ b/spec/ruby/core/integer/bit_xor_spec.rb @@ -5,13 +5,34 @@ 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 and") + obj.should_receive(:coerce).with(6).and_return([3, 6]) + (6 ^ obj).should == 5 + end + it "raises a TypeError when passed a Float" do -> { (3 ^ 3.4) }.should raise_error(TypeError) 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 diff --git a/spec/ruby/core/integer/chr_spec.rb b/spec/ruby/core/integer/chr_spec.rb index 9f105e4241..a919d29f12 100644 --- a/spec/ruby/core/integer/chr_spec.rb +++ b/spec/ruby/core/integer/chr_spec.rb @@ -11,7 +11,11 @@ describe "Integer#chr without argument" do it "raises a RangeError is self is less than 0" do -> { -1.chr }.should raise_error(RangeError) - -> { -bignum_value.chr }.should raise_error(RangeError) + -> { (-bignum_value).chr }.should raise_error(RangeError) + end + + it "raises a RangeError if self is too large" do + -> { 2206368128.chr(Encoding::UTF_8) }.should raise_error(RangeError) end describe "when Encoding.default_internal is nil" do @@ -162,7 +166,7 @@ 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 -> { -1.chr(Encoding::UTF_8) }.should raise_error(RangeError) - -> { -bignum_value.chr(Encoding::EUC_JP) }.should raise_error(RangeError) + -> { (-bignum_value).chr(Encoding::EUC_JP) }.should raise_error(RangeError) end it "raises a RangeError if self is too large" do 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/div_spec.rb b/spec/ruby/core/integer/div_spec.rb index bc1c4363d4..344e095179 100644 --- a/spec/ruby/core/integer/div_spec.rb +++ b/spec/ruby/core/integer/div_spec.rb @@ -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 @@ -124,11 +124,11 @@ describe "Integer#div" do 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 diff --git a/spec/ruby/core/integer/divide_spec.rb b/spec/ruby/core/integer/divide_spec.rb index 5ac2dc538d..a878c4668c 100644 --- a/spec/ruby/core/integer/divide_spec.rb +++ b/spec/ruby/core/integer/divide_spec.rb @@ -47,7 +47,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 @@ -60,15 +60,15 @@ describe "Integer#/" do 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 diff --git a/spec/ruby/core/integer/divmod_spec.rb b/spec/ruby/core/integer/divmod_spec.rb index d88925caad..7a489e9344 100644 --- a/spec/ruby/core/integer/divmod_spec.rb +++ b/spec/ruby/core/integer/divmod_spec.rb @@ -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] diff --git a/spec/ruby/core/integer/left_shift_spec.rb b/spec/ruby/core/integer/left_shift_spec.rb index 2b8c26223b..135af90421 100644 --- a/spec/ruby/core/integer/left_shift_spec.rb +++ b/spec/ruby/core/integer/left_shift_spec.rb @@ -96,7 +96,7 @@ describe "Integer#<< (with n << m)" do 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 @@ -127,10 +127,6 @@ 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(Integer) @@ -165,4 +161,51 @@ describe "Integer#<< (with n << m)" do -> { @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 + + ruby_bug "#18517", ""..."3.2" do + it "returns 0 when m > 0 long and n == 0" do + (0 << (2**40)).should == 0 + end + end + + it "returns 0 when m > 0 bignum and n == 0" do + (0 << bignum_value).should == 0 + end + + ruby_bug "#18518", ""..."3.3" do + it "raises NoMemoryError when m > 0 and n != 0" do + coerce_long = mock("long") + coerce_long.stub!(:to_int).and_return(2**40) + coerce_bignum = mock("bignum") + coerce_bignum.stub!(:to_int).and_return(bignum_value) + exps = [2**40, bignum_value, coerce_long, coerce_bignum] + + exps.each { |exp| + -> { (1 << exp) }.should raise_error(NoMemoryError) + -> { (-1 << exp) }.should raise_error(NoMemoryError) + -> { (bignum_value << exp) }.should raise_error(NoMemoryError) + -> { (-bignum_value << exp) }.should raise_error(NoMemoryError) + } + end + end + end end diff --git a/spec/ruby/core/integer/minus_spec.rb b/spec/ruby/core/integer/minus_spec.rb index ce50c8752f..aadf416a05 100644 --- a/spec/ruby/core/integer/minus_spec.rb +++ b/spec/ruby/core/integer/minus_spec.rb @@ -10,7 +10,7 @@ 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 @@ -29,8 +29,8 @@ 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 diff --git a/spec/ruby/core/integer/multiply_spec.rb b/spec/ruby/core/integer/multiply_spec.rb index d1e9c2640d..5037d27458 100644 --- a/spec/ruby/core/integer/multiply_spec.rb +++ b/spec/ruby/core/integer/multiply_spec.rb @@ -10,7 +10,7 @@ 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 @@ -32,8 +32,8 @@ 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 diff --git a/spec/ruby/core/integer/plus_spec.rb b/spec/ruby/core/integer/plus_spec.rb index 511a436872..d01a76ab58 100644 --- a/spec/ruby/core/integer/plus_spec.rb +++ b/spec/ruby/core/integer/plus_spec.rb @@ -9,7 +9,7 @@ describe "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 @@ -29,9 +29,9 @@ 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 diff --git a/spec/ruby/core/integer/remainder_spec.rb b/spec/ruby/core/integer/remainder_spec.rb index cd10dad6f2..96268b3af5 100644 --- a/spec/ruby/core/integer/remainder_spec.rb +++ b/spec/ruby/core/integer/remainder_spec.rb @@ -33,7 +33,7 @@ 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 diff --git a/spec/ruby/core/integer/right_shift_spec.rb b/spec/ruby/core/integer/right_shift_spec.rb index c8e3f45f21..81405667b2 100644 --- a/spec/ruby/core/integer/right_shift_spec.rb +++ b/spec/ruby/core/integer/right_shift_spec.rb @@ -52,10 +52,6 @@ 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 a Bignum == fixnum_max * 2 when fixnum_max >> -1 and n > 0" do result = fixnum_max >> -1 result.should be_an_instance_of(Integer) @@ -96,7 +92,7 @@ describe "Integer#>> (with n >> m)" do 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 @@ -153,10 +149,6 @@ 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(Integer) @@ -191,4 +183,51 @@ describe "Integer#>> (with n >> m)" do -> { @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 + + ruby_bug "#18517", ""..."3.2" do + it "returns 0 when m < 0 long and n == 0" do + (0 >> -(2**40)).should == 0 + end + end + + it "returns 0 when m < 0 bignum and n == 0" do + (0 >> -bignum_value).should == 0 + end + + ruby_bug "#18518", ""..."3.3" do + it "raises NoMemoryError when m < 0 and n != 0" do + coerce_long = mock("long") + coerce_long.stub!(:to_int).and_return(-(2**40)) + coerce_bignum = mock("bignum") + coerce_bignum.stub!(:to_int).and_return(-bignum_value) + exps = [-(2**40), -bignum_value, coerce_long, coerce_bignum] + + exps.each { |exp| + -> { (1 >> exp) }.should raise_error(NoMemoryError) + -> { (-1 >> exp) }.should raise_error(NoMemoryError) + -> { (bignum_value >> exp) }.should raise_error(NoMemoryError) + -> { (-bignum_value >> exp) }.should raise_error(NoMemoryError) + } + end + end + 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/exponent.rb b/spec/ruby/core/integer/shared/exponent.rb index f949c514c8..15df518b7e 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 @@ -96,8 +98,8 @@ 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 @@ -116,8 +118,9 @@ describe :integer_exponent, shared: true do 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/modulo.rb b/spec/ruby/core/integer/shared/modulo.rb index b06d81e17d..f678a10806 100644 --- a/spec/ruby/core/integer/shared/modulo.rb +++ b/spec/ruby/core/integer/shared/modulo.rb @@ -48,11 +48,11 @@ describe :integer_modulo, shared: true do 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 + @bignum.send(@method, 5).should == 1 + @bignum.send(@method, -5).should == -4 + @bignum.send(@method, -100).should == -84 + @bignum.send(@method, 2.22).should be_close(1.5603603603605034, TOLERANCE) + @bignum.send(@method, bignum_value(10)).should == 18446744073709551616 end it "raises a ZeroDivisionError when the given argument is 0" do 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_s_spec.rb b/spec/ruby/core/integer/to_s_spec.rb index 7988bfde7a..ca08dad95c 100644 --- a/spec/ruby/core/integer/to_s_spec.rb +++ b/spec/ruby/core/integer/to_s_spec.rb @@ -68,9 +68,9 @@ describe "Integer#to_s" do 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/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/io/write_spec.rb b/spec/ruby/core/io/write_spec.rb index 60e66e998f..f29fdf3a01 100644 --- a/spec/ruby/core/io/write_spec.rb +++ b/spec/ruby/core/io/write_spec.rb @@ -168,3 +168,27 @@ platform_is :windows do end end end + +ruby_version_is "3.0" do + describe "IO#write on STDOUT" do + # https://bugs.ruby-lang.org/issues/14413 + platform_is_not :windows do + it "raises SignalException SIGPIPE if the stream is closed instead of Errno::EPIPE like other IOs" do + stderr_file = tmp("stderr") + begin + IO.popen([*ruby_exe, "-e", "loop { puts :ok }"], "r", err: stderr_file) do |io| + io.gets.should == "ok\n" + io.close + end + status = $? + status.should_not.success? + status.should.signaled? + Signal.signame(status.termsig).should == 'PIPE' + File.read(stderr_file).should.empty? + ensure + rm_r stderr_file + end + end + end + end +end diff --git a/spec/ruby/core/kernel/instance_variable_set_spec.rb b/spec/ruby/core/kernel/instance_variable_set_spec.rb index 7fda30f72c..dbd257f7b9 100644 --- a/spec/ruby/core/kernel/instance_variable_set_spec.rb +++ b/spec/ruby/core/kernel/instance_variable_set_spec.rb @@ -89,5 +89,11 @@ describe "Kernel#instance_variable_set" do it "raises a FrozenError when passed replacement is different from stored object" do -> { @frozen.instance_variable_set(:@ivar, :replacement) }.should raise_error(FrozenError) end + + it "accepts unicode instance variable names" do + o = Object.new + o.instance_variable_set(:@💙, 42) + o.instance_variable_get(:@💙).should == 42 + end end end diff --git a/spec/ruby/core/module/ruby2_keywords_spec.rb b/spec/ruby/core/module/ruby2_keywords_spec.rb index 34c45cb1bc..996774891c 100644 --- a/spec/ruby/core/module/ruby2_keywords_spec.rb +++ b/spec/ruby/core/module/ruby2_keywords_spec.rb @@ -15,6 +15,32 @@ ruby_version_is "2.7" do Hash.ruby2_keywords_hash?(last).should == true end + it "applies to the underlying method and applies across aliasing" do + obj = Object.new + + obj.singleton_class.class_exec do + def foo(*a) a.last end + alias_method :bar, :foo + ruby2_keywords :foo + + def baz(*a) a.last end + ruby2_keywords :baz + alias_method :bob, :baz + end + + last = obj.foo(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + + last = obj.bar(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + + last = obj.baz(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + + last = obj.bob(1, 2, a: "a") + Hash.ruby2_keywords_hash?(last).should == true + end + ruby_version_is "2.7" ... "3.0" do it "fixes delegation warnings when calling a method accepting keywords" do obj = Object.new diff --git a/spec/ruby/core/numeric/quo_spec.rb b/spec/ruby/core/numeric/quo_spec.rb index b4a23fd476..67bacee9b5 100644 --- a/spec/ruby/core/numeric/quo_spec.rb +++ b/spec/ruby/core/numeric/quo_spec.rb @@ -20,7 +20,7 @@ describe "Numeric#quo" do -> { 10.quo(0) }.should raise_error(ZeroDivisionError) -> { -10.quo(0) }.should raise_error(ZeroDivisionError) -> { bignum_value.quo(0) }.should raise_error(ZeroDivisionError) - -> { -bignum_value.quo(0) }.should raise_error(ZeroDivisionError) + -> { (-bignum_value).quo(0) }.should raise_error(ZeroDivisionError) end it "calls #to_r to convert the object to a Rational" do diff --git a/spec/ruby/core/proc/ruby2_keywords_spec.rb b/spec/ruby/core/proc/ruby2_keywords_spec.rb index 4f6bc151b6..1fba3b9398 100644 --- a/spec/ruby/core/proc/ruby2_keywords_spec.rb +++ b/spec/ruby/core/proc/ruby2_keywords_spec.rb @@ -10,6 +10,22 @@ ruby_version_is "2.7" do Hash.ruby2_keywords_hash?(last).should == true end + it "applies to the underlying method and applies across duplication" do + f1 = -> *a { a.last } + f1.ruby2_keywords + f2 = f1.dup + + Hash.ruby2_keywords_hash?(f1.call(1, 2, a: "a")).should == true + Hash.ruby2_keywords_hash?(f2.call(1, 2, a: "a")).should == true + + f3 = -> *a { a.last } + f4 = f3.dup + f3.ruby2_keywords + + Hash.ruby2_keywords_hash?(f3.call(1, 2, a: "a")).should == true + Hash.ruby2_keywords_hash?(f4.call(1, 2, a: "a")).should == true + end + ruby_version_is "2.7" ... "3.0" do it "fixes delegation warnings when calling a method accepting keywords" do obj = Object.new diff --git a/spec/ruby/core/random/bytes_spec.rb b/spec/ruby/core/random/bytes_spec.rb index 06e84d03bd..ed1b3a7b41 100644 --- a/spec/ruby/core/random/bytes_spec.rb +++ b/spec/ruby/core/random/bytes_spec.rb @@ -18,7 +18,7 @@ describe "Random#bytes" do end it "returns the same numeric output for a given huge seed across all implementations and platforms" do - rnd = Random.new(bignum_value ** 4) + rnd = Random.new(2 ** (63 * 4)) rnd.bytes(2).should == "_\x91" rnd.bytes(1000) # skip some rnd.bytes(2).should == "\x17\x12" diff --git a/spec/ruby/core/range/dup_spec.rb b/spec/ruby/core/range/dup_spec.rb index 6c9d0c954a..976d4fd1d0 100644 --- a/spec/ruby/core/range/dup_spec.rb +++ b/spec/ruby/core/range/dup_spec.rb @@ -12,4 +12,10 @@ describe "Range#dup" do copy.end.should == "z" copy.should.exclude_end? end + + it "creates an unfrozen range" do + (1..2).dup.should_not.frozen? + (1..).dup.should_not.frozen? + Range.new(1, 2).dup.should_not.frozen? + end end diff --git a/spec/ruby/core/range/frozen_spec.rb b/spec/ruby/core/range/frozen_spec.rb new file mode 100644 index 0000000000..9a3e6eb373 --- /dev/null +++ b/spec/ruby/core/range/frozen_spec.rb @@ -0,0 +1,27 @@ +require_relative '../../spec_helper' + +# There is no Range#frozen? method but this feels like the best place for these specs +describe "Range#frozen?" do + ruby_version_is "3.0" do + it "is true for literal ranges" do + (1..2).should.frozen? + (1..).should.frozen? + eval("(..1)").should.frozen? + end + + it "is true for Range.new" do + Range.new(1, 2).should.frozen? + Range.new(1, nil).should.frozen? + Range.new(nil, 1).should.frozen? + end + + it "is false for instances of a subclass of Range" do + sub_range = Class.new(Range).new(1, 2) + sub_range.should_not.frozen? + end + + it "is false for Range.allocate" do + Range.allocate.should_not.frozen? + end + end +end diff --git a/spec/ruby/core/string/split_spec.rb b/spec/ruby/core/string/split_spec.rb index 94f6c9aaee..2e03955a26 100644 --- a/spec/ruby/core/string/split_spec.rb +++ b/spec/ruby/core/string/split_spec.rb @@ -224,6 +224,17 @@ describe "String#split with String" do end end end + + it "returns an empty array when whitespace is split on whitespace" do + " ".split(" ").should == [] + " \n ".split(" ").should == [] + " ".split(" ").should == [] + " \t ".split(" ").should == [] + end + + it "doesn't split on non-ascii whitespace" do + "a\u{2008}b".split(" ").should == ["a\u{2008}b"] + end end describe "String#split with Regexp" do |