1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
This commit is contained in:
Benoit Daloze 2021-07-29 22:11:21 +02:00
parent 15d05f8120
commit 6998d75824
186 changed files with 3956 additions and 3339 deletions

View file

@ -1,7 +1,7 @@
inherit_from: .rubocop_todo.yml
AllCops:
TargetRubyVersion: 2.5
TargetRubyVersion: 2.6
DisplayCopNames: true
Exclude:
- command_line/fixtures/bad_syntax.rb

View file

@ -178,7 +178,7 @@ First, file a bug at https://bugs.ruby-lang.org/.
It is better to use a `ruby_version_is` guard if there was a release with the fix.
```ruby
ruby_bug '#13669', ''...'2.5' do
ruby_bug '#13669', ''...'2.7' do
it "works like this" do
# Specify the expected behavior here, not the bug
end

View file

@ -29,8 +29,8 @@ ruby/spec is known to be tested in these implementations for every commit:
* [TruffleRuby](https://github.com/oracle/truffleruby/tree/master/spec/ruby)
* [Opal](https://github.com/opal/opal/tree/master/spec)
ruby/spec describes the behavior of Ruby 2.5 and more recent Ruby versions.
More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (2.5.x, 2.6.x, 2.7.x, etc), and those are tested in CI.
ruby/spec describes the behavior of Ruby 2.6 and more recent Ruby versions.
More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (2.6.x, 2.7.x, 3.0.x, etc), and those are tested in CI.
### Synchronization with Ruby Implementations
@ -57,6 +57,7 @@ For older specs try these commits:
* Ruby 2.2.10 - [Suite](https://github.com/ruby/spec/commit/cbaa0e412270c944df0c2532fc500c920dba0e92) using [MSpec](https://github.com/ruby/mspec/commit/d84d7668449e96856c5f6bac8cb1526b6d357ce3)
* Ruby 2.3.8 - [Suite](https://github.com/ruby/spec/commit/dc733114d8ae66a3368ba3a98422c50147a76ba5) using [MSpec](https://github.com/ruby/mspec/commit/4599bc195fb109f2a482a01c32a7d659518369ea)
* Ruby 2.4.10 - [Suite](https://github.com/ruby/spec/commit/bce4f2b81d6c31db67cf4d023a0625ceadde59bd) using [MSpec](https://github.com/ruby/mspec/commit/e7eb8aa4c26495b7b461e687d950b96eb08b3ff2)
* Ruby 2.5.9 - [Suite](https://github.com/ruby/spec/commit/c503335d3d9f6ec6ef24de60a0716c34af69b64f) using [MSpec](https://github.com/ruby/mspec/commit/0091e8a62e954717cd54641f935eaf1403692041)
### Running the specs

View file

@ -1,6 +1,12 @@
require_relative '../spec_helper'
describe "The --enable and --disable flags" do
before :all do
# Since some specs disable reading RUBYOPT, we instead pass its contents as :options for those specs
rubyopt = [ENV["RUBYOPT"]]
rubyopt << ENV["#{RUBY_ENGINE.upcase}OPT"] unless RUBY_ENGINE == 'ruby'
@rubyopt = RUBY_ENGINE == "ruby" ? "" : rubyopt.compact.join(" ")
end
it "can be used with gems" do
ruby_exe("p defined?(Gem)", options: "--enable=gems").chomp.should == "\"constant\""
@ -25,9 +31,9 @@ describe "The --enable and --disable flags" do
it "can be used with rubyopt" do
ruby_exe("p $VERBOSE", options: "--enable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true"
ruby_exe("p $VERBOSE", options: "--disable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
ruby_exe("p $VERBOSE", options: "#{@rubyopt} --disable=rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
ruby_exe("p $VERBOSE", options: "--enable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "true"
ruby_exe("p $VERBOSE", options: "--disable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
ruby_exe("p $VERBOSE", options: "#{@rubyopt} --disable-rubyopt", env: {'RUBYOPT' => '-w'}).chomp.should == "false"
end
it "can be used with frozen-string-literal" do
@ -49,8 +55,8 @@ describe "The --enable and --disable flags" do
it "can be used with all for disable" do
e = "p [defined?(Gem), defined?(DidYouMean), $VERBOSE, 'foo'.frozen?]"
env = {'RUBYOPT' => '-w'}
ruby_exe(e, options: "--disable=all", env: env).chomp.should == "[nil, nil, false, false]"
ruby_exe(e, options: "--disable-all", env: env).chomp.should == "[nil, nil, false, false]"
ruby_exe(e, options: "#{@rubyopt} --disable=all", env: env).chomp.should == "[nil, nil, false, false]"
ruby_exe(e, options: "#{@rubyopt} --disable-all", env: env).chomp.should == "[nil, nil, false, false]"
end
it "prints a warning for unknown features" do

View file

@ -2,8 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/difference'
ruby_version_is "2.6" do
describe "Array#difference" do
describe "Array#difference" do
it_behaves_like :array_binary_difference, :difference
it "returns a copy when called without any parameter" do
@ -20,5 +19,4 @@ ruby_version_is "2.6" do
x = [1, 2, 3, 1]
x.difference([], [0, 1], [3, 4], [3]).should == [2]
end
end
end

View file

@ -445,8 +445,7 @@ describe "Array#[]= with [m..n]" do
end
end
ruby_version_is "2.6" do
describe "Array#[]= with [m..]" do
describe "Array#[]= with [m..]" do
it "just sets the section defined by range to nil even if the rhs is nil" do
a = [1, 2, 3, 4, 5]
a[eval("(2..)")] = nil
@ -480,7 +479,6 @@ ruby_version_is "2.6" do
a[eval("(5..)")] = [6]
a.should == [1, 2, 3, 4, nil, 6]
end
end
end
ruby_version_is "2.7" do

View file

@ -316,14 +316,12 @@ describe "Array#fill with (filler, range)" do
-> { [].fill('a', obj..obj) }.should raise_error(TypeError)
end
ruby_version_is "2.6" do
it "works with endless ranges" do
[1, 2, 3, 4].fill('x', eval("(1..)")).should == [1, 'x', 'x', 'x']
[1, 2, 3, 4].fill('x', eval("(3...)")).should == [1, 2, 3, 'x']
[1, 2, 3, 4].fill(eval("(1..)")) { |x| x + 2 }.should == [1, 3, 4, 5]
[1, 2, 3, 4].fill(eval("(3...)")) { |x| x + 2 }.should == [1, 2, 3, 5]
end
end
ruby_version_is "2.7" do
it "works with beginless ranges" do

View file

@ -1,16 +1,14 @@
require_relative '../../spec_helper'
require_relative 'shared/select'
ruby_version_is "2.6" do
describe "Array#filter" do
describe "Array#filter" do
it_behaves_like :array_select, :filter
end
end
describe "Array#filter!" do
describe "Array#filter!" do
it "returns nil if no changes were made in the array" do
[1, 2, 3].filter! { true }.should be_nil
end
it_behaves_like :keep_if, :filter!
end
end

View file

@ -521,7 +521,6 @@ describe :array_slice, shared: true do
-> { "hello".send(@method, 0..bignum_value) }.should raise_error(RangeError)
end
ruby_version_is "2.6" do
it "can accept endless ranges" do
a = [0, 1, 2, 3, 4, 5]
a.send(@method, eval("(2..)")).should == [2, 3, 4, 5]
@ -533,7 +532,6 @@ describe :array_slice, shared: true do
a.send(@method, eval("(-9..)")).should == nil
a.send(@method, eval("(-9...)")).should == nil
end
end
ruby_version_is "2.7" do
it "can accept beginless ranges" do

View file

@ -154,7 +154,6 @@ describe "Array#slice!" do
-> { ArraySpecs.frozen_array.slice!(0, 0) }.should raise_error(FrozenError)
end
ruby_version_is "2.6" do
it "works with endless ranges" do
a = [1, 2, 3]
a.slice!(eval("(1..)")).should == [2, 3]
@ -172,7 +171,6 @@ describe "Array#slice!" do
a.slice!(eval("(-1...)")).should == [3]
a.should == [1, 2]
end
end
ruby_version_is "2.7" do
it "works with beginless ranges" do

View file

@ -39,7 +39,6 @@ describe "Array#to_h" do
[[:a, 1], [:b, 2]].to_h[:c].should be_nil
end
ruby_version_is "2.6" do
context "with block" do
it "converts [key, value] pairs returned by the block to a Hash" do
[:a, :b].to_h { |k| [k, k.to_s] }.should == { a: 'a', b: 'b' }
@ -77,5 +76,4 @@ describe "Array#to_h" do
end.should raise_error(TypeError, /wrong element type MockObject at 0/)
end
end
end
end

View file

@ -6,8 +6,7 @@ describe "Array#|" do
it_behaves_like :array_binary_union, :|
end
ruby_version_is "2.6" do
describe "Array#union" do
describe "Array#union" do
it_behaves_like :array_binary_union, :union
it "returns unique elements when given no argument" do
@ -23,5 +22,4 @@ ruby_version_is "2.6" do
x = [1, 2, 3]
x.union(x, x, x, x, [3, 4], x).should == [1, 2, 3, 4]
end
end
end

View file

@ -61,12 +61,10 @@ describe "Array#values_at" do
ArraySpecs::MyArray[1, 2, 3].values_at(0, 1..2, 1).should be_an_instance_of(Array)
end
ruby_version_is "2.6" do
it "works when given endless ranges" do
[1, 2, 3, 4].values_at(eval("(1..)")).should == [2, 3, 4]
[1, 2, 3, 4].values_at(eval("(3...)")).should == [4]
end
end
ruby_version_is "2.7" do
it "works when given beginless ranges" do

View file

@ -1,11 +1,9 @@
require_relative '../../spec_helper'
require_relative 'fixtures/location'
ruby_version_is "2.6" do
describe "Binding#source_location" do
describe "Binding#source_location" do
it "returns an [file, line] pair" do
b = BindingSpecs::LocationMethod::TEST_BINDING
b.source_location.should == [BindingSpecs::LocationMethod::FILE_PATH, 4]
end
end
end

View file

@ -69,8 +69,7 @@ describe "Dir.children" do
end
end
ruby_version_is "2.6" do
describe "Dir#children" do
describe "Dir#children" do
before :all do
DirSpecs.create_mock_dirs
end
@ -140,5 +139,4 @@ ruby_version_is "2.6" do
children = @dir.children.sort
children.first.encoding.should equal(Encoding::EUC_KR)
end
end
end

View file

@ -62,8 +62,7 @@ describe "Dir.each_child" do
end
end
ruby_version_is "2.6" do
describe "Dir#each_child" do
describe "Dir#each_child" do
before :all do
DirSpecs.create_mock_dirs
end
@ -111,5 +110,4 @@ ruby_version_is "2.6" do
end
end
end
end
end

View file

@ -29,6 +29,23 @@ describe "Dir.glob" do
%w!file_one.ext file_two.ext!
end
it 'returns matching file paths when supplied :base keyword argument' do
dir = tmp('dir_glob_base')
file_1 = "#{dir}/lib/bloop.rb"
file_2 = "#{dir}/lib/soup.rb"
file_3 = "#{dir}/lib/mismatched_file_type.txt"
file_4 = "#{dir}/mismatched_directory.rb"
touch file_1
touch file_2
touch file_3
touch file_4
Dir.glob('**/*.rb', base: "#{dir}/lib").sort.should == ["bloop.rb", "soup.rb"].sort
ensure
rm_r dir
end
it "calls #to_path to convert multiple patterns" do
pat1 = mock('file_one.ext')
pat1.should_receive(:to_path).and_return('file_one.ext')
@ -133,6 +150,14 @@ describe "Dir.glob" do
Dir.glob('{deeply/**/,subdir_two/*}').sort.should == expected
end
it "preserves multiple /s before a **" do
expected = %w[
deeply//nested/directory/structure
]
Dir.glob('{deeply//**/structure}').sort.should == expected
end
it "accepts a block and yields it with each elements" do
ary = []
ret = Dir.glob(["file_o*", "file_t*"]) { |t| ary << t }

View file

@ -23,14 +23,7 @@ describe :dir_glob, shared: true do
Dir.send(@method, obj).should == %w[file_one.ext]
end
ruby_version_is ""..."2.6" do
it "splits the string on \\0 if there is only one string given" do
Dir.send(@method, "file_o*\0file_t*").should ==
%w!file_one.ext file_two.ext!
end
end
ruby_version_is "2.6"..."2.7" do
ruby_version_is ""..."2.7" do
it "splits the string on \\0 if there is only one string given and warns" do
-> {
Dir.send(@method, "file_o*\0file_t*").should ==
@ -205,6 +198,14 @@ describe :dir_glob, shared: true do
Dir.send(@method, '**/').sort.should == expected
end
it "recursively matches any subdirectories except './' or '../' with '**/' from the base directory if that is specified" do
expected = %w[
nested/directory
]
Dir.send(@method, '**/*ory', base: 'deeply').sort.should == expected
end
ruby_version_is ''...'3.1' do
it "recursively matches any subdirectories including ./ and ../ with '.**/'" do
Dir.chdir("#{DirSpecs.mock_dir}/subdir_one") do

View file

@ -132,14 +132,6 @@ describe "Enumerable#all?" do
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.all?(NilClass) { raise }.should == false
[1, 2, nil].all?(NilClass) { raise }.should == false
{a: 1}.all?(Array) { raise }.should == true
end
end
it "always returns true on empty enumeration" do
@empty.all?(Integer).should == true
[].all?(Integer).should == true

View file

@ -146,14 +146,6 @@ describe "Enumerable#any?" do
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.any?(NilClass) { raise }.should == true
[1, 2, nil].any?(NilClass) { raise }.should == true
{a: 1}.any?(Array) { raise }.should == true
end
end
it "always returns false on empty enumeration" do
@empty.any?(Integer).should == false
[].any?(Integer).should == false

View file

@ -1,8 +1,7 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
ruby_version_is "2.6" do
describe "Enumerable#chain" do
describe "Enumerable#chain" do
before :each do
ScratchPad.record []
end
@ -21,5 +20,4 @@ ruby_version_is "2.6" do
it "returns an Enumerator::Chain if given a block" do
EnumerableSpecs::Numerous.new.chain.should be_an_instance_of(Enumerator::Chain)
end
end
end

View file

@ -2,8 +2,6 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative 'shared/find_all'
ruby_version_is "2.6" do
describe "Enumerable#filter" do
describe "Enumerable#filter" do
it_behaves_like(:enumerable_find_all , :filter)
end
end

View file

@ -101,14 +101,6 @@ describe "Enumerable#none?" do
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.none?(Integer) { raise }.should == true
[1, 2, nil].none?(TrueClass) { raise }.should == true
{a: 1}.none?(Hash) { raise }.should == true
end
end
it "always returns true on empty enumeration" do
@empty.none?(Integer).should == true
[].none?(Integer).should == true

View file

@ -92,14 +92,6 @@ describe "Enumerable#one?" do
end
# may raise an exception in future versions
ruby_version_is ""..."2.6" do
it "ignores block" do
@enum2.one?(NilClass) { raise }.should == true
[1, 2, nil].one?(NilClass) { raise }.should == true
{a: 1}.one?(Array) { raise }.should == true
end
end
it "always returns false on empty enumeration" do
@empty.one?(Integer).should == false
[].one?(Integer).should == false

View file

@ -44,7 +44,6 @@ describe "Enumerable#to_h" do
-> { enum.to_h }.should raise_error(ArgumentError)
end
ruby_version_is "2.6" do
context "with block" do
before do
@enum = EnumerableSpecs::EachDefiner.new(:a, :b)
@ -86,5 +85,4 @@ describe "Enumerable#to_h" do
end.should raise_error(TypeError, /wrong element type MockObject/)
end
end
end
end

View file

@ -1,11 +1,9 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#begin" do
describe "Enumerator::ArithmeticSequence#begin" do
it "returns the begin of the sequence" do
1.step(10).begin.should == 1
(1..10).step.begin.should == 1
(1...10).step.begin.should == 1
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#each" do
describe "Enumerator::ArithmeticSequence#each" do
before :each do
ScratchPad.record []
@seq = 1.step(10, 4)
@ -15,5 +14,4 @@ ruby_version_is "2.6" do
it "returns self" do
@seq.each { |item| }.should equal(@seq)
end
end
end

View file

@ -1,11 +1,9 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#end" do
describe "Enumerator::ArithmeticSequence#end" do
it "returns the end of the sequence" do
1.step(10).end.should == 10
(1..10).step.end.should == 10
(1...10).step(17).end.should == 10
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#==" do
describe "Enumerator::ArithmeticSequence#==" do
it "returns true if begin, end, step and exclude_end? are equal" do
1.step(10).should == 1.step(10)
1.step(10, 5).should == 1.step(10, 5)
@ -16,5 +15,4 @@ ruby_version_is "2.6" do
((1..10).step == (1...10).step).should == false
((1..10).step == (1..10).step(2)).should == false
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#exclude_end?" do
describe "Enumerator::ArithmeticSequence#exclude_end?" do
context "when created using Numeric#step" do
it "always returns false" do
1.step(10).should_not.exclude_end?
@ -15,5 +14,4 @@ ruby_version_is "2.6" do
(1..10).step.should_not.exclude_end?
end
end
end
end

View file

@ -1,11 +1,9 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#first" do
describe "Enumerator::ArithmeticSequence#first" do
it "returns the first element of the sequence" do
1.step(10).first.should == 1
(1..10).step.first.should == 1
(1...10).step.first.should == 1
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#hash" do
describe "Enumerator::ArithmeticSequence#hash" do
it "is based on begin, end, step and exclude_end?" do
1.step(10).hash.should be_an_instance_of(Integer)
@ -18,5 +17,4 @@ ruby_version_is "2.6" do
((1..10).step.hash == (1...10).step.hash).should == false
((1..10).step.hash == (1..10).step(2).hash).should == false
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#inspect" do
describe "Enumerator::ArithmeticSequence#inspect" do
context 'when Numeric#step is used' do
it "returns '(begin.step(end{, step}))'" do
1.step(10).inspect.should == "(1.step(10))"
@ -18,5 +17,4 @@ ruby_version_is "2.6" do
(1...10).step(3).inspect.should == "((1...10).step(3))"
end
end
end
end

View file

@ -1,11 +1,9 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#last" do
describe "Enumerator::ArithmeticSequence#last" do
it "returns the last element of the sequence" do
1.step(10).last.should == 10
(1..10).step.last.should == 10
(1...10).step(4).last.should == 9
end
end
end

View file

@ -1,19 +1,17 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence.new" do
describe "Enumerator::ArithmeticSequence.new" do
it "is not defined" do
-> {
Enumerator::ArithmeticSequence.new
}.should raise_error(NoMethodError)
end
end
end
describe "Enumerator::ArithmeticSequence.allocate" do
describe "Enumerator::ArithmeticSequence.allocate" do
it "is not defined" do
-> {
Enumerator::ArithmeticSequence.allocate
}.should raise_error(TypeError, 'allocator undefined for Enumerator::ArithmeticSequence')
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#size" do
describe "Enumerator::ArithmeticSequence#size" do
context "for finite sequence" do
it "returns the number of elements in this arithmetic sequence" do
1.step(10).size.should == 10
@ -15,5 +14,4 @@ ruby_version_is "2.6" do
(1..Float::INFINITY).step.size.should == Float::INFINITY
end
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::ArithmeticSequence#step" do
describe "Enumerator::ArithmeticSequence#step" do
it "returns the original value given to step method" do
(1..10).step.step.should == 1
(1..10).step(3).step.should == 3
@ -9,5 +8,4 @@ ruby_version_is "2.6" do
1.step(10).step.should == 1
1.step(10, 3).step.should == 3
end
end
end

View file

@ -1,8 +1,7 @@
require_relative '../../../spec_helper'
require_relative '../../enumerable/fixtures/classes'
ruby_version_is "2.6" do
describe "Enumerator::Chain#each" do
describe "Enumerator::Chain#each" do
it "calls each on its constituents as needed" do
a = EnumerableSpecs::EachCounter.new(:a, :b)
b = EnumerableSpecs::EachCounter.new(:c, :d)
@ -13,5 +12,4 @@ ruby_version_is "2.6" do
end
ScratchPad.recorded.should == [:a, 0, :b, 0, :c, 1, :d, 2]
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::Chain#initialize" do
describe "Enumerator::Chain#initialize" do
before :each do
@uninitialized = Enumerator::Chain.allocate
end
@ -29,5 +28,4 @@ ruby_version_is "2.6" do
}.should raise_error(RuntimeError)
end
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::Chain#inspect" do
describe "Enumerator::Chain#inspect" do
it "shows a representation of the Enumerator" do
Enumerator::Chain.new.inspect.should == "#<Enumerator::Chain: []>"
Enumerator::Chain.new(1..2, 3..4).inspect.should == "#<Enumerator::Chain: [1..2, 3..4]>"
@ -12,5 +11,4 @@ ruby_version_is "2.6" do
obj.should_receive(:inspect).and_return('some desc')
Enumerator::Chain.new(obj).inspect.should == "#<Enumerator::Chain: [some desc]>"
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator::Chain#rewind" do
describe "Enumerator::Chain#rewind" do
before(:each) do
@obj = mock('obj')
@obj.should_receive(:each).any_number_of_times.and_yield
@ -49,5 +48,4 @@ ruby_version_is "2.6" do
-> { @enum.each {} }.should raise_error(RuntimeError)
@enum.rewind
end
end
end

View file

@ -1,8 +1,7 @@
require_relative '../../../spec_helper'
require_relative '../../enumerable/fixtures/classes'
ruby_version_is "2.6" do
describe "Enumerator::Chain#size" do
describe "Enumerator::Chain#size" do
it "returns the sum of the sizes of the elements" do
a = mock('size')
a.should_receive(:size).and_return(40)
@ -20,5 +19,4 @@ ruby_version_is "2.6" do
Enumerator::Chain.new(a, b, c).size.should == special
end
end
end
end

View file

@ -1,8 +1,6 @@
require_relative '../../../spec_helper'
require_relative 'shared/select'
ruby_version_is "2.6" do
describe "Enumerator::Lazy#filter" do
describe "Enumerator::Lazy#filter" do
it_behaves_like :enumerator_lazy_select, :filter
end
end

View file

@ -0,0 +1,30 @@
# -*- encoding: us-ascii -*-
require_relative '../../../spec_helper'
require_relative 'fixtures/classes'
ruby_version_is "2.7" do
describe "Enumerator::Lazy#with_index" do
it "enumerates with an index" do
(0..Float::INFINITY).lazy.with_index.map { |i, idx| [i, idx] }.first(3).should == [[0, 0], [1, 1], [2, 2]]
end
it "enumerates with an index starting at a given offset" do
(0..Float::INFINITY).lazy.with_index(3).map { |i, idx| [i, idx] }.first(3).should == [[0, 3], [1, 4], [2, 5]]
end
it "enumerates with an index starting at 0 when offset is nil" do
(0..Float::INFINITY).lazy.with_index(nil).map { |i, idx| [i, idx] }.first(3).should == [[0, 0], [1, 1], [2, 2]]
end
it "raises TypeError when offset does not convert to Integer" do
-> { (0..Float::INFINITY).lazy.with_index(false).map { |i, idx| i }.first(3) }.should raise_error(TypeError)
end
it "enumerates with a given block" do
result = []
(0..Float::INFINITY).lazy.with_index { |i, idx| result << [i * 2, idx] }.first(3)
result.should == [[0,0],[2,1],[4,2]]
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../spec_helper'
ruby_version_is "2.6" do
describe "Enumerator#+" do
describe "Enumerator#+" do
before :each do
ScratchPad.record []
end
@ -31,5 +30,4 @@ ruby_version_is "2.6" do
chain.each { |item| ScratchPad << item }
ScratchPad.recorded.should == ["one", "two", "three"]
end
end
end

View file

@ -23,17 +23,6 @@ describe "Enumerator::Yielder#<<" do
end
context "when multiple arguments passed" do
ruby_version_is '' ... '2.6' do
it "yields the arguments list to the block" do
ary = []
y = Enumerator::Yielder.new { |*x| ary << x }
y.<<(1, 2)
ary.should == [[1, 2]]
end
end
ruby_version_is '2.6' do
it "raises an ArgumentError" do
ary = []
y = Enumerator::Yielder.new { |*x| ary << x }
@ -43,5 +32,4 @@ describe "Enumerator::Yielder#<<" do
}.should raise_error(ArgumentError, /wrong number of arguments/)
end
end
end
end

View file

@ -2,14 +2,12 @@ require_relative '../../spec_helper'
require_relative '../enumerable/shared/enumeratorized'
require_relative 'shared/select'
ruby_version_is "2.6" do
describe "ENV.filter!" do
describe "ENV.filter!" do
it_behaves_like :env_select!, :filter!
it_behaves_like :enumeratorized_with_origin_size, :filter!, ENV
end
end
describe "ENV.filter" do
describe "ENV.filter" do
it_behaves_like :env_select, :filter
it_behaves_like :enumeratorized_with_origin_size, :filter, ENV
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../spec_helper'
ruby_version_is "2.6" do
describe "ENV.slice" do
describe "ENV.slice" do
before :each do
@saved_foo = ENV["foo"]
@saved_bar = ENV["bar"]
@ -25,5 +24,4 @@ ruby_version_is "2.6" do
it "raises TypeError if any argument is not a String and does not respond to #to_str" do
-> { ENV.slice(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
end
end

View file

@ -4,7 +4,6 @@ require_relative 'shared/to_hash'
describe "ENV.to_h" do
it_behaves_like :env_to_hash, :to_h
ruby_version_is "2.6" do
context "with block" do
before do
@orig_hash = ENV.to_hash
@ -56,5 +55,4 @@ describe "ENV.to_h" do
end.should raise_error(TypeError, /wrong element type MockObject/)
end
end
end
end

View file

@ -12,7 +12,6 @@ describe "Exception#full_message" do
full_message.should include "b.rb:2"
end
ruby_version_is "2.5.1" do
it "supports :highlight option and adds escape sequences to highlight some strings" do
e = RuntimeError.new("Some runtime error")
@ -51,9 +50,7 @@ describe "Exception#full_message" do
full_message[1].should == "second line\n"
end
end
end
ruby_version_is "2.6" do
it "contains cause of exception" do
begin
begin
@ -88,5 +85,4 @@ describe "Exception#full_message" do
exception.full_message.should include "intermediate exception"
exception.full_message.should include "origin exception"
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../spec_helper'
describe "KeyError" do
ruby_version_is "2.6" do
it "accepts :receiver and :key options" do
receiver = mock("receiver")
key = mock("key")
@ -17,5 +16,4 @@ describe "KeyError" do
error.receiver.should == receiver
error.key.should == key
end
end
end

View file

@ -5,7 +5,6 @@ describe "NameError.new" do
NameError.new("msg","name").name.should == "name"
end
ruby_version_is "2.6" do
it "accepts a :receiver keyword argument" do
receiver = mock("receiver")
@ -14,7 +13,6 @@ describe "NameError.new" do
error.receiver.should == receiver
error.name.should == :name
end
end
end
describe "NameError#dup" do

View file

@ -10,7 +10,6 @@ describe "NoMethodError.new" do
NoMethodError.new("msg").message.should == "msg"
end
ruby_version_is "2.6" do
it "accepts a :receiver keyword argument" do
receiver = mock("receiver")
@ -19,7 +18,6 @@ describe "NoMethodError.new" do
error.receiver.should == receiver
error.name.should == :name
end
end
end
describe "NoMethodError#args" do

View file

@ -30,11 +30,9 @@ describe "SignalException.new" do
-> { SignalException.new("NONEXISTENT") }.should raise_error(ArgumentError)
end
ruby_version_is "2.6" do
it "raises an exception with an invalid first argument type" do
-> { SignalException.new(Object.new) }.should raise_error(ArgumentError)
end
end
it "takes a signal symbol without SIG prefix as the first argument" do
exc = SignalException.new(:INT)

View file

@ -5,7 +5,6 @@ describe "An Exception reaching the top level" do
ruby_exe('raise "foo"', args: "2>&1", exit_status: 1).should.include?("in `<main>': foo (RuntimeError)")
end
ruby_version_is "2.6" do
it "the Exception#cause is printed to STDERR with backtraces" do
code = <<-RUBY
def raise_cause
@ -28,7 +27,6 @@ describe "An Exception reaching the top level" do
"in `raise_cause': the cause (RuntimeError)",
"in `<main>'"]
end
end
describe "with a custom backtrace" do
it "is printed on STDERR" do

