summaryrefslogtreecommitdiff
path: root/spec/ruby/core
diff options
context:
space:
mode:
authorBenoit Daloze <eregontp@gmail.com>2023-09-04 16:07:46 +0200
committerBenoit Daloze <eregontp@gmail.com>2023-09-04 16:07:46 +0200
commit0b5c61494eb30c8c1867b9e6a52ad678e3f47901 (patch)
tree30ca3af5dadae196c39dae8c7e35c28b0537dd4a /spec/ruby/core
parent3504f928dfb60b763e7b66149ca45cdbb45df78a (diff)
Update to ruby/spec@96d1072
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/class/dup_spec.rb3
-rw-r--r--spec/ruby/core/data/fixtures/classes.rb2
-rw-r--r--spec/ruby/core/dir/exist_spec.rb8
-rw-r--r--spec/ruby/core/dir/shared/chroot.rb4
-rw-r--r--spec/ruby/core/dir/shared/exist.rb8
-rw-r--r--spec/ruby/core/enumerator/chain/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/each_spec.rb18
-rw-r--r--spec/ruby/core/enumerator/generator/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/lazy/initialize_spec.rb4
-rw-r--r--spec/ruby/core/enumerator/product/each_spec.rb73
-rw-r--r--spec/ruby/core/enumerator/product/initialize_copy_spec.rb54
-rw-r--r--spec/ruby/core/enumerator/product/initialize_spec.rb33
-rw-r--r--spec/ruby/core/enumerator/product/inspect_spec.rb22
-rw-r--r--spec/ruby/core/enumerator/product/rewind_spec.rb64
-rw-r--r--spec/ruby/core/enumerator/product/size_spec.rb64
-rw-r--r--spec/ruby/core/enumerator/product_spec.rb5
-rw-r--r--spec/ruby/core/enumerator/rewind_spec.rb4
-rw-r--r--spec/ruby/core/env/delete_spec.rb8
-rw-r--r--spec/ruby/core/env/key_spec.rb32
-rw-r--r--spec/ruby/core/env/shared/include.rb7
-rw-r--r--spec/ruby/core/env/shared/key.rb31
-rw-r--r--spec/ruby/core/env/shared/value.rb7
-rw-r--r--spec/ruby/core/env/slice_spec.rb10
-rw-r--r--spec/ruby/core/exception/equal_value_spec.rb14
-rw-r--r--spec/ruby/core/false/singleton_method_spec.rb6
-rw-r--r--spec/ruby/core/fiber/storage_spec.rb92
-rw-r--r--spec/ruby/core/file/absolute_path_spec.rb2
-rw-r--r--spec/ruby/core/file/exist_spec.rb8
-rw-r--r--spec/ruby/core/file/open_spec.rb2
-rw-r--r--spec/ruby/core/file/realpath_spec.rb4
-rw-r--r--spec/ruby/core/io/eof_spec.rb2
-rw-r--r--spec/ruby/core/io/getbyte_spec.rb16
-rw-r--r--spec/ruby/core/io/new_spec.rb2
-rw-r--r--spec/ruby/core/io/select_spec.rb15
-rw-r--r--spec/ruby/core/io/shared/new.rb2
-rw-r--r--spec/ruby/core/kernel/initialize_copy_spec.rb9
-rw-r--r--spec/ruby/core/kernel/require_relative_spec.rb8
-rw-r--r--spec/ruby/core/kernel/shared/sprintf.rb4
-rw-r--r--spec/ruby/core/kernel/test_spec.rb4
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb15
-rw-r--r--spec/ruby/core/marshal/shared/load.rb8
-rw-r--r--spec/ruby/core/method/source_location_spec.rb2
-rw-r--r--spec/ruby/core/module/const_added_spec.rb35
-rw-r--r--spec/ruby/core/module/define_method_spec.rb27
-rw-r--r--spec/ruby/core/mutex/lock_spec.rb4
-rw-r--r--spec/ruby/core/nil/singleton_method_spec.rb6
-rw-r--r--spec/ruby/core/numeric/clone_spec.rb2
-rw-r--r--spec/ruby/core/proc/source_location_spec.rb8
-rw-r--r--spec/ruby/core/process/argv0_spec.rb2
-rw-r--r--spec/ruby/core/process/exec_spec.rb2
-rw-r--r--spec/ruby/core/process/spawn_spec.rb2
-rw-r--r--spec/ruby/core/random/bytes_spec.rb1
-rw-r--r--spec/ruby/core/range/cover_spec.rb4
-rw-r--r--spec/ruby/core/range/include_spec.rb4
-rw-r--r--spec/ruby/core/range/shared/cover_and_include.rb1
-rw-r--r--spec/ruby/core/refinement/extend_object_spec.rb6
-rw-r--r--spec/ruby/core/struct/constants_spec.rb15
-rw-r--r--spec/ruby/core/thread/backtrace/location/path_spec.rb2
-rw-r--r--spec/ruby/core/true/singleton_method_spec.rb6
-rw-r--r--spec/ruby/core/unboundmethod/source_location_spec.rb2
-rw-r--r--spec/ruby/core/warning/element_reference_spec.rb4
-rw-r--r--spec/ruby/core/warning/element_set_spec.rb12
63 files changed, 687 insertions, 146 deletions
diff --git a/spec/ruby/core/class/dup_spec.rb b/spec/ruby/core/class/dup_spec.rb
index 701fd72e19..c09ed71b31 100644
--- a/spec/ruby/core/class/dup_spec.rb
+++ b/spec/ruby/core/class/dup_spec.rb
@@ -61,4 +61,7 @@ describe "Class#dup" do
CoreClassSpecs::RecordCopy.name.should == "CoreClassSpecs::RecordCopy"
end
+ it "raises TypeError if called on BasicObject" do
+ -> { BasicObject.dup }.should raise_error(TypeError, "can't copy the root class")
+ end
end
diff --git a/spec/ruby/core/data/fixtures/classes.rb b/spec/ruby/core/data/fixtures/classes.rb
index d1e10e02ed..46a6b48bb2 100644
--- a/spec/ruby/core/data/fixtures/classes.rb
+++ b/spec/ruby/core/data/fixtures/classes.rb
@@ -1,5 +1,5 @@
module DataSpecs
- ruby_version_is "3.2" do
+ guard -> { ruby_version_is "3.2" and Data.respond_to?(:define) } do
Measure = Data.define(:amount, :unit)
end
end
diff --git a/spec/ruby/core/dir/exist_spec.rb b/spec/ruby/core/dir/exist_spec.rb
index 43987b0f32..9023de533f 100644
--- a/spec/ruby/core/dir/exist_spec.rb
+++ b/spec/ruby/core/dir/exist_spec.rb
@@ -13,3 +13,11 @@ describe "Dir.exist?" do
it_behaves_like :dir_exist, :exist?
end
+
+ruby_version_is "3.2" do
+ describe "Dir.exists?" do
+ it "has been removed" do
+ Dir.should_not.respond_to?(:exists?)
+ end
+ end
+end
diff --git a/spec/ruby/core/dir/shared/chroot.rb b/spec/ruby/core/dir/shared/chroot.rb
index 8c0599fe3f..a8f7c10a19 100644
--- a/spec/ruby/core/dir/shared/chroot.rb
+++ b/spec/ruby/core/dir/shared/chroot.rb
@@ -2,7 +2,7 @@ describe :dir_chroot_as_root, shared: true do
before :all do
DirSpecs.create_mock_dirs
- @real_root = "../" * (File.dirname(__FILE__).count('/') - 1)
+ @real_root = "../" * (__dir__.count('/') - 1)
@ref_dir = File.join("/", File.basename(Dir["/*"].first))
end
@@ -18,7 +18,7 @@ describe :dir_chroot_as_root, shared: true do
compilations_ci = ENV["GITHUB_WORKFLOW"] == "Compilations"
it "can be used to change the process' root directory" do
- -> { Dir.send(@method, File.dirname(__FILE__)) }.should_not raise_error
+ -> { Dir.send(@method, __dir__) }.should_not raise_error
File.should.exist?("/#{File.basename(__FILE__)}")
end unless compilations_ci
diff --git a/spec/ruby/core/dir/shared/exist.rb b/spec/ruby/core/dir/shared/exist.rb
index 765d1b656c..2ea4f88a80 100644
--- a/spec/ruby/core/dir/shared/exist.rb
+++ b/spec/ruby/core/dir/shared/exist.rb
@@ -1,6 +1,6 @@
describe :dir_exist, shared: true do
it "returns true if the given directory exists" do
- Dir.send(@method, File.dirname(__FILE__)).should be_true
+ Dir.send(@method, __dir__).should be_true
end
it "returns true for '.'" do
@@ -20,7 +20,7 @@ describe :dir_exist, shared: true do
end
it "understands relative paths" do
- Dir.send(@method, File.dirname(__FILE__) + '/../').should be_true
+ Dir.send(@method, __dir__ + '/../').should be_true
end
it "returns false if the given directory doesn't exist" do
@@ -28,7 +28,7 @@ describe :dir_exist, shared: true do
end
it "doesn't require the name to have a trailing slash" do
- dir = File.dirname(__FILE__)
+ dir = __dir__
dir.sub!(/\/$/,'')
Dir.send(@method, dir).should be_true
end
@@ -50,7 +50,7 @@ describe :dir_exist, shared: true do
it "calls #to_path on non String arguments" do
p = mock('path')
- p.should_receive(:to_path).and_return(File.dirname(__FILE__))
+ p.should_receive(:to_path).and_return(__dir__)
Dir.send(@method, p)
end
end
diff --git a/spec/ruby/core/enumerator/chain/initialize_spec.rb b/spec/ruby/core/enumerator/chain/initialize_spec.rb
index 69484dfcb4..daa30351d7 100644
--- a/spec/ruby/core/enumerator/chain/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/chain/initialize_spec.rb
@@ -22,10 +22,10 @@ describe "Enumerator::Chain#initialize" do
end
describe "on frozen instance" do
- it "raises a RuntimeError" do
+ it "raises a FrozenError" do
-> {
@uninitialized.freeze.send(:initialize)
- }.should raise_error(RuntimeError)
+ }.should raise_error(FrozenError)
end
end
end
diff --git a/spec/ruby/core/enumerator/each_spec.rb b/spec/ruby/core/enumerator/each_spec.rb
index 99ac3120af..3af16e5587 100644
--- a/spec/ruby/core/enumerator/each_spec.rb
+++ b/spec/ruby/core/enumerator/each_spec.rb
@@ -10,41 +10,41 @@ describe "Enumerator#each" do
@enum_with_arguments = object_each_with_arguments.to_enum(:each_with_arguments, :arg0, :arg1, :arg2)
- @enum_with_yielder = Enumerator.new {|y| y.yield :ok}
+ @enum_with_yielder = Enumerator.new { |y| y.yield :ok }
end
it "yields each element of self to the given block" do
acc = []
- [1,2,3].to_enum.each {|e| acc << e }
- acc.should == [1,2,3]
+ [1, 2, 3].to_enum.each { |e| acc << e }
+ acc.should == [1, 2, 3]
end
it "calls #each on the object given in the constructor by default" do
each = mock('each')
each.should_receive(:each)
- each.to_enum.each {|e| e }
+ each.to_enum.each { |e| e }
end
it "calls #each on the underlying object until it's exhausted" do
each = mock('each')
each.should_receive(:each).and_yield(1).and_yield(2).and_yield(3)
acc = []
- each.to_enum.each {|e| acc << e }
- acc.should == [1,2,3]
+ each.to_enum.each { |e| acc << e }
+ acc.should == [1, 2, 3]
end
it "calls the method given in the constructor instead of #each" do
each = mock('peach')
each.should_receive(:peach)
- each.to_enum(:peach).each {|e| e }
+ each.to_enum(:peach).each { |e| e }
end
it "calls the method given in the constructor until it's exhausted" do
each = mock('peach')
each.should_receive(:peach).and_yield(1).and_yield(2).and_yield(3)
acc = []
- each.to_enum(:peach).each {|e| acc << e }
- acc.should == [1,2,3]
+ each.to_enum(:peach).each { |e| acc << e }
+ acc.should == [1, 2, 3]
end
it "raises a NoMethodError if the object doesn't respond to #each" do
diff --git a/spec/ruby/core/enumerator/generator/initialize_spec.rb b/spec/ruby/core/enumerator/generator/initialize_spec.rb
index f75c7d6f26..acc1174253 100644
--- a/spec/ruby/core/enumerator/generator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/generator/initialize_spec.rb
@@ -17,10 +17,10 @@ describe "Enumerator::Generator#initialize" do
end
describe "on frozen instance" do
- it "raises a RuntimeError" do
+ it "raises a FrozenError" do
-> {
@uninitialized.freeze.send(:initialize) {}
- }.should raise_error(RuntimeError)
+ }.should raise_error(FrozenError)
end
end
end
diff --git a/spec/ruby/core/enumerator/initialize_spec.rb b/spec/ruby/core/enumerator/initialize_spec.rb
index 5e937aff2b..5e0256ca46 100644
--- a/spec/ruby/core/enumerator/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/initialize_spec.rb
@@ -48,10 +48,10 @@ describe "Enumerator#initialize" do
end
describe "on frozen instance" do
- it "raises a RuntimeError" do
+ it "raises a FrozenError" do
-> {
@uninitialized.freeze.send(:initialize) {}
- }.should raise_error(RuntimeError)
+ }.should raise_error(FrozenError)
end
end
end
diff --git a/spec/ruby/core/enumerator/lazy/initialize_spec.rb b/spec/ruby/core/enumerator/lazy/initialize_spec.rb
index f23018d010..e1e0b1d608 100644
--- a/spec/ruby/core/enumerator/lazy/initialize_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/initialize_spec.rb
@@ -56,8 +56,8 @@ describe "Enumerator::Lazy#initialize" do
end
describe "on frozen instance" do
- it "raises a RuntimeError" do
- -> { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(RuntimeError)
+ it "raises a FrozenError" do
+ -> { @uninitialized.freeze.send(:initialize, @receiver) {} }.should raise_error(FrozenError)
end
end
end
diff --git a/spec/ruby/core/enumerator/product/each_spec.rb b/spec/ruby/core/enumerator/product/each_spec.rb
new file mode 100644
index 0000000000..868a1ea6bf
--- /dev/null
+++ b/spec/ruby/core/enumerator/product/each_spec.rb
@@ -0,0 +1,73 @@
+require_relative '../../../spec_helper'
+require_relative '../../enumerable/shared/enumeratorized'
+
+ruby_version_is "3.2" do
+ describe "Enumerator::Product#each" do
+ it_behaves_like :enumeratorized_with_origin_size, :each, Enumerator::Product.new([1, 2], [:a, :b])
+
+ it "yields each element of Cartesian product of enumerators" do
+ enum = Enumerator::Product.new([1, 2], [:a, :b])
+ acc = []
+ enum.each { |e| acc << e }
+ acc.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ end
+
+ it "calls #each_entry method on enumerators" do
+ object1 = Object.new
+ def object1.each_entry
+ yield 1
+ yield 2
+ end
+
+ object2 = Object.new
+ def object2.each_entry
+ yield :a
+ yield :b
+ end
+
+ enum = Enumerator::Product.new(object1, object2)
+ acc = []
+ enum.each { |e| acc << e }
+ acc.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ end
+
+ it "raises a NoMethodError if the object doesn't respond to #each_entry" do
+ -> {
+ Enumerator::Product.new(Object.new).each {}
+ }.should raise_error(NoMethodError, /undefined method `each_entry' for/)
+ end
+
+ it "returns enumerator if not given a block" do
+ enum = Enumerator::Product.new([1, 2], [:a, :b])
+ enum.each.should.kind_of?(Enumerator)
+
+ enum = Enumerator::Product.new([1, 2], [:a, :b])
+ enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ end
+
+ it "returns self if given a block" do
+ enum = Enumerator::Product.new([1, 2], [:a, :b])
+ enum.each {}.should.equal?(enum)
+ end
+
+ it "doesn't accept arguments" do
+ Enumerator::Product.instance_method(:each).arity.should == 0
+ end
+
+ it "yields each element to a block that takes multiple arguments" do
+ enum = Enumerator::Product.new([1, 2], [:a, :b])
+
+ acc = []
+ enum.each { |x, y| acc << x }
+ acc.should == [1, 1, 2, 2]
+
+ acc = []
+ enum.each { |x, y| acc << y }
+ acc.should == [:a, :b, :a, :b]
+
+ acc = []
+ enum.each { |x, y, z| acc << z }
+ acc.should == [nil, nil, nil, nil]
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/product/initialize_copy_spec.rb b/spec/ruby/core/enumerator/product/initialize_copy_spec.rb
new file mode 100644
index 0000000000..46e8421322
--- /dev/null
+++ b/spec/ruby/core/enumerator/product/initialize_copy_spec.rb
@@ -0,0 +1,54 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "3.2" do
+ describe "Enumerator::Product#initialize_copy" do
+ it "replaces content of the receiver with content of the other object" do
+ enum = Enumerator::Product.new([true, false])
+ enum2 = Enumerator::Product.new([1, 2], [:a, :b])
+
+ enum.send(:initialize_copy, enum2)
+ enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ end
+
+ it "returns self" do
+ enum = Enumerator::Product.new([true, false])
+ enum2 = Enumerator::Product.new([1, 2], [:a, :b])
+
+ enum.send(:initialize_copy, enum2).should.equal?(enum)
+ end
+
+ it "is a private method" do
+ Enumerator::Product.should have_private_instance_method(:initialize_copy, false)
+ end
+
+ it "does nothing if the argument is the same as the receiver" do
+ enum = Enumerator::Product.new(1..2)
+ enum.send(:initialize_copy, enum).should.equal?(enum)
+
+ enum.freeze
+ enum.send(:initialize_copy, enum).should.equal?(enum)
+ end
+
+ it "raises FrozenError if the receiver is frozen" do
+ enum = Enumerator::Product.new(1..2)
+ enum2 = Enumerator::Product.new(3..4)
+
+ -> { enum.freeze.send(:initialize_copy, enum2) }.should raise_error(FrozenError)
+ end
+
+ it "raises TypeError if the objects are of different class" do
+ enum = Enumerator::Product.new(1..2)
+ enum2 = Class.new(Enumerator::Product).new(3..4)
+
+ -> { enum.send(:initialize_copy, enum2) }.should raise_error(TypeError, 'initialize_copy should take same class object')
+ -> { enum2.send(:initialize_copy, enum) }.should raise_error(TypeError, 'initialize_copy should take same class object')
+ end
+
+ it "raises ArgumentError if the argument is not initialized yet" do
+ enum = Enumerator::Product.new(1..2)
+ enum2 = Enumerator::Product.allocate
+
+ -> { enum.send(:initialize_copy, enum2) }.should raise_error(ArgumentError, 'uninitialized product')
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/product/initialize_spec.rb b/spec/ruby/core/enumerator/product/initialize_spec.rb
new file mode 100644
index 0000000000..4b60564240
--- /dev/null
+++ b/spec/ruby/core/enumerator/product/initialize_spec.rb
@@ -0,0 +1,33 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "3.2" do
+ describe "Enumerator::Product#initialize" do
+ before :each do
+ @uninitialized = Enumerator::Product.allocate
+ end
+
+ it "is a private method" do
+ Enumerator::Product.should have_private_instance_method(:initialize, false)
+ end
+
+ it "returns self" do
+ @uninitialized.send(:initialize).should equal(@uninitialized)
+ end
+
+ it "accepts many arguments" do
+ @uninitialized.send(:initialize, 0..1, 2..3, 4..5).should equal(@uninitialized)
+ end
+
+ it "accepts arguments that are not Enumerable nor responding to :each_entry" do
+ @uninitialized.send(:initialize, Object.new).should equal(@uninitialized)
+ end
+
+ describe "on frozen instance" do
+ it "raises a FrozenError" do
+ -> {
+ @uninitialized.freeze.send(:initialize, 0..1)
+ }.should raise_error(FrozenError)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/product/inspect_spec.rb b/spec/ruby/core/enumerator/product/inspect_spec.rb
new file mode 100644
index 0000000000..1ea8e9c49b
--- /dev/null
+++ b/spec/ruby/core/enumerator/product/inspect_spec.rb
@@ -0,0 +1,22 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "3.2" do
+ describe "Enumerator::Product#inspect" do
+ it "returns a String including enumerators" do
+ enum = Enumerator::Product.new([1, 2], [:a, :b])
+ enum.inspect.should == "#<Enumerator::Product: [[1, 2], [:a, :b]]>"
+ end
+
+ it "represents a recursive element with '[...]'" do
+ enum = [1, 2]
+ enum_recursive = Enumerator::Product.new(enum)
+
+ enum << enum_recursive
+ enum_recursive.inspect.should == "#<Enumerator::Product: [[1, 2, #<Enumerator::Product: ...>]]>"
+ end
+
+ it "returns a not initialized representation if #initialized is not called yet" do
+ Enumerator::Product.allocate.inspect.should == "#<Enumerator::Product: uninitialized>"
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/product/rewind_spec.rb b/spec/ruby/core/enumerator/product/rewind_spec.rb
new file mode 100644
index 0000000000..e8ee730239
--- /dev/null
+++ b/spec/ruby/core/enumerator/product/rewind_spec.rb
@@ -0,0 +1,64 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "3.2" do
+ describe "Enumerator::Product#rewind" do
+ before :each do
+ @enum = Enumerator::Product.new([1, 2].each.to_enum, [:a, :b].each.to_enum)
+ end
+
+ it "resets the enumerator to its initial state" do
+ @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ @enum.rewind
+ @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ end
+
+ it "returns self" do
+ @enum.rewind.should.equal? @enum
+ end
+
+ it "has no effect on a new enumerator" do
+ @enum.rewind
+ @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ end
+
+ it "has no effect if called multiple, consecutive times" do
+ @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ @enum.rewind
+ @enum.rewind
+ @enum.each.to_a.should == [[1, :a], [1, :b], [2, :a], [2, :b]]
+ end
+
+ it "calls the enclosed object's rewind method if one exists" do
+ obj = mock('rewinder')
+ enum = Enumerator::Product.new(obj.to_enum)
+
+ obj.should_receive(:rewind)
+ enum.rewind
+ end
+
+ it "does nothing if the object doesn't have a #rewind method" do
+ obj = mock('rewinder')
+ enum = Enumerator::Product.new(obj.to_enum)
+
+ enum.rewind.should == enum
+ end
+
+ it "calls a rewind method on each enumerable in direct order" do
+ ScratchPad.record []
+
+ object1 = Object.new
+ def object1.rewind; ScratchPad << :object1; end
+
+ object2 = Object.new
+ def object2.rewind; ScratchPad << :object2; end
+
+ object3 = Object.new
+ def object3.rewind; ScratchPad << :object3; end
+
+ enum = Enumerator::Product.new(object1, object2, object3)
+ enum.rewind
+
+ ScratchPad.recorded.should == [:object1, :object2, :object3]
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/product/size_spec.rb b/spec/ruby/core/enumerator/product/size_spec.rb
new file mode 100644
index 0000000000..fb0efdf748
--- /dev/null
+++ b/spec/ruby/core/enumerator/product/size_spec.rb
@@ -0,0 +1,64 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is "3.2" do
+ describe "Enumerator::Product#size" do
+ it "returns the total size of the enumerator product calculated by multiplying the sizes of enumerables in the product" do
+ product = Enumerator::Product.new(1..2, 1..3, 1..4)
+ product.size.should == 24 # 2 * 3 * 4
+ end
+
+ it "returns nil if any enumerable reports its size as nil" do
+ enum = Object.new
+ def enum.size; nil; end
+
+ product = Enumerator::Product.new(1..2, enum)
+ product.size.should == nil
+ end
+
+ it "returns Float::INFINITY if any enumerable reports its size as Float::INFINITY" do
+ enum = Object.new
+ def enum.size; Float::INFINITY; end
+
+ product = Enumerator::Product.new(1..2, enum)
+ product.size.should == Float::INFINITY
+ end
+
+ it "returns -Float::INFINITY if any enumerable reports its size as -Float::INFINITY" do
+ enum = Object.new
+ def enum.size; -Float::INFINITY; end
+
+ product = Enumerator::Product.new(1..2, enum)
+ product.size.should == -Float::INFINITY
+ end
+
+ it "returns nil if any enumerable reports its size as Float::NAN" do
+ enum = Object.new
+ def enum.size; Float::NAN; end
+
+ product = Enumerator::Product.new(1..2, enum)
+ product.size.should == nil
+ end
+
+ it "returns nil if any enumerable doesn't respond to #size" do
+ enum = Object.new
+ product = Enumerator::Product.new(1..2, enum)
+ product.size.should == nil
+ end
+
+ it "returns nil if any enumerable reports a not-convertible to Integer" do
+ enum = Object.new
+ def enum.size; :symbol; end
+
+ product = Enumerator::Product.new(1..2, enum)
+ product.size.should == nil
+ end
+
+ it "returns nil if any enumerable reports a non-Integer but convertible to Integer size" do
+ enum = Object.new
+ def enum.size; 1.0; end
+
+ product = Enumerator::Product.new(1..2, enum)
+ product.size.should == nil
+ end
+ end
+end
diff --git a/spec/ruby/core/enumerator/product_spec.rb b/spec/ruby/core/enumerator/product_spec.rb
index 44fc6441e1..0fb00fc7ee 100644
--- a/spec/ruby/core/enumerator/product_spec.rb
+++ b/spec/ruby/core/enumerator/product_spec.rb
@@ -44,6 +44,11 @@ ruby_version_is "3.2" do
elems.should == [[1, "X"], [1, "Y"], [2, "X"], [2, "Y"]]
end
+ it "returns nil when a block passed" do
+ Enumerator.product(1..2) {}.should == nil
+ end
+
+ # https://bugs.ruby-lang.org/issues/19829
it "reject keyword arguments" do
-> {
Enumerator.product(1..3, foo: 1, bar: 2)
diff --git a/spec/ruby/core/enumerator/rewind_spec.rb b/spec/ruby/core/enumerator/rewind_spec.rb
index a105f2c619..6ba0edf174 100644
--- a/spec/ruby/core/enumerator/rewind_spec.rb
+++ b/spec/ruby/core/enumerator/rewind_spec.rb
@@ -14,7 +14,7 @@ describe "Enumerator#rewind" do
end
it "returns self" do
- @enum.rewind.should == @enum
+ @enum.rewind.should.equal? @enum
end
it "has no effect on a new enumerator" do
@@ -49,7 +49,7 @@ describe "Enumerator#rewind" do
obj = mock('rewinder')
enum = obj.to_enum
obj.should_receive(:each).at_most(1)
- -> { enum.rewind.should == enum }.should_not raise_error
+ enum.rewind.should == enum
end
end
diff --git a/spec/ruby/core/env/delete_spec.rb b/spec/ruby/core/env/delete_spec.rb
index 3d69e4b022..f28ac97911 100644
--- a/spec/ruby/core/env/delete_spec.rb
+++ b/spec/ruby/core/env/delete_spec.rb
@@ -41,6 +41,14 @@ describe "ENV.delete" do
ENV["foo"].should == nil
end
+ it "removes the variable coerced with #to_str" do
+ ENV["foo"] = "bar"
+ k = mock('key')
+ k.should_receive(:to_str).and_return("foo")
+ ENV.delete(k)
+ ENV["foo"].should == nil
+ end
+
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.delete(Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
diff --git a/spec/ruby/core/env/key_spec.rb b/spec/ruby/core/env/key_spec.rb
index 82cfbefa39..cf70286409 100644
--- a/spec/ruby/core/env/key_spec.rb
+++ b/spec/ruby/core/env/key_spec.rb
@@ -1,11 +1,39 @@
require_relative '../../spec_helper'
require_relative 'shared/include'
-require_relative 'shared/key'
describe "ENV.key?" do
it_behaves_like :env_include, :key?
end
describe "ENV.key" do
- it_behaves_like :env_key, :key
+ before :each do
+ @saved_foo = ENV["foo"]
+ end
+
+ after :each do
+ ENV["foo"] = @saved_foo
+ end
+
+ it "returns the index associated with the passed value" do
+ ENV["foo"] = "bar"
+ ENV.key("bar").should == "foo"
+ end
+
+ it "returns nil if the passed value is not found" do
+ ENV.delete("foo")
+ ENV.key("foo").should be_nil
+ end
+
+ it "coerces the key element with #to_str" do
+ ENV["foo"] = "bar"
+ k = mock('key')
+ k.should_receive(:to_str).and_return("bar")
+ ENV.key(k).should == "foo"
+ end
+
+ it "raises TypeError if the argument is not a String and does not respond to #to_str" do
+ -> {
+ ENV.key(Object.new)
+ }.should raise_error(TypeError, "no implicit conversion of Object into String")
+ end
end
diff --git a/spec/ruby/core/env/shared/include.rb b/spec/ruby/core/env/shared/include.rb
index 3efcd523d6..70aa555301 100644
--- a/spec/ruby/core/env/shared/include.rb
+++ b/spec/ruby/core/env/shared/include.rb
@@ -17,6 +17,13 @@ describe :env_include, shared: true do
ENV.send(@method, "foo").should == false
end
+ it "coerces the key with #to_str" do
+ ENV["foo"] = "bar"
+ k = mock('key')
+ k.should_receive(:to_str).and_return("foo")
+ ENV.send(@method, k).should == true
+ end
+
it "raises TypeError if the argument is not a String and does not respond to #to_str" do
-> { ENV.send(@method, Object.new) }.should raise_error(TypeError, "no implicit conversion of Object into String")
end
diff --git a/spec/ruby/core/env/shared/key.rb b/spec/ruby/core/env/shared/key.rb
deleted file mode 100644
index 93396d2aca..0000000000
--- a/spec/ruby/core/env/shared/key.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-describe :env_key, shared: true do
- before :each do
- @saved_foo = ENV["foo"]
- end
-
- after :each do
- ENV["foo"] = @saved_foo
- end
-
- it "returns the index associated with the passed value" do
- ENV["foo"] = "bar"
- suppress_warning {
- ENV.send(@method, "bar").should == "foo"
- }
- end
-
- it "returns nil if the passed value is not found" do
- ENV.delete("foo")
- suppress_warning {
- ENV.send(@method, "foo").should be_nil
- }
- end
-
- it "raises TypeError if the argument is not a String and does not respond to #to_str" do
- -> {
- suppress_warning {
- ENV.send(@method, Object.new)
- }
- }.should raise_error(TypeError, "no implicit conversion of Object into String")
- end
-end
diff --git a/spec/ruby/core/env/shared/value.rb b/spec/ruby/core/env/shared/value.rb
index bef96b5fef..c2b5025465 100644
--- a/spec/ruby/core/env/shared/value.rb
+++ b/spec/ruby/core/env/shared/value.rb
@@ -16,6 +16,13 @@ describe :env_value, shared: true do
ENV.send(@method, "foo").should == false
end
+ it "coerces the value element with #to_str" do
+ ENV["foo"] = "bar"
+ v = mock('value')
+ v.should_receive(:to_str).and_return("bar")
+ ENV.send(@method, v).should == true
+ end
+
it "returns nil if the argument is not a String and does not respond to #to_str" do
ENV.send(@method, Object.new).should == nil
end
diff --git a/spec/ruby/core/env/slice_spec.rb b/spec/ruby/core/env/slice_spec.rb
index e3b6020391..959239d2b2 100644
--- a/spec/ruby/core/env/slice_spec.rb
+++ b/spec/ruby/core/env/slice_spec.rb
@@ -21,6 +21,16 @@ describe "ENV.slice" do
ENV.slice("foo", "boo", "bar").should == {"foo" => "0", "bar" => "1"}
end
+ it "returns the values for the keys coerced with #to_str, but keeps the original objects as result keys" do
+ foo = mock('key 1')
+ foo.should_receive(:to_str).and_return("foo")
+ boo = mock('key 2')
+ boo.should_receive(:to_str).and_return("boo")
+ bar = mock('key 3')
+ bar.should_receive(:to_str).and_return("bar")
+ ENV.slice(foo, boo, bar).should == {foo => "0", bar => "1"}
+ end
+
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
diff --git a/spec/ruby/core/exception/equal_value_spec.rb b/spec/ruby/core/exception/equal_value_spec.rb
index 7f2065511a..e8f3ce0f8d 100644
--- a/spec/ruby/core/exception/equal_value_spec.rb
+++ b/spec/ruby/core/exception/equal_value_spec.rb
@@ -22,18 +22,18 @@ describe "Exception#==" do
it "returns true if both exceptions have the same class, the same message, and the same backtrace" do
one = TypeError.new("message")
- one.set_backtrace [File.dirname(__FILE__)]
+ one.set_backtrace [__dir__]
two = TypeError.new("message")
- two.set_backtrace [File.dirname(__FILE__)]
+ two.set_backtrace [__dir__]
one.should == two
end
it "returns false if the two exceptions inherit from Exception but have different classes" do
one = RuntimeError.new("message")
- one.set_backtrace [File.dirname(__FILE__)]
+ one.set_backtrace [__dir__]
one.should be_kind_of(Exception)
two = TypeError.new("message")
- two.set_backtrace [File.dirname(__FILE__)]
+ two.set_backtrace [__dir__]
two.should be_kind_of(Exception)
one.should_not == two
end
@@ -52,7 +52,7 @@ describe "Exception#==" do
it "returns false if the two exceptions differ only in their backtrace" do
one = RuntimeError.new("message")
- one.set_backtrace [File.dirname(__FILE__)]
+ one.set_backtrace [__dir__]
two = RuntimeError.new("message")
two.set_backtrace nil
one.should_not == two
@@ -60,9 +60,9 @@ describe "Exception#==" do
it "returns false if the two exceptions differ only in their message" do
one = RuntimeError.new("message")
- one.set_backtrace [File.dirname(__FILE__)]
+ one.set_backtrace [__dir__]
two = RuntimeError.new("message2")
- two.set_backtrace [File.dirname(__FILE__)]
+ two.set_backtrace [__dir__]
one.should_not == two
end
end
diff --git a/spec/ruby/core/false/singleton_method_spec.rb b/spec/ruby/core/false/singleton_method_spec.rb
index 6cf29af411..738794b46c 100644
--- a/spec/ruby/core/false/singleton_method_spec.rb
+++ b/spec/ruby/core/false/singleton_method_spec.rb
@@ -3,10 +3,10 @@ require_relative '../../spec_helper'
describe "FalseClass#singleton_method" do
ruby_version_is '3.3' do
it "raises regardless of whether FalseClass defines the method" do
- proc{false.singleton_method(:foo)}.should raise_error(NameError)
+ -> { false.singleton_method(:foo) }.should raise_error(NameError)
begin
- def false.foo; end
- proc{false.singleton_method(:foo)}.should raise_error(NameError)
+ def (false).foo; end
+ -> { false.singleton_method(:foo) }.should raise_error(NameError)
ensure
FalseClass.send(:remove_method, :foo)
end
diff --git a/spec/ruby/core/fiber/storage_spec.rb b/spec/ruby/core/fiber/storage_spec.rb
index e5232c8894..5c87ed5d41 100644
--- a/spec/ruby/core/fiber/storage_spec.rb
+++ b/spec/ruby/core/fiber/storage_spec.rb
@@ -1,9 +1,7 @@
require_relative '../../spec_helper'
-require 'fiber'
-
-describe "Fiber.new(storage:)" do
- ruby_version_is "3.2" do
+ruby_version_is "3.2" do
+ describe "Fiber.new(storage:)" do
it "creates a Fiber with the given storage" do
storage = {life: 42}
fiber = Fiber.new(storage: storage) { Fiber.current.storage }
@@ -24,11 +22,26 @@ describe "Fiber.new(storage:)" do
it "cannot create a fiber with non-hash storage" do
-> { Fiber.new(storage: 42) {} }.should raise_error(TypeError)
end
+
+ it "cannot create a fiber with a frozen hash as storage" do
+ -> { Fiber.new(storage: {life: 43}.freeze) {} }.should raise_error(FrozenError)
+ end
+
+ it "cannot create a fiber with a storage hash with non-symbol keys" do
+ -> { Fiber.new(storage: {life: 43, Object.new => 44}) {} }.should raise_error(TypeError)
+ end
end
-end
-describe "Fiber#storage=" do
- ruby_version_is "3.2" do
+ describe "Fiber#storage" do
+ it "cannot be accessed from a different fiber" do
+ f = Fiber.new(storage: {life: 42}) { nil }
+ -> {
+ f.storage
+ }.should raise_error(ArgumentError, /Fiber storage can only be accessed from the Fiber it belongs to/)
+ end
+ end
+
+ describe "Fiber#storage=" do
it "can clear the storage of the fiber" do
fiber = Fiber.new(storage: {life: 42}) do
Fiber.current.storage = nil
@@ -58,10 +71,8 @@ describe "Fiber#storage=" do
-> { Fiber.current.storage = {life: 43, Object.new => 44} }.should raise_error(TypeError)
end
end
-end
-describe "Fiber.[]" do
- ruby_version_is "3.2" do
+ describe "Fiber.[]" do
it "returns the value of the given key in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:life] }.resume.should == 42
end
@@ -73,25 +84,34 @@ describe "Fiber.[]" do
it "returns nil if the current fiber has no storage" do
Fiber.new { Fiber[:life] }.resume.should be_nil
end
- end
- ruby_version_is "3.2.3" do
- it "can use dynamically defined keys" do
- key = :"#{self.class.name}#.#{self.object_id}"
- Fiber.new { Fiber[key] = 42; Fiber[key] }.resume.should == 42
+ ruby_version_is "3.2.3" do
+ it "can use dynamically defined keys" do
+ key = :"#{self.class.name}#.#{self.object_id}"
+ Fiber.new { Fiber[key] = 42; Fiber[key] }.resume.should == 42
+ end
+
+ it "can't use invalid keys" do
+ invalid_keys = [Object.new, "Foo", 12]
+ invalid_keys.each do |key|
+ -> { Fiber[key] }.should raise_error(TypeError)
+ end
+ end
end
- it "can't use invalid keys" do
- invalid_keys = [Object.new, "Foo", 12]
- invalid_keys.each do |key|
- -> { Fiber[key] }.should raise_error(TypeError)
+ it "can access the storage of the parent fiber" do
+ f = Fiber.new(storage: {life: 42}) do
+ Fiber.new { Fiber[:life] }.resume
end
+ f.resume.should == 42
+ end
+
+ it "can't access the storage of the fiber with non-symbol keys" do
+ -> { Fiber[Object.new] }.should raise_error(TypeError)
end
end
-end
-describe "Fiber.[]=" do
- ruby_version_is "3.2" do
+ describe "Fiber.[]=" do
it "sets the value of the given key in the storage of the current fiber" do
Fiber.new(storage: {life: 42}) { Fiber[:life] = 43; Fiber[:life] }.resume.should == 43
end
@@ -103,17 +123,31 @@ describe "Fiber.[]=" do
it "sets the value of the given key in the storage of the current fiber" do
Fiber.new { Fiber[:life] = 43; Fiber[:life] }.resume.should == 43
end
- end
- ruby_version_is "3.3" do
- it "deletes the fiber storage key when assigning nil" do
- Fiber.new(storage: {life: 42}) { Fiber[:life] = nil; Fiber.current.storage }.resume.should == {}
+ it "does not overwrite the storage of the parent fiber" do
+ f = Fiber.new(storage: {life: 42}) do
+ Fiber.yield Fiber.new { Fiber[:life] = 43; Fiber[:life] }.resume
+ Fiber[:life]
+ end
+ f.resume.should == 43 # Value of the inner fiber
+ f.resume.should == 42 # Value of the outer fiber
+ end
+
+ it "can't access the storage of the fiber with non-symbol keys" do
+ -> { Fiber[Object.new] = 44 }.should raise_error(TypeError)
+ end
+
+ ruby_version_is "3.3" do
+ it "deletes the fiber storage key when assigning nil" do
+ Fiber.new(storage: {life: 42}) {
+ Fiber[:life] = nil
+ Fiber.current.storage
+ }.resume.should == {}
+ end
end
end
-end
-describe "Thread.new" do
- ruby_version_is "3.2" do
+ describe "Thread.new" do
it "creates a thread with the storage of the current fiber" do
fiber = Fiber.new(storage: {life: 42}) do
Thread.new { Fiber.current.storage }.value
diff --git a/spec/ruby/core/file/absolute_path_spec.rb b/spec/ruby/core/file/absolute_path_spec.rb
index e35c80ec3c..315eead34f 100644
--- a/spec/ruby/core/file/absolute_path_spec.rb
+++ b/spec/ruby/core/file/absolute_path_spec.rb
@@ -85,7 +85,7 @@ describe "File.absolute_path" do
end
it "accepts a second argument of a directory from which to resolve the path" do
- File.absolute_path(__FILE__, File.dirname(__FILE__)).should == @abs
+ File.absolute_path(__FILE__, __dir__).should == @abs
end
it "calls #to_path on its argument" do
diff --git a/spec/ruby/core/file/exist_spec.rb b/spec/ruby/core/file/exist_spec.rb
index ddb5febcba..2633376880 100644
--- a/spec/ruby/core/file/exist_spec.rb
+++ b/spec/ruby/core/file/exist_spec.rb
@@ -4,3 +4,11 @@ require_relative '../../shared/file/exist'
describe "File.exist?" do
it_behaves_like :file_exist, :exist?, File
end
+
+ruby_version_is "3.2" do
+ describe "File.exists?" do
+ it "has been removed" do
+ File.should_not.respond_to?(:exists?)
+ end
+ end
+end
diff --git a/spec/ruby/core/file/open_spec.rb b/spec/ruby/core/file/open_spec.rb
index 0346224b93..4c41f70e12 100644
--- a/spec/ruby/core/file/open_spec.rb
+++ b/spec/ruby/core/file/open_spec.rb
@@ -314,7 +314,7 @@ describe "File.open" do
end
end
- it "raises an IOError when read in a block opened with File::RDONLY|File::APPEND mode" do
+ it "raises an IOError when write in a block opened with File::RDONLY|File::APPEND mode" do
-> {
File.open(@file, File::RDONLY|File::APPEND ) do |f|
f.puts("writing")
diff --git a/spec/ruby/core/file/realpath_spec.rb b/spec/ruby/core/file/realpath_spec.rb
index bd27e09da6..bd25bfdecf 100644
--- a/spec/ruby/core/file/realpath_spec.rb
+++ b/spec/ruby/core/file/realpath_spec.rb
@@ -54,6 +54,10 @@ platform_is_not :windows do
File.realpath(@relative_symlink).should == @file
end
+ it "removes the file element when going one level up" do
+ File.realpath('../', @file).should == @real_dir
+ end
+
it "raises an Errno::ELOOP if the symlink points to itself" do
File.unlink @link
File.symlink(@link, @link)
diff --git a/spec/ruby/core/io/eof_spec.rb b/spec/ruby/core/io/eof_spec.rb
index 315345d942..b4850df437 100644
--- a/spec/ruby/core/io/eof_spec.rb
+++ b/spec/ruby/core/io/eof_spec.rb
@@ -76,7 +76,7 @@ describe "IO#eof?" do
end
it "returns true on one-byte stream after single-byte read" do
- File.open(File.dirname(__FILE__) + '/fixtures/one_byte.txt') { |one_byte|
+ File.open(__dir__ + '/fixtures/one_byte.txt') { |one_byte|
one_byte.read(1)
one_byte.should.eof?
}
diff --git a/spec/ruby/core/io/getbyte_spec.rb b/spec/ruby/core/io/getbyte_spec.rb
index 6ba8f0a3e0..b4351160e6 100644
--- a/spec/ruby/core/io/getbyte_spec.rb
+++ b/spec/ruby/core/io/getbyte_spec.rb
@@ -40,3 +40,19 @@ describe "IO#getbyte" do
@io.getbyte.should == nil
end
end
+
+describe "IO#getbyte" do
+ before :each do
+ @name = tmp("io_getbyte.txt")
+ @io = new_io(@name, 'w')
+ end
+
+ after :each do
+ @io.close if @io
+ rm_r @name if @name
+ end
+
+ it "raises an IOError if the stream is not readable" do
+ -> { @io.getbyte }.should raise_error(IOError)
+ end
+end
diff --git a/spec/ruby/core/io/new_spec.rb b/spec/ruby/core/io/new_spec.rb
index 0ef30991fd..9d14ec18ad 100644
--- a/spec/ruby/core/io/new_spec.rb
+++ b/spec/ruby/core/io/new_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
require_relative 'shared/new'
-# NOTE: should be syncronized with library/stringio/initialize_spec.rb
+# NOTE: should be synchronized with library/stringio/initialize_spec.rb
describe "IO.new" do
it_behaves_like :io_new, :new
diff --git a/spec/ruby/core/io/select_spec.rb b/spec/ruby/core/io/select_spec.rb
index 4603c1fbbc..1e4e50a81b 100644
--- a/spec/ruby/core/io/select_spec.rb
+++ b/spec/ruby/core/io/select_spec.rb
@@ -55,8 +55,8 @@ describe "IO.select" do
end
end
- it "returns supplied objects correctly even when monitoring the same object in different arrays" do
- filename = tmp("IO_select_pipe_file") + $$.to_s
+ it "returns supplied objects correctly when monitoring the same object in different arrays" do
+ filename = tmp("IO_select_pipe_file")
io = File.open(filename, 'w+')
result = IO.select [io], [io], nil, 0
result.should == [[io], [io], []]
@@ -64,6 +64,17 @@ describe "IO.select" do
rm_r filename
end
+ it "returns the pipe read end in read set if the pipe write end is closed concurrently" do
+ main = Thread.current
+ t = Thread.new {
+ Thread.pass until main.stop?
+ @wr.close
+ }
+ IO.select([@rd]).should == [[@rd], [], []]
+ ensure
+ t.join
+ end
+
it "invokes to_io on supplied objects that are not IO and returns the supplied objects" do
# make some data available
@wr.write("foobar")
diff --git a/spec/ruby/core/io/shared/new.rb b/spec/ruby/core/io/shared/new.rb
index 99b19e6a1b..cba5f33ebf 100644
--- a/spec/ruby/core/io/shared/new.rb
+++ b/spec/ruby/core/io/shared/new.rb
@@ -1,6 +1,6 @@
require_relative '../fixtures/classes'
-# NOTE: should be syncronized with library/stringio/initialize_spec.rb
+# NOTE: should be synchronized with library/stringio/initialize_spec.rb
# This group of specs may ONLY contain specs that do successfully create
# an IO instance from the file descriptor returned by #new_fd helper.
diff --git a/spec/ruby/core/kernel/initialize_copy_spec.rb b/spec/ruby/core/kernel/initialize_copy_spec.rb
index fe08d184ad..d71ca9f60f 100644
--- a/spec/ruby/core/kernel/initialize_copy_spec.rb
+++ b/spec/ruby/core/kernel/initialize_copy_spec.rb
@@ -1,11 +1,18 @@
require_relative '../../spec_helper'
describe "Kernel#initialize_copy" do
+ it "returns self" do
+ obj = Object.new
+ obj.send(:initialize_copy, obj).should.equal?(obj)
+ end
+
it "does nothing if the argument is the same as the receiver" do
obj = Object.new
obj.send(:initialize_copy, obj).should.equal?(obj)
- obj.freeze
+
+ obj = Object.new.freeze
obj.send(:initialize_copy, obj).should.equal?(obj)
+
1.send(:initialize_copy, 1).should.equal?(1)
end
diff --git a/spec/ruby/core/kernel/require_relative_spec.rb b/spec/ruby/core/kernel/require_relative_spec.rb
index 5999855de6..6188d13a4e 100644
--- a/spec/ruby/core/kernel/require_relative_spec.rb
+++ b/spec/ruby/core/kernel/require_relative_spec.rb
@@ -5,9 +5,9 @@ describe "Kernel#require_relative with a relative path" do
before :each do
CodeLoadingSpecs.spec_setup
@dir = "../../fixtures/code"
- @abs_dir = File.realpath(@dir, File.dirname(__FILE__))
+ @abs_dir = File.realpath(@dir, __dir__)
@path = "#{@dir}/load_fixture.rb"
- @abs_path = File.realpath(@path, File.dirname(__FILE__))
+ @abs_path = File.realpath(@path, __dir__)
end
after :each do
@@ -92,7 +92,7 @@ describe "Kernel#require_relative with a relative path" do
it "raises a LoadError that includes the missing path" do
missing_path = "#{@dir}/nonexistent.rb"
- expanded_missing_path = File.expand_path(missing_path, File.dirname(__FILE__))
+ expanded_missing_path = File.expand_path(missing_path, __dir__)
-> { require_relative(missing_path) }.should raise_error(LoadError) { |e|
e.message.should include(expanded_missing_path)
e.path.should == expanded_missing_path
@@ -277,7 +277,7 @@ end
describe "Kernel#require_relative with an absolute path" do
before :each do
CodeLoadingSpecs.spec_setup
- @dir = File.expand_path "../../fixtures/code", File.dirname(__FILE__)
+ @dir = File.expand_path "../../fixtures/code", __dir__
@abs_dir = @dir
@path = File.join @dir, "load_fixture.rb"
@abs_path = @path
diff --git a/spec/ruby/core/kernel/shared/sprintf.rb b/spec/ruby/core/kernel/shared/sprintf.rb
index 2db50bd686..13dc6e97f0 100644
--- a/spec/ruby/core/kernel/shared/sprintf.rb
+++ b/spec/ruby/core/kernel/shared/sprintf.rb
@@ -356,13 +356,13 @@ describe :kernel_sprintf, shared: true do
it "raises TypeError if converting to Integer with to_int returns non-Integer" do
obj = BasicObject.new
- def obj.to_str
+ def obj.to_int
:foo
end
-> {
@method.call("%c", obj)
- }.should raise_error(TypeError, /can't convert BasicObject to String/)
+ }.should raise_error(TypeError, /can't convert BasicObject to Integer/)
end
end
diff --git a/spec/ruby/core/kernel/test_spec.rb b/spec/ruby/core/kernel/test_spec.rb
index abb365aed2..d26dc06361 100644
--- a/spec/ruby/core/kernel/test_spec.rb
+++ b/spec/ruby/core/kernel/test_spec.rb
@@ -3,8 +3,8 @@ require_relative 'fixtures/classes'
describe "Kernel#test" do
before :all do
- @file = File.dirname(__FILE__) + '/fixtures/classes.rb'
- @dir = File.dirname(__FILE__) + '/fixtures'
+ @file = __dir__ + '/fixtures/classes.rb'
+ @dir = __dir__ + '/fixtures'
end
it "is a private method" do
diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb
index c694b48bab..eaf238bbd9 100644
--- a/spec/ruby/core/marshal/dump_spec.rb
+++ b/spec/ruby/core/marshal/dump_spec.rb
@@ -271,6 +271,18 @@ describe "Marshal.dump" do
end
end
+ describe "with a Rational" do
+ it "dumps a Rational" do
+ Marshal.dump(Rational(2, 3)).should == "\x04\bU:\rRational[\ai\ai\b"
+ end
+ end
+
+ describe "with a Complex" do
+ it "dumps a Complex" do
+ Marshal.dump(Complex(2, 3)).should == "\x04\bU:\fComplex[\ai\ai\b"
+ end
+ end
+
describe "with a String" do
it "dumps a blank String" do
Marshal.dump("".force_encoding("binary")).should == "\004\b\"\000"
@@ -769,7 +781,6 @@ describe "Marshal.dump" do
end
describe "when passed an IO" do
-
it "writes the serialized data to the IO-Object" do
(obj = mock('test')).should_receive(:write).at_least(1)
Marshal.dump("test", obj)
@@ -792,8 +803,6 @@ describe "Marshal.dump" do
obj.should_receive(:binmode).at_least(1)
Marshal.dump("test", obj)
end
-
-
end
describe "when passed a StringIO" do
diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb
index b37e65071d..b70fb7a974 100644
--- a/spec/ruby/core/marshal/shared/load.rb
+++ b/spec/ruby/core/marshal/shared/load.rb
@@ -1034,13 +1034,17 @@ describe :marshal_load, shared: true do
describe "for a Rational" do
it "loads" do
- Marshal.send(@method, Marshal.dump(Rational(1, 3))).should == Rational(1, 3)
+ r = Marshal.send(@method, Marshal.dump(Rational(1, 3)))
+ r.should == Rational(1, 3)
+ r.should.frozen?
end
end
describe "for a Complex" do
it "loads" do
- Marshal.send(@method, Marshal.dump(Complex(4, 3))).should == Complex(4, 3)
+ c = Marshal.send(@method, Marshal.dump(Complex(4, 3)))
+ c.should == Complex(4, 3)
+ c.should.frozen?
end
end
diff --git a/spec/ruby/core/method/source_location_spec.rb b/spec/ruby/core/method/source_location_spec.rb
index 4cfb21c5d0..c5b296f6e2 100644
--- a/spec/ruby/core/method/source_location_spec.rb
+++ b/spec/ruby/core/method/source_location_spec.rb
@@ -13,7 +13,7 @@ describe "Method#source_location" do
it "sets the first value to the path of the file in which the method was defined" do
file = @method.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('../fixtures/classes.rb', __FILE__)
+ file.should == File.realpath('fixtures/classes.rb', __dir__)
end
it "sets the last value to an Integer representing the line on which the method was defined" do
diff --git a/spec/ruby/core/module/const_added_spec.rb b/spec/ruby/core/module/const_added_spec.rb
index 31ac6eb105..f9edda3a07 100644
--- a/spec/ruby/core/module/const_added_spec.rb
+++ b/spec/ruby/core/module/const_added_spec.rb
@@ -121,5 +121,40 @@ describe "Module#const_added" do
ScratchPad.recorded.should == [line + 2, line + 4, line + 7, line + 11]
end
+
+ it "is called when the constant is already assigned a value" do
+ ScratchPad.record []
+
+ mod = Module.new do
+ def self.const_added(name)
+ ScratchPad.record const_get(name)
+ end
+ end
+
+ mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
+ TEST = 123
+ RUBY
+
+ ScratchPad.recorded.should == 123
+ end
+
+ it "records re-definition of existing constants" do
+ ScratchPad.record []
+
+ mod = Module.new do
+ def self.const_added(name)
+ ScratchPad << const_get(name)
+ end
+ end
+
+ -> {
+ mod.module_eval(<<-RUBY, __FILE__, __LINE__ + 1)
+ TEST = 123
+ TEST = 456
+ RUBY
+ }.should complain(/warning: already initialized constant .+::TEST/)
+
+ ScratchPad.recorded.should == [123, 456]
+ end
end
end
diff --git a/spec/ruby/core/module/define_method_spec.rb b/spec/ruby/core/module/define_method_spec.rb
index 381aacadb7..d742ece6bc 100644
--- a/spec/ruby/core/module/define_method_spec.rb
+++ b/spec/ruby/core/module/define_method_spec.rb
@@ -499,6 +499,33 @@ describe "Module#define_method" do
Class.new { define_method :bar, m }
}.should raise_error(TypeError, /can't bind singleton method to a different class/)
end
+
+ it "defines a new method with public visibility when a Method passed and the class/module of the context isn't equal to the receiver of #define_method" do
+ c = Class.new do
+ private def foo
+ "public"
+ end
+ end
+
+ object = c.new
+ object.singleton_class.define_method(:bar, object.method(:foo))
+
+ object.bar.should == "public"
+ end
+
+ it "defines the new method according to the scope visibility when a Method passed and the class/module of the context is equal to the receiver of #define_method" do
+ c = Class.new do
+ def foo; end
+ end
+
+ object = c.new
+ object.singleton_class.class_eval do
+ private
+ define_method(:bar, c.new.method(:foo))
+ end
+
+ -> { object.bar }.should raise_error(NoMethodError)
+ end
end
describe "Module#define_method" do
diff --git a/spec/ruby/core/mutex/lock_spec.rb b/spec/ruby/core/mutex/lock_spec.rb
index 7a39817b11..e9d33f5fd9 100644
--- a/spec/ruby/core/mutex/lock_spec.rb
+++ b/spec/ruby/core/mutex/lock_spec.rb
@@ -1,10 +1,6 @@
require_relative '../../spec_helper'
describe "Mutex#lock" do
- before :each do
- ScratchPad.clear
- end
-
it "returns self" do
m = Mutex.new
m.lock.should == m
diff --git a/spec/ruby/core/nil/singleton_method_spec.rb b/spec/ruby/core/nil/singleton_method_spec.rb
index f9163da3f1..8d898b1cc9 100644
--- a/spec/ruby/core/nil/singleton_method_spec.rb
+++ b/spec/ruby/core/nil/singleton_method_spec.rb
@@ -3,10 +3,10 @@ require_relative '../../spec_helper'
describe "NilClass#singleton_method" do
ruby_version_is '3.3' do
it "raises regardless of whether NilClass defines the method" do
- proc{nil.singleton_method(:foo)}.should raise_error(NameError)
+ -> { nil.singleton_method(:foo) }.should raise_error(NameError)
begin
- def nil.foo; end
- proc{nil.singleton_method(:foo)}.should raise_error(NameError)
+ def (nil).foo; end
+ -> { nil.singleton_method(:foo) }.should raise_error(NameError)
ensure
NilClass.send(:remove_method, :foo)
end
diff --git a/spec/ruby/core/numeric/clone_spec.rb b/spec/ruby/core/numeric/clone_spec.rb
index 5834b17089..423cec85dd 100644
--- a/spec/ruby/core/numeric/clone_spec.rb
+++ b/spec/ruby/core/numeric/clone_spec.rb
@@ -14,7 +14,7 @@ describe "Numeric#clone" do
1.clone.frozen?.should == true
end
- it "accepts optonal keyword argument :freeze" do
+ it "accepts optional keyword argument :freeze" do
value = 1
value.clone(freeze: true).should equal(value)
end
diff --git a/spec/ruby/core/proc/source_location_spec.rb b/spec/ruby/core/proc/source_location_spec.rb
index a5895a7fcb..a8b99287d5 100644
--- a/spec/ruby/core/proc/source_location_spec.rb
+++ b/spec/ruby/core/proc/source_location_spec.rb
@@ -19,19 +19,19 @@ describe "Proc#source_location" do
it "sets the first value to the path of the file in which the proc was defined" do
file = @proc.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
+ file.should == File.realpath('fixtures/source_location.rb', __dir__)
file = @proc_new.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
+ file.should == File.realpath('fixtures/source_location.rb', __dir__)
file = @lambda.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
+ file.should == File.realpath('fixtures/source_location.rb', __dir__)
file = @method.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('../fixtures/source_location.rb', __FILE__)
+ file.should == File.realpath('fixtures/source_location.rb', __dir__)
end
it "sets the last value to an Integer representing the line on which the proc was defined" do
diff --git a/spec/ruby/core/process/argv0_spec.rb b/spec/ruby/core/process/argv0_spec.rb
index 7c2342f959..f5aba719e9 100644
--- a/spec/ruby/core/process/argv0_spec.rb
+++ b/spec/ruby/core/process/argv0_spec.rb
@@ -8,7 +8,7 @@ describe "Process.argv0" do
it "is the path given as the main script and the same as __FILE__" do
script = "fixtures/argv0.rb"
- Dir.chdir(File.dirname(__FILE__)) do
+ Dir.chdir(__dir__) do
ruby_exe(script).should == "#{script}\n#{script}\nOK"
end
end
diff --git a/spec/ruby/core/process/exec_spec.rb b/spec/ruby/core/process/exec_spec.rb
index deb8913b6b..2fa8b08975 100644
--- a/spec/ruby/core/process/exec_spec.rb
+++ b/spec/ruby/core/process/exec_spec.rb
@@ -30,7 +30,7 @@ describe "Process.exec" do
end
it "raises Errno::EACCES when passed a directory" do
- -> { Process.exec File.dirname(__FILE__) }.should raise_error(Errno::EACCES)
+ -> { Process.exec __dir__ }.should raise_error(Errno::EACCES)
end
it "runs the specified command, replacing current process" do
diff --git a/spec/ruby/core/process/spawn_spec.rb b/spec/ruby/core/process/spawn_spec.rb
index c8a58c4d04..283a7f033d 100644
--- a/spec/ruby/core/process/spawn_spec.rb
+++ b/spec/ruby/core/process/spawn_spec.rb
@@ -714,7 +714,7 @@ describe "Process.spawn" do
end
it "raises an Errno::EACCES or Errno::EISDIR when passed a directory" do
- -> { Process.spawn File.dirname(__FILE__) }.should raise_error(SystemCallError) { |e|
+ -> { Process.spawn __dir__ }.should raise_error(SystemCallError) { |e|
[Errno::EACCES, Errno::EISDIR].should include(e.class)
}
end
diff --git a/spec/ruby/core/random/bytes_spec.rb b/spec/ruby/core/random/bytes_spec.rb
index ed1b3a7b41..b42dc61234 100644
--- a/spec/ruby/core/random/bytes_spec.rb
+++ b/spec/ruby/core/random/bytes_spec.rb
@@ -9,7 +9,6 @@ describe "Random#bytes" do
Random.new(33).bytes(2).should == Random.new(33).bytes(2)
end
- # Should double check this is official spec
it "returns the same numeric output for a given seed across all implementations and platforms" do
rnd = Random.new(33)
rnd.bytes(2).should == "\x14\\"
diff --git a/spec/ruby/core/range/cover_spec.rb b/spec/ruby/core/range/cover_spec.rb
index fa881607e9..eb7cddc967 100644
--- a/spec/ruby/core/range/cover_spec.rb
+++ b/spec/ruby/core/range/cover_spec.rb
@@ -7,4 +7,8 @@ describe "Range#cover?" do
it_behaves_like :range_cover_and_include, :cover?
it_behaves_like :range_cover, :cover?
it_behaves_like :range_cover_subrange, :cover?
+
+ it "covers U+9995 in the range U+0999..U+9999" do
+ ("\u{999}".."\u{9999}").cover?("\u{9995}").should be_true
+ end
end
diff --git a/spec/ruby/core/range/include_spec.rb b/spec/ruby/core/range/include_spec.rb
index b2c7a54545..277de205d1 100644
--- a/spec/ruby/core/range/include_spec.rb
+++ b/spec/ruby/core/range/include_spec.rb
@@ -7,4 +7,8 @@ require_relative 'shared/cover'
describe "Range#include?" do
it_behaves_like :range_cover_and_include, :include?
it_behaves_like :range_include, :include?
+
+ it "does not include U+9995 in the range U+0999..U+9999" do
+ ("\u{999}".."\u{9999}").include?("\u{9995}").should be_false
+ end
end
diff --git a/spec/ruby/core/range/shared/cover_and_include.rb b/spec/ruby/core/range/shared/cover_and_include.rb
index 7028afaa89..f36a2cef8b 100644
--- a/spec/ruby/core/range/shared/cover_and_include.rb
+++ b/spec/ruby/core/range/shared/cover_and_include.rb
@@ -57,7 +57,6 @@ describe :range_cover_and_include, shared: true do
it "returns true if argument is less than the last value of the range and greater than the first value" do
(20..30).send(@method, 28).should be_true
('e'..'h').send(@method, 'g').should be_true
- ("\u{999}".."\u{9999}").send @method, "\u{9995}"
end
it "returns true if argument is sole element in the range" do
diff --git a/spec/ruby/core/refinement/extend_object_spec.rb b/spec/ruby/core/refinement/extend_object_spec.rb
index e44e9f46d8..6c2a0af4f3 100644
--- a/spec/ruby/core/refinement/extend_object_spec.rb
+++ b/spec/ruby/core/refinement/extend_object_spec.rb
@@ -11,8 +11,10 @@ describe "Refinement#extend_object" do
Module.new do
refine c do
called = false
- define_method(:extend_object){called = true}
- proc{c.extend(self)}.should raise_error(TypeError)
+ define_method(:extend_object) { called = true }
+ -> {
+ c.extend(self)
+ }.should raise_error(TypeError)
called.should == false
end
end
diff --git a/spec/ruby/core/struct/constants_spec.rb b/spec/ruby/core/struct/constants_spec.rb
new file mode 100644
index 0000000000..fa61a4b912
--- /dev/null
+++ b/spec/ruby/core/struct/constants_spec.rb
@@ -0,0 +1,15 @@
+require_relative '../../spec_helper'
+
+ruby_version_is "3.2" do
+ describe "Struct::Group" do
+ it "is no longer defined" do
+ Struct.should_not.const_defined?(:Group)
+ end
+ end
+
+ describe "Struct::Passwd" do
+ it "is no longer defined" do
+ Struct.should_not.const_defined?(:Passwd)
+ end
+ end
+end
diff --git a/spec/ruby/core/thread/backtrace/location/path_spec.rb b/spec/ruby/core/thread/backtrace/location/path_spec.rb
index 7863c055d3..75f76833a9 100644
--- a/spec/ruby/core/thread/backtrace/location/path_spec.rb
+++ b/spec/ruby/core/thread/backtrace/location/path_spec.rb
@@ -41,7 +41,7 @@ describe 'Thread::Backtrace::Location#path' do
context 'when using a relative script path' do
it 'returns a path relative to the working directory' do
path = 'fixtures/main.rb'
- directory = File.dirname(__FILE__)
+ directory = __dir__
Dir.chdir(directory) {
ruby_exe(path)
}.should == path
diff --git a/spec/ruby/core/true/singleton_method_spec.rb b/spec/ruby/core/true/singleton_method_spec.rb
index f765054c5f..c06793850f 100644
--- a/spec/ruby/core/true/singleton_method_spec.rb
+++ b/spec/ruby/core/true/singleton_method_spec.rb
@@ -3,10 +3,10 @@ require_relative '../../spec_helper'
describe "TrueClass#singleton_method" do
ruby_version_is '3.3' do
it "raises regardless of whether TrueClass defines the method" do
- proc{true.singleton_method(:foo)}.should raise_error(NameError)
+ -> { true.singleton_method(:foo) }.should raise_error(NameError)
begin
- def true.foo; end
- proc{true.singleton_method(:foo)}.should raise_error(NameError)
+ def (true).foo; end
+ -> { true.singleton_method(:foo) }.should raise_error(NameError)
ensure
TrueClass.send(:remove_method, :foo)
end
diff --git a/spec/ruby/core/unboundmethod/source_location_spec.rb b/spec/ruby/core/unboundmethod/source_location_spec.rb
index c6823aa84b..5c2f14362c 100644
--- a/spec/ruby/core/unboundmethod/source_location_spec.rb
+++ b/spec/ruby/core/unboundmethod/source_location_spec.rb
@@ -9,7 +9,7 @@ describe "UnboundMethod#source_location" do
it "sets the first value to the path of the file in which the method was defined" do
file = @method.source_location.first
file.should be_an_instance_of(String)
- file.should == File.realpath('../fixtures/classes.rb', __FILE__)
+ file.should == File.realpath('fixtures/classes.rb', __dir__)
end
it "sets the last value to an Integer representing the line on which the method was defined" do
diff --git a/spec/ruby/core/warning/element_reference_spec.rb b/spec/ruby/core/warning/element_reference_spec.rb
index 41129e533a..bd024d19b4 100644
--- a/spec/ruby/core/warning/element_reference_spec.rb
+++ b/spec/ruby/core/warning/element_reference_spec.rb
@@ -3,8 +3,8 @@ require_relative '../../spec_helper'
describe "Warning.[]" do
ruby_version_is '2.7.2' do
it "returns default values for categories :deprecated and :experimental" do
- ruby_exe('p Warning[:deprecated]').chomp.should == "false"
- ruby_exe('p Warning[:experimental]').chomp.should == "true"
+ ruby_exe('p [Warning[:deprecated], Warning[:experimental]]').chomp.should == "[false, true]"
+ ruby_exe('p [Warning[:deprecated], Warning[:experimental]]', options: "-w").chomp.should == "[true, true]"
end
end
diff --git a/spec/ruby/core/warning/element_set_spec.rb b/spec/ruby/core/warning/element_set_spec.rb
index f439ffde0a..d59a7d4c9e 100644
--- a/spec/ruby/core/warning/element_set_spec.rb
+++ b/spec/ruby/core/warning/element_set_spec.rb
@@ -17,6 +17,18 @@ describe "Warning.[]=" do
end
end
+ ruby_version_is '3.3' do
+ it "enables or disables performance warnings" do
+ original = Warning[:performance]
+ begin
+ Warning[:performance] = !original
+ Warning[:performance].should == !original
+ ensure
+ Warning[:performance] = original
+ end
+ end
+ end
+
it "raises for unknown category" do
-> { Warning[:noop] = false }.should raise_error(ArgumentError, /unknown category: noop/)
end