summaryrefslogtreecommitdiff
path: root/spec/ruby/core
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2021-02-27 13:00:26 +0100
committerBenoit Daloze <eregontp@gmail.com>2021-02-27 13:00:26 +0100
commit36dde35e029c7a6607e6c674062ce6fc7a51c0bd (patch)
tree47f9c820a93d5b9a68f7e903cc01ee607913e2dd /spec/ruby/core
parentdbea0be13dc1f44833eca43a73f3ab898fa27c15 (diff)
Update to ruby/spec@37e52e5
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/array/drop_spec.rb13
-rw-r--r--spec/ruby/core/array/drop_while_spec.rb13
-rw-r--r--spec/ruby/core/array/slice_spec.rb58
-rw-r--r--spec/ruby/core/array/take_spec.rb13
-rw-r--r--spec/ruby/core/array/take_while_spec.rb13
-rw-r--r--spec/ruby/core/basicobject/singleton_method_added_spec.rb59
-rw-r--r--spec/ruby/core/dir/children_spec.rb14
-rw-r--r--spec/ruby/core/dir/each_child_spec.rb12
-rw-r--r--spec/ruby/core/dir/entries_spec.rb13
-rw-r--r--spec/ruby/core/dir/foreach_spec.rb12
-rw-r--r--spec/ruby/core/enumerator/lazy/chunk_while_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_after_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_before_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/lazy/slice_when_spec.rb5
-rw-r--r--spec/ruby/core/env/except_spec.rb36
-rw-r--r--spec/ruby/core/io/close_spec.rb43
-rw-r--r--spec/ruby/core/io/fixtures/classes.rb3
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb17
-rw-r--r--spec/ruby/core/kernel/public_send_spec.rb8
-rw-r--r--spec/ruby/core/kernel/shared/method.rb8
-rw-r--r--spec/ruby/core/kernel/shared/require.rb8
-rw-r--r--spec/ruby/core/main/ruby2_keywords_spec.rb11
-rw-r--r--spec/ruby/core/module/attr_accessor_spec.rb15
-rw-r--r--spec/ruby/core/module/attr_writer_spec.rb12
-rw-r--r--spec/ruby/core/module/const_defined_spec.rb5
-rw-r--r--spec/ruby/core/module/const_get_spec.rb8
-rw-r--r--spec/ruby/core/module/refine_spec.rb39
-rw-r--r--spec/ruby/core/proc/shared/call.rb3
-rw-r--r--spec/ruby/core/regexp/case_compare_spec.rb10
-rw-r--r--spec/ruby/core/signal/trap_spec.rb14
-rw-r--r--spec/ruby/core/string/scrub_spec.rb14
-rw-r--r--spec/ruby/core/time/shared/now.rb12
32 files changed, 467 insertions, 39 deletions
diff --git a/spec/ruby/core/array/drop_spec.rb b/spec/ruby/core/array/drop_spec.rb
index 84ea86b04c..f911fd9018 100644
--- a/spec/ruby/core/array/drop_spec.rb
+++ b/spec/ruby/core/array/drop_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#drop" do
it "removes the specified number of elements from the start of the array" do
@@ -48,4 +49,16 @@ describe "Array#drop" do
-> { [1, 2].drop(obj) }.should raise_error(TypeError)
end
+
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop(1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop(1).should be_an_instance_of(Array)
+ end
+ end
end
diff --git a/spec/ruby/core/array/drop_while_spec.rb b/spec/ruby/core/array/drop_while_spec.rb
index cfb6b1e267..bb783d22a5 100644
--- a/spec/ruby/core/array/drop_while_spec.rb
+++ b/spec/ruby/core/array/drop_while_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#drop_while" do
it "removes elements from the start of the array while the block evaluates to true" do
@@ -12,4 +13,16 @@ describe "Array#drop_while" do
it "removes elements from the start of the array until the block returns false" do
[1, 2, 3, false, 5].drop_while { |n| n }.should == [false, 5]
end
+
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop_while { |n| n < 4 }.should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].drop_while { |n| n < 4 }.should be_an_instance_of(Array)
+ end
+ end
end
diff --git a/spec/ruby/core/array/slice_spec.rb b/spec/ruby/core/array/slice_spec.rb
index f416d8d0ce..2f98df9488 100644
--- a/spec/ruby/core/array/slice_spec.rb
+++ b/spec/ruby/core/array/slice_spec.rb
@@ -185,6 +185,64 @@ describe "Array#slice!" do
a.should == [3, 4]
end
end
+
+ describe "with a subclass of Array" do
+ before :each do
+ @array = ArraySpecs::MyArray[1, 2, 3, 4, 5]
+ end
+
+ ruby_version_is ''...'3.0' do
+ it "returns a subclass instance with [n, m]" do
+ @array.slice!(0, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n, m]" do
+ @array.slice!(-3, 2).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [n..m]" do
+ @array.slice!(1..3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [n...m]" do
+ @array.slice!(1...3).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n..-m]" do
+ @array.slice!(-3..-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+
+ it "returns a subclass instance with [-n...-m]" do
+ @array.slice!(-3...-1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it "returns a Array instance with [n, m]" do
+ @array.slice!(0, 2).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n, m]" do
+ @array.slice!(-3, 2).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [n..m]" do
+ @array.slice!(1..3).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [n...m]" do
+ @array.slice!(1...3).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n..-m]" do
+ @array.slice!(-3..-1).should be_an_instance_of(Array)
+ end
+
+ it "returns a Array instance with [-n...-m]" do
+ @array.slice!(-3...-1).should be_an_instance_of(Array)
+ end
+ end
+ end
end
describe "Array#slice" do
diff --git a/spec/ruby/core/array/take_spec.rb b/spec/ruby/core/array/take_spec.rb
index 0de99b0a7e..4fb6f0ce75 100644
--- a/spec/ruby/core/array/take_spec.rb
+++ b/spec/ruby/core/array/take_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#take" do
it "returns the first specified number of elements" do
@@ -24,4 +25,16 @@ describe "Array#take" do
it "raises an ArgumentError when the argument is negative" do
->{ [1].take(-3) }.should raise_error(ArgumentError)
end
+
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take(1).should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take(1).should be_an_instance_of(Array)
+ end
+ end
end
diff --git a/spec/ruby/core/array/take_while_spec.rb b/spec/ruby/core/array/take_while_spec.rb
index f159e6f251..363419b265 100644
--- a/spec/ruby/core/array/take_while_spec.rb
+++ b/spec/ruby/core/array/take_while_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
describe "Array#take_while" do
it "returns all elements until the block returns false" do
@@ -12,4 +13,16 @@ describe "Array#take_while" do
it "returns all elements until the block returns false" do
[1, 2, false, 4].take_while{ |element| element }.should == [1, 2]
end
+
+ ruby_version_is ''...'3.0' do
+ it 'returns a subclass instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take_while { |n| n < 4 }.should be_an_instance_of(ArraySpecs::MyArray)
+ end
+ end
+
+ ruby_version_is '3.0' do
+ it 'returns a Array instance for Array subclasses' do
+ ArraySpecs::MyArray[1, 2, 3, 4, 5].take_while { |n| n < 4 }.should be_an_instance_of(Array)
+ end
+ end
end
diff --git a/spec/ruby/core/basicobject/singleton_method_added_spec.rb b/spec/ruby/core/basicobject/singleton_method_added_spec.rb
index 8d256e22db..ab6b2a2d10 100644
--- a/spec/ruby/core/basicobject/singleton_method_added_spec.rb
+++ b/spec/ruby/core/basicobject/singleton_method_added_spec.rb
@@ -83,4 +83,63 @@ describe "BasicObject#singleton_method_added" do
end
ScratchPad.recorded.should == [:singleton_method_added, :new_method_with_define_method]
end
+
+ describe "when singleton_method_added is undefined" do
+ it "raises NoMethodError for a metaclass" do
+ class BasicObjectSpecs::NoSingletonMethodAdded
+ class << self
+ undef_method :singleton_method_added
+ end
+
+ -> {
+ def self.foo
+ end
+ }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for/)
+ end
+ end
+
+ it "raises NoMethodError for a singleton instance" do
+ object = Object.new
+ class << object
+ undef_method :singleton_method_added
+
+ -> {
+ def foo
+ end
+ }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for #<Object:/)
+
+ -> {
+ define_method(:bar) {}
+ }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for #<Object:/)
+ end
+
+ -> {
+ object.define_singleton_method(:baz) {}
+ }.should raise_error(NoMethodError, /undefined method `singleton_method_added' for #<Object:/)
+ end
+
+ it "calls #method_missing" do
+ ScratchPad.record []
+ object = Object.new
+ class << object
+ def method_missing(*args)
+ ScratchPad << args
+ end
+
+ undef_method :singleton_method_added
+
+ def foo
+ end
+
+ define_method(:bar) {}
+ end
+ object.define_singleton_method(:baz) {}
+
+ ScratchPad.recorded.should == [
+ [:singleton_method_added, :foo],
+ [:singleton_method_added, :bar],
+ [:singleton_method_added, :baz],
+ ]
+ end
+ end
end
diff --git a/spec/ruby/core/dir/children_spec.rb b/spec/ruby/core/dir/children_spec.rb
index e0325a24b8..f890f54eb4 100644
--- a/spec/ruby/core/dir/children_spec.rb
+++ b/spec/ruby/core/dir/children_spec.rb
@@ -100,10 +100,18 @@ ruby_version_is "2.6" do
a.should == %w|.dotfile.ext directory|
end
- it "accepts an options Hash" do
+ it "accepts an encoding keyword for the encoding of the entries" do
@dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8")
- a = @dir.children.sort
- a.should == %w|.dotfile.ext directory|
+ dirs = @dir.to_a.sort
+ dirs.each { |d| d.encoding.should == Encoding::UTF_8 }
+ end
+
+ ruby_version_is ""..."2.7" do
+ it "accepts nil options" do
+ @dir = Dir.new("#{DirSpecs.mock_dir}/deeply/nested", nil)
+ dirs = @dir.to_a.sort
+ dirs.each { |d| d.encoding.should == Encoding.find("filesystem") }
+ end
end
it "returns children encoded with the filesystem encoding by default" do
diff --git a/spec/ruby/core/dir/each_child_spec.rb b/spec/ruby/core/dir/each_child_spec.rb
index 93b4a1aec1..684f42acc0 100644
--- a/spec/ruby/core/dir/each_child_spec.rb
+++ b/spec/ruby/core/dir/each_child_spec.rb
@@ -10,6 +10,18 @@ describe "Dir.each_child" do
DirSpecs.delete_mock_dirs
end
+ it "accepts an encoding keyword for the encoding of the entries" do
+ dirs = Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").to_a.sort
+ dirs.each {|dir| dir.encoding.should == Encoding::UTF_8}
+ end
+
+ ruby_version_is ""..."2.7" do
+ it "accepts nil options" do
+ dirs = Dir.each_child("#{DirSpecs.mock_dir}/deeply/nested", nil).to_a.sort
+ dirs.each {|dir| dir.encoding.should == Encoding.find("filesystem")}
+ end
+ end
+
it "yields all names in an existing directory to the provided block" do
a, b = [], []
diff --git a/spec/ruby/core/dir/entries_spec.rb b/spec/ruby/core/dir/entries_spec.rb
index 33568b6fc4..9aa58657db 100644
--- a/spec/ruby/core/dir/entries_spec.rb
+++ b/spec/ruby/core/dir/entries_spec.rb
@@ -35,9 +35,16 @@ describe "Dir.entries" do
Dir.entries(p)
end
- it "accepts an options Hash" do
- a = Dir.entries("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").sort
- a.should == %w|. .. .dotfile.ext directory|
+ it "accepts an encoding keyword for the encoding of the entries" do
+ dirs = Dir.entries("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").to_a.sort
+ dirs.each {|dir| dir.encoding.should == Encoding::UTF_8}
+ end
+
+ ruby_version_is ""..."2.7" do
+ it "accepts nil options" do
+ dirs = Dir.entries("#{DirSpecs.mock_dir}/deeply/nested", nil).to_a.sort
+ dirs.each {|dir| dir.encoding.should == Encoding.find("filesystem")}
+ end
end
it "returns entries encoded with the filesystem encoding by default" do
diff --git a/spec/ruby/core/dir/foreach_spec.rb b/spec/ruby/core/dir/foreach_spec.rb
index 1560b85f8a..c3ddb27a84 100644
--- a/spec/ruby/core/dir/foreach_spec.rb
+++ b/spec/ruby/core/dir/foreach_spec.rb
@@ -39,6 +39,18 @@ describe "Dir.foreach" do
Dir.foreach(DirSpecs.mock_dir).to_a.sort.should == DirSpecs.expected_paths
end
+ it "accepts an encoding keyword for the encoding of the entries" do
+ dirs = Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", encoding: "utf-8").to_a.sort
+ dirs.each {|dir| dir.encoding.should == Encoding::UTF_8}
+ end
+
+ ruby_version_is ""..."2.7" do
+ it "accepts nil options" do
+ dirs = Dir.foreach("#{DirSpecs.mock_dir}/deeply/nested", nil).to_a.sort
+ dirs.each {|dir| dir.encoding.should == Encoding.find("filesystem")}
+ end
+ end
+
describe "when no block is given" do
it "returns an Enumerator" do
Dir.foreach(DirSpecs.mock_dir).should be_an_instance_of(Enumerator)
diff --git a/spec/ruby/core/enumerator/lazy/chunk_while_spec.rb b/spec/ruby/core/enumerator/lazy/chunk_while_spec.rb
index d555089872..772bd42de9 100644
--- a/spec/ruby/core/enumerator/lazy/chunk_while_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/chunk_while_spec.rb
@@ -6,4 +6,9 @@ describe "Enumerator::Lazy#chunk_while" do
s.lazy.chunk_while { |a, b| false }.first(100).should ==
s.first(100).chunk_while { |a, b| false }.to_a
end
+
+ it "should return a lazy enumerator" do
+ s = 0..Float::INFINITY
+ s.lazy.chunk_while { |a, b| false }.should be_kind_of(Enumerator::Lazy)
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/slice_after_spec.rb b/spec/ruby/core/enumerator/lazy/slice_after_spec.rb
index 438df8d550..8b08a1ecfd 100644
--- a/spec/ruby/core/enumerator/lazy/slice_after_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/slice_after_spec.rb
@@ -6,4 +6,9 @@ describe "Enumerator::Lazy#slice_after" do
s.lazy.slice_after { |n| true }.first(100).should ==
s.first(100).slice_after { |n| true }.to_a
end
+
+ it "should return a lazy enumerator" do
+ s = 0..Float::INFINITY
+ s.lazy.slice_after { |n| true }.should be_kind_of(Enumerator::Lazy)
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/slice_before_spec.rb b/spec/ruby/core/enumerator/lazy/slice_before_spec.rb
index 6c8660c1a1..9c1ec9ba4a 100644
--- a/spec/ruby/core/enumerator/lazy/slice_before_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/slice_before_spec.rb
@@ -6,4 +6,9 @@ describe "Enumerator::Lazy#slice_before" do
s.lazy.slice_before { |n| true }.first(100).should ==
s.first(100).slice_before { |n| true }.to_a
end
+
+ it "should return a lazy enumerator" do
+ s = 0..Float::INFINITY
+ s.lazy.slice_before { |n| true }.should be_kind_of(Enumerator::Lazy)
+ end
end
diff --git a/spec/ruby/core/enumerator/lazy/slice_when_spec.rb b/spec/ruby/core/enumerator/lazy/slice_when_spec.rb
index e7673def47..f83403425d 100644
--- a/spec/ruby/core/enumerator/lazy/slice_when_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/slice_when_spec.rb
@@ -6,4 +6,9 @@ describe "Enumerator::Lazy#slice_when" do
s.lazy.slice_when { |a, b| true }.first(100).should ==
s.first(100).slice_when { |a, b| true }.to_a
end
+
+ it "should return a lazy enumerator" do
+ s = 0..Float::INFINITY
+ s.lazy.slice_when { |a, b| true }.should be_kind_of(Enumerator::Lazy)
+ end
end
diff --git a/spec/ruby/core/env/except_spec.rb b/spec/ruby/core/env/except_spec.rb
new file mode 100644
index 0000000000..cfe5865abe
--- /dev/null
+++ b/spec/ruby/core/env/except_spec.rb
@@ -0,0 +1,36 @@
+require_relative 'spec_helper'
+require_relative 'shared/to_hash'
+
+ruby_version_is "3.0" do
+ describe "ENV.except" do
+ before do
+ @orig_hash = ENV.to_hash
+ end
+
+ after do
+ ENV.replace @orig_hash
+ end
+
+ # Testing the method without arguments is covered via
+ it_behaves_like :env_to_hash, :except
+
+ it "returns a hash without the requested subset" do
+ ENV.clear
+
+ ENV['one'] = '1'
+ ENV['two'] = '2'
+ ENV['three'] = '3'
+
+ ENV.except('one', 'three').should == { 'two' => '2' }
+ end
+
+ it "ignores keys not present in the original hash" do
+ ENV.clear
+
+ ENV['one'] = '1'
+ ENV['two'] = '2'
+
+ ENV.except('one', 'three').should == { 'two' => '2' }
+ end
+ end
+end
diff --git a/spec/ruby/core/io/close_spec.rb b/spec/ruby/core/io/close_spec.rb
index dda82b34de..eb560eaf67 100644
--- a/spec/ruby/core/io/close_spec.rb
+++ b/spec/ruby/core/io/close_spec.rb
@@ -45,19 +45,36 @@ describe "IO#close" do
end
it 'raises an IOError with a clear message' do
- read_io, write_io = IO.pipe
- going_to_read = false
- thread = Thread.new do
- -> do
- going_to_read = true
- read_io.read
- end.should raise_error(IOError, 'stream closed in another thread')
- end
-
- Thread.pass until going_to_read && thread.stop?
- read_io.close
- thread.join
- write_io.close
+ matching_exception = nil
+
+ -> do
+ IOSpecs::THREAD_CLOSE_RETRIES.times do
+ read_io, write_io = IO.pipe
+ going_to_read = false
+
+ thread = Thread.new do
+ begin
+ going_to_read = true
+ read_io.read
+ rescue IOError => ioe
+ if ioe.message == IOSpecs::THREAD_CLOSE_ERROR_MESSAGE
+ matching_exception = ioe
+ end
+ # try again
+ end
+ end
+
+ # best attempt to ensure the thread is actually blocked on read
+ Thread.pass until going_to_read && thread.stop?
+ sleep(0.001)
+
+ read_io.close
+ thread.join
+ write_io.close
+
+ matching_exception&.tap {|ex| raise ex}
+ end
+ end.should raise_error(IOError, IOSpecs::THREAD_CLOSE_ERROR_MESSAGE)
end
end
diff --git a/spec/ruby/core/io/fixtures/classes.rb b/spec/ruby/core/io/fixtures/classes.rb
index 5cc42c9b44..5d81d5fcd9 100644
--- a/spec/ruby/core/io/fixtures/classes.rb
+++ b/spec/ruby/core/io/fixtures/classes.rb
@@ -1,6 +1,9 @@
# -*- encoding: utf-8 -*-
module IOSpecs
+ THREAD_CLOSE_RETRIES = 10
+ THREAD_CLOSE_ERROR_MESSAGE = 'stream closed in another thread'
+
class SubIO < IO
end
diff --git a/spec/ruby/core/kernel/fixtures/classes.rb b/spec/ruby/core/kernel/fixtures/classes.rb
index 8702c925c8..1bf5715c50 100644
--- a/spec/ruby/core/kernel/fixtures/classes.rb
+++ b/spec/ruby/core/kernel/fixtures/classes.rb
@@ -362,18 +362,19 @@ module KernelSpecs
class RespondViaMissing
def respond_to_missing?(method, priv=false)
case method
- when :handled_publicly
- true
- when :handled_privately
- priv
- when :not_handled
- false
- else
- raise "Typo in method name"
+ when :handled_publicly
+ true
+ when :handled_privately
+ priv
+ when :not_handled
+ false
+ else
+ raise "Typo in method name: #{method.inspect}"
end
end
def method_missing(method, *args)
+ raise "the method name should be a Symbol" unless Symbol === method
"Done #{method}(#{args})"
end
end
diff --git a/spec/ruby/core/kernel/public_send_spec.rb b/spec/ruby/core/kernel/public_send_spec.rb
index 6b942a2e4b..4dae419ff9 100644
--- a/spec/ruby/core/kernel/public_send_spec.rb
+++ b/spec/ruby/core/kernel/public_send_spec.rb
@@ -104,5 +104,13 @@ describe "Kernel#public_send" do
}.should raise_error(NoMethodError)
end
+ it "includes `public_send` in the backtrace when passed not enough arguments" do
+ -> { public_send() }.should raise_error(ArgumentError) { |e| e.backtrace[0].should.include?("`public_send'") }
+ end
+
+ it "includes `public_send` in the backtrace when passed a single incorrect argument" do
+ -> { public_send(Object.new) }.should raise_error(TypeError) { |e| e.backtrace[0].should.include?("`public_send'") }
+ end
+
it_behaves_like :basicobject_send, :public_send
end
diff --git a/spec/ruby/core/kernel/shared/method.rb b/spec/ruby/core/kernel/shared/method.rb
index 3418966b1b..8b6ab23fd3 100644
--- a/spec/ruby/core/kernel/shared/method.rb
+++ b/spec/ruby/core/kernel/shared/method.rb
@@ -15,12 +15,18 @@ describe :kernel_method, shared: true do
m.call.should == 'class done'
end
- it "returns a method object if we repond_to_missing? method" do
+ it "returns a method object if respond_to_missing?(method) is true" do
m = KernelSpecs::RespondViaMissing.new.send(@method, :handled_publicly)
m.should be_an_instance_of Method
m.call(42).should == "Done handled_publicly([42])"
end
+ it "the returned method object if respond_to_missing?(method) calls #method_missing with a Symbol name" do
+ m = KernelSpecs::RespondViaMissing.new.send(@method, "handled_publicly")
+ m.should be_an_instance_of Method
+ m.call(42).should == "Done handled_publicly([42])"
+ end
+
it "raises a NameError for an invalid method name" do
class KernelSpecs::Foo; def bar; 'done'; end; end
-> {
diff --git a/spec/ruby/core/kernel/shared/require.rb b/spec/ruby/core/kernel/shared/require.rb
index d656b3b2f2..9a2c38be1a 100644
--- a/spec/ruby/core/kernel/shared/require.rb
+++ b/spec/ruby/core/kernel/shared/require.rb
@@ -546,8 +546,12 @@ describe :kernel_require, shared: true do
ScratchPad.recorded.should == []
end
- it "complex, enumerator, rational and thread are already required" do
- provided = %w[complex enumerator rational thread]
+ provided = %w[complex enumerator rational thread]
+ ruby_version_is "2.7" do
+ provided << 'ruby2_keywords'
+ end
+
+ it "#{provided.join(', ')} are already required" do
features = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems')
provided.each { |feature|
features.should =~ /\b#{feature}\.(rb|so|jar)$/
diff --git a/spec/ruby/core/main/ruby2_keywords_spec.rb b/spec/ruby/core/main/ruby2_keywords_spec.rb
new file mode 100644
index 0000000000..0999cddeed
--- /dev/null
+++ b/spec/ruby/core/main/ruby2_keywords_spec.rb
@@ -0,0 +1,11 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "2.7" do
+ describe "main.ruby2_keywords" do
+ it "is the same as Object.ruby2_keywords" do
+ main = TOPLEVEL_BINDING.receiver
+ main.should have_private_method(:ruby2_keywords)
+ end
+ end
+end
diff --git a/spec/ruby/core/module/attr_accessor_spec.rb b/spec/ruby/core/module/attr_accessor_spec.rb
index e6a6ac7b66..ba5289cbea 100644
--- a/spec/ruby/core/module/attr_accessor_spec.rb
+++ b/spec/ruby/core/module/attr_accessor_spec.rb
@@ -33,7 +33,20 @@ describe "Module#attr_accessor" do
attr_accessor :spec_attr_accessor
end
- -> { true.spec_attr_accessor = "a" }.should raise_error(RuntimeError)
+ -> { true.spec_attr_accessor = "a" }.should raise_error(FrozenError)
+ end
+
+ it "raises FrozenError if the receiver if frozen" do
+ c = Class.new do
+ attr_accessor :foo
+ end
+ obj = c.new
+ obj.foo = 1
+ obj.foo.should == 1
+
+ obj.freeze
+ -> { obj.foo = 42 }.should raise_error(FrozenError)
+ obj.foo.should == 1
end
it "converts non string/symbol names to strings using to_str" do
diff --git a/spec/ruby/core/module/attr_writer_spec.rb b/spec/ruby/core/module/attr_writer_spec.rb
index dbf30c8144..0e9d201317 100644
--- a/spec/ruby/core/module/attr_writer_spec.rb
+++ b/spec/ruby/core/module/attr_writer_spec.rb
@@ -29,7 +29,17 @@ describe "Module#attr_writer" do
attr_writer :spec_attr_writer
end
- -> { true.spec_attr_writer = "a" }.should raise_error(RuntimeError)
+ -> { true.spec_attr_writer = "a" }.should raise_error(FrozenError)
+ end
+
+ it "raises FrozenError if the receiver if frozen" do
+ c = Class.new do
+ attr_writer :foo
+ end
+ obj = c.new
+ obj.freeze
+
+ -> { obj.foo = 42 }.should raise_error(FrozenError)
end
it "converts non string/symbol names to strings using to_str" do
diff --git a/spec/ruby/core/module/const_defined_spec.rb b/spec/ruby/core/module/const_defined_spec.rb
index 0673adca3d..75730395e8 100644
--- a/spec/ruby/core/module/const_defined_spec.rb
+++ b/spec/ruby/core/module/const_defined_spec.rb
@@ -40,6 +40,11 @@ describe "Module#const_defined?" do
ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST4, true).should be_true
end
+ it "coerces the inherit flag to a boolean" do
+ ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST4, nil).should be_false
+ ConstantSpecs::ContainerA::ChildA.const_defined?(:CS_CONST4, :true).should be_true
+ end
+
it "returns true if the given String names a constant defined in the receiver" do
ConstantSpecs.const_defined?("CS_CONST2").should == true
ConstantSpecs.const_defined?("ModuleA").should == true
diff --git a/spec/ruby/core/module/const_get_spec.rb b/spec/ruby/core/module/const_get_spec.rb
index 0a6702903f..9f9fafe5bb 100644
--- a/spec/ruby/core/module/const_get_spec.rb
+++ b/spec/ruby/core/module/const_get_spec.rb
@@ -88,6 +88,14 @@ describe "Module#const_get" do
end.should raise_error(NameError)
end
+ it "coerces the inherit flag to a boolean" do
+ ConstantSpecs::ContainerA::ChildA.const_get(:CS_CONST4, :true).should == :const4
+
+ -> do
+ ConstantSpecs::ContainerA::ChildA.const_get(:CS_CONST1, nil)
+ end.should raise_error(NameError)
+ end
+
it "accepts a toplevel scope qualifier" do
ConstantSpecs.const_get("::CS_CONST1").should == :const1
end
diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb
index 54217a9326..e5f65f5f96 100644
--- a/spec/ruby/core/module/refine_spec.rb
+++ b/spec/ruby/core/module/refine_spec.rb
@@ -574,6 +574,43 @@ describe "Module#refine" do
end
ruby_version_is "" ... "2.7" do
+ it "is not honored by Kernel#public_method" do
+ klass = Class.new
+ refinement = Module.new do
+ refine klass do
+ def foo; end
+ end
+ end
+
+ -> {
+ Module.new do
+ using refinement
+ klass.new.public_method(:foo)
+ end
+ }.should raise_error(NameError, /undefined method `foo'/)
+ end
+ end
+
+ ruby_version_is "2.7" do
+ it "is honored by Kernel#public_method" 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.public_method(:foo).class
+ end
+
+ result.should == Method
+ end
+ end
+
+ ruby_version_is "" ... "2.7" do
it "is not honored by Kernel#instance_method" do
klass = Class.new
refinement = Module.new do
@@ -592,7 +629,7 @@ describe "Module#refine" do
end
ruby_version_is "2.7" do
- it "is honored by Kernel#method" do
+ it "is honored by Kernel#instance_method" do
klass = Class.new
refinement = Module.new do
refine klass do
diff --git a/spec/ruby/core/proc/shared/call.rb b/spec/ruby/core/proc/shared/call.rb
index c30ea84b23..dbec34df4b 100644
--- a/spec/ruby/core/proc/shared/call.rb
+++ b/spec/ruby/core/proc/shared/call.rb
@@ -49,6 +49,9 @@ describe :proc_call_on_proc_or_lambda, shared: true do
a = proc {|x| x}.send(@method, 1, 2, 3)
a.should == 1
+
+ a = proc {|x:| x}.send(@method, 2, x: 1)
+ a.should == 1
end
it "will call #to_ary on argument and return self if return is nil" do
diff --git a/spec/ruby/core/regexp/case_compare_spec.rb b/spec/ruby/core/regexp/case_compare_spec.rb
index a621713f6f..5ae8b56c6a 100644
--- a/spec/ruby/core/regexp/case_compare_spec.rb
+++ b/spec/ruby/core/regexp/case_compare_spec.rb
@@ -22,4 +22,14 @@ describe "Regexp#===" do
(/abc/ === nil).should be_false
(/abc/ === /abc/).should be_false
end
+
+ it "uses #to_str on string-like objects" do
+ stringlike = Class.new do
+ def to_str
+ "abc"
+ end
+ end.new
+
+ (/abc/ === stringlike).should be_true
+ end
end
diff --git a/spec/ruby/core/signal/trap_spec.rb b/spec/ruby/core/signal/trap_spec.rb
index 831a5ee23e..45879b7147 100644
--- a/spec/ruby/core/signal/trap_spec.rb
+++ b/spec/ruby/core/signal/trap_spec.rb
@@ -49,7 +49,21 @@ platform_is_not :windows do
it "registers an handler doing nothing with :IGNORE" do
Signal.trap :HUP, :IGNORE
+ Signal.trap(:HUP, @saved_trap).should == "IGNORE"
+ end
+
+ it "can register a new handler after :IGNORE" do
+ Signal.trap :HUP, :IGNORE
+
+ done = false
+ Signal.trap(:HUP) do
+ ScratchPad.record :block_trap
+ done = true
+ end
+
Process.kill(:HUP, Process.pid).should == 1
+ Thread.pass until done
+ ScratchPad.recorded.should == :block_trap
end
it "ignores the signal when passed nil" do
diff --git a/spec/ruby/core/string/scrub_spec.rb b/spec/ruby/core/string/scrub_spec.rb
index 86fd4e85ba..b513acfb70 100644
--- a/spec/ruby/core/string/scrub_spec.rb
+++ b/spec/ruby/core/string/scrub_spec.rb
@@ -105,4 +105,18 @@ describe "String#scrub!" do
input.scrub! { |b| "<?>" }
input.should == "a<?>"
end
+
+ it "maintains the state of frozen strings that are already valid" do
+ input = "a"
+ input.freeze
+ input.scrub!
+ input.frozen?.should be_true
+ end
+
+ it "preserves the instance variables of already valid strings" do
+ input = "a"
+ input.instance_variable_set(:@a, 'b')
+ input.scrub!
+ input.instance_variable_get(:@a).should == 'b'
+ end
end
diff --git a/spec/ruby/core/time/shared/now.rb b/spec/ruby/core/time/shared/now.rb
index 80f66a1134..f4018d72f4 100644
--- a/spec/ruby/core/time/shared/now.rb
+++ b/spec/ruby/core/time/shared/now.rb
@@ -19,15 +19,15 @@ describe :time_now, shared: true do
end
it "has at least microsecond precision" do
- times = []
- 10_000.times do
- times << Time.now.nsec
- end
-
# The clock should not be less accurate than expected (times should
# not all be a multiple of the next precision up, assuming precisions
# are multiples of ten.)
expected = 1_000
- times.select { |t| t % (expected * 10) == 0 }.size.should_not == times.size
+ t = 0
+ 10_000.times.find do
+ t = Time.now.nsec
+ t % (expected * 10) != 0
+ end
+ (t % (expected * 10)).should != 0
end
end