View file

@ -629,7 +629,6 @@ describe "File.open" do
}.should raise_error(ArgumentError, "newline decorator with binary mode")
end
ruby_version_is "2.6" do
context "'x' flag" do
before :each do
@xfile = tmp("x-flag")
@ -655,7 +654,6 @@ describe "File.open" do
-> { File.open(@xfile, "ax") }.should raise_error(ArgumentError, 'invalid access mode ax')
end
end
end
end
describe "File.open when passed a file descriptor" do

View file

@ -63,4 +63,28 @@ describe "Float#<=>" do
it "returns 1 when self is negative and other is -Infinity" do
(-Float::MAX.to_i*2 <=> -infinity_value).should == 1
end
it "returns 0 when self is Infinity and other other is infinite?=1" do
obj = Object.new
def obj.infinite?
1
end
(infinity_value <=> obj).should == 0
end
it "returns 1 when self is Infinity and other is infinite?=-1" do
obj = Object.new
def obj.infinite?
-1
end
(infinity_value <=> obj).should == 1
end
it "returns 1 when self is Infinity and other is infinite?=nil (which means finite)" do
obj = Object.new
def obj.infinite?
nil
end
(infinity_value <=> obj).should == 1
end
end

View file

@ -1,12 +1,10 @@
require_relative '../../spec_helper'
require_relative 'shared/select'
ruby_version_is "2.6" do
describe "Hash#filter" do
describe "Hash#filter" do
it_behaves_like :hash_select, :filter
end
describe "Hash#filter!" do
it_behaves_like :hash_select!, :filter!
end
end
describe "Hash#filter!" do
it_behaves_like :hash_select!, :filter!
end

View file

@ -81,7 +81,6 @@ describe "Hash#merge" do
merge_pairs.should == expected_pairs
end
ruby_version_is "2.6" do
it "accepts multiple hashes" do
result = { a: 1 }.merge({ b: 2 }, { c: 3 }, { d: 4 })
result.should == { a: 1, b: 2, c: 3, d: 4 }
@ -94,7 +93,6 @@ describe "Hash#merge" do
merged.should eql(hash)
merged.should_not equal(hash)
end
end
end
describe "Hash#merge!" do

View file

@ -64,7 +64,6 @@ describe :hash_update, shared: true do
hash.should == {1 => :foo, 3 => :bar, 5 => 6}
end
ruby_version_is "2.6" do
it "accepts multiple hashes" do
result = { a: 1 }.send(@method, { b: 2 }, { c: 3 }, { d: 4 })
result.should == { a: 1, b: 2, c: 3, d: 4 }
@ -74,5 +73,4 @@ describe :hash_update, shared: true do
hash = { a: 1 }
hash.send(@method).should eql(hash)
end
end
end

View file

@ -32,7 +32,6 @@ describe "Hash#to_h" do
end
end
ruby_version_is "2.6" do
context "with block" do
it "converts [key, value] pairs returned by the block to a hash" do
{ a: 1, b: 2 }.to_h { |k, v| [k.to_s, v*v]}.should == { "a" => 1, "b" => 4 }
@ -70,5 +69,4 @@ describe "Hash#to_h" do
end.should raise_error(TypeError, /wrong element type MockObject/)
end
end
end
end

View file

@ -60,31 +60,12 @@ describe "Hash#transform_keys!" do
end
# https://bugs.ruby-lang.org/issues/14380
ruby_version_is ""..."2.5.1" do
it "does not prevent conflicts between new keys and old ones" do
@hash.transform_keys!(&:succ)
@hash.should == { e: 1 }
end
end
ruby_version_is "2.5.1" do
it "prevents conflicts between new keys and old ones" do
@hash.transform_keys!(&:succ)
@hash.should == { b: 1, c: 2, d: 3, e: 4 }
end
end
ruby_version_is ""..."2.5.1" do
it "partially modifies the contents if we broke from the block" do
@hash.transform_keys! do |v|
break if v == :c
v.succ
end
@hash.should == { c: 1, d: 4 }
end
end
ruby_version_is "2.5.1"..."3.0.2" do # https://bugs.ruby-lang.org/issues/17735
ruby_version_is ""..."3.0.2" do # https://bugs.ruby-lang.org/issues/17735
it "returns the processed keys if we broke from the block" do
@hash.transform_keys! do |v|
break if v == :c

View file

@ -67,5 +67,11 @@ describe "IO#set_encoding_by_bom" do
-> { @io.set_encoding_by_bom }.should raise_error(ArgumentError, 'encoding is set to UTF-8 already')
end
it 'returns exception if encoding conversion is already set' do
@io.set_encoding(Encoding::UTF_8, Encoding::UTF_16BE)
-> { @io.set_encoding_by_bom }.should raise_error(ArgumentError, 'encoding conversion is set')
end
end
end

View file

@ -36,20 +36,7 @@ describe "IO#ungetbyte" do
@io.getbyte.should == 97
end
ruby_version_is ''...'2.6' do
it "puts back one byte for an Integer argument..." do
@io.ungetbyte(4095).should be_nil
@io.getbyte.should == 255
end
it "... but not for Integer argument (eh?)" do
-> {
@io.ungetbyte(0x4f7574206f6620636861722072616e6765)
}.should raise_error(TypeError)
end
end
ruby_version_is '2.6'...'2.6.1' do
ruby_version_is ''...'2.6.1' do
it "is an RangeError if the integer is not in 8bit" do
for i in [4095, 0x4f7574206f6620636861722072616e6765] do
-> { @io.ungetbyte(i) }.should raise_error(RangeError)

View file

@ -139,7 +139,6 @@ describe "Kernel.Complex()" do
end
end
ruby_version_is "2.6" do
describe "when passed exception: false" do
describe "and [Numeric]" do
it "returns a complex number" do
@ -183,5 +182,4 @@ describe "Kernel.Complex()" do
end
end
end
end
end

View file

@ -306,7 +306,6 @@ describe :kernel_float, shared: true do
-> { @object.send(:Float, c) }.should raise_error(RangeError)
end
ruby_version_is "2.6" do
describe "when passed exception: false" do
describe "and valid input" do
it "returns a Float number" do
@ -329,7 +328,6 @@ describe :kernel_float, shared: true do
end
end
end
end
end
describe "Kernel.Float" do

View file

@ -10,16 +10,6 @@ describe :kernel_integer, shared: true do
Integer(100).should == 100
end
ruby_version_is ""..."2.6" do
it "uncritically return the value of to_int even if it is not an Integer" do
obj = mock("object")
obj.should_receive(:to_int).and_return("1")
obj.should_not_receive(:to_i)
Integer(obj).should == "1"
end
end
ruby_version_is "2.6" do
it "raises a TypeError when to_int returns not-an-Integer object and to_i returns nil" do
obj = mock("object")
obj.should_receive(:to_int).and_return("1")
@ -33,7 +23,6 @@ describe :kernel_integer, shared: true do
obj.should_receive(:to_i).and_return(42)
Integer(obj).should == 42
end
end
it "raises a TypeError when passed nil" do
-> { Integer(nil) }.should raise_error(TypeError)
@ -100,7 +89,6 @@ describe :kernel_integer, shared: true do
-> { Integer(infinity_value) }.should raise_error(FloatDomainError)
end
ruby_version_is "2.6" do
describe "when passed exception: false" do
describe "and to_i returns a value that is not an Integer" do
it "swallows an error" do
@ -155,7 +143,6 @@ describe :kernel_integer, shared: true do
end
end
end
end
end
describe "Integer() given a String", shared: true do
@ -246,7 +233,6 @@ describe "Integer() given a String", shared: true do
-> { Integer("") }.should raise_error(ArgumentError)
end
ruby_version_is "2.6" do
describe "when passed exception: false" do
describe "and multiple leading -s" do
it "swallows an error" do
@ -272,7 +258,6 @@ describe "Integer() given a String", shared: true do
end
end
end
end
it "parses the value as 0 if the string consists of a single zero character" do
Integer("0").should == 0
@ -594,7 +579,6 @@ describe "Integer() given a String and base", shared: true do
end
end
ruby_version_is "2.6" do
describe "when passed exception: false" do
describe "and valid argument" do
it "returns an Integer number" do
@ -610,7 +594,6 @@ describe "Integer() given a String and base", shared: true do
end
end
end
end
end
describe :kernel_Integer, shared: true do

View file

@ -56,6 +56,21 @@ describe "Kernel#autoload" do
end
end
describe "inside a Class.new method body" do
# NOTE: this spec is being discussed in https://github.com/ruby/spec/pull/839
it "should define on the new anonymous class" do
cls = Class.new do
def go
autoload :Object, 'bogus'
autoload? :Object
end
end
cls.new.go.should == 'bogus'
cls.autoload?(:Object).should == 'bogus'
end
end
describe "when Object is frozen" do
it "raises a FrozenError before defining the constant" do
ruby_exe(fixture(__FILE__, "autoload_frozen.rb")).should == "FrozenError - nil"

View file

@ -28,13 +28,11 @@ describe 'Kernel#caller_locations' do
locations1[2..4].map(&:to_s).should == locations2.map(&:to_s)
end
ruby_version_is "2.6" do
it "works with endless ranges" do
locations1 = caller_locations(0)
locations2 = caller_locations(eval("(2..)"))
locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s)
end
end
ruby_version_is "2.7" do
it "works with beginless ranges" do

View file

@ -44,13 +44,11 @@ describe 'Kernel#caller' do
]
end
ruby_version_is "2.6" do
it "works with endless ranges" do
locations1 = KernelSpecs::CallerTest.locations(0)
locations2 = KernelSpecs::CallerTest.locations(eval("(2..)"))
locations2.map(&:to_s).should == locations1[2..-1].map(&:to_s)
end
end
ruby_version_is "2.7" do
it "works with beginless ranges" do

View file

@ -14,11 +14,9 @@ describe "Kernel#=~" do
end
end
ruby_version_is "2.6" do
it "is deprecated" do
-> do
Object.new =~ /regexp/
end.should complain(/deprecated Object#=~ is called on Object/, verbose: true)
end
end
end

View file

@ -2,7 +2,6 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Kernel#open" do
before :each do
@name = tmp("kernel_open.txt")
@content = "This is a test"
@ -137,6 +136,18 @@ describe "Kernel#open" do
it "accepts nil for mode and permission" do
open(@name, nil, nil) { |f| f.gets }.should == @content
end
ruby_version_is ""..."3.0" do
it "works correctly when redefined by open-uri" do
code = <<~RUBY
require 'open-uri'
obj = Object.new
def obj.to_open; self; end
p open(obj) == obj
RUBY
ruby_exe(code, args: "2>&1").should == "true\n"
end
end
end
describe "Kernel.open" do

View file

@ -28,7 +28,6 @@ describe "Kernel#raise" do
ScratchPad.recorded.should be_nil
end
ruby_version_is "2.6" do
it "accepts a cause keyword argument that sets the cause" do
cause = StandardError.new
-> { raise("error", cause: cause) }.should raise_error(RuntimeError) { |e| e.cause.should == cause }
@ -47,7 +46,6 @@ describe "Kernel#raise" do
cause = StandardError.new
-> { raise(cause: cause) }.should raise_error(ArgumentError)
end
end
end
describe "Kernel#raise" do

View file

@ -25,7 +25,6 @@ describe :kernel_system, shared: true do
$?.exitstatus.should == 1
end
ruby_version_is "2.6" do
it "raises RuntimeError when `exception: true` is given and the command exits with a non-zero exit status" do
-> { @object.system(ruby_cmd('exit 1'), exception: true) }.should raise_error(RuntimeError)
end
@ -33,7 +32,6 @@ describe :kernel_system, shared: true do
it "raises Errno::ENOENT when `exception: true` is given and the specified command does not exist" do
-> { @object.system('feature_14386', exception: true) }.should raise_error(Errno::ENOENT)
end
end
it "returns nil when command execution fails" do
@object.system("sad").should be_nil

View file

@ -1,8 +1,6 @@
require_relative '../../spec_helper'
require_relative 'shared/then'
ruby_version_is "2.6" do
describe "Kernel#then" do
describe "Kernel#then" do
it_behaves_like :kernel_then, :then
end
end

View file

@ -107,12 +107,10 @@ describe "Kernel#warn" do
ruby_exe(file, options: "--disable-gems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n"
end
ruby_version_is "2.6" do
it "shows the caller of #require and not #require itself with RubyGems loaded" do
file = fixture(__FILE__ , "warn_require_caller.rb")
ruby_exe(file, options: "-rrubygems", args: "2>&1").should == "#{file}:2: warning: warn-require-warning\n"
end
end
guard -> { Kernel.instance_method(:tap).source_location } do
it "skips <internal: core library methods defined in Ruby" do

View file

@ -78,6 +78,20 @@ describe "Marshal.dump" do
s = "\u2192".force_encoding("binary").to_sym
Marshal.dump(s).should == "\x04\b:\b\xE2\x86\x92"
end
it "dumps multiple Symbols sharing the same encoding" do
# Note that the encoding is a link for the second Symbol
symbol1 = "I:\t\xE2\x82\xACa\x06:\x06ET"
symbol2 = "I:\t\xE2\x82\xACb\x06;\x06T"
value = [
"€a".force_encoding(Encoding::UTF_8).to_sym,
"€b".force_encoding(Encoding::UTF_8).to_sym
]
Marshal.dump(value).should == "\x04\b[\a#{symbol1}#{symbol2}"
value = [*value, value[0]]
Marshal.dump(value).should == "\x04\b[\b#{symbol1}#{symbol2};\x00"
end
end
describe "with an object responding to #marshal_dump" do
@ -343,8 +357,13 @@ describe "Marshal.dump" do
end
it "dumps an extended Struct" do
st = Struct.new("Extended", :a, :b).new
Marshal.dump(st.extend(Meths)).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0"
obj = Struct.new("Extended", :a, :b).new.extend(Meths)
Marshal.dump(obj).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0"
s = 'hi'
obj.a = [:a, s]
obj.b = [:Meths, s]
Marshal.dump(obj).should == "\004\be:\nMethsS:\025Struct::Extended\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a"
Struct.send(:remove_const, :Extended)
end
end

View file

@ -83,7 +83,7 @@ class UserPreviouslyDefinedWithInitializedIvar
end
class UserMarshal
attr_reader :data
attr_accessor :data
def initialize
@data = 'stuff'

View file

@ -309,7 +309,8 @@ describe :marshal_load, shared: true do
it "loads an extended Array object containing a user-marshaled object" do
obj = [UserMarshal.new, UserMarshal.new].extend(Meths)
new_obj = Marshal.send(@method, "\x04\be:\nMeths[\ao:\x10UserMarshal\x06:\n@dataI\"\nstuff\x06:\x06ETo;\x06\x06;\aI\"\nstuff\x06;\bT")
dump = "\x04\be:\nMeths[\ao:\x10UserMarshal\x06:\n@dataI\"\nstuff\x06:\x06ETo;\x06\x06;\aI\"\nstuff\x06;\bT"
new_obj = Marshal.send(@method, dump)
new_obj.should == obj
obj_ancestors = class << obj; ancestors[1..-1]; end
@ -399,6 +400,24 @@ describe :marshal_load, shared: true do
sym.should == s
sym.encoding.should == Encoding::BINARY
end
it "loads multiple Symbols sharing the same encoding" do
# Note that the encoding is a link for the second Symbol
symbol1 = "I:\t\xE2\x82\xACa\x06:\x06ET"
symbol2 = "I:\t\xE2\x82\xACb\x06;\x06T"
dump = "\x04\b[\a#{symbol1}#{symbol2}"
value = Marshal.send(@method, dump)
value.map(&:encoding).should == [Encoding::UTF_8, Encoding::UTF_8]
expected = [
"€a".force_encoding(Encoding::UTF_8).to_sym,
"€b".force_encoding(Encoding::UTF_8).to_sym
]
value.should == expected
value = Marshal.send(@method, "\x04\b[\b#{symbol1}#{symbol2};\x00")
value.map(&:encoding).should == [Encoding::UTF_8, Encoding::UTF_8, Encoding::UTF_8]
value.should == [*expected, expected[0]]
end
end
describe "for a String" do
@ -460,20 +479,23 @@ describe :marshal_load, shared: true do
describe "for a Struct" do
it "loads a extended_struct having fields with same objects" do
s = 'hi'
obj = Struct.new("Ure2", :a, :b).new.extend(Meths)
obj = Struct.new("Extended", :a, :b).new.extend(Meths)
dump = "\004\be:\nMethsS:\025Struct::Extended\a:\006a0:\006b0"
Marshal.send(@method, dump).should == obj
obj.a = [:a, s]
obj.b = [:Meths, s]
Marshal.send(@method,
"\004\be:\nMethsS:\021Struct::Ure2\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a"
).should == obj
Struct.send(:remove_const, :Ure2)
dump = "\004\be:\nMethsS:\025Struct::Extended\a:\006a[\a;\a\"\ahi:\006b[\a;\000@\a"
Marshal.send(@method, dump).should == obj
Struct.send(:remove_const, :Extended)
end
it "loads a struct having ivar" do
obj = Struct.new("Thick").new
obj.instance_variable_set(:@foo, 5)
Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n").should == obj
reloaded = Marshal.send(@method, "\004\bIS:\022Struct::Thick\000\006:\t@fooi\n")
reloaded.should == obj
reloaded.instance_variable_get(:@foo).should == 5
Struct.send(:remove_const, :Thick)
end
@ -588,6 +610,18 @@ describe :marshal_load, shared: true do
end
end
describe "for an object responding to #marshal_dump and #marshal_load" do
it "loads a user-marshaled object" do
obj = UserMarshal.new
obj.data = :data
value = [obj, :data]
dump = Marshal.dump(value)
dump.should == "\x04\b[\aU:\x10UserMarshal:\tdata;\x06"
reloaded = Marshal.load(dump)
reloaded.should == value
end
end
describe "for a user object" do
it "loads a user-marshaled extended object" do
obj = UserMarshal.new.extend(Meths)

View file

@ -2,8 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
require_relative '../proc/shared/compose'
ruby_version_is "2.6" do
describe "Method#<<" do
describe "Method#<<" do
it "returns a Proc that is the composition of self and the passed Proc" do
succ = MethodSpecs::Composition.new.method(:succ)
upcase = proc { |s| s.upcase }
@ -50,9 +49,9 @@ ruby_version_is "2.6" do
(inc << mul).call(2, 3).should == 7
end
end
end
end
describe "Method#>>" do
describe "Method#>>" do
it "returns a Proc that is the composition of self and the passed Proc" do
upcase = proc { |s| s.upcase }
succ = MethodSpecs::Composition.new.method(:succ)
@ -98,5 +97,4 @@ ruby_version_is "2.6" do
(mul >> inc).call(2, 3).should == 7
end
end
end
end

View file

@ -376,6 +376,162 @@ describe "Module#include" do
foo.call.should == 'n'
end
it "updates the constant when an included module is updated" do
module ModuleSpecs::ConstUpdated
module A
FOO = 'a'
end
module M
end
module B
include A
include M
def self.foo
FOO
end
end
B.foo.should == 'a'
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
end
it "updates the constant when a module included after a call is later updated" do
module ModuleSpecs::ConstLaterUpdated
module A
FOO = 'a'
end
module B
include A
def self.foo
FOO
end
end
B.foo.should == 'a'
module M
end
B.include M
B.foo.should == 'a'
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
end
it "updates the constant when a module included in another module after a call is later updated" do
module ModuleSpecs::ConstModuleLaterUpdated
module A
FOO = 'a'
end
module B
include A
def self.foo
FOO
end
end
B.foo.should == 'a'
module M
end
B.include M
B.foo.should == 'a'
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
end
it "updates the constant when a nested included module is updated" do
module ModuleSpecs::ConstUpdatedNestedIncludeUpdated
module A
FOO = 'a'
end
module N
end
module M
include N
end
module B
include A
include M
def self.foo
FOO
end
end
B.foo.should == 'a'
N.const_set(:FOO, 'n')
B.foo.should == 'n'
end
end
it "updates the constant when a new module is included" do
module ModuleSpecs::ConstUpdatedNewInclude
module A
FOO = 'a'
end
module M
FOO = 'm'
end
module B
include A
def self.foo
FOO
end
end
B.foo.should == 'a'
B.include(M)
B.foo.should == 'm'
end
end
it "updates the constant when a new module with nested module is included" do
module ModuleSpecs::ConstUpdatedNestedIncluded
module A
FOO = 'a'
end
module N
FOO = 'n'
end
module M
include N
end
module B
include A
def self.foo
FOO
end
end
B.foo.should == 'a'
B.include M
B.foo.should == 'n'
end
end
end
describe "Module#include?" do

View file

@ -47,7 +47,6 @@ describe "Module#method_defined?" do
c.method_defined?(o).should == true
end
ruby_version_is "2.6" do
# works as method_defined?(method_name)
describe "when passed true as a second optional argument" do
it "performs a lookup in ancestors" do
@ -96,5 +95,4 @@ describe "Module#method_defined?" do
ModuleSpecs::Child.method_defined?(:private_super_module, false).should == false
end
end
end
end

View file

@ -222,6 +222,191 @@ describe "Module#prepend" do
foo.call.should == 'n'
end
it "updates the constant when a module is prepended" do
module ModuleSpecs::ConstUpdatePrepended
module M
FOO = 'm'
end
module A
FOO = 'a'
end
module B
include A
def self.foo
FOO
end
end
B.foo.should == 'a'
B.prepend M
B.foo.should == 'm'
end
end
it "updates the constant when a prepended module is updated" do
module ModuleSpecs::ConstPrependedUpdated
module M
end
module A
FOO = 'a'
end
module B
include A
prepend M
def self.foo
FOO
end
end
B.foo.should == 'a'
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
end
it "updates the constant when there is a base included constant and the prepended module overrides it" do
module ModuleSpecs::ConstIncludedPrependedOverride
module Base
FOO = 'a'
end
module A
include Base
def self.foo
FOO
end
end
A.foo.should == 'a'
module M
FOO = 'm'
end
A.prepend M
A.foo.should == 'm'
end
end
it "updates the constant when there is a base included constant and the prepended module is later updated" do
module ModuleSpecs::ConstIncludedPrependedLaterUpdated
module Base
FOO = 'a'
end
module A
include Base
def self.foo
FOO
end
end
A.foo.should == 'a'
module M
end
A.prepend M
A.foo.should == 'a'
M.const_set(:FOO, 'm')
A.foo.should == 'm'
end
end
it "updates the constant when a module prepended after a constant is later updated" do
module ModuleSpecs::ConstUpdatedPrependedAfterLaterUpdated
module M
end
module A
FOO = 'a'
end
module B
include A
def self.foo
FOO
end
end
B.foo.should == 'a'
B.prepend M
B.foo.should == 'a'
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
end
it "updates the constant when a module is prepended after another and the constant is defined later on that module" do
module ModuleSpecs::ConstUpdatedPrependedAfterConstDefined
module M
FOO = 'm'
end
module A
prepend M
def self.foo
FOO
end
end
A.foo.should == 'm'
module N
end
A.prepend N
A.foo.should == 'm'
N.const_set(:FOO, 'n')
A.foo.should == 'n'
end
end
it "updates the constant when a module is included in a prepended module and the constant is defined later" do
module ModuleSpecs::ConstUpdatedIncludedInPrependedConstDefinedLater
module A
def self.foo
FOO
end
end
module Base
FOO = 'a'
end
A.prepend Base
A.foo.should == 'a'
module N
end
module M
include N
end
A.prepend M
N.const_set(:FOO, 'n')
A.foo.should == 'n'
end
end
it "updates the constant when a new module with an included module is prepended" do
module ModuleSpecs::ConstUpdatedNewModuleIncludedPrepended
module A
FOO = 'a'
end
module B
include A
def self.foo
FOO
end
end
module N
FOO = 'n'
end
module M
include N
end
B.foo.should == 'a'
B.prepend M
B.foo.should == 'n'
end
end
it "raises a TypeError when the argument is not a Module" do
-> { ModuleSpecs::Basic.prepend(Class.new) }.should raise_error(TypeError)
end

View file

@ -70,7 +70,6 @@ describe "Module#private_method_defined?" do
ModuleSpecs::CountsMixin.private_method_defined?(str).should == true
end
ruby_version_is "2.6" do
describe "when passed true as a second optional argument" do
it "performs a lookup in ancestors" do
ModuleSpecs::Child.private_method_defined?(:public_child, true).should == false
@ -118,5 +117,4 @@ describe "Module#private_method_defined?" do
ModuleSpecs::Child.private_method_defined?(:private_super_module, false).should == false
end
end
end
end

View file

@ -70,7 +70,6 @@ describe "Module#protected_method_defined?" do
ModuleSpecs::CountsMixin.protected_method_defined?(str).should == true
end
ruby_version_is "2.6" do
describe "when passed true as a second optional argument" do
it "performs a lookup in ancestors" do
ModuleSpecs::Child.protected_method_defined?(:public_child, true).should == false
@ -118,5 +117,4 @@ describe "Module#protected_method_defined?" do
ModuleSpecs::Child.protected_method_defined?(:private_super_module, false).should == false
end
end
end
end

View file

@ -453,27 +453,6 @@ describe "Module#refine" do
result.should == ["(1)", "(2)", "(3)"]
end
ruby_version_is "" ... "2.6" do
it "is not honored by Kernel#public_send" do
refined_class = ModuleSpecs.build_refined_class
refinement = Module.new do
refine refined_class do
def foo; "foo from refinement"; end
end
end
result = nil
Module.new do
using refinement
result = refined_class.new.public_send :foo
end
result.should == "foo"
end
end
ruby_version_is "2.6" do
it "is honored by Kernel#public_send" do
refined_class = ModuleSpecs.build_refined_class
@ -491,7 +470,6 @@ describe "Module#refine" do
result.should == "foo from refinement"
end
end
it "is honored by string interpolation" do
refinement = Module.new do
@ -647,26 +625,6 @@ describe "Module#refine" do
end
end
ruby_version_is "" ... "2.6" do
it "is not honored by Kernel#respond_to?" do
klass = Class.new
refinement = Module.new do
refine klass do
def foo; end
end
end
result = nil
Module.new do
using refinement
result = klass.new.respond_to?(:foo)
end
result.should == false
end
end
ruby_version_is "2.6" do
it "is honored by Kernel#respond_to?" do
klass = Class.new
refinement = Module.new do
@ -683,28 +641,7 @@ describe "Module#refine" do
result.should == true
end
end
ruby_version_is ""..."2.6" do
it "is not honored by &" do
refinement = Module.new do
refine String do
def to_proc(*args)
-> * { 'foo' }
end
end
end
-> do
Module.new do
using refinement
["hola"].map(&"upcase")
end
end.should raise_error(TypeError, /wrong argument type String \(expected Proc\)/)
end
end
ruby_version_is "2.6" do
it "is honored by &" do
refinement = Module.new do
refine String do
@ -723,7 +660,6 @@ describe "Module#refine" do
result.should == ['foo']
end
end
end
context "when super is called in a refinement" do
it "looks in the included to refinery module" do

View file

@ -81,4 +81,25 @@ describe "Module#remove_const" do
ConstantSpecs.autoload :AutoloadedConstant, 'a_file'
ConstantSpecs.send(:remove_const, :AutoloadedConstant).should be_nil
end
it "updates the constant value" do
module ConstantSpecs::RemovedConstantUpdate
module M
FOO = 'm'
end
module A
include M
FOO = 'a'
def self.foo
FOO
end
end
A.foo.should == 'a'
A.send(:remove_const,:FOO)
A.foo.should == 'm'
end
end
end

View file

@ -1,7 +1,6 @@
require_relative '../../spec_helper'
ruby_version_is "2.6" do
describe "NilClass#=~" do
describe "NilClass#=~" do
it "returns nil matching any object" do
o = Object.new
@ -19,5 +18,4 @@ ruby_version_is "2.6" do
it "should not warn" do
-> { nil =~ /a/ }.should_not complain(verbose: true)
end
end
end

View file

@ -257,9 +257,7 @@ describe :numeric_step, :shared => true do
describe "when no block is given" do
step_enum_class = Enumerator
ruby_version_is "2.6" do
step_enum_class = Enumerator::ArithmeticSequence
end
ruby_version_is ""..."3.0" do
it "returns an #{step_enum_class} when step is 0" do

View file

@ -22,9 +22,7 @@ describe "Numeric#step" do
describe "when no block is given" do
step_enum_class = Enumerator
ruby_version_is "2.6" do
step_enum_class = Enumerator::ArithmeticSequence
end
ruby_version_is ""..."3.0" do
it "returns an #{step_enum_class} when step is 0" do
@ -38,19 +36,7 @@ describe "Numeric#step" do
describe "returned #{step_enum_class}" do
describe "size" do
ruby_version_is ""..."2.6" do
it "raises an ArgumentError when step is 0" do
enum = 1.step(5, 0)
-> { enum.size }.should raise_error(ArgumentError)
end
it "raises an ArgumentError when step is 0.0" do
enum = 1.step(2, 0.0)
-> { enum.size }.should raise_error(ArgumentError)
end
end
ruby_version_is "2.6"..."3.0" do
ruby_version_is ""..."3.0" do
it "is infinity when step is 0" do
enum = 1.step(5, 0)
enum.size.should == Float::INFINITY
@ -69,20 +55,12 @@ describe "Numeric#step" do
end
describe "type" do
ruby_version_is ""..."2.6" do
it "returns an instance of Enumerator" do
1.step(10).class.should == Enumerator
end
end
ruby_version_is "2.6" do
it "returns an instance of Enumerator::ArithmeticSequence" do
1.step(10).class.should == Enumerator::ArithmeticSequence
end
end
end
end
end
end

View file

@ -1,8 +1,7 @@
require_relative '../../spec_helper'
require_relative 'shared/compose'
ruby_version_is "2.6" do
describe "Proc#<<" do
describe "Proc#<<" do
it "returns a Proc that is the composition of self and the passed Proc" do
upcase = proc { |s| s.upcase }
succ = proc { |s| s.succ }
@ -83,9 +82,9 @@ ruby_version_is "2.6" do
ScratchPad.recorded.should == [:two]
end
end
end
end
describe "Proc#>>" do
describe "Proc#>>" do
it "returns a Proc that is the composition of self and the passed Proc" do
upcase = proc { |s| s.upcase }
succ = proc { |s| s.succ }
@ -152,5 +151,4 @@ ruby_version_is "2.6" do
ScratchPad.recorded.should == [:one]
end
end
end
end

View file

@ -1,5 +1,5 @@
describe :proc_compose, shared: true do
ruby_version_is "2.6"..."2.7" do
ruby_version_is ""..."2.7" do
it "raises NoMethodError when called if passed not callable object" do
not_callable = Object.new
composed = @object.call.send(@method, not_callable)

View file

@ -551,18 +551,6 @@ describe "Process.spawn" do
platform_is_not :windows do
context "defaults :close_others to" do
ruby_version_is ""..."2.6" do
it "true" do
IO.pipe do |r, w|
w.close_on_exec = false
code = "begin; IO.new(#{w.fileno}).close; rescue Errno::EBADF; puts 'not inherited'; end"
Process.wait Process.spawn(ruby_cmd(code), :out => @name)
File.read(@name).should == "not inherited\n"
end
end
end
ruby_version_is "2.6" do
it "false" do
IO.pipe do |r, w|
w.close_on_exec = false
@ -574,7 +562,6 @@ describe "Process.spawn" do
end
end
end
end
context "when passed close_others: true" do
before :each do

View file

@ -0,0 +1,102 @@
require_relative '../../../spec_helper'
require_relative '../fixtures/common'
ruby_version_is "3.0" do
describe "Process::Status.wait" do
ProcessSpecs.use_system_ruby(self)
before :all do
begin
leaked = Process.waitall
# Ruby-space should not see PIDs used by mjit
raise "subprocesses leaked before wait specs: #{leaked}" unless leaked.empty?
rescue NotImplementedError
end
end
it "returns a status with pid -1 if there are no child processes" do
Process::Status.wait.pid.should == -1
end
platform_is_not :windows do
it "returns a status with its child pid" do
pid = Process.spawn(ruby_cmd('exit'))
status = Process::Status.wait
status.should be_an_instance_of(Process::Status)
status.pid.should == pid
end
it "should not set $? to the Process::Status" do
pid = Process.spawn(ruby_cmd('exit'))
status = Process::Status.wait
$?.should_not equal(status)
end
it "should not change the value of $?" do
pid = Process.spawn(ruby_cmd('exit'))
Process.wait
status = $?
Process::Status.wait
status.should equal($?)
end
it "waits for any child process if no pid is given" do
pid = Process.spawn(ruby_cmd('exit'))
Process::Status.wait.pid.should == pid
-> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH)
end
it "waits for a specific child if a pid is given" do
pid1 = Process.spawn(ruby_cmd('exit'))
pid2 = Process.spawn(ruby_cmd('exit'))
Process::Status.wait(pid2).pid.should == pid2
Process::Status.wait(pid1).pid.should == pid1
-> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH)
-> { Process.kill(0, pid2) }.should raise_error(Errno::ESRCH)
end
it "coerces the pid to an Integer" do
pid1 = Process.spawn(ruby_cmd('exit'))
Process::Status.wait(mock_int(pid1)).pid.should == pid1
-> { Process.kill(0, pid1) }.should raise_error(Errno::ESRCH)
end
# This spec is probably system-dependent.
it "waits for a child whose process group ID is that of the calling process" do
pid1 = Process.spawn(ruby_cmd('exit'), pgroup: true)
pid2 = Process.spawn(ruby_cmd('exit'))
Process::Status.wait(0).pid.should == pid2
Process::Status.wait.pid.should == pid1
end
# This spec is probably system-dependent.
it "doesn't block if no child is available when WNOHANG is used" do
read, write = IO.pipe
pid = Process.fork do
read.close
Signal.trap("TERM") { Process.exit! }
write << 1
write.close
sleep
end
Process::Status.wait(pid, Process::WNOHANG).should be_nil
# wait for the child to setup its TERM handler
write.close
read.read(1)
read.close
Process.kill("TERM", pid)
Process::Status.wait.pid.should == pid
end
it "always accepts flags=0" do
pid = Process.spawn(ruby_cmd('exit'))
Process::Status.wait(-1, 0).pid.should == pid
-> { Process.kill(0, pid) }.should raise_error(Errno::ESRCH)
end
end
end
end

View file

@ -25,8 +25,6 @@ describe "Random#bytes" do
end
end
ruby_version_is "2.6" do
describe "Random.bytes" do
describe "Random.bytes" do
it_behaves_like :random_bytes, :bytes, Random
end
end

View file

@ -4,7 +4,5 @@ require_relative 'shared/rand'
describe "Random.random_number" do
it_behaves_like :random_number, :random_number, Random.new
ruby_version_is "2.6" do
it_behaves_like :random_number, :random_number, Random
end
end

View file

@ -215,7 +215,6 @@ describe "Range#bsearch" do
end
end
ruby_version_is "2.6" do
context "with endless ranges and Integer values" do
context "with a block returning true or false" do
it "returns minimum element if the block returns true for every element" do
@ -329,7 +328,6 @@ describe "Range#bsearch" do
end
end
end
end
ruby_version_is "2.7" do

View file

@ -3,28 +3,10 @@ require_relative 'shared/cover_and_include'
require_relative 'shared/cover'
describe "Range#===" do
ruby_version_is ""..."2.6" do
it "returns the result of calling #include? on self" do
range = 0...10
range.should_receive(:include?).with(2).and_return(:true)
(range === 2).should == :true
end
it "requires #succ method to be implemented" do
range = RangeSpecs::WithoutSucc.new(0)..RangeSpecs::WithoutSucc.new(10)
-> do
range === RangeSpecs::WithoutSucc.new(2)
end.should raise_error(TypeError, /can't iterate from/)
end
end
ruby_version_is "2.6" do
it "returns the result of calling #cover? on self" do
range = RangeSpecs::WithoutSucc.new(0)..RangeSpecs::WithoutSucc.new(10)
(range === RangeSpecs::WithoutSucc.new(2)).should == true
end
end
ruby_version_is "2.7" do
it_behaves_like :range_cover_and_include, :===

View file

@ -38,7 +38,6 @@ describe "Range#each" do
a.should == ["Σ", "Τ", "Υ", "Φ", "Χ", "Ψ", "Ω"]
end
ruby_version_is "2.6" do
it "works with endless ranges" do
a = []
eval("(-2..)").each { |x| break if x > 2; a << x }
@ -58,7 +57,6 @@ describe "Range#each" do
eval("('A'...)").each { |x| break if x > "D"; a << x }
a.should == ["A", "B", "C", "D"]
end
end
ruby_version_is "2.7" do
it "raises a TypeError beginless ranges" do

View file

@ -8,11 +8,9 @@ describe "Range#==" do
(0..1).should == (0..1.0)
end
ruby_version_is "2.6" do
it "returns true if the endpoints are == for endless ranges" do
eval("(1.0..)").should == eval("(1.0..)")
end
end
ruby_version_is "2.7" do
it "returns true if the endpoints are == for beginless ranges" do

Some files were not shown because too many files have changed in this diff Show more