summaryrefslogtreecommitdiff
path: root/spec/ruby/core
diff options
context:
space:
mode:
Diffstat (limited to 'spec/ruby/core')
-rw-r--r--spec/ruby/core/array/drop_spec.rb2
-rw-r--r--spec/ruby/core/array/intersect_spec.rb92
-rw-r--r--spec/ruby/core/basicobject/instance_eval_spec.rb19
-rw-r--r--spec/ruby/core/basicobject/singleton_method_added_spec.rb2
-rw-r--r--spec/ruby/core/class/dup_spec.rb2
-rw-r--r--spec/ruby/core/class/new_spec.rb2
-rw-r--r--spec/ruby/core/class/subclasses_spec.rb126
-rw-r--r--spec/ruby/core/complex/shared/rect.rb12
-rw-r--r--spec/ruby/core/data/deconstruct_keys_spec.rb107
-rw-r--r--spec/ruby/core/data/deconstruct_spec.rb10
-rw-r--r--spec/ruby/core/data/eql_spec.rb65
-rw-r--r--spec/ruby/core/data/equal_value_spec.rb65
-rw-r--r--spec/ruby/core/data/fixtures/classes.rb8
-rw-r--r--spec/ruby/core/data/hash_spec.rb27
-rw-r--r--spec/ruby/core/data/inspect_spec.rb8
-rw-r--r--spec/ruby/core/data/members_spec.rb23
-rw-r--r--spec/ruby/core/data/shared/inspect.rb54
-rw-r--r--spec/ruby/core/data/to_s_spec.rb8
-rw-r--r--spec/ruby/core/dir/chdir_spec.rb2
-rw-r--r--spec/ruby/core/dir/glob_spec.rb81
-rw-r--r--spec/ruby/core/dir/shared/glob.rb63
-rw-r--r--spec/ruby/core/encoding/converter/finish_spec.rb4
-rw-r--r--spec/ruby/core/encoding/converter/search_convpath_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/compact_spec.rb10
-rw-r--r--spec/ruby/core/enumerable/each_cons_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/each_slice_spec.rb6
-rw-r--r--spec/ruby/core/enumerable/tally_spec.rb112
-rw-r--r--spec/ruby/core/enumerator/lazy/compact_spec.rb18
-rw-r--r--spec/ruby/core/enumerator/lazy/lazy_spec.rb9
-rw-r--r--spec/ruby/core/env/dup_spec.rb10
-rw-r--r--spec/ruby/core/env/fetch_spec.rb2
-rw-r--r--spec/ruby/core/env/length_spec.rb2
-rw-r--r--spec/ruby/core/env/size_spec.rb2
-rw-r--r--spec/ruby/core/exception/errno_spec.rb2
-rw-r--r--spec/ruby/core/exception/system_call_error_spec.rb2
-rw-r--r--spec/ruby/core/fiber/alive_spec.rb44
-rw-r--r--spec/ruby/core/fiber/blocking_spec.rb2
-rw-r--r--spec/ruby/core/fiber/current_spec.rb50
-rw-r--r--spec/ruby/core/fiber/inspect_spec.rb1
-rw-r--r--spec/ruby/core/fiber/raise_spec.rb1
-rw-r--r--spec/ruby/core/fiber/resume_spec.rb15
-rw-r--r--spec/ruby/core/fiber/shared/resume.rb58
-rw-r--r--spec/ruby/core/fiber/transfer_spec.rb84
-rw-r--r--spec/ruby/core/file/dirname_spec.rb80
-rw-r--r--spec/ruby/core/file/shared/path.rb12
-rw-r--r--spec/ruby/core/float/comparison_spec.rb2
-rw-r--r--spec/ruby/core/float/round_spec.rb9
-rw-r--r--spec/ruby/core/gc/measure_total_time_spec.rb24
-rw-r--r--spec/ruby/core/gc/total_time_spec.rb18
-rw-r--r--spec/ruby/core/hash/hash_spec.rb10
-rw-r--r--spec/ruby/core/hash/shared/store.rb6
-rw-r--r--spec/ruby/core/hash/transform_keys_spec.rb24
-rw-r--r--spec/ruby/core/integer/try_convert_spec.rb76
-rw-r--r--spec/ruby/core/io/external_encoding_spec.rb10
-rw-r--r--spec/ruby/core/io/internal_encoding_spec.rb10
-rw-r--r--spec/ruby/core/io/readpartial_spec.rb10
-rw-r--r--spec/ruby/core/io/write_nonblock_spec.rb2
-rw-r--r--spec/ruby/core/kernel/block_given_spec.rb5
-rw-r--r--spec/ruby/core/kernel/eval_spec.rb16
-rw-r--r--spec/ruby/core/kernel/fixtures/classes.rb54
-rw-r--r--spec/ruby/core/kernel/require_spec.rb5
-rw-r--r--spec/ruby/core/kernel/shared/load.rb48
-rw-r--r--spec/ruby/core/main/private_spec.rb12
-rw-r--r--spec/ruby/core/main/public_spec.rb12
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb20
-rw-r--r--spec/ruby/core/marshal/shared/load.rb486
-rw-r--r--spec/ruby/core/matchdata/match_length_spec.rb46
-rw-r--r--spec/ruby/core/matchdata/match_spec.rb46
-rw-r--r--spec/ruby/core/method/parameters_spec.rb27
-rw-r--r--spec/ruby/core/method/private_spec.rb2
-rw-r--r--spec/ruby/core/method/protected_spec.rb2
-rw-r--r--spec/ruby/core/method/public_spec.rb2
-rw-r--r--spec/ruby/core/module/autoload_spec.rb98
-rw-r--r--spec/ruby/core/module/const_defined_spec.rb2
-rw-r--r--spec/ruby/core/module/const_get_spec.rb24
-rw-r--r--spec/ruby/core/module/const_set_spec.rb13
-rw-r--r--spec/ruby/core/module/const_source_location_spec.rb24
-rw-r--r--spec/ruby/core/module/define_method_spec.rb3
-rw-r--r--spec/ruby/core/module/include_spec.rb18
-rw-r--r--spec/ruby/core/module/module_function_spec.rb37
-rw-r--r--spec/ruby/core/module/name_spec.rb13
-rw-r--r--spec/ruby/core/module/prepend_spec.rb57
-rw-r--r--spec/ruby/core/module/private_spec.rb26
-rw-r--r--spec/ruby/core/module/protected_spec.rb26
-rw-r--r--spec/ruby/core/module/public_spec.rb26
-rw-r--r--spec/ruby/core/module/refine_spec.rb313
-rw-r--r--spec/ruby/core/module/remove_const_spec.rb2
-rw-r--r--spec/ruby/core/module/to_s_spec.rb2
-rw-r--r--spec/ruby/core/numeric/shared/imag.rb6
-rw-r--r--spec/ruby/core/numeric/shared/rect.rb26
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb30
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/clear_spec.rb27
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/delete_spec.rb13
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb83
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb59
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/fixtures/classes.rb5
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb14
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb4
-rw-r--r--spec/ruby/core/objectspace/weakkeymap/key_spec.rb11
-rw-r--r--spec/ruby/core/proc/parameters_spec.rb8
-rw-r--r--spec/ruby/core/process/_fork_spec.rb28
-rw-r--r--spec/ruby/core/process/gid_spec.rb4
-rw-r--r--spec/ruby/core/process/tms/cstime_spec.rb17
-rw-r--r--spec/ruby/core/process/tms/cutime_spec.rb17
-rw-r--r--spec/ruby/core/process/tms/stime_spec.rb17
-rw-r--r--spec/ruby/core/process/tms/utime_spec.rb17
-rw-r--r--spec/ruby/core/queue/initialize_spec.rb64
-rw-r--r--spec/ruby/core/range/each_spec.rb35
-rw-r--r--spec/ruby/core/range/shared/cover_and_include.rb15
-rw-r--r--spec/ruby/core/range/step_spec.rb58
-rw-r--r--spec/ruby/core/refinement/import_methods_spec.rb354
-rw-r--r--spec/ruby/core/refinement/include_spec.rb2
-rw-r--r--spec/ruby/core/refinement/prepend_spec.rb2
-rw-r--r--spec/ruby/core/string/byterindex_spec.rb4
-rw-r--r--spec/ruby/core/string/chilled_string_spec.rb4
-rw-r--r--spec/ruby/core/string/lstrip_spec.rb14
-rw-r--r--spec/ruby/core/string/rindex_spec.rb4
-rw-r--r--spec/ruby/core/string/scan_spec.rb20
-rw-r--r--spec/ruby/core/string/shared/slice.rb17
-rw-r--r--spec/ruby/core/string/sub_spec.rb16
-rw-r--r--spec/ruby/core/string/swapcase_spec.rb6
-rw-r--r--spec/ruby/core/string/to_c_spec.rb16
-rw-r--r--spec/ruby/core/string/to_f_spec.rb94
-rw-r--r--spec/ruby/core/string/to_i_spec.rb2
-rw-r--r--spec/ruby/core/string/to_r_spec.rb4
-rw-r--r--spec/ruby/core/string/unpack1_spec.rb38
-rw-r--r--spec/ruby/core/string/unpack_spec.rb32
-rw-r--r--spec/ruby/core/struct/deconstruct_keys_spec.rb25
-rw-r--r--spec/ruby/core/struct/fixtures/classes.rb2
-rw-r--r--spec/ruby/core/struct/initialize_spec.rb2
-rw-r--r--spec/ruby/core/struct/keyword_init_spec.rb61
-rw-r--r--spec/ruby/core/struct/members_spec.rb12
-rw-r--r--spec/ruby/core/struct/new_spec.rb21
-rw-r--r--spec/ruby/core/symbol/shared/slice.rb2
-rw-r--r--spec/ruby/core/thread/abort_on_exception_spec.rb2
-rw-r--r--spec/ruby/core/thread/backtrace/limit_spec.rb18
-rw-r--r--spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb17
-rw-r--r--spec/ruby/core/thread/native_thread_id_spec.rb52
-rw-r--r--spec/ruby/core/time/at_spec.rb40
-rw-r--r--spec/ruby/core/time/getlocal_spec.rb37
-rw-r--r--spec/ruby/core/time/localtime_spec.rb47
-rw-r--r--spec/ruby/core/time/new_spec.rb220
-rw-r--r--spec/ruby/core/time/now_spec.rb201
-rw-r--r--spec/ruby/core/time/strftime_spec.rb62
-rw-r--r--spec/ruby/core/time/utc_spec.rb22
-rw-r--r--spec/ruby/core/time/zone_spec.rb22
-rw-r--r--spec/ruby/core/tracepoint/allow_reentry_spec.rb44
-rw-r--r--spec/ruby/core/unboundmethod/private_spec.rb2
-rw-r--r--spec/ruby/core/unboundmethod/protected_spec.rb2
-rw-r--r--spec/ruby/core/unboundmethod/public_spec.rb2
-rw-r--r--spec/ruby/core/unboundmethod/source_location_spec.rb2
151 files changed, 2825 insertions, 2263 deletions
diff --git a/spec/ruby/core/array/drop_spec.rb b/spec/ruby/core/array/drop_spec.rb
index 0ea748e47d..5926c291b8 100644
--- a/spec/ruby/core/array/drop_spec.rb
+++ b/spec/ruby/core/array/drop_spec.rb
@@ -7,7 +7,7 @@ describe "Array#drop" do
end
it "raises an ArgumentError if the number of elements specified is negative" do
- -> { [1, 2].drop(-3) }.should raise_error(ArgumentError)
+ -> { [1, 2].drop(-3) }.should raise_error(ArgumentError)
end
it "returns an empty Array if all elements are dropped" do
diff --git a/spec/ruby/core/array/intersect_spec.rb b/spec/ruby/core/array/intersect_spec.rb
index 62ac157278..456aa26c6e 100644
--- a/spec/ruby/core/array/intersect_spec.rb
+++ b/spec/ruby/core/array/intersect_spec.rb
@@ -2,65 +2,63 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe 'Array#intersect?' do
- ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/15198
- describe 'when at least one element in two Arrays is the same' do
- it 'returns true' do
- [1, 2].intersect?([2, 3, 4]).should == true
- [2, 3, 4].intersect?([1, 2]).should == true
- end
+ describe 'when at least one element in two Arrays is the same' do
+ it 'returns true' do
+ [1, 2].intersect?([2, 3, 4]).should == true
+ [2, 3, 4].intersect?([1, 2]).should == true
end
+ end
- describe 'when there are no elements in common between two Arrays' do
- it 'returns false' do
- [0, 1, 2].intersect?([3, 4]).should == false
- [3, 4].intersect?([0, 1, 2]).should == false
- [3, 4].intersect?([]).should == false
- [].intersect?([0, 1, 2]).should == false
- end
+ describe 'when there are no elements in common between two Arrays' do
+ it 'returns false' do
+ [0, 1, 2].intersect?([3, 4]).should == false
+ [3, 4].intersect?([0, 1, 2]).should == false
+ [3, 4].intersect?([]).should == false
+ [].intersect?([0, 1, 2]).should == false
end
+ end
- it "tries to convert the passed argument to an Array using #to_ary" do
- obj = mock('[1,2,3]')
- obj.should_receive(:to_ary).and_return([1, 2, 3])
+ it "tries to convert the passed argument to an Array using #to_ary" do
+ obj = mock('[1,2,3]')
+ obj.should_receive(:to_ary).and_return([1, 2, 3])
- [1, 2].intersect?(obj).should == true
- end
+ [1, 2].intersect?(obj).should == true
+ end
- it "determines equivalence between elements in the sense of eql?" do
- obj1 = mock('1')
- obj2 = mock('2')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.stub!(:eql?).and_return(true)
- obj2.stub!(:eql?).and_return(true)
+ it "determines equivalence between elements in the sense of eql?" do
+ obj1 = mock('1')
+ obj2 = mock('2')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj1.stub!(:eql?).and_return(true)
+ obj2.stub!(:eql?).and_return(true)
- [obj1].intersect?([obj2]).should == true
+ [obj1].intersect?([obj2]).should == true
- obj1 = mock('3')
- obj2 = mock('4')
- obj1.stub!(:hash).and_return(0)
- obj2.stub!(:hash).and_return(0)
- obj1.stub!(:eql?).and_return(false)
- obj2.stub!(:eql?).and_return(false)
+ obj1 = mock('3')
+ obj2 = mock('4')
+ obj1.stub!(:hash).and_return(0)
+ obj2.stub!(:hash).and_return(0)
+ obj1.stub!(:eql?).and_return(false)
+ obj2.stub!(:eql?).and_return(false)
- [obj1].intersect?([obj2]).should == false
- end
+ [obj1].intersect?([obj2]).should == false
+ end
- it "does not call to_ary on array subclasses" do
- [5, 6].intersect?(ArraySpecs::ToAryArray[1, 2, 5, 6]).should == true
- end
+ it "does not call to_ary on array subclasses" do
+ [5, 6].intersect?(ArraySpecs::ToAryArray[1, 2, 5, 6]).should == true
+ end
- it "properly handles an identical item even when its #eql? isn't reflexive" do
- x = mock('x')
- x.stub!(:hash).and_return(42)
- x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
+ it "properly handles an identical item even when its #eql? isn't reflexive" do
+ x = mock('x')
+ x.stub!(:hash).and_return(42)
+ x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
- [x].intersect?([x]).should == true
- end
+ [x].intersect?([x]).should == true
+ end
- it "has semantic of !(a & b).empty?" do
- [].intersect?([]).should == false
- [nil].intersect?([nil]).should == true
- end
+ it "has semantic of !(a & b).empty?" do
+ [].intersect?([]).should == false
+ [nil].intersect?([nil]).should == true
end
end
diff --git a/spec/ruby/core/basicobject/instance_eval_spec.rb b/spec/ruby/core/basicobject/instance_eval_spec.rb
index 1f3a43f341..633b5c2cb1 100644
--- a/spec/ruby/core/basicobject/instance_eval_spec.rb
+++ b/spec/ruby/core/basicobject/instance_eval_spec.rb
@@ -141,22 +141,11 @@ describe "BasicObject#instance_eval" do
caller.get_constant_with_string(receiver).should == :singleton_class
end
- ruby_version_is ""..."3.1" do
- it "looks in the caller scope next" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::CallerScope::Caller.new
+ it "looks in the receiver class next" do
+ receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::ReceiverScope::Receiver.new
+ caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::CallerScope::Caller.new
- caller.get_constant_with_string(receiver).should == :Caller
- end
- end
-
- ruby_version_is "3.1" do
- it "looks in the receiver class next" do
- receiver = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::ReceiverScope::Receiver.new
- caller = BasicObjectSpecs::InstEval::Constants::ConstantInReceiverClass::CallerScope::Caller.new
-
- caller.get_constant_with_string(receiver).should == :Receiver
- end
+ caller.get_constant_with_string(receiver).should == :Receiver
end
it "looks in the caller class next" do
diff --git a/spec/ruby/core/basicobject/singleton_method_added_spec.rb b/spec/ruby/core/basicobject/singleton_method_added_spec.rb
index fc65a091aa..bd21458ea7 100644
--- a/spec/ruby/core/basicobject/singleton_method_added_spec.rb
+++ b/spec/ruby/core/basicobject/singleton_method_added_spec.rb
@@ -96,6 +96,8 @@ describe "BasicObject#singleton_method_added" do
end
}.should raise_error(NoMethodError, /undefined method [`']singleton_method_added' for/)
end
+ ensure
+ BasicObjectSpecs.send(:remove_const, :NoSingletonMethodAdded)
end
it "raises NoMethodError for a singleton instance" do
diff --git a/spec/ruby/core/class/dup_spec.rb b/spec/ruby/core/class/dup_spec.rb
index c09ed71b31..1ff9abf7b4 100644
--- a/spec/ruby/core/class/dup_spec.rb
+++ b/spec/ruby/core/class/dup_spec.rb
@@ -59,6 +59,8 @@ describe "Class#dup" do
it "stores the new name if assigned to a constant" do
CoreClassSpecs::RecordCopy = CoreClassSpecs::Record.dup
CoreClassSpecs::RecordCopy.name.should == "CoreClassSpecs::RecordCopy"
+ ensure
+ CoreClassSpecs.send(:remove_const, :RecordCopy)
end
it "raises TypeError if called on BasicObject" do
diff --git a/spec/ruby/core/class/new_spec.rb b/spec/ruby/core/class/new_spec.rb
index 93152a83ee..6fe54c3209 100644
--- a/spec/ruby/core/class/new_spec.rb
+++ b/spec/ruby/core/class/new_spec.rb
@@ -83,6 +83,8 @@ describe "Class.new" do
a = Class.new
MyClass::NestedClass = a
MyClass::NestedClass.name.should == "MyClass::NestedClass"
+ ensure
+ Object.send(:remove_const, :MyClass)
end
it "sets the new class' superclass to the given class" do
diff --git a/spec/ruby/core/class/subclasses_spec.rb b/spec/ruby/core/class/subclasses_spec.rb
index 50eb5358d9..f692152787 100644
--- a/spec/ruby/core/class/subclasses_spec.rb
+++ b/spec/ruby/core/class/subclasses_spec.rb
@@ -1,87 +1,85 @@
require_relative '../../spec_helper'
require_relative '../module/fixtures/classes'
-ruby_version_is '3.1' do
- describe "Class#subclasses" do
- it "returns a list of classes directly inheriting from self" do
- assert_subclasses(ModuleSpecs::Parent, [ModuleSpecs::Child, ModuleSpecs::Child2])
- end
+describe "Class#subclasses" do
+ it "returns a list of classes directly inheriting from self" do
+ assert_subclasses(ModuleSpecs::Parent, [ModuleSpecs::Child, ModuleSpecs::Child2])
+ end
- it "does not return included modules from the parent" do
- parent = Class.new
- child = Class.new(parent)
- mod = Module.new
- parent.include(mod)
+ it "does not return included modules from the parent" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ parent.include(mod)
- assert_subclasses(parent, [child])
- end
-
- it "does not return included modules from the child" do
- parent = Class.new
- child = Class.new(parent)
- mod = Module.new
- parent.include(mod)
+ assert_subclasses(parent, [child])
+ end
- assert_subclasses(parent, [child])
- end
+ it "does not return included modules from the child" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ parent.include(mod)
- it "does not return prepended modules from the parent" do
- parent = Class.new
- child = Class.new(parent)
- mod = Module.new
- parent.prepend(mod)
+ assert_subclasses(parent, [child])
+ end
- assert_subclasses(parent, [child])
- end
+ it "does not return prepended modules from the parent" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ parent.prepend(mod)
- it "does not return prepended modules from the child" do
- parent = Class.new
- child = Class.new(parent)
- mod = Module.new
- child.prepend(mod)
+ assert_subclasses(parent, [child])
+ end
- assert_subclasses(parent, [child])
- end
+ it "does not return prepended modules from the child" do
+ parent = Class.new
+ child = Class.new(parent)
+ mod = Module.new
+ child.prepend(mod)
- it "does not return singleton classes" do
- a = Class.new
+ assert_subclasses(parent, [child])
+ end
- a_obj = a.new
- def a_obj.force_singleton_class
- 42
- end
+ it "does not return singleton classes" do
+ a = Class.new
- a.subclasses.should_not include(a_obj.singleton_class)
+ a_obj = a.new
+ def a_obj.force_singleton_class
+ 42
end
- it "has 1 entry per module or class" do
- ModuleSpecs::Parent.subclasses.should == ModuleSpecs::Parent.subclasses.uniq
- end
+ a.subclasses.should_not include(a_obj.singleton_class)
+ end
+
+ it "has 1 entry per module or class" do
+ ModuleSpecs::Parent.subclasses.should == ModuleSpecs::Parent.subclasses.uniq
+ end
- it "works when creating subclasses concurrently" do
- t = 16
- n = 1000
- go = false
- superclass = Class.new
-
- threads = t.times.map do
- Thread.new do
- Thread.pass until go
- n.times.map do
- Class.new(superclass)
- end
+ it "works when creating subclasses concurrently" do
+ t = 16
+ n = 1000
+ go = false
+ superclass = Class.new
+
+ threads = t.times.map do
+ Thread.new do
+ Thread.pass until go
+ n.times.map do
+ Class.new(superclass)
end
end
+ end
- go = true
- classes = threads.map(&:value)
+ go = true
+ classes = threads.map(&:value)
- superclass.subclasses.size.should == t * n
- superclass.subclasses.each { |c| c.should be_kind_of(Class) }
- end
+ superclass.subclasses.size.should == t * n
+ superclass.subclasses.each { |c| c.should be_kind_of(Class) }
+ end
- def assert_subclasses(mod,subclasses)
- mod.subclasses.sort_by(&:inspect).should == subclasses.sort_by(&:inspect)
- end
+ def assert_subclasses(mod,subclasses)
+ mod.subclasses.sort_by(&:inspect).should == subclasses.sort_by(&:inspect)
end
end
diff --git a/spec/ruby/core/complex/shared/rect.rb b/spec/ruby/core/complex/shared/rect.rb
index 9f5de1ffeb..4ac294e771 100644
--- a/spec/ruby/core/complex/shared/rect.rb
+++ b/spec/ruby/core/complex/shared/rect.rb
@@ -24,15 +24,15 @@ describe :complex_rect, shared: true do
end
it "returns the real part of self as the first element" do
- @numbers.each do |number|
- number.send(@method).first.should == number.real
- end
+ @numbers.each do |number|
+ number.send(@method).first.should == number.real
+ end
end
it "returns the imaginary part of self as the last element" do
- @numbers.each do |number|
- number.send(@method).last.should == number.imaginary
- end
+ @numbers.each do |number|
+ number.send(@method).last.should == number.imaginary
+ end
end
it "raises an ArgumentError if given any arguments" do
diff --git a/spec/ruby/core/data/deconstruct_keys_spec.rb b/spec/ruby/core/data/deconstruct_keys_spec.rb
new file mode 100644
index 0000000000..07af87771d
--- /dev/null
+++ b/spec/ruby/core/data/deconstruct_keys_spec.rb
@@ -0,0 +1,107 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "3.2" do
+ describe "Data#deconstruct" do
+ it "returns a hash of attributes" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+ d.deconstruct_keys([:x, :y]).should == {x: 1, y: 2}
+ end
+
+ it "requires one argument" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ -> {
+ d.deconstruct_keys
+ }.should raise_error(ArgumentError, /wrong number of arguments \(given 0, expected 1\)/)
+ end
+
+ it "returns only specified keys" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ d.deconstruct_keys([:x, :y]).should == {x: 1, y: 2}
+ d.deconstruct_keys([:x] ).should == {x: 1}
+ d.deconstruct_keys([] ).should == {}
+ end
+
+ it "accepts string attribute names" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+ d.deconstruct_keys(['x', 'y']).should == {'x' => 1, 'y' => 2}
+ end
+
+ it "accepts argument position number as well but returns them as keys" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ d.deconstruct_keys([0, 1]).should == {0 => 1, 1 => 2}
+ d.deconstruct_keys([0] ).should == {0 => 1}
+ d.deconstruct_keys([-1] ).should == {-1 => 2}
+ end
+
+ it "ignores incorrect position numbers" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ d.deconstruct_keys([0, 3]).should == {0 => 1}
+ end
+
+ it "support mixing attribute names and argument position numbers" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ d.deconstruct_keys([0, :x]).should == {0 => 1, :x => 1}
+ end
+
+ it "returns an empty hash when there are more keys than attributes" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+ d.deconstruct_keys([:x, :y, :x]).should == {}
+ end
+
+ it "returns at first not existing attribute name" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ d.deconstruct_keys([:a, :x]).should == {}
+ d.deconstruct_keys([:x, :a]).should == {x: 1}
+ end
+
+ it "returns at first not existing argument position number" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ d.deconstruct_keys([3, 0]).should == {}
+ d.deconstruct_keys([0, 3]).should == {0 => 1}
+ end
+
+ it "accepts nil argument and return all the attributes" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ d.deconstruct_keys(nil).should == {x: 1, y: 2}
+ end
+
+ it "raises TypeError if index is not a String, a Symbol and not convertible to Integer " do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ -> {
+ d.deconstruct_keys([0, []])
+ }.should raise_error(TypeError, "no implicit conversion of Array into Integer")
+ end
+
+ it "raise TypeError if passed anything except nil or array" do
+ klass = Data.define(:x, :y)
+ d = klass.new(1, 2)
+
+ -> { d.deconstruct_keys('x') }.should raise_error(TypeError, /expected Array or nil/)
+ -> { d.deconstruct_keys(1) }.should raise_error(TypeError, /expected Array or nil/)
+ -> { d.deconstruct_keys(:x) }.should raise_error(TypeError, /expected Array or nil/)
+ -> { d.deconstruct_keys({}) }.should raise_error(TypeError, /expected Array or nil/)
+ end
+ end
+end
diff --git a/spec/ruby/core/data/deconstruct_spec.rb b/spec/ruby/core/data/deconstruct_spec.rb
new file mode 100644
index 0000000000..f0995e8fed
--- /dev/null
+++ b/spec/ruby/core/data/deconstruct_spec.rb
@@ -0,0 +1,10 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "3.2" do
+ describe "Data#deconstruct" do
+ it "returns an array of attribute values" do
+ DataSpecs::Measure.new(42, "km").deconstruct.should == [42, "km"]
+ end
+ end
+end
diff --git a/spec/ruby/core/data/eql_spec.rb b/spec/ruby/core/data/eql_spec.rb
new file mode 100644
index 0000000000..906e46316c
--- /dev/null
+++ b/spec/ruby/core/data/eql_spec.rb
@@ -0,0 +1,65 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "3.2" do
+ describe "Data#eql?" do
+ it "returns true if the other is the same object" do
+ a = DataSpecs::Measure.new(42, "km")
+ a.should.eql?(a)
+ end
+
+ it "returns true if the other has all the same fields" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42, "km")
+ a.should.eql?(b)
+ end
+
+ it "returns false if the other is a different object or has different fields" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42, "mi")
+ a.should_not.eql?(b)
+ end
+
+ it "returns false if other is of a different class" do
+ a = DataSpecs::Measure.new(42, "km")
+ klass = Data.define(*DataSpecs::Measure.members)
+ b = klass.new(42, "km")
+ a.should_not.eql?(b)
+ end
+
+ it "returns false if any corresponding elements are not equal with #eql?" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42.0, "mi")
+ a.should_not.eql?(b)
+ end
+
+ context "recursive structure" do
+ it "returns true the other is the same object" do
+ a = DataSpecs::Measure.allocate
+ a.send(:initialize, amount: 42, unit: a)
+
+ a.should.eql?(a)
+ end
+
+ it "returns true if the other has all the same fields" do
+ a = DataSpecs::Measure.allocate
+ a.send(:initialize, amount: 42, unit: a)
+
+ b = DataSpecs::Measure.allocate
+ b.send(:initialize, amount: 42, unit: b)
+
+ a.should.eql?(b)
+ end
+
+ it "returns false if any corresponding elements are not equal with #eql?" do
+ a = DataSpecs::Measure.allocate
+ a.send(:initialize, amount: a, unit: "km")
+
+ b = DataSpecs::Measure.allocate
+ b.send(:initialize, amount: b, unit: "mi")
+
+ a.should_not.eql?(b)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/data/equal_value_spec.rb b/spec/ruby/core/data/equal_value_spec.rb
new file mode 100644
index 0000000000..f90a7d7a62
--- /dev/null
+++ b/spec/ruby/core/data/equal_value_spec.rb
@@ -0,0 +1,65 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "3.2" do
+ describe "Data#==" do
+ it "returns true if the other is the same object" do
+ a = DataSpecs::Measure.new(42, "km")
+ a.should == a
+ end
+
+ it "returns true if the other has all the same fields" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42, "km")
+ a.should == b
+ end
+
+ it "returns false if the other is a different object or has different fields" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42, "mi")
+ a.should_not == b
+ end
+
+ it "returns false if other is of a different class" do
+ a = DataSpecs::Measure.new(42, "km")
+ klass = Data.define(*DataSpecs::Measure.members)
+ b = klass.new(42, "km")
+ a.should_not == b
+ end
+
+ it "returns false if any corresponding elements are not equal with #==" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42.0, "mi")
+ a.should_not == b
+ end
+
+ context "recursive structure" do
+ it "returns true the other is the same object" do
+ a = DataSpecs::Measure.allocate
+ a.send(:initialize, amount: 42, unit: a)
+
+ a.should == a
+ end
+
+ it "returns true if the other has all the same fields" do
+ a = DataSpecs::Measure.allocate
+ a.send(:initialize, amount: 42, unit: a)
+
+ b = DataSpecs::Measure.allocate
+ b.send(:initialize, amount: 42, unit: b)
+
+ a.should == b
+ end
+
+ it "returns false if any corresponding elements are not equal with #==" do
+ a = DataSpecs::Measure.allocate
+ a.send(:initialize, amount: a, unit: "km")
+
+ b = DataSpecs::Measure.allocate
+ b.send(:initialize, amount: b, unit: "mi")
+
+ a.should_not == b
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/data/fixtures/classes.rb b/spec/ruby/core/data/fixtures/classes.rb
index 46a6b48bb2..f0a526517d 100644
--- a/spec/ruby/core/data/fixtures/classes.rb
+++ b/spec/ruby/core/data/fixtures/classes.rb
@@ -1,5 +1,13 @@
module DataSpecs
guard -> { ruby_version_is "3.2" and Data.respond_to?(:define) } do
Measure = Data.define(:amount, :unit)
+
+ class MeasureWithOverriddenName < Measure
+ def self.name
+ "A"
+ end
+ end
+
+ class DataSubclass < Data; end
end
end
diff --git a/spec/ruby/core/data/hash_spec.rb b/spec/ruby/core/data/hash_spec.rb
new file mode 100644
index 0000000000..324a2abca4
--- /dev/null
+++ b/spec/ruby/core/data/hash_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "3.2" do
+ describe "Data#hash" do
+ it "returns the same integer for objects with the same content" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42, "km")
+ a.hash.should == b.hash
+ a.hash.should be_an_instance_of(Integer)
+ end
+
+ it "returns different hashes for objects with different values" do
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(42, "ml")
+ a.hash.should_not == b.hash
+
+ a = DataSpecs::Measure.new(42, "km")
+ b = DataSpecs::Measure.new(13, "km")
+ a.hash.should_not == b.hash
+ end
+
+ it "returns different hashes for different classes" do
+ Data.define(:x).new(1).hash.should != Data.define(:x).new(1).hash
+ end
+ end
+end
diff --git a/spec/ruby/core/data/inspect_spec.rb b/spec/ruby/core/data/inspect_spec.rb
new file mode 100644
index 0000000000..3d337fac68
--- /dev/null
+++ b/spec/ruby/core/data/inspect_spec.rb
@@ -0,0 +1,8 @@
+require_relative '../../spec_helper'
+require_relative 'shared/inspect'
+
+ruby_version_is "3.2" do
+ describe "Data#inspect" do
+ it_behaves_like :data_inspect, :inspect
+ end
+end
diff --git a/spec/ruby/core/data/members_spec.rb b/spec/ruby/core/data/members_spec.rb
new file mode 100644
index 0000000000..1776b0b9c1
--- /dev/null
+++ b/spec/ruby/core/data/members_spec.rb
@@ -0,0 +1,23 @@
+require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
+
+ruby_version_is "3.2" do
+ describe "Data#members" do
+ it "returns an array of attribute names" do
+ measure = DataSpecs::Measure.new(amount: 42, unit: 'km')
+ measure.members.should == [:amount, :unit]
+ end
+ end
+
+ describe "DataClass#members" do
+ it "returns an array of attribute names" do
+ DataSpecs::Measure.members.should == [:amount, :unit]
+ end
+
+ context "class inheriting Data" do
+ it "isn't available in a subclass" do
+ DataSpecs::DataSubclass.should_not.respond_to?(:members)
+ end
+ end
+ end
+end
diff --git a/spec/ruby/core/data/shared/inspect.rb b/spec/ruby/core/data/shared/inspect.rb
new file mode 100644
index 0000000000..7f54a46de3
--- /dev/null
+++ b/spec/ruby/core/data/shared/inspect.rb
@@ -0,0 +1,54 @@
+require_relative '../fixtures/classes'
+
+describe :data_inspect, shared: true do
+ it "returns a string representation showing members and values" do
+ a = DataSpecs::Measure.new(42, "km")
+ a.send(@method).should == '#<data DataSpecs::Measure amount=42, unit="km">'
+ end
+
+ it "returns a string representation without the class name for anonymous structs" do
+ Data.define(:a).new("").send(@method).should == '#<data a="">'
+ end
+
+ it "returns a string representation without the class name for structs nested in anonymous classes" do
+ c = Class.new
+ c.class_eval <<~DOC
+ Foo = Data.define(:a)
+ DOC
+
+ c::Foo.new("").send(@method).should == '#<data a="">'
+ end
+
+ it "returns a string representation without the class name for structs nested in anonymous modules" do
+ m = Module.new
+ m.class_eval <<~DOC
+ Foo = Data.define(:a)
+ DOC
+
+ m::Foo.new("").send(@method).should == '#<data a="">'
+ end
+
+ it "does not call #name method" do
+ struct = DataSpecs::MeasureWithOverriddenName.new(42, "km")
+ struct.send(@method).should == '#<data DataSpecs::MeasureWithOverriddenName amount=42, unit="km">'
+ end
+
+ it "does not call #name method when struct is anonymous" do
+ klass = Class.new(DataSpecs::Measure) do
+ def self.name
+ "A"
+ end
+ end
+ struct = klass.new(42, "km")
+ struct.send(@method).should == '#<data amount=42, unit="km">'
+ end
+
+ context "recursive structure" do
+ it "returns string representation with recursive attribute replaced with ..." do
+ a = DataSpecs::Measure.allocate
+ a.send(:initialize, amount: 42, unit: a)
+
+ a.send(@method).should == "#<data DataSpecs::Measure amount=42, unit=#<data DataSpecs::Measure:...>>"
+ end
+ end
+end
diff --git a/spec/ruby/core/data/to_s_spec.rb b/spec/ruby/core/data/to_s_spec.rb
new file mode 100644
index 0000000000..0b9099f035
--- /dev/null
+++ b/spec/ruby/core/data/to_s_spec.rb
@@ -0,0 +1,8 @@
+require_relative '../../spec_helper'
+require_relative 'shared/inspect'
+
+ruby_version_is "3.2" do
+ describe "Data#to_s" do
+ it_behaves_like :data_inspect, :to_s
+ end
+end
diff --git a/spec/ruby/core/dir/chdir_spec.rb b/spec/ruby/core/dir/chdir_spec.rb
index 015386a902..1da9307599 100644
--- a/spec/ruby/core/dir/chdir_spec.rb
+++ b/spec/ruby/core/dir/chdir_spec.rb
@@ -177,7 +177,7 @@ ruby_version_is '3.3' do
dir.close
end
- platform_is_not :windows do
+ guard -> { Dir.respond_to? :fchdir } do
it "does not raise an Errno::ENOENT if the original directory no longer exists" do
dir_name1 = tmp('testdir1')
dir_name2 = tmp('testdir2')
diff --git a/spec/ruby/core/dir/glob_spec.rb b/spec/ruby/core/dir/glob_spec.rb
index 32f515c81d..a60b233bc0 100644
--- a/spec/ruby/core/dir/glob_spec.rb
+++ b/spec/ruby/core/dir/glob_spec.rb
@@ -89,31 +89,15 @@ describe "Dir.glob" do
Dir.glob('**/', File::FNM_DOTMATCH).sort.should == expected
end
- ruby_version_is ''...'3.1' do
- it "recursively matches files and directories in nested dot subdirectory with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do
- expected = %w[
- nested/.
- nested/.dotsubir
- nested/.dotsubir/.
- nested/.dotsubir/.dotfile
- nested/.dotsubir/nondotfile
- ]
-
- Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
- end
- end
-
- ruby_version_is '3.1' do
- it "recursively matches files and directories in nested dot subdirectory except . with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do
- expected = %w[
- nested/.
- nested/.dotsubir
- nested/.dotsubir/.dotfile
- nested/.dotsubir/nondotfile
- ]
+ it "recursively matches files and directories in nested dot subdirectory except . with 'nested/**/*' from the current directory and option File::FNM_DOTMATCH" do
+ expected = %w[
+ nested/.
+ nested/.dotsubir
+ nested/.dotsubir/.dotfile
+ nested/.dotsubir/nondotfile
+ ]
- Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
- end
+ Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
end
# This is a separate case to check **/ coming after a constant
@@ -260,34 +244,31 @@ describe "Dir.glob" do
Dir.glob('**/.*', base: "deeply/nested").sort.should == expected
end
- # < 3.1 include a "." entry for every dir: ["directory/.", "directory/structure/.", ...]
- ruby_version_is '3.1' do
- it "handles **/.* with base keyword argument and FNM_DOTMATCH" do
- expected = %w[
- .
- .dotfile.ext
- directory/structure/.ext
- ].sort
+ it "handles **/.* with base keyword argument and FNM_DOTMATCH" do
+ expected = %w[
+ .
+ .dotfile.ext
+ directory/structure/.ext
+ ].sort
- Dir.glob('**/.*', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
- end
+ Dir.glob('**/.*', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
+ end
- it "handles **/** with base keyword argument and FNM_DOTMATCH" do
- expected = %w[
- .
- .dotfile.ext
- directory
- directory/structure
- directory/structure/.ext
- directory/structure/bar
- directory/structure/baz
- directory/structure/file_one
- directory/structure/file_one.ext
- directory/structure/foo
- ].sort
-
- Dir.glob('**/**', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
- end
+ it "handles **/** with base keyword argument and FNM_DOTMATCH" do
+ expected = %w[
+ .
+ .dotfile.ext
+ directory
+ directory/structure
+ directory/structure/.ext
+ directory/structure/bar
+ directory/structure/baz
+ directory/structure/file_one
+ directory/structure/file_one.ext
+ directory/structure/foo
+ ].sort
+
+ Dir.glob('**/**', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
end
it "handles **/*pattern* with base keyword argument and FNM_DOTMATCH" do
diff --git a/spec/ruby/core/dir/shared/glob.rb b/spec/ruby/core/dir/shared/glob.rb
index 8db74881ba..b1fc924f08 100644
--- a/spec/ruby/core/dir/shared/glob.rb
+++ b/spec/ruby/core/dir/shared/glob.rb
@@ -42,25 +42,10 @@ describe :dir_glob, shared: true do
result.sort.should == Dir.send(@method, '*').sort
end
- ruby_version_is ""..."3.1" do
- it "result is sorted with any non false value of sort:" do
- result = Dir.send(@method, '*', sort: 0)
- result.should == result.sort
-
- result = Dir.send(@method, '*', sort: nil)
- result.should == result.sort
-
- result = Dir.send(@method, '*', sort: 'false')
- result.should == result.sort
- end
- end
-
- ruby_version_is "3.1" do
- it "raises an ArgumentError if sort: is not true or false" do
- -> { Dir.send(@method, '*', sort: 0) }.should raise_error ArgumentError, /expected true or false/
- -> { Dir.send(@method, '*', sort: nil) }.should raise_error ArgumentError, /expected true or false/
- -> { Dir.send(@method, '*', sort: 'false') }.should raise_error ArgumentError, /expected true or false/
- end
+ it "raises an ArgumentError if sort: is not true or false" do
+ -> { Dir.send(@method, '*', sort: 0) }.should raise_error ArgumentError, /expected true or false/
+ -> { Dir.send(@method, '*', sort: nil) }.should raise_error ArgumentError, /expected true or false/
+ -> { Dir.send(@method, '*', sort: 'false') }.should raise_error ArgumentError, /expected true or false/
end
it "matches non-dotfiles with '*'" do
@@ -151,16 +136,8 @@ describe :dir_glob, shared: true do
Dir.send(@method, 'special/test\{1\}/*').should == ['special/test{1}/file[1]']
end
- ruby_version_is ''...'3.1' do
- it "matches dotfiles with '.*'" do
- Dir.send(@method, '.*').sort.should == %w|. .. .dotfile .dotsubdir|.sort
- end
- end
-
- ruby_version_is '3.1' do
- it "matches dotfiles except .. with '.*'" do
- Dir.send(@method, '.*').sort.should == %w|. .dotfile .dotsubdir|.sort
- end
+ it "matches dotfiles except .. with '.*'" do
+ Dir.send(@method, '.*').sort.should == %w|. .dotfile .dotsubdir|.sort
end
it "matches non-dotfiles with '*<non-special characters>'" do
@@ -205,16 +182,8 @@ describe :dir_glob, shared: true do
Dir.send(@method, '**').sort.should == expected
end
- ruby_version_is ''...'3.1' do
- it "matches dotfiles in the current directory with '.**'" do
- Dir.send(@method, '.**').sort.should == %w|. .. .dotsubdir .dotfile|.sort
- end
- end
-
- ruby_version_is '3.1' do
- it "matches dotfiles in the current directory except .. with '.**'" do
- Dir.send(@method, '.**').sort.should == %w|. .dotsubdir .dotfile|.sort
- end
+ it "matches dotfiles in the current directory except .. with '.**'" do
+ Dir.send(@method, '.**').sort.should == %w|. .dotsubdir .dotfile|.sort
end
it "recursively matches any nondot subdirectories with '**/'" do
@@ -245,19 +214,9 @@ describe :dir_glob, shared: true do
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
- Dir.send(@method, '.**/').sort.should == %w|./ ../|.sort
- end
- end
- end
-
- ruby_version_is '3.1' do
- it "recursively matches any subdirectories including ./ with '.**/'" do
- Dir.chdir("#{DirSpecs.mock_dir}/subdir_one") do
- Dir.send(@method, '.**/').should == ['./']
- end
+ it "recursively matches any subdirectories including ./ with '.**/'" do
+ Dir.chdir("#{DirSpecs.mock_dir}/subdir_one") do
+ Dir.send(@method, '.**/').should == ['./']
end
end
diff --git a/spec/ruby/core/encoding/converter/finish_spec.rb b/spec/ruby/core/encoding/converter/finish_spec.rb
index 239243430b..22e66df38c 100644
--- a/spec/ruby/core/encoding/converter/finish_spec.rb
+++ b/spec/ruby/core/encoding/converter/finish_spec.rb
@@ -16,8 +16,8 @@ describe "Encoding::Converter#finish" do
end
it "returns the last part of the converted String if it hasn't already" do
- @ec.convert("\u{9999}").should == "\e$B9a".dup.force_encoding('iso-2022-jp')
- @ec.finish.should == "\e(B".dup.force_encoding('iso-2022-jp')
+ @ec.convert("\u{9999}").should == "\e$B9a".dup.force_encoding('iso-2022-jp')
+ @ec.finish.should == "\e(B".dup.force_encoding('iso-2022-jp')
end
it "returns a String in the destination encoding" do
diff --git a/spec/ruby/core/encoding/converter/search_convpath_spec.rb b/spec/ruby/core/encoding/converter/search_convpath_spec.rb
index 0882af5539..59fe4520c0 100644
--- a/spec/ruby/core/encoding/converter/search_convpath_spec.rb
+++ b/spec/ruby/core/encoding/converter/search_convpath_spec.rb
@@ -23,8 +23,8 @@ describe "Encoding::Converter.search_convpath" do
end
it "raises an Encoding::ConverterNotFoundError if no conversion path exists" do
- -> do
- Encoding::Converter.search_convpath(Encoding::BINARY, Encoding::Emacs_Mule)
- end.should raise_error(Encoding::ConverterNotFoundError)
+ -> do
+ Encoding::Converter.search_convpath(Encoding::BINARY, Encoding::Emacs_Mule)
+ end.should raise_error(Encoding::ConverterNotFoundError)
end
end
diff --git a/spec/ruby/core/enumerable/compact_spec.rb b/spec/ruby/core/enumerable/compact_spec.rb
index 86e95dce08..1895430c4e 100644
--- a/spec/ruby/core/enumerable/compact_spec.rb
+++ b/spec/ruby/core/enumerable/compact_spec.rb
@@ -1,11 +1,9 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-ruby_version_is '3.1' do
- describe "Enumerable#compact" do
- it 'returns array without nil elements' do
- arr = EnumerableSpecs::Numerous.new(nil, 1, 2, nil, true)
- arr.compact.should == [1, 2, true]
- end
+describe "Enumerable#compact" do
+ it 'returns array without nil elements' do
+ arr = EnumerableSpecs::Numerous.new(nil, 1, 2, nil, true)
+ arr.compact.should == [1, 2, true]
end
end
diff --git a/spec/ruby/core/enumerable/each_cons_spec.rb b/spec/ruby/core/enumerable/each_cons_spec.rb
index 8fb31fb925..ed77741862 100644
--- a/spec/ruby/core/enumerable/each_cons_spec.rb
+++ b/spec/ruby/core/enumerable/each_cons_spec.rb
@@ -56,10 +56,8 @@ describe "Enumerable#each_cons" do
multi.each_cons(2).to_a.should == [[[1, 2], [3, 4, 5]], [[3, 4, 5], [6, 7, 8, 9]]]
end
- ruby_version_is "3.1" do
- it "returns self when a block is given" do
- @enum.each_cons(3){}.should == @enum
- end
+ it "returns self when a block is given" do
+ @enum.each_cons(3){}.should == @enum
end
describe "when no block is given" do
diff --git a/spec/ruby/core/enumerable/each_slice_spec.rb b/spec/ruby/core/enumerable/each_slice_spec.rb
index a57a1dba81..47b8c9ba33 100644
--- a/spec/ruby/core/enumerable/each_slice_spec.rb
+++ b/spec/ruby/core/enumerable/each_slice_spec.rb
@@ -57,10 +57,8 @@ describe "Enumerable#each_slice" do
e.to_a.should == @sliced
end
- ruby_version_is "3.1" do
- it "returns self when a block is given" do
- @enum.each_slice(3){}.should == @enum
- end
+ it "returns self when a block is given" do
+ @enum.each_slice(3){}.should == @enum
end
it "gathers whole arrays as elements when each yields multiple" do
diff --git a/spec/ruby/core/enumerable/tally_spec.rb b/spec/ruby/core/enumerable/tally_spec.rb
index e0edc8dc75..95c64c1294 100644
--- a/spec/ruby/core/enumerable/tally_spec.rb
+++ b/spec/ruby/core/enumerable/tally_spec.rb
@@ -32,62 +32,60 @@ describe "Enumerable#tally" do
end
end
-ruby_version_is "3.1" do
- describe "Enumerable#tally with a hash" do
- before :each do
- ScratchPad.record []
- end
-
- it "returns a hash with counts according to the value" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- enum.tally({ 'foo' => 1 }).should == { 'foo' => 3, 'bar' => 1, 'baz' => 1}
- end
-
- it "returns the given hash" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- hash = { 'foo' => 1 }
- enum.tally(hash).should equal(hash)
- end
-
- it "calls #to_hash to convert argument to Hash implicitly if passed not a Hash" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- object = Object.new
- def object.to_hash; { 'foo' => 1 }; end
- enum.tally(object).should == { 'foo' => 3, 'bar' => 1, 'baz' => 1}
- end
-
- it "raises a FrozenError and does not update the given hash when the hash is frozen" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- hash = { 'foo' => 1 }.freeze
- -> { enum.tally(hash) }.should raise_error(FrozenError)
- hash.should == { 'foo' => 1 }
- end
-
- it "raises a FrozenError even if enumerable is empty" do
- enum = EnumerableSpecs::Numerous.new()
- hash = { 'foo' => 1 }.freeze
- -> { enum.tally(hash) }.should raise_error(FrozenError)
- end
-
- it "does not call given block" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- enum.tally({ 'foo' => 1 }) { |v| ScratchPad << v }
- ScratchPad.recorded.should == []
- end
-
- it "ignores the default value" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- enum.tally(Hash.new(100)).should == { 'foo' => 2, 'bar' => 1, 'baz' => 1}
- end
-
- it "ignores the default proc" do
- enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
- enum.tally(Hash.new {100}).should == { 'foo' => 2, 'bar' => 1, 'baz' => 1}
- end
-
- it "needs the values counting each elements to be an integer" do
- enum = EnumerableSpecs::Numerous.new('foo')
- -> { enum.tally({ 'foo' => 'bar' }) }.should raise_error(TypeError)
- end
+describe "Enumerable#tally with a hash" do
+ before :each do
+ ScratchPad.record []
+ end
+
+ it "returns a hash with counts according to the value" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ enum.tally({ 'foo' => 1 }).should == { 'foo' => 3, 'bar' => 1, 'baz' => 1}
+ end
+
+ it "returns the given hash" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ hash = { 'foo' => 1 }
+ enum.tally(hash).should equal(hash)
+ end
+
+ it "calls #to_hash to convert argument to Hash implicitly if passed not a Hash" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ object = Object.new
+ def object.to_hash; { 'foo' => 1 }; end
+ enum.tally(object).should == { 'foo' => 3, 'bar' => 1, 'baz' => 1}
+ end
+
+ it "raises a FrozenError and does not update the given hash when the hash is frozen" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ hash = { 'foo' => 1 }.freeze
+ -> { enum.tally(hash) }.should raise_error(FrozenError)
+ hash.should == { 'foo' => 1 }
+ end
+
+ it "raises a FrozenError even if enumerable is empty" do
+ enum = EnumerableSpecs::Numerous.new()
+ hash = { 'foo' => 1 }.freeze
+ -> { enum.tally(hash) }.should raise_error(FrozenError)
+ end
+
+ it "does not call given block" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ enum.tally({ 'foo' => 1 }) { |v| ScratchPad << v }
+ ScratchPad.recorded.should == []
+ end
+
+ it "ignores the default value" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ enum.tally(Hash.new(100)).should == { 'foo' => 2, 'bar' => 1, 'baz' => 1}
+ end
+
+ it "ignores the default proc" do
+ enum = EnumerableSpecs::Numerous.new('foo', 'bar', 'foo', 'baz')
+ enum.tally(Hash.new {100}).should == { 'foo' => 2, 'bar' => 1, 'baz' => 1}
+ end
+
+ it "needs the values counting each elements to be an integer" do
+ enum = EnumerableSpecs::Numerous.new('foo')
+ -> { enum.tally({ 'foo' => 'bar' }) }.should raise_error(TypeError)
end
end
diff --git a/spec/ruby/core/enumerator/lazy/compact_spec.rb b/spec/ruby/core/enumerator/lazy/compact_spec.rb
index e678bc71eb..65c544f062 100644
--- a/spec/ruby/core/enumerator/lazy/compact_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/compact_spec.rb
@@ -1,16 +1,14 @@
require_relative '../../../spec_helper'
require_relative 'fixtures/classes'
-ruby_version_is '3.1' do
- describe "Enumerator::Lazy#compact" do
- it 'returns array without nil elements' do
- arr = [1, nil, 3, false, 5].to_enum.lazy.compact
- arr.should be_an_instance_of(Enumerator::Lazy)
- arr.force.should == [1, 3, false, 5]
- end
+describe "Enumerator::Lazy#compact" do
+ it 'returns array without nil elements' do
+ arr = [1, nil, 3, false, 5].to_enum.lazy.compact
+ arr.should be_an_instance_of(Enumerator::Lazy)
+ arr.force.should == [1, 3, false, 5]
+ end
- it "sets #size to nil" do
- Enumerator::Lazy.new(Object.new, 100) {}.compact.size.should == nil
- end
+ it "sets #size to nil" do
+ Enumerator::Lazy.new(Object.new, 100) {}.compact.size.should == nil
end
end
diff --git a/spec/ruby/core/enumerator/lazy/lazy_spec.rb b/spec/ruby/core/enumerator/lazy/lazy_spec.rb
index 0fb104e25a..b43864b673 100644
--- a/spec/ruby/core/enumerator/lazy/lazy_spec.rb
+++ b/spec/ruby/core/enumerator/lazy/lazy_spec.rb
@@ -9,16 +9,11 @@ describe "Enumerator::Lazy" do
it "defines lazy versions of a whitelist of Enumerator methods" do
lazy_methods = [
- :chunk, :collect, :collect_concat, :drop, :drop_while, :enum_for,
+ :chunk, :chunk_while, :collect, :collect_concat, :compact, :drop, :drop_while, :enum_for,
:find_all, :flat_map, :force, :grep, :grep_v, :lazy, :map, :reject,
:select, :slice_after, :slice_before, :slice_when, :take, :take_while,
- :to_enum, :zip
+ :to_enum, :uniq, :zip
]
- lazy_methods += [:chunk_while, :uniq]
-
- ruby_version_is '3.1' do
- lazy_methods += [:compact]
- end
Enumerator::Lazy.instance_methods(false).should include(*lazy_methods)
end
diff --git a/spec/ruby/core/env/dup_spec.rb b/spec/ruby/core/env/dup_spec.rb
index 46d125aca8..ac66b455cd 100644
--- a/spec/ruby/core/env/dup_spec.rb
+++ b/spec/ruby/core/env/dup_spec.rb
@@ -1,11 +1,9 @@
require_relative '../../spec_helper'
describe "ENV#dup" do
- ruby_version_is "3.1" do
- it "raises TypeError" do
- -> {
- ENV.dup
- }.should raise_error(TypeError, /Cannot dup ENV, use ENV.to_h to get a copy of ENV as a hash/)
- end
+ it "raises TypeError" do
+ -> {
+ ENV.dup
+ }.should raise_error(TypeError, /Cannot dup ENV, use ENV.to_h to get a copy of ENV as a hash/)
end
end
diff --git a/spec/ruby/core/env/fetch_spec.rb b/spec/ruby/core/env/fetch_spec.rb
index b2e7a88cab..2c5d7cc3a0 100644
--- a/spec/ruby/core/env/fetch_spec.rb
+++ b/spec/ruby/core/env/fetch_spec.rb
@@ -47,7 +47,7 @@ describe "ENV.fetch" do
it "warns on block and default parameter given" do
-> do
- ENV.fetch("foo", "default") { "bar" }.should == "bar"
+ ENV.fetch("foo", "default") { "bar" }.should == "bar"
end.should complain(/block supersedes default value argument/)
end
diff --git a/spec/ruby/core/env/length_spec.rb b/spec/ruby/core/env/length_spec.rb
index 536af9edf5..c6f9062892 100644
--- a/spec/ruby/core/env/length_spec.rb
+++ b/spec/ruby/core/env/length_spec.rb
@@ -2,5 +2,5 @@ require_relative '../../spec_helper'
require_relative 'shared/length'
describe "ENV.length" do
- it_behaves_like :env_length, :length
+ it_behaves_like :env_length, :length
end
diff --git a/spec/ruby/core/env/size_spec.rb b/spec/ruby/core/env/size_spec.rb
index f050e9e5a9..7c8072481e 100644
--- a/spec/ruby/core/env/size_spec.rb
+++ b/spec/ruby/core/env/size_spec.rb
@@ -2,5 +2,5 @@ require_relative '../../spec_helper'
require_relative 'shared/length'
describe "ENV.size" do
- it_behaves_like :env_length, :size
+ it_behaves_like :env_length, :size
end
diff --git a/spec/ruby/core/exception/errno_spec.rb b/spec/ruby/core/exception/errno_spec.rb
index a063e522ea..1ab4277700 100644
--- a/spec/ruby/core/exception/errno_spec.rb
+++ b/spec/ruby/core/exception/errno_spec.rb
@@ -29,6 +29,8 @@ describe "Errno::EMFILE" do
ExceptionSpecs::EMFILESub = Class.new(Errno::EMFILE)
exc = ExceptionSpecs::EMFILESub.new
exc.should be_an_instance_of(ExceptionSpecs::EMFILESub)
+ ensure
+ ExceptionSpecs.send(:remove_const, :EMFILESub)
end
end
diff --git a/spec/ruby/core/exception/system_call_error_spec.rb b/spec/ruby/core/exception/system_call_error_spec.rb
index 07f807c0ca..4fe51901c8 100644
--- a/spec/ruby/core/exception/system_call_error_spec.rb
+++ b/spec/ruby/core/exception/system_call_error_spec.rb
@@ -16,6 +16,8 @@ describe "SystemCallError" do
exc = ExceptionSpecs::SCESub.new
ScratchPad.recorded.should equal(:initialize)
exc.should be_an_instance_of(ExceptionSpecs::SCESub)
+ ensure
+ ExceptionSpecs.send(:remove_const, :SCESub)
end
end
diff --git a/spec/ruby/core/fiber/alive_spec.rb b/spec/ruby/core/fiber/alive_spec.rb
new file mode 100644
index 0000000000..a1df582435
--- /dev/null
+++ b/spec/ruby/core/fiber/alive_spec.rb
@@ -0,0 +1,44 @@
+require_relative '../../spec_helper'
+
+describe "Fiber#alive?" do
+ it "returns true for a Fiber that hasn't had #resume called" do
+ fiber = Fiber.new { true }
+ fiber.alive?.should be_true
+ end
+
+ # FIXME: Better description?
+ it "returns true for a Fiber that's yielded to the caller" do
+ fiber = Fiber.new { Fiber.yield }
+ fiber.resume
+ fiber.alive?.should be_true
+ end
+
+ it "returns true when called from its Fiber" do
+ fiber = Fiber.new { fiber.alive?.should be_true }
+ fiber.resume
+ end
+
+ it "doesn't invoke the block associated with the Fiber" do
+ offthehook = mock('do not call')
+ offthehook.should_not_receive(:ring)
+ fiber = Fiber.new { offthehook.ring }
+ fiber.alive?
+ end
+
+ it "returns false for a Fiber that's dead" do
+ fiber = Fiber.new { true }
+ fiber.resume
+ -> { fiber.resume }.should raise_error(FiberError)
+ fiber.alive?.should be_false
+ end
+
+ it "always returns false for a dead Fiber" do
+ fiber = Fiber.new { true }
+ fiber.resume
+ -> { fiber.resume }.should raise_error(FiberError)
+ fiber.alive?.should be_false
+ -> { fiber.resume }.should raise_error(FiberError)
+ fiber.alive?.should be_false
+ fiber.alive?.should be_false
+ end
+end
diff --git a/spec/ruby/core/fiber/blocking_spec.rb b/spec/ruby/core/fiber/blocking_spec.rb
index ebefa116af..ed3c057516 100644
--- a/spec/ruby/core/fiber/blocking_spec.rb
+++ b/spec/ruby/core/fiber/blocking_spec.rb
@@ -1,8 +1,6 @@
require_relative '../../spec_helper'
require_relative 'shared/blocking'
-require "fiber"
-
describe "Fiber.blocking?" do
it_behaves_like :non_blocking_fiber, -> { Fiber.blocking? }
diff --git a/spec/ruby/core/fiber/current_spec.rb b/spec/ruby/core/fiber/current_spec.rb
new file mode 100644
index 0000000000..b93df77a89
--- /dev/null
+++ b/spec/ruby/core/fiber/current_spec.rb
@@ -0,0 +1,50 @@
+require_relative '../../spec_helper'
+
+describe "Fiber.current" do
+ it "returns the root Fiber when called outside of a Fiber" do
+ root = Fiber.current
+ root.should be_an_instance_of(Fiber)
+ # We can always transfer to the root Fiber; it will never die
+ 5.times do
+ root.transfer.should be_nil
+ root.alive?.should be_true
+ end
+ end
+
+ it "returns the current Fiber when called from a Fiber" do
+ fiber = Fiber.new do
+ this = Fiber.current
+ this.should be_an_instance_of(Fiber)
+ this.should == fiber
+ this.alive?.should be_true
+ end
+ fiber.resume
+ end
+
+ it "returns the current Fiber when called from a Fiber that transferred to another" do
+ states = []
+ fiber = Fiber.new do
+ states << :fiber
+ this = Fiber.current
+ this.should be_an_instance_of(Fiber)
+ this.should == fiber
+ this.alive?.should be_true
+ end
+
+ fiber2 = Fiber.new do
+ states << :fiber2
+ fiber.transfer
+ flunk
+ end
+
+ fiber3 = Fiber.new do
+ states << :fiber3
+ fiber2.transfer
+ states << :fiber3_terminated
+ end
+
+ fiber3.resume
+
+ states.should == [:fiber3, :fiber2, :fiber, :fiber3_terminated]
+ end
+end
diff --git a/spec/ruby/core/fiber/inspect_spec.rb b/spec/ruby/core/fiber/inspect_spec.rb
index f20a153fc2..fcfef20716 100644
--- a/spec/ruby/core/fiber/inspect_spec.rb
+++ b/spec/ruby/core/fiber/inspect_spec.rb
@@ -1,5 +1,4 @@
require_relative '../../spec_helper'
-require 'fiber'
describe "Fiber#inspect" do
describe "status" do
diff --git a/spec/ruby/core/fiber/raise_spec.rb b/spec/ruby/core/fiber/raise_spec.rb
index 2f2baa4a12..124f56fe7d 100644
--- a/spec/ruby/core/fiber/raise_spec.rb
+++ b/spec/ruby/core/fiber/raise_spec.rb
@@ -130,7 +130,6 @@ end
describe "Fiber#raise" do
it "transfers and raises on a transferring fiber" do
- require "fiber"
root = Fiber.current
fiber = Fiber.new { root.transfer }
fiber.transfer
diff --git a/spec/ruby/core/fiber/resume_spec.rb b/spec/ruby/core/fiber/resume_spec.rb
index ab9a6799ab..4b20f4b4bf 100644
--- a/spec/ruby/core/fiber/resume_spec.rb
+++ b/spec/ruby/core/fiber/resume_spec.rb
@@ -1,5 +1,5 @@
require_relative '../../spec_helper'
-require_relative '../../shared/fiber/resume'
+require_relative 'shared/resume'
describe "Fiber#resume" do
it_behaves_like :fiber_resume, :resume
@@ -67,4 +67,17 @@ describe "Fiber#resume" do
ruby_exe(code).should == "ensure executed\n"
end
+
+ it "can work with Fiber#transfer" do
+ fiber1 = Fiber.new { true }
+ fiber2 = Fiber.new { fiber1.transfer; Fiber.yield 10 ; Fiber.yield 20; raise }
+ fiber2.resume.should == 10
+ fiber2.resume.should == 20
+ end
+
+ it "raises a FiberError if the Fiber attempts to resume a resuming fiber" do
+ root_fiber = Fiber.current
+ fiber1 = Fiber.new { root_fiber.resume }
+ -> { fiber1.resume }.should raise_error(FiberError, /attempt to resume a resuming fiber/)
+ end
end
diff --git a/spec/ruby/core/fiber/shared/resume.rb b/spec/ruby/core/fiber/shared/resume.rb
new file mode 100644
index 0000000000..5ee27d1d24
--- /dev/null
+++ b/spec/ruby/core/fiber/shared/resume.rb
@@ -0,0 +1,58 @@
+describe :fiber_resume, shared: true do
+ it "can be invoked from the root Fiber" do
+ fiber = Fiber.new { :fiber }
+ fiber.send(@method).should == :fiber
+ end
+
+ it "raises a FiberError if invoked from a different Thread" do
+ fiber = Fiber.new { 42 }
+ Thread.new do
+ -> {
+ fiber.send(@method)
+ }.should raise_error(FiberError)
+ end.join
+
+ # Check the Fiber can still be used
+ fiber.send(@method).should == 42
+ end
+
+ it "passes control to the beginning of the block on first invocation" do
+ invoked = false
+ fiber = Fiber.new { invoked = true }
+ fiber.send(@method)
+ invoked.should be_true
+ end
+
+ it "returns the last value encountered on first invocation" do
+ fiber = Fiber.new { 1+1; true }
+ fiber.send(@method).should be_true
+ end
+
+ it "runs until the end of the block" do
+ obj = mock('obj')
+ obj.should_receive(:do).once
+ fiber = Fiber.new { 1 + 2; a = "glark"; obj.do }
+ fiber.send(@method)
+ end
+
+ it "accepts any number of arguments" do
+ fiber = Fiber.new { |a| }
+ -> { fiber.send(@method, *(1..10).to_a) }.should_not raise_error
+ end
+
+ it "raises a FiberError if the Fiber is dead" do
+ fiber = Fiber.new { true }
+ fiber.send(@method)
+ -> { fiber.send(@method) }.should raise_error(FiberError)
+ end
+
+ it "raises a LocalJumpError if the block includes a return statement" do
+ fiber = Fiber.new { return; }
+ -> { fiber.send(@method) }.should raise_error(LocalJumpError)
+ end
+
+ it "raises a LocalJumpError if the block includes a break statement" do
+ fiber = Fiber.new { break; }
+ -> { fiber.send(@method) }.should raise_error(LocalJumpError)
+ end
+end
diff --git a/spec/ruby/core/fiber/transfer_spec.rb b/spec/ruby/core/fiber/transfer_spec.rb
new file mode 100644
index 0000000000..238721475d
--- /dev/null
+++ b/spec/ruby/core/fiber/transfer_spec.rb
@@ -0,0 +1,84 @@
+require_relative '../../spec_helper'
+require_relative 'shared/resume'
+
+describe "Fiber#transfer" do
+ it_behaves_like :fiber_resume, :transfer
+end
+
+describe "Fiber#transfer" do
+ it "transfers control from one Fiber to another when called from a Fiber" do
+ fiber1 = Fiber.new { :fiber1 }
+ fiber2 = Fiber.new { fiber1.transfer; :fiber2 }
+ fiber2.resume.should == :fiber2
+ end
+
+ it "returns to the root Fiber when finished" do
+ f1 = Fiber.new { :fiber_1 }
+ f2 = Fiber.new { f1.transfer; :fiber_2 }
+
+ f2.transfer.should == :fiber_1
+ f2.transfer.should == :fiber_2
+ end
+
+ it "can be invoked from the same Fiber it transfers control to" do
+ states = []
+ fiber = Fiber.new { states << :start; fiber.transfer; states << :end }
+ fiber.transfer
+ states.should == [:start, :end]
+
+ states = []
+ fiber = Fiber.new { states << :start; fiber.transfer; states << :end }
+ fiber.resume
+ states.should == [:start, :end]
+ end
+
+ it "can not transfer control to a Fiber that has suspended by Fiber.yield" do
+ states = []
+ fiber1 = Fiber.new { states << :fiber1 }
+ fiber2 = Fiber.new { states << :fiber2_start; Fiber.yield fiber1.transfer; states << :fiber2_end}
+ fiber2.resume.should == [:fiber2_start, :fiber1]
+ -> { fiber2.transfer }.should raise_error(FiberError)
+ end
+
+ it "raises a FiberError when transferring to a Fiber which resumes itself" do
+ fiber = Fiber.new { fiber.resume }
+ -> { fiber.transfer }.should raise_error(FiberError)
+ end
+
+ it "works if Fibers in different Threads each transfer to a Fiber in the same Thread" do
+ # This catches a bug where Fibers are running on a thread-pool
+ # and Fibers from a different Ruby Thread reuse the same native thread.
+ # Caching the Ruby Thread based on the native thread is not correct in that case,
+ # and the check for "fiber called across threads" in Fiber#transfer
+ # might be incorrect based on that.
+ 2.times do
+ Thread.new do
+ io_fiber = Fiber.new do |calling_fiber|
+ calling_fiber.transfer
+ end
+ io_fiber.transfer(Fiber.current)
+ value = Object.new
+ io_fiber.transfer(value).should equal value
+ end.join
+ end
+ end
+
+ it "transfers control between a non-main thread's root fiber to a child fiber and back again" do
+ states = []
+ thread = Thread.new do
+ f1 = Fiber.new do |f0|
+ states << 0
+ value2 = f0.transfer(1)
+ states << value2
+ 3
+ end
+
+ value1 = f1.transfer(Fiber.current)
+ states << value1
+ value3 = f1.transfer(2)
+ states << value3
+ end
+ thread.join
+ states.should == [0, 1, 2, 3]
+ end
+end
diff --git a/spec/ruby/core/file/dirname_spec.rb b/spec/ruby/core/file/dirname_spec.rb
index 8dd6c4ca88..8e6016ce6f 100644
--- a/spec/ruby/core/file/dirname_spec.rb
+++ b/spec/ruby/core/file/dirname_spec.rb
@@ -11,34 +11,32 @@ describe "File.dirname" do
File.dirname('/foo/foo').should == '/foo'
end
- ruby_version_is '3.1' do
- context "when level is passed" do
- it "returns all the components of filename except the last parts by the level" do
- File.dirname('/home/jason', 2).should == '/'
- File.dirname('/home/jason/poot.txt', 2).should == '/home'
- end
-
- it "returns the same String if the level is 0" do
- File.dirname('poot.txt', 0).should == 'poot.txt'
- File.dirname('/', 0).should == '/'
- end
-
- it "raises ArgumentError if the level is negative" do
- -> {
- File.dirname('/home/jason', -1)
- }.should raise_error(ArgumentError, "negative level: -1")
- end
-
- it "returns '/' when level exceeds the number of segments in the path" do
- File.dirname("/home/jason", 100).should == '/'
- end
-
- it "calls #to_int if passed not numeric value" do
- object = Object.new
- def object.to_int; 2; end
-
- File.dirname("/a/b/c/d", object).should == '/a/b'
- end
+ context "when level is passed" do
+ it "returns all the components of filename except the last parts by the level" do
+ File.dirname('/home/jason', 2).should == '/'
+ File.dirname('/home/jason/poot.txt', 2).should == '/home'
+ end
+
+ it "returns the same String if the level is 0" do
+ File.dirname('poot.txt', 0).should == 'poot.txt'
+ File.dirname('/', 0).should == '/'
+ end
+
+ it "raises ArgumentError if the level is negative" do
+ -> {
+ File.dirname('/home/jason', -1)
+ }.should raise_error(ArgumentError, "negative level: -1")
+ end
+
+ it "returns '/' when level exceeds the number of segments in the path" do
+ File.dirname("/home/jason", 100).should == '/'
+ end
+
+ it "calls #to_int if passed not numeric value" do
+ object = Object.new
+ def object.to_int; 2; end
+
+ File.dirname("/a/b/c/d", object).should == '/a/b'
end
end
@@ -65,19 +63,19 @@ describe "File.dirname" do
end
it "returns all the components of filename except the last one (edge cases on all platforms)" do
- File.dirname("").should == "."
- File.dirname(".").should == "."
- File.dirname("./").should == "."
- File.dirname("./b/./").should == "./b"
- File.dirname("..").should == "."
- File.dirname("../").should == "."
- File.dirname("/").should == "/"
- File.dirname("/.").should == "/"
- File.dirname("/foo/").should == "/"
- File.dirname("/foo/.").should == "/foo"
- File.dirname("/foo/./").should == "/foo"
- File.dirname("/foo/../.").should == "/foo/.."
- File.dirname("foo/../").should == "foo"
+ File.dirname("").should == "."
+ File.dirname(".").should == "."
+ File.dirname("./").should == "."
+ File.dirname("./b/./").should == "./b"
+ File.dirname("..").should == "."
+ File.dirname("../").should == "."
+ File.dirname("/").should == "/"
+ File.dirname("/.").should == "/"
+ File.dirname("/foo/").should == "/"
+ File.dirname("/foo/.").should == "/foo"
+ File.dirname("/foo/./").should == "/foo"
+ File.dirname("/foo/../.").should == "/foo/.."
+ File.dirname("foo/../").should == "foo"
end
platform_is_not :windows do
diff --git a/spec/ruby/core/file/shared/path.rb b/spec/ruby/core/file/shared/path.rb
index aa2a64cf25..5a9fe1b0c5 100644
--- a/spec/ruby/core/file/shared/path.rb
+++ b/spec/ruby/core/file/shared/path.rb
@@ -77,18 +77,6 @@ describe :file_path, shared: true do
after :each do
rm_r @dir
end
-
- ruby_version_is ""..."3.1" do
- it "raises IOError if file was opened with File::TMPFILE" do
- begin
- File.open(@dir, File::RDWR | File::TMPFILE) do |f|
- -> { f.send(@method) }.should raise_error(IOError)
- end
- rescue Errno::EOPNOTSUPP, Errno::EINVAL, Errno::EISDIR
- skip "no support from the filesystem"
- end
- end
- end
end
end
end
diff --git a/spec/ruby/core/float/comparison_spec.rb b/spec/ruby/core/float/comparison_spec.rb
index d2e47937ff..0cd290f4ad 100644
--- a/spec/ruby/core/float/comparison_spec.rb
+++ b/spec/ruby/core/float/comparison_spec.rb
@@ -91,7 +91,7 @@ describe "Float#<=>" do
it "returns 1 when self is Infinity and other is infinite?=nil (which means finite)" do
obj = Object.new
def obj.infinite?
- nil
+ nil
end
(infinity_value <=> obj).should == 1
end
diff --git a/spec/ruby/core/float/round_spec.rb b/spec/ruby/core/float/round_spec.rb
index 9b4c307f9d..7e8c792051 100644
--- a/spec/ruby/core/float/round_spec.rb
+++ b/spec/ruby/core/float/round_spec.rb
@@ -30,6 +30,11 @@ describe "Float#round" do
12.345678.round(3.999).should == 12.346
end
+ it "correctly rounds exact floats with a numerous digits in a fraction part" do
+ 0.8241000000000004.round(10).should == 0.8241
+ 0.8241000000000002.round(10).should == 0.8241
+ end
+
it "returns zero when passed a negative argument with magnitude greater than magnitude of the whole number portion of the Float" do
0.8346268.round(-1).should eql(0)
end
@@ -68,6 +73,10 @@ describe "Float#round" do
0.42.round(2.0**30).should == 0.42
end
+ it "returns rounded values for not so big argument" do
+ 0.42.round(2.0**23).should == 0.42
+ end
+
it "returns big values rounded to nearest" do
+2.5e20.round(-20).should eql( +3 * 10 ** 20 )
-2.5e20.round(-20).should eql( -3 * 10 ** 20 )
diff --git a/spec/ruby/core/gc/measure_total_time_spec.rb b/spec/ruby/core/gc/measure_total_time_spec.rb
index 05d4598ebc..f5377c18fd 100644
--- a/spec/ruby/core/gc/measure_total_time_spec.rb
+++ b/spec/ruby/core/gc/measure_total_time_spec.rb
@@ -1,19 +1,17 @@
require_relative '../../spec_helper'
-ruby_version_is "3.1" do
- describe "GC.measure_total_time" do
- before :each do
- @default = GC.measure_total_time
- end
+describe "GC.measure_total_time" do
+ before :each do
+ @default = GC.measure_total_time
+ end
- after :each do
- GC.measure_total_time = @default
- end
+ after :each do
+ GC.measure_total_time = @default
+ end
- it "can set and get a boolean value" do
- original = GC.measure_total_time
- GC.measure_total_time = !original
- GC.measure_total_time.should == !original
- end
+ it "can set and get a boolean value" do
+ original = GC.measure_total_time
+ GC.measure_total_time = !original
+ GC.measure_total_time.should == !original
end
end
diff --git a/spec/ruby/core/gc/total_time_spec.rb b/spec/ruby/core/gc/total_time_spec.rb
index fcc8f45a83..a8430fbe9a 100644
--- a/spec/ruby/core/gc/total_time_spec.rb
+++ b/spec/ruby/core/gc/total_time_spec.rb
@@ -1,15 +1,13 @@
require_relative '../../spec_helper'
-ruby_version_is "3.1" do
- describe "GC.total_time" do
- it "returns an Integer" do
- GC.total_time.should be_kind_of(Integer)
- end
+describe "GC.total_time" do
+ it "returns an Integer" do
+ GC.total_time.should be_kind_of(Integer)
+ end
- it "increases as collections are run" do
- time_before = GC.total_time
- GC.start
- GC.total_time.should >= time_before
- end
+ it "increases as collections are run" do
+ time_before = GC.total_time
+ GC.start
+ GC.total_time.should >= time_before
end
end
diff --git a/spec/ruby/core/hash/hash_spec.rb b/spec/ruby/core/hash/hash_spec.rb
index 9b47d4b2bf..cd67f7a652 100644
--- a/spec/ruby/core/hash/hash_spec.rb
+++ b/spec/ruby/core/hash/hash_spec.rb
@@ -42,12 +42,10 @@ describe "Hash#hash" do
# Like above, because h.eql?(x: [h])
end
- ruby_version_is "3.1" do
- it "allows omitting values" do
- a = 1
- b = 2
+ it "allows omitting values" do
+ a = 1
+ b = 2
- eval('{a:, b:}.should == { a: 1, b: 2 }')
- end
+ {a:, b:}.should == { a: 1, b: 2 }
end
end
diff --git a/spec/ruby/core/hash/shared/store.rb b/spec/ruby/core/hash/shared/store.rb
index dd1bb52bac..72a462a42f 100644
--- a/spec/ruby/core/hash/shared/store.rb
+++ b/spec/ruby/core/hash/shared/store.rb
@@ -91,9 +91,9 @@ describe :hash_store, shared: true do
end
it "does not raise an exception if changing the value of an existing key during iteration" do
- hash = {1 => 2, 3 => 4, 5 => 6}
- hash.each { hash.send(@method, 1, :foo) }
- hash.should == {1 => :foo, 3 => 4, 5 => 6}
+ hash = {1 => 2, 3 => 4, 5 => 6}
+ hash.each { hash.send(@method, 1, :foo) }
+ hash.should == {1 => :foo, 3 => 4, 5 => 6}
end
it "does not dispatch to hash for Boolean, Integer, Float, String, or Symbol" do
diff --git a/spec/ruby/core/hash/transform_keys_spec.rb b/spec/ruby/core/hash/transform_keys_spec.rb
index 2fbb17a8e2..f63d39ecc8 100644
--- a/spec/ruby/core/hash/transform_keys_spec.rb
+++ b/spec/ruby/core/hash/transform_keys_spec.rb
@@ -76,24 +76,12 @@ describe "Hash#transform_keys!" do
@hash.should == { b: 1, c: 2, d: 3, e: 4 }
end
- ruby_version_is ""..."3.0.2" do # https://bugs.ruby-lang.org/issues/17735
- it "returns the processed keys if we break from the block" do
- @hash.transform_keys! do |v|
- break if v == :c
- v.succ
- end
- @hash.should == { b: 1, c: 2 }
- end
- end
-
- ruby_version_is "3.0.2" do
- it "returns the processed keys and non evaluated keys if we break from the block" do
- @hash.transform_keys! do |v|
- break if v == :c
- v.succ
- end
- @hash.should == { b: 1, c: 2, d: 4 }
+ it "returns the processed keys and non evaluated keys if we break from the block" do
+ @hash.transform_keys! do |v|
+ break if v == :c
+ v.succ
end
+ @hash.should == { b: 1, c: 2, d: 4 }
end
it "keeps later pair if new keys conflict" do
@@ -129,7 +117,7 @@ describe "Hash#transform_keys!" do
end
it "raises a FrozenError on hash argument" do
- ->{ @hash.transform_keys!({ a: :A, b: :B, c: :C }) }.should raise_error(FrozenError)
+ ->{ @hash.transform_keys!({ a: :A, b: :B, c: :C }) }.should raise_error(FrozenError)
end
context "when no block is given" do
diff --git a/spec/ruby/core/integer/try_convert_spec.rb b/spec/ruby/core/integer/try_convert_spec.rb
index 4bc7d3851a..8a0ca671a9 100644
--- a/spec/ruby/core/integer/try_convert_spec.rb
+++ b/spec/ruby/core/integer/try_convert_spec.rb
@@ -1,50 +1,48 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-ruby_version_is "3.1" do
- describe "Integer.try_convert" do
- it "returns the argument if it's an Integer" do
- x = 42
- Integer.try_convert(x).should equal(x)
- end
+describe "Integer.try_convert" do
+ it "returns the argument if it's an Integer" do
+ x = 42
+ Integer.try_convert(x).should equal(x)
+ end
- it "returns nil when the argument does not respond to #to_int" do
- Integer.try_convert(Object.new).should be_nil
- end
+ it "returns nil when the argument does not respond to #to_int" do
+ Integer.try_convert(Object.new).should be_nil
+ end
- it "sends #to_int to the argument and returns the result if it's nil" do
- obj = mock("to_int")
- obj.should_receive(:to_int).and_return(nil)
- Integer.try_convert(obj).should be_nil
- end
+ it "sends #to_int to the argument and returns the result if it's nil" do
+ obj = mock("to_int")
+ obj.should_receive(:to_int).and_return(nil)
+ Integer.try_convert(obj).should be_nil
+ end
- it "sends #to_int to the argument and returns the result if it's an Integer" do
- x = 234
- obj = mock("to_int")
- obj.should_receive(:to_int).and_return(x)
- Integer.try_convert(obj).should equal(x)
- end
+ it "sends #to_int to the argument and returns the result if it's an Integer" do
+ x = 234
+ obj = mock("to_int")
+ obj.should_receive(:to_int).and_return(x)
+ Integer.try_convert(obj).should equal(x)
+ end
- it "sends #to_int to the argument and raises TypeError if it's not a kind of Integer" do
- obj = mock("to_int")
- obj.should_receive(:to_int).and_return(Object.new)
- -> {
- Integer.try_convert obj
- }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives Object)")
- end
+ it "sends #to_int to the argument and raises TypeError if it's not a kind of Integer" do
+ obj = mock("to_int")
+ obj.should_receive(:to_int).and_return(Object.new)
+ -> {
+ Integer.try_convert obj
+ }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives Object)")
+ end
- it "responds with a different error message when it raises a TypeError, depending on the type of the non-Integer object :to_int returns" do
- obj = mock("to_int")
- obj.should_receive(:to_int).and_return("A String")
- -> {
- Integer.try_convert obj
- }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives String)")
- end
+ it "responds with a different error message when it raises a TypeError, depending on the type of the non-Integer object :to_int returns" do
+ obj = mock("to_int")
+ obj.should_receive(:to_int).and_return("A String")
+ -> {
+ Integer.try_convert obj
+ }.should raise_error(TypeError, "can't convert MockObject to Integer (MockObject#to_int gives String)")
+ end
- it "does not rescue exceptions raised by #to_int" do
- obj = mock("to_int")
- obj.should_receive(:to_int).and_raise(RuntimeError)
- -> { Integer.try_convert obj }.should raise_error(RuntimeError)
- end
+ it "does not rescue exceptions raised by #to_int" do
+ obj = mock("to_int")
+ obj.should_receive(:to_int).and_raise(RuntimeError)
+ -> { Integer.try_convert obj }.should raise_error(RuntimeError)
end
end
diff --git a/spec/ruby/core/io/external_encoding_spec.rb b/spec/ruby/core/io/external_encoding_spec.rb
index 2fcf1c7218..7765c6c0f5 100644
--- a/spec/ruby/core/io/external_encoding_spec.rb
+++ b/spec/ruby/core/io/external_encoding_spec.rb
@@ -94,12 +94,10 @@ describe "IO#external_encoding" do
rm_r @name
end
- ruby_version_is '3.1' do
- it "can be retrieved from a closed stream" do
- io = IOSpecs.io_fixture("lines.txt", "r")
- io.close
- io.external_encoding.should equal(Encoding.default_external)
- end
+ it "can be retrieved from a closed stream" do
+ io = IOSpecs.io_fixture("lines.txt", "r")
+ io.close
+ io.external_encoding.should equal(Encoding.default_external)
end
describe "with 'r' mode" do
diff --git a/spec/ruby/core/io/internal_encoding_spec.rb b/spec/ruby/core/io/internal_encoding_spec.rb
index 60afaf2ebd..7a583d4bcb 100644
--- a/spec/ruby/core/io/internal_encoding_spec.rb
+++ b/spec/ruby/core/io/internal_encoding_spec.rb
@@ -113,12 +113,10 @@ describe "IO#internal_encoding" do
Encoding.default_internal = @internal
end
- ruby_version_is '3.1' do
- it "can be retrieved from a closed stream" do
- io = IOSpecs.io_fixture("lines.txt", "r")
- io.close
- io.internal_encoding.should equal(Encoding.default_internal)
- end
+ it "can be retrieved from a closed stream" do
+ io = IOSpecs.io_fixture("lines.txt", "r")
+ io.close
+ io.internal_encoding.should equal(Encoding.default_internal)
end
describe "with 'r' mode" do
diff --git a/spec/ruby/core/io/readpartial_spec.rb b/spec/ruby/core/io/readpartial_spec.rb
index 0852f20b2d..547da0677d 100644
--- a/spec/ruby/core/io/readpartial_spec.rb
+++ b/spec/ruby/core/io/readpartial_spec.rb
@@ -93,12 +93,10 @@ describe "IO#readpartial" do
@rd.readpartial(0).should == ""
end
- ruby_bug "#18421", ""..."3.0.4" do
- it "clears and returns the given buffer if the length argument is 0" do
- buffer = +"existing content"
- @rd.readpartial(0, buffer).should == buffer
- buffer.should == ""
- end
+ it "clears and returns the given buffer if the length argument is 0" do
+ buffer = +"existing content"
+ @rd.readpartial(0, buffer).should == buffer
+ buffer.should == ""
end
it "preserves the encoding of the given buffer" do
diff --git a/spec/ruby/core/io/write_nonblock_spec.rb b/spec/ruby/core/io/write_nonblock_spec.rb
index c403c864fd..5bfc690f9b 100644
--- a/spec/ruby/core/io/write_nonblock_spec.rb
+++ b/spec/ruby/core/io/write_nonblock_spec.rb
@@ -43,7 +43,7 @@ platform_is_not :windows do
it "checks if the file is writable if writing zero bytes" do
-> {
- @readonly_file.write_nonblock("")
+ @readonly_file.write_nonblock("")
}.should raise_error(IOError)
end
end
diff --git a/spec/ruby/core/kernel/block_given_spec.rb b/spec/ruby/core/kernel/block_given_spec.rb
index b00bfabfc3..aece4c821d 100644
--- a/spec/ruby/core/kernel/block_given_spec.rb
+++ b/spec/ruby/core/kernel/block_given_spec.rb
@@ -5,15 +5,20 @@ describe :kernel_block_given, shared: true do
it "returns true if and only if a block is supplied" do
@object.accept_block {}.should == true
@object.accept_block_as_argument {}.should == true
+ @object.accept_block_inside_block {}.should == true
+ @object.accept_block_as_argument_inside_block {}.should == true
@object.accept_block.should == false
@object.accept_block_as_argument.should == false
+ @object.accept_block_inside_block.should == false
+ @object.accept_block_as_argument_inside_block.should == false
end
# Clarify: Based on http://www.ruby-forum.com/topic/137822 it appears
# that Matz wanted this to be true in 1.9.
it "returns false when a method defined by define_method is called with a block" do
@object.defined_block {}.should == false
+ @object.defined_block_inside_block {}.should == false
end
end
diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb
index 5f4cd27da0..c189d5f0a2 100644
--- a/spec/ruby/core/kernel/eval_spec.rb
+++ b/spec/ruby/core/kernel/eval_spec.rb
@@ -313,6 +313,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπ")
EvalSpecs::Vπ.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπ)
end
it "allows an emacs-style magic comment encoding" do
@@ -326,6 +328,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπemacs")
EvalSpecs::Vπemacs.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπemacs)
end
it "allows spaces before the magic encoding comment" do
@@ -339,6 +343,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπspaces")
EvalSpecs::Vπspaces.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπspaces)
end
it "allows a shebang line before the magic encoding comment" do
@@ -353,6 +359,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπshebang")
EvalSpecs::Vπshebang.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπshebang)
end
it "allows a shebang line and some spaces before the magic encoding comment" do
@@ -367,6 +375,8 @@ CODE
eval(code)
EvalSpecs.constants(false).should include(:"Vπshebang_spaces")
EvalSpecs::Vπshebang_spaces.should == 3.14
+ ensure
+ EvalSpecs.send(:remove_const, :Vπshebang_spaces)
end
it "allows a magic encoding comment and a subsequent frozen_string_literal magic comment" do
@@ -385,6 +395,8 @@ CODE
EvalSpecs::Vπstring.should == "frozen"
EvalSpecs::Vπstring.encoding.should == Encoding::UTF_8
EvalSpecs::Vπstring.frozen?.should == !frozen_string_default
+ ensure
+ EvalSpecs.send(:remove_const, :Vπstring)
end
it "allows a magic encoding comment and a frozen_string_literal magic comment on the same line in emacs style" do
@@ -400,6 +412,8 @@ CODE
EvalSpecs::Vπsame_line.should == "frozen"
EvalSpecs::Vπsame_line.encoding.should == Encoding::UTF_8
EvalSpecs::Vπsame_line.frozen?.should be_true
+ ensure
+ EvalSpecs.send(:remove_const, :Vπsame_line)
end
it "ignores the magic encoding comment if it is after a frozen_string_literal magic comment" do
@@ -420,6 +434,8 @@ CODE
value.should == "frozen"
value.encoding.should == Encoding::BINARY
value.frozen?.should == !frozen_string_default
+ ensure
+ EvalSpecs.send(:remove_const, binary_constant)
end
it "ignores the frozen_string_literal magic comment if it appears after a token and warns if $VERBOSE is true" do
diff --git a/spec/ruby/core/kernel/fixtures/classes.rb b/spec/ruby/core/kernel/fixtures/classes.rb
index 541a4c075e..0e2b81988f 100644
--- a/spec/ruby/core/kernel/fixtures/classes.rb
+++ b/spec/ruby/core/kernel/fixtures/classes.rb
@@ -219,10 +219,28 @@ module KernelSpecs
block_given?
end
+ def self.accept_block_inside_block()
+ yield_self {
+ block_given?
+ }
+ end
+
+ def self.accept_block_as_argument_inside_block(&block)
+ yield_self {
+ block_given?
+ }
+ end
+
class << self
define_method(:defined_block) do
block_given?
end
+
+ define_method(:defined_block_inside_block) do
+ yield_self {
+ block_given?
+ }
+ end
end
end
@@ -235,10 +253,28 @@ module KernelSpecs
self.send(:block_given?)
end
+ def self.accept_block_inside_block
+ yield_self {
+ self.send(:block_given?)
+ }
+ end
+
+ def self.accept_block_as_argument_inside_block(&block)
+ yield_self {
+ self.send(:block_given?)
+ }
+ end
+
class << self
define_method(:defined_block) do
self.send(:block_given?)
end
+
+ define_method(:defined_block_inside_block) do
+ yield_self {
+ self.send(:block_given?)
+ }
+ end
end
end
@@ -251,10 +287,28 @@ module KernelSpecs
Kernel.block_given?
end
+ def self.accept_block_inside_block
+ yield_self {
+ Kernel.block_given?
+ }
+ end
+
+ def self.accept_block_as_argument_inside_block(&block)
+ yield_self {
+ Kernel.block_given?
+ }
+ end
+
class << self
define_method(:defined_block) do
Kernel.block_given?
end
+
+ define_method(:defined_block_inside_block) do
+ yield_self {
+ Kernel.block_given?
+ }
+ end
end
end
diff --git a/spec/ruby/core/kernel/require_spec.rb b/spec/ruby/core/kernel/require_spec.rb
index 4029e68725..e78e7176ec 100644
--- a/spec/ruby/core/kernel/require_spec.rb
+++ b/spec/ruby/core/kernel/require_spec.rb
@@ -16,10 +16,7 @@ describe "Kernel#require" do
Kernel.should have_private_instance_method(:require)
end
- provided = %w[complex enumerator rational thread ruby2_keywords]
- ruby_version_is "3.1" do
- provided << "fiber"
- end
+ provided = %w[complex enumerator fiber rational thread ruby2_keywords]
it "#{provided.join(', ')} are already required" do
out = ruby_exe("puts $LOADED_FEATURES", options: '--disable-gems --disable-did-you-mean')
diff --git a/spec/ruby/core/kernel/shared/load.rb b/spec/ruby/core/kernel/shared/load.rb
index 0fe2d5ce16..62c5c7be9b 100644
--- a/spec/ruby/core/kernel/shared/load.rb
+++ b/spec/ruby/core/kernel/shared/load.rb
@@ -165,37 +165,35 @@ describe :kernel_load, shared: true do
end
describe "when passed a module for 'wrap'" do
- ruby_version_is "3.1" do
- it "sets the enclosing scope to the supplied module" do
- path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR
- mod = Module.new
- @object.load(path, mod)
+ it "sets the enclosing scope to the supplied module" do
+ path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR
+ mod = Module.new
+ @object.load(path, mod)
- Object.const_defined?(:LoadSpecWrap).should be_false
- mod.const_defined?(:LoadSpecWrap).should be_true
+ Object.const_defined?(:LoadSpecWrap).should be_false
+ mod.const_defined?(:LoadSpecWrap).should be_true
- wrap_module = ScratchPad.recorded[1]
- wrap_module.should == mod
- end
+ wrap_module = ScratchPad.recorded[1]
+ wrap_module.should == mod
+ end
- it "makes constants and instance methods in the source file reachable with the supplied module" do
- path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR
- mod = Module.new
- @object.load(path, mod)
+ it "makes constants and instance methods in the source file reachable with the supplied module" do
+ path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR
+ mod = Module.new
+ @object.load(path, mod)
- mod::LOAD_WRAP_SPECS_TOP_LEVEL_CONSTANT.should == 1
- obj = Object.new
- obj.extend(mod)
- obj.send(:load_wrap_specs_top_level_method).should == :load_wrap_specs_top_level_method
- end
+ mod::LOAD_WRAP_SPECS_TOP_LEVEL_CONSTANT.should == 1
+ obj = Object.new
+ obj.extend(mod)
+ obj.send(:load_wrap_specs_top_level_method).should == :load_wrap_specs_top_level_method
+ end
- it "makes instance methods in the source file private" do
- path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR
- mod = Module.new
- @object.load(path, mod)
+ it "makes instance methods in the source file private" do
+ path = File.expand_path "load_wrap_fixture.rb", CODE_LOADING_DIR
+ mod = Module.new
+ @object.load(path, mod)
- mod.private_instance_methods.include?(:load_wrap_specs_top_level_method).should == true
- end
+ mod.private_instance_methods.include?(:load_wrap_specs_top_level_method).should == true
end
end
diff --git a/spec/ruby/core/main/private_spec.rb b/spec/ruby/core/main/private_spec.rb
index e8c1f3f44c..76895fd649 100644
--- a/spec/ruby/core/main/private_spec.rb
+++ b/spec/ruby/core/main/private_spec.rb
@@ -30,16 +30,8 @@ describe "main#private" do
end
end
- ruby_version_is ''...'3.1' do
- it "returns Object" do
- eval("private :main_public_method", TOPLEVEL_BINDING).should equal(Object)
- end
- end
-
- ruby_version_is '3.1' do
- it "returns argument" do
- eval("private :main_public_method", TOPLEVEL_BINDING).should equal(:main_public_method)
- end
+ it "returns argument" do
+ eval("private :main_public_method", TOPLEVEL_BINDING).should equal(:main_public_method)
end
it "raises a NameError when at least one of given method names is undefined" do
diff --git a/spec/ruby/core/main/public_spec.rb b/spec/ruby/core/main/public_spec.rb
index 31baad4583..3c77798fbc 100644
--- a/spec/ruby/core/main/public_spec.rb
+++ b/spec/ruby/core/main/public_spec.rb
@@ -30,16 +30,8 @@ describe "main#public" do
end
end
- ruby_version_is ''...'3.1' do
- it "returns Object" do
- eval("public :main_private_method", TOPLEVEL_BINDING).should equal(Object)
- end
- end
-
- ruby_version_is '3.1' do
- it "returns argument" do
- eval("public :main_private_method", TOPLEVEL_BINDING).should equal(:main_private_method)
- end
+ it "returns argument" do
+ eval("public :main_private_method", TOPLEVEL_BINDING).should equal(:main_private_method)
end
diff --git a/spec/ruby/core/marshal/dump_spec.rb b/spec/ruby/core/marshal/dump_spec.rb
index cc5337b50e..c2a2b77999 100644
--- a/spec/ruby/core/marshal/dump_spec.rb
+++ b/spec/ruby/core/marshal/dump_spec.rb
@@ -599,20 +599,18 @@ describe "Marshal.dump" do
Marshal.dump(Hash.new(1)).should == "\004\b}\000i\006"
end
- ruby_version_is "3.1" do
- it "dumps a Hash with compare_by_identity" do
- h = {}
- h.compare_by_identity
+ it "dumps a Hash with compare_by_identity" do
+ h = {}
+ h.compare_by_identity
- Marshal.dump(h).should == "\004\bC:\tHash{\x00"
- end
+ Marshal.dump(h).should == "\004\bC:\tHash{\x00"
+ end
- it "dumps a Hash subclass with compare_by_identity" do
- h = UserHash.new
- h.compare_by_identity
+ it "dumps a Hash subclass with compare_by_identity" do
+ h = UserHash.new
+ h.compare_by_identity
- Marshal.dump(h).should == "\x04\bC:\rUserHashC:\tHash{\x00"
- end
+ Marshal.dump(h).should == "\x04\bC:\rUserHashC:\tHash{\x00"
end
it "raises a TypeError with hash having default proc" do
diff --git a/spec/ruby/core/marshal/shared/load.rb b/spec/ruby/core/marshal/shared/load.rb
index fd6490153c..f73fa67e9a 100644
--- a/spec/ruby/core/marshal/shared/load.rb
+++ b/spec/ruby/core/marshal/shared/load.rb
@@ -23,250 +23,164 @@ describe :marshal_load, shared: true do
-> { Marshal.send(@method, kaboom) }.should raise_error(ArgumentError)
end
- ruby_version_is "3.1" do
- describe "when called with freeze: true" do
- it "returns frozen strings" do
- string = Marshal.send(@method, Marshal.dump("foo"), freeze: true)
- string.should == "foo"
- string.should.frozen?
-
- utf8_string = "foo".encode(Encoding::UTF_8)
- string = Marshal.send(@method, Marshal.dump(utf8_string), freeze: true)
- string.should == utf8_string
- string.should.frozen?
- end
-
- it "returns frozen arrays" do
- array = Marshal.send(@method, Marshal.dump([1, 2, 3]), freeze: true)
- array.should == [1, 2, 3]
- array.should.frozen?
- end
-
- it "returns frozen hashes" do
- hash = Marshal.send(@method, Marshal.dump({foo: 42}), freeze: true)
- hash.should == {foo: 42}
- hash.should.frozen?
- end
-
- it "returns frozen regexps" do
- regexp = Marshal.send(@method, Marshal.dump(/foo/), freeze: true)
- regexp.should == /foo/
- regexp.should.frozen?
- end
+ describe "when called with freeze: true" do
+ it "returns frozen strings" do
+ string = Marshal.send(@method, Marshal.dump("foo"), freeze: true)
+ string.should == "foo"
+ string.should.frozen?
- it "returns frozen structs" do
- struct = Marshal.send(@method, Marshal.dump(MarshalSpec::StructToDump.new(1, 2)), freeze: true)
- struct.should == MarshalSpec::StructToDump.new(1, 2)
- struct.should.frozen?
- end
+ utf8_string = "foo".encode(Encoding::UTF_8)
+ string = Marshal.send(@method, Marshal.dump(utf8_string), freeze: true)
+ string.should == utf8_string
+ string.should.frozen?
+ end
- it "returns frozen objects" do
- source_object = Object.new
+ it "returns frozen arrays" do
+ array = Marshal.send(@method, Marshal.dump([1, 2, 3]), freeze: true)
+ array.should == [1, 2, 3]
+ array.should.frozen?
+ end
- object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- object.should.frozen?
- end
+ it "returns frozen hashes" do
+ hash = Marshal.send(@method, Marshal.dump({foo: 42}), freeze: true)
+ hash.should == {foo: 42}
+ hash.should.frozen?
+ end
- describe "deep freezing" do
- it "returns hashes with frozen keys and values" do
- key = Object.new
- value = Object.new
- source_object = {key => value}
+ it "returns frozen regexps" do
+ regexp = Marshal.send(@method, Marshal.dump(/foo/), freeze: true)
+ regexp.should == /foo/
+ regexp.should.frozen?
+ end
- hash = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- hash.size.should == 1
- hash.keys[0].should.frozen?
- hash.values[0].should.frozen?
- end
+ it "returns frozen structs" do
+ struct = Marshal.send(@method, Marshal.dump(MarshalSpec::StructToDump.new(1, 2)), freeze: true)
+ struct.should == MarshalSpec::StructToDump.new(1, 2)
+ struct.should.frozen?
+ end
- it "returns arrays with frozen elements" do
- object = Object.new
- source_object = [object]
+ it "returns frozen objects" do
+ source_object = Object.new
- array = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- array.size.should == 1
- array[0].should.frozen?
- end
+ object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ object.should.frozen?
+ end
- it "returns structs with frozen members" do
- object1 = Object.new
- object2 = Object.new
- source_object = MarshalSpec::StructToDump.new(object1, object2)
+ describe "deep freezing" do
+ it "returns hashes with frozen keys and values" do
+ key = Object.new
+ value = Object.new
+ source_object = {key => value}
- struct = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- struct.a.should.frozen?
- struct.b.should.frozen?
- end
+ hash = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ hash.size.should == 1
+ hash.keys[0].should.frozen?
+ hash.values[0].should.frozen?
+ end
- it "returns objects with frozen instance variables" do
- source_object = Object.new
- instance_variable = Object.new
- source_object.instance_variable_set(:@a, instance_variable)
+ it "returns arrays with frozen elements" do
+ object = Object.new
+ source_object = [object]
- object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- object.instance_variable_get(:@a).should != nil
- object.instance_variable_get(:@a).should.frozen?
- end
+ array = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ array.size.should == 1
+ array[0].should.frozen?
+ end
- it "deduplicates frozen strings" do
- source_object = ["foo" + "bar", "foobar"]
- object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ it "returns structs with frozen members" do
+ object1 = Object.new
+ object2 = Object.new
+ source_object = MarshalSpec::StructToDump.new(object1, object2)
- object[0].should equal(object[1])
- end
+ struct = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ struct.a.should.frozen?
+ struct.b.should.frozen?
end
- it "does not freeze modules" do
- object = Marshal.send(@method, Marshal.dump(Kernel), freeze: true)
- object.should_not.frozen?
- Kernel.should_not.frozen?
- end
+ it "returns objects with frozen instance variables" do
+ source_object = Object.new
+ instance_variable = Object.new
+ source_object.instance_variable_set(:@a, instance_variable)
- it "does not freeze classes" do
- object = Marshal.send(@method, Marshal.dump(Object), freeze: true)
- object.should_not.frozen?
- Object.should_not.frozen?
+ object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ object.instance_variable_get(:@a).should != nil
+ object.instance_variable_get(:@a).should.frozen?
end
- ruby_bug "#19427", ""..."3.3" do
- it "does freeze extended objects" do
- object = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x00", freeze: true)
- object.should.frozen?
- end
+ it "deduplicates frozen strings" do
+ source_object = ["foo" + "bar", "foobar"]
+ object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
- it "does freeze extended objects with instance variables" do
- object = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x06:\n@ivarT", freeze: true)
- object.should.frozen?
- end
+ object[0].should equal(object[1])
end
+ end
- ruby_bug "#19427", "3.1"..."3.3" do
- it "returns frozen object having #_dump method" do
- object = Marshal.send(@method, Marshal.dump(UserDefined.new), freeze: true)
- object.should.frozen?
- end
-
- it "returns frozen object responding to #marshal_dump and #marshal_load" do
- object = Marshal.send(@method, Marshal.dump(UserMarshal.new), freeze: true)
- object.should.frozen?
- end
+ it "does not freeze modules" do
+ object = Marshal.send(@method, Marshal.dump(Kernel), freeze: true)
+ object.should_not.frozen?
+ Kernel.should_not.frozen?
+ end
- it "returns frozen object extended by a module" do
- object = Object.new
- object.extend(MarshalSpec::ModuleToExtendBy)
+ it "does not freeze classes" do
+ object = Marshal.send(@method, Marshal.dump(Object), freeze: true)
+ object.should_not.frozen?
+ Object.should_not.frozen?
+ end
- object = Marshal.send(@method, Marshal.dump(object), freeze: true)
- object.should.frozen?
- end
+ ruby_bug "#19427", ""..."3.3" do
+ it "does freeze extended objects" do
+ object = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x00", freeze: true)
+ object.should.frozen?
end
- it "does not call freeze method" do
- object = MarshalSpec::ObjectWithFreezeRaisingException.new
- object = Marshal.send(@method, Marshal.dump(object), freeze: true)
+ it "does freeze extended objects with instance variables" do
+ object = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x06:\n@ivarT", freeze: true)
object.should.frozen?
end
+ end
- it "returns frozen object even if object does not respond to freeze method" do
- object = MarshalSpec::ObjectWithoutFreeze.new
- object = Marshal.send(@method, Marshal.dump(object), freeze: true)
+ ruby_bug "#19427", "3.1"..."3.3" do
+ it "returns frozen object having #_dump method" do
+ object = Marshal.send(@method, Marshal.dump(UserDefined.new), freeze: true)
object.should.frozen?
end
- it "returns a frozen object when is an instance of String/Array/Regexp/Hash subclass and has instance variables" do
- source_object = UserString.new
- source_object.instance_variable_set(:@foo, "bar")
-
- object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ it "returns frozen object responding to #marshal_dump and #marshal_load" do
+ object = Marshal.send(@method, Marshal.dump(UserMarshal.new), freeze: true)
object.should.frozen?
end
- describe "when called with a proc" do
- it "call the proc with frozen objects" do
- arr = []
- s = +'hi'
- s.instance_variable_set(:@foo, 5)
- st = Struct.new("Brittle", :a).new
- st.instance_variable_set(:@clue, 'none')
- st.a = 0.0
- h = Hash.new('def')
- h['nine'] = 9
- a = [:a, :b, :c]
- a.instance_variable_set(:@two, 2)
- obj = [s, 10, s, s, st, a]
- obj.instance_variable_set(:@zoo, 'ant')
- proc = Proc.new { |o| arr << o; o}
-
- Marshal.send(
- @method,
- "\x04\bI[\vI\"\ahi\a:\x06EF:\t@fooi\ni\x0F@\x06@\x06IS:\x14Struct::Brittle\x06:\x06af\x060\x06:\n@clueI\"\tnone\x06;\x00FI[\b;\b:\x06b:\x06c\x06:\t@twoi\a\x06:\t@zooI\"\bant\x06;\x00F",
- proc,
- freeze: true,
- )
-
- arr.should == [
- false, 5, "hi", 10, "hi", "hi", 0.0, false, "none", st,
- :b, :c, 2, a, false, "ant", ["hi", 10, "hi", "hi", st, [:a, :b, :c]],
- ]
-
- arr.each do |v|
- v.should.frozen?
- end
-
- Struct.send(:remove_const, :Brittle)
- end
+ it "returns frozen object extended by a module" do
+ object = Object.new
+ object.extend(MarshalSpec::ModuleToExtendBy)
- it "does not freeze the object returned by the proc" do
- string = Marshal.send(@method, Marshal.dump("foo"), proc { |o| o.upcase }, freeze: true)
- string.should == "FOO"
- string.should_not.frozen?
- end
+ object = Marshal.send(@method, Marshal.dump(object), freeze: true)
+ object.should.frozen?
end
end
- end
- describe "when called with a proc" do
- ruby_bug "#18141", ""..."3.1" do
- it "call the proc with fully initialized strings" do
- utf8_string = "foo".encode(Encoding::UTF_8)
- Marshal.send(@method, Marshal.dump(utf8_string), proc { |arg|
- if arg.is_a?(String)
- arg.should == utf8_string
- arg.encoding.should == Encoding::UTF_8
- end
- arg
- })
- end
-
- it "no longer mutate the object after it was passed to the proc" do
- string = Marshal.load(Marshal.dump("foo"), :freeze.to_proc)
- string.should.frozen?
- end
+ it "does not call freeze method" do
+ object = MarshalSpec::ObjectWithFreezeRaisingException.new
+ object = Marshal.send(@method, Marshal.dump(object), freeze: true)
+ object.should.frozen?
end
- ruby_bug "#19427", ""..."3.3" do
- it "call the proc with extended objects" do
- objs = []
- obj = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x00", Proc.new { |o| objs << o; o })
- objs.should == [obj]
- end
+ it "returns frozen object even if object does not respond to freeze method" do
+ object = MarshalSpec::ObjectWithoutFreeze.new
+ object = Marshal.send(@method, Marshal.dump(object), freeze: true)
+ object.should.frozen?
end
- it "returns the value of the proc" do
- Marshal.send(@method, Marshal.dump([1,2]), proc { [3,4] }).should == [3,4]
- end
+ it "returns a frozen object when is an instance of String/Array/Regexp/Hash subclass and has instance variables" do
+ source_object = UserString.new
+ source_object.instance_variable_set(:@foo, "bar")
- ruby_bug "#18141", ""..."3.1" do
- it "calls the proc for recursively visited data" do
- a = [1]
- a << a
- ret = []
- Marshal.send(@method, Marshal.dump(a), proc { |arg| ret << arg.inspect; arg })
- ret[0].should == 1.inspect
- ret[1].should == a.inspect
- ret.size.should == 2
- end
+ object = Marshal.send(@method, Marshal.dump(source_object), freeze: true)
+ object.should.frozen?
+ end
- it "loads an Array with proc" do
+ describe "when called with a proc" do
+ it "call the proc with frozen objects" do
arr = []
s = +'hi'
s.instance_variable_set(:@foo, 5)
@@ -279,16 +193,96 @@ describe :marshal_load, shared: true do
a.instance_variable_set(:@two, 2)
obj = [s, 10, s, s, st, a]
obj.instance_variable_set(:@zoo, 'ant')
- proc = Proc.new { |o| arr << o.dup; o}
+ proc = Proc.new { |o| arr << o; o}
- Marshal.send(@method, "\x04\bI[\vI\"\ahi\a:\x06EF:\t@fooi\ni\x0F@\x06@\x06IS:\x14Struct::Brittle\x06:\x06af\x060\x06:\n@clueI\"\tnone\x06;\x00FI[\b;\b:\x06b:\x06c\x06:\t@twoi\a\x06:\t@zooI\"\bant\x06;\x00F", proc)
+ Marshal.send(
+ @method,
+ "\x04\bI[\vI\"\ahi\a:\x06EF:\t@fooi\ni\x0F@\x06@\x06IS:\x14Struct::Brittle\x06:\x06af\x060\x06:\n@clueI\"\tnone\x06;\x00FI[\b;\b:\x06b:\x06c\x06:\t@twoi\a\x06:\t@zooI\"\bant\x06;\x00F",
+ proc,
+ freeze: true,
+ )
arr.should == [
false, 5, "hi", 10, "hi", "hi", 0.0, false, "none", st,
:b, :c, 2, a, false, "ant", ["hi", 10, "hi", "hi", st, [:a, :b, :c]],
]
+
+ arr.each do |v|
+ v.should.frozen?
+ end
+
Struct.send(:remove_const, :Brittle)
end
+
+ it "does not freeze the object returned by the proc" do
+ string = Marshal.send(@method, Marshal.dump("foo"), proc { |o| o.upcase }, freeze: true)
+ string.should == "FOO"
+ string.should_not.frozen?
+ end
+ end
+ end
+
+ describe "when called with a proc" do
+ it "call the proc with fully initialized strings" do
+ utf8_string = "foo".encode(Encoding::UTF_8)
+ Marshal.send(@method, Marshal.dump(utf8_string), proc { |arg|
+ if arg.is_a?(String)
+ arg.should == utf8_string
+ arg.encoding.should == Encoding::UTF_8
+ end
+ arg
+ })
+ end
+
+ it "no longer mutate the object after it was passed to the proc" do
+ string = Marshal.load(Marshal.dump("foo"), :freeze.to_proc)
+ string.should.frozen?
+ end
+
+ ruby_bug "#19427", ""..."3.3" do
+ it "call the proc with extended objects" do
+ objs = []
+ obj = Marshal.load("\x04\be:\x0FEnumerableo:\vObject\x00", Proc.new { |o| objs << o; o })
+ objs.should == [obj]
+ end
+ end
+
+ it "returns the value of the proc" do
+ Marshal.send(@method, Marshal.dump([1,2]), proc { [3,4] }).should == [3,4]
+ end
+
+ it "calls the proc for recursively visited data" do
+ a = [1]
+ a << a
+ ret = []
+ Marshal.send(@method, Marshal.dump(a), proc { |arg| ret << arg.inspect; arg })
+ ret[0].should == 1.inspect
+ ret[1].should == a.inspect
+ ret.size.should == 2
+ end
+
+ it "loads an Array with proc" do
+ arr = []
+ s = +'hi'
+ s.instance_variable_set(:@foo, 5)
+ st = Struct.new("Brittle", :a).new
+ st.instance_variable_set(:@clue, 'none')
+ st.a = 0.0
+ h = Hash.new('def')
+ h['nine'] = 9
+ a = [:a, :b, :c]
+ a.instance_variable_set(:@two, 2)
+ obj = [s, 10, s, s, st, a]
+ obj.instance_variable_set(:@zoo, 'ant')
+ proc = Proc.new { |o| arr << o.dup; o}
+
+ Marshal.send(@method, "\x04\bI[\vI\"\ahi\a:\x06EF:\t@fooi\ni\x0F@\x06@\x06IS:\x14Struct::Brittle\x06:\x06af\x060\x06:\n@clueI\"\tnone\x06;\x00FI[\b;\b:\x06b:\x06c\x06:\t@twoi\a\x06:\t@zooI\"\bant\x06;\x00F", proc)
+
+ arr.should == [
+ false, 5, "hi", 10, "hi", "hi", 0.0, false, "none", st,
+ :b, :c, 2, a, false, "ant", ["hi", 10, "hi", "hi", st, [:a, :b, :c]],
+ ]
+ Struct.send(:remove_const, :Brittle)
end
end
@@ -364,39 +358,37 @@ describe :marshal_load, shared: true do
end
end
- ruby_bug "#18141", ""..."3.1" do
- it "loads an array containing objects having _dump method, and with proc" do
- arr = []
- myproc = Proc.new { |o| arr << o.dup; o }
- o1 = UserDefined.new;
- o2 = UserDefinedWithIvar.new
- obj = [o1, o2, o1, o2]
+ it "loads an array containing objects having _dump method, and with proc" do
+ arr = []
+ myproc = Proc.new { |o| arr << o.dup; o }
+ o1 = UserDefined.new;
+ o2 = UserDefinedWithIvar.new
+ obj = [o1, o2, o1, o2]
- Marshal.send(@method, "\x04\b[\tu:\x10UserDefined\x18\x04\b[\aI\"\nstuff\x06:\x06EF@\x06u:\x18UserDefinedWithIvar>\x04\b[\bI\"\nstuff\a:\x06EF:\t@foo:\x18UserDefinedWithIvarI\"\tmore\x06;\x00F@\a@\x06@\a", myproc)
+ Marshal.send(@method, "\x04\b[\tu:\x10UserDefined\x18\x04\b[\aI\"\nstuff\x06:\x06EF@\x06u:\x18UserDefinedWithIvar>\x04\b[\bI\"\nstuff\a:\x06EF:\t@foo:\x18UserDefinedWithIvarI\"\tmore\x06;\x00F@\a@\x06@\a", myproc)
- arr[0].should == o1
- arr[1].should == o2
- arr[2].should == obj
- arr.size.should == 3
- end
+ arr[0].should == o1
+ arr[1].should == o2
+ arr[2].should == obj
+ arr.size.should == 3
+ end
- it "loads an array containing objects having marshal_dump method, and with proc" do
- arr = []
- proc = Proc.new { |o| arr << o.dup; o }
- o1 = UserMarshal.new
- o2 = UserMarshalWithIvar.new
+ it "loads an array containing objects having marshal_dump method, and with proc" do
+ arr = []
+ proc = Proc.new { |o| arr << o.dup; o }
+ o1 = UserMarshal.new
+ o2 = UserMarshalWithIvar.new
- Marshal.send(@method, "\004\b[\tU:\020UserMarshal\"\nstuffU:\030UserMarshalWithIvar[\006\"\fmy data@\006@\b", proc)
+ Marshal.send(@method, "\004\b[\tU:\020UserMarshal\"\nstuffU:\030UserMarshalWithIvar[\006\"\fmy data@\006@\b", proc)
- arr[0].should == 'stuff'
- arr[1].should == o1
- arr[2].should == 'my data'
- arr[3].should == ['my data']
- arr[4].should == o2
- arr[5].should == [o1, o2, o1, o2]
+ arr[0].should == 'stuff'
+ arr[1].should == o1
+ arr[2].should == 'my data'
+ arr[3].should == ['my data']
+ arr[4].should == o2
+ arr[5].should == [o1, o2, o1, o2]
- arr.size.should == 6
- end
+ arr.size.should == 6
end
it "assigns classes to nested subclasses of Array correctly" do
@@ -526,28 +518,26 @@ describe :marshal_load, shared: true do
unmarshalled[:key].instance_variable_get(:@string_ivar).should == 'string ivar'
end
- ruby_version_is "3.1" do
- it "preserves compare_by_identity behaviour" do
- h = { a: 1 }
- h.compare_by_identity
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should.compare_by_identity?
+ it "preserves compare_by_identity behaviour" do
+ h = { a: 1 }
+ h.compare_by_identity
+ unmarshalled = Marshal.send(@method, Marshal.dump(h))
+ unmarshalled.should.compare_by_identity?
- h = { a: 1 }
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should_not.compare_by_identity?
- end
+ h = { a: 1 }
+ unmarshalled = Marshal.send(@method, Marshal.dump(h))
+ unmarshalled.should_not.compare_by_identity?
+ end
- it "preserves compare_by_identity behaviour for a Hash subclass" do
- h = UserHash.new({ a: 1 })
- h.compare_by_identity
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should.compare_by_identity?
+ it "preserves compare_by_identity behaviour for a Hash subclass" do
+ h = UserHash.new({ a: 1 })
+ h.compare_by_identity
+ unmarshalled = Marshal.send(@method, Marshal.dump(h))
+ unmarshalled.should.compare_by_identity?
- h = UserHash.new({ a: 1 })
- unmarshalled = Marshal.send(@method, Marshal.dump(h))
- unmarshalled.should_not.compare_by_identity?
- end
+ h = UserHash.new({ a: 1 })
+ unmarshalled = Marshal.send(@method, Marshal.dump(h))
+ unmarshalled.should_not.compare_by_identity?
end
it "allocates an instance of the proper class when Hash subclass with compare_by_identity behaviour" do
diff --git a/spec/ruby/core/matchdata/match_length_spec.rb b/spec/ruby/core/matchdata/match_length_spec.rb
index f7785ab1a0..824f94a397 100644
--- a/spec/ruby/core/matchdata/match_length_spec.rb
+++ b/spec/ruby/core/matchdata/match_length_spec.rb
@@ -2,33 +2,31 @@
require_relative '../../spec_helper'
-ruby_version_is "3.1" do
- describe "MatchData#match_length" do
- it "returns the length of the corresponding match when given an Integer" do
- md = /(.)(.)(\d+)(\d)/.match("THX1138.")
+describe "MatchData#match_length" do
+ it "returns the length of the corresponding match when given an Integer" do
+ md = /(.)(.)(\d+)(\d)/.match("THX1138.")
- md.match_length(0).should == 6
- md.match_length(1).should == 1
- md.match_length(2).should == 1
- md.match_length(3).should == 3
- md.match_length(4).should == 1
- end
+ md.match_length(0).should == 6
+ md.match_length(1).should == 1
+ md.match_length(2).should == 1
+ md.match_length(3).should == 3
+ md.match_length(4).should == 1
+ end
- it "returns nil on non-matching index matches" do
- md = /\d+(\w)?/.match("THX1138.")
- md.match_length(1).should == nil
- end
+ it "returns nil on non-matching index matches" do
+ md = /\d+(\w)?/.match("THX1138.")
+ md.match_length(1).should == nil
+ end
- it "returns the length of the corresponding named match when given a Symbol" do
- md = 'haystack'.match(/(?<t>t(?<a>ack))/)
- md.match_length(:a).should == 3
- md.match_length(:t).should == 4
- end
+ it "returns the length of the corresponding named match when given a Symbol" do
+ md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+ md.match_length(:a).should == 3
+ md.match_length(:t).should == 4
+ end
- it "returns nil on non-matching index matches" do
- md = 'haystack'.match(/(?<t>t)(?<a>all)?/)
- md.match_length(:t).should == 1
- md.match_length(:a).should == nil
- end
+ it "returns nil on non-matching index matches" do
+ md = 'haystack'.match(/(?<t>t)(?<a>all)?/)
+ md.match_length(:t).should == 1
+ md.match_length(:a).should == nil
end
end
diff --git a/spec/ruby/core/matchdata/match_spec.rb b/spec/ruby/core/matchdata/match_spec.rb
index 545de6f93f..a16914ea15 100644
--- a/spec/ruby/core/matchdata/match_spec.rb
+++ b/spec/ruby/core/matchdata/match_spec.rb
@@ -2,33 +2,31 @@
require_relative '../../spec_helper'
-ruby_version_is "3.1" do
- describe "MatchData#match" do
- it "returns the corresponding match when given an Integer" do
- md = /(.)(.)(\d+)(\d)/.match("THX1138.")
+describe "MatchData#match" do
+ it "returns the corresponding match when given an Integer" do
+ md = /(.)(.)(\d+)(\d)/.match("THX1138.")
- md.match(0).should == 'HX1138'
- md.match(1).should == 'H'
- md.match(2).should == 'X'
- md.match(3).should == '113'
- md.match(4).should == '8'
- end
+ md.match(0).should == 'HX1138'
+ md.match(1).should == 'H'
+ md.match(2).should == 'X'
+ md.match(3).should == '113'
+ md.match(4).should == '8'
+ end
- it "returns nil on non-matching index matches" do
- md = /\d+(\w)?/.match("THX1138.")
- md.match(1).should == nil
- end
+ it "returns nil on non-matching index matches" do
+ md = /\d+(\w)?/.match("THX1138.")
+ md.match(1).should == nil
+ end
- it "returns the corresponding named match when given a Symbol" do
- md = 'haystack'.match(/(?<t>t(?<a>ack))/)
- md.match(:a).should == 'ack'
- md.match(:t).should == 'tack'
- end
+ it "returns the corresponding named match when given a Symbol" do
+ md = 'haystack'.match(/(?<t>t(?<a>ack))/)
+ md.match(:a).should == 'ack'
+ md.match(:t).should == 'tack'
+ end
- it "returns nil on non-matching index matches" do
- md = 'haystack'.match(/(?<t>t)(?<a>all)?/)
- md.match(:t).should == 't'
- md.match(:a).should == nil
- end
+ it "returns nil on non-matching index matches" do
+ md = 'haystack'.match(/(?<t>t)(?<a>all)?/)
+ md.match(:t).should == 't'
+ md.match(:a).should == nil
end
end
diff --git a/spec/ruby/core/method/parameters_spec.rb b/spec/ruby/core/method/parameters_spec.rb
index 8495aef4d2..0178a61de6 100644
--- a/spec/ruby/core/method/parameters_spec.rb
+++ b/spec/ruby/core/method/parameters_spec.rb
@@ -257,30 +257,17 @@ describe "Method#parameters" do
end
end
- ruby_version_is '3.1' do
- it "adds block arg with name & for anonymous block argument" do
- object = Object.new
-
- eval(<<~RUBY).should == [[:block, :&]]
- def object.foo(&)
- end
- object.method(:foo).parameters
- RUBY
+ it "adds block arg with name & for anonymous block argument" do
+ object = Object.new
+ def object.foo(&)
end
- end
- ruby_version_is ""..."3.1" do
- it "returns [:rest, :*], [:block, :&] for forward parameters operator" do
- m = MethodSpecs::Methods.new
- m.method(:forward_parameters).parameters.should == [[:rest, :*], [:block, :&]]
- end
+ object.method(:foo).parameters.should == [[:block, :&]]
end
- ruby_version_is "3.1" do
- it "returns [:rest, :*], [:keyrest, :**], [:block, :&] for forward parameters operator" do
- m = MethodSpecs::Methods.new
- m.method(:forward_parameters).parameters.should == [[:rest, :*], [:keyrest, :**], [:block, :&]]
- end
+ it "returns [:rest, :*], [:keyrest, :**], [:block, :&] for forward parameters operator" do
+ m = MethodSpecs::Methods.new
+ m.method(:forward_parameters).parameters.should == [[:rest, :*], [:keyrest, :**], [:block, :&]]
end
it "returns the args and block for a splat and block argument" do
diff --git a/spec/ruby/core/method/private_spec.rb b/spec/ruby/core/method/private_spec.rb
index fd550036a3..9b67a77243 100644
--- a/spec/ruby/core/method/private_spec.rb
+++ b/spec/ruby/core/method/private_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Method#private?" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "returns false when the method is public" do
obj = MethodSpecs::Methods.new
obj.method(:my_public_method).private?.should == false
diff --git a/spec/ruby/core/method/protected_spec.rb b/spec/ruby/core/method/protected_spec.rb
index 8423e8c64c..28c60c7536 100644
--- a/spec/ruby/core/method/protected_spec.rb
+++ b/spec/ruby/core/method/protected_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Method#protected?" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "returns false when the method is public" do
obj = MethodSpecs::Methods.new
obj.method(:my_public_method).protected?.should == false
diff --git a/spec/ruby/core/method/public_spec.rb b/spec/ruby/core/method/public_spec.rb
index 20d0081a27..4844f4b90b 100644
--- a/spec/ruby/core/method/public_spec.rb
+++ b/spec/ruby/core/method/public_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Method#public?" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "returns true when the method is public" do
obj = MethodSpecs::Methods.new
obj.method(:my_public_method).public?.should == true
diff --git a/spec/ruby/core/module/autoload_spec.rb b/spec/ruby/core/module/autoload_spec.rb
index 45d18b8608..3cdc48f9ba 100644
--- a/spec/ruby/core/module/autoload_spec.rb
+++ b/spec/ruby/core/module/autoload_spec.rb
@@ -486,42 +486,21 @@ describe "Module#autoload" do
ScratchPad.recorded.should == [:raise, :raise]
end
- ruby_version_is "3.1" do
- it "removes the constant from Module#constants if the loaded file does not define it" do
- path = fixture(__FILE__, "autoload_o.rb")
- ScratchPad.record []
- ModuleSpecs::Autoload.autoload :O, path
-
- ModuleSpecs::Autoload.const_defined?(:O).should == true
- ModuleSpecs::Autoload.should have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == path
-
- -> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
-
- ModuleSpecs::Autoload.const_defined?(:O).should == false
- ModuleSpecs::Autoload.should_not have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == nil
- -> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
- end
- end
-
- ruby_version_is ""..."3.1" do
- it "does not remove the constant from Module#constants if the loaded file does not define it, but leaves it as 'undefined'" do
- path = fixture(__FILE__, "autoload_o.rb")
- ScratchPad.record []
- ModuleSpecs::Autoload.autoload :O, path
+ it "removes the constant from Module#constants if the loaded file does not define it" do
+ path = fixture(__FILE__, "autoload_o.rb")
+ ScratchPad.record []
+ ModuleSpecs::Autoload.autoload :O, path
- ModuleSpecs::Autoload.const_defined?(:O).should == true
- ModuleSpecs::Autoload.should have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == path
+ ModuleSpecs::Autoload.const_defined?(:O).should == true
+ ModuleSpecs::Autoload.should have_constant(:O)
+ ModuleSpecs::Autoload.autoload?(:O).should == path
- -> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
+ -> { ModuleSpecs::Autoload::O }.should raise_error(NameError)
- ModuleSpecs::Autoload.const_defined?(:O).should == false
- ModuleSpecs::Autoload.should have_constant(:O)
- ModuleSpecs::Autoload.autoload?(:O).should == nil
- -> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
- end
+ ModuleSpecs::Autoload.const_defined?(:O).should == false
+ ModuleSpecs::Autoload.should_not have_constant(:O)
+ ModuleSpecs::Autoload.autoload?(:O).should == nil
+ -> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
end
it "does not try to load the file again if the loaded file did not define the constant" do
@@ -654,48 +633,23 @@ describe "Module#autoload" do
end
end
- ruby_version_is "3.1" do
- it "looks up in parent scope after failed autoload" do
- @remove << :DeclaredInCurrentDefinedInParent
- module ModuleSpecs::Autoload
- ScratchPad.record -> {
- DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
- }
-
- class LexicalScope
- autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
- -> { DeclaredInCurrentDefinedInParent }.should_not raise_error(NameError)
- # Basically, the autoload constant remains in a "undefined" state
- self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
- const_defined?(:DeclaredInCurrentDefinedInParent).should == false
- -> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
- end
+ it "looks up in parent scope after failed autoload" do
+ @remove << :DeclaredInCurrentDefinedInParent
+ module ModuleSpecs::Autoload
+ ScratchPad.record -> {
+ DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
+ }
- DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
+ class LexicalScope
+ autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
+ -> { DeclaredInCurrentDefinedInParent }.should_not raise_error(NameError)
+ # Basically, the autoload constant remains in a "undefined" state
+ self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
+ const_defined?(:DeclaredInCurrentDefinedInParent).should == false
+ -> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
end
- end
- end
-
- ruby_version_is ""..."3.1" do
- it "and fails when finding the undefined autoload constant in the current scope when declared in current and defined in parent" do
- @remove << :DeclaredInCurrentDefinedInParent
- module ModuleSpecs::Autoload
- ScratchPad.record -> {
- DeclaredInCurrentDefinedInParent = :declared_in_current_defined_in_parent
- }
- class LexicalScope
- autoload :DeclaredInCurrentDefinedInParent, fixture(__FILE__, "autoload_callback.rb")
- -> { DeclaredInCurrentDefinedInParent }.should raise_error(NameError)
- # Basically, the autoload constant remains in a "undefined" state
- self.autoload?(:DeclaredInCurrentDefinedInParent).should == nil
- const_defined?(:DeclaredInCurrentDefinedInParent).should == false
- self.should have_constant(:DeclaredInCurrentDefinedInParent)
- -> { const_get(:DeclaredInCurrentDefinedInParent) }.should raise_error(NameError)
- end
-
- DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
- end
+ DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
end
end
diff --git a/spec/ruby/core/module/const_defined_spec.rb b/spec/ruby/core/module/const_defined_spec.rb
index 027cf5a245..8b137cd134 100644
--- a/spec/ruby/core/module/const_defined_spec.rb
+++ b/spec/ruby/core/module/const_defined_spec.rb
@@ -65,6 +65,8 @@ describe "Module#const_defined?" do
str = "CS_CONSTλ".encode("euc-jp")
ConstantSpecs.const_set str, 1
ConstantSpecs.const_defined?(str).should be_true
+ ensure
+ ConstantSpecs.send(:remove_const, str)
end
it "returns false if the constant is not defined in the receiver, its superclass, or any included modules" do
diff --git a/spec/ruby/core/module/const_get_spec.rb b/spec/ruby/core/module/const_get_spec.rb
index 0233118f4b..4b53cbe7b3 100644
--- a/spec/ruby/core/module/const_get_spec.rb
+++ b/spec/ruby/core/module/const_get_spec.rb
@@ -131,7 +131,7 @@ describe "Module#const_get" do
end
it "does read private constants" do
- ConstantSpecs.const_get(:CS_PRIVATE).should == :cs_private
+ ConstantSpecs.const_get(:CS_PRIVATE).should == :cs_private
end
it 'does autoload a constant' do
@@ -202,40 +202,60 @@ describe "Module#const_get" do
ConstantSpecs::ContainerA::ChildA::CS_CONST301 = :const301_5
ConstantSpecs::ContainerA::ChildA.const_get(:CS_CONST301).should == :const301_5
+ ensure
+ ConstantSpecs::ClassA.send(:remove_const, :CS_CONST301)
+ ConstantSpecs::ModuleA.send(:remove_const, :CS_CONST301)
+ ConstantSpecs::ParentA.send(:remove_const, :CS_CONST301)
+ ConstantSpecs::ContainerA::ChildA.send(:remove_const, :CS_CONST301)
end
it "searches a module included in the immediate class before the superclass" do
ConstantSpecs::ParentB::CS_CONST302 = :const302_1
ConstantSpecs::ModuleF::CS_CONST302 = :const302_2
ConstantSpecs::ContainerB::ChildB.const_get(:CS_CONST302).should == :const302_2
+ ensure
+ ConstantSpecs::ParentB.send(:remove_const, :CS_CONST302)
+ ConstantSpecs::ModuleF.send(:remove_const, :CS_CONST302)
end
it "searches the superclass before a module included in the superclass" do
ConstantSpecs::ModuleE::CS_CONST303 = :const303_1
ConstantSpecs::ParentB::CS_CONST303 = :const303_2
ConstantSpecs::ContainerB::ChildB.const_get(:CS_CONST303).should == :const303_2
+ ensure
+ ConstantSpecs::ModuleE.send(:remove_const, :CS_CONST303)
+ ConstantSpecs::ParentB.send(:remove_const, :CS_CONST303)
end
it "searches a module included in the superclass" do
ConstantSpecs::ModuleA::CS_CONST304 = :const304_1
ConstantSpecs::ModuleE::CS_CONST304 = :const304_2
ConstantSpecs::ContainerB::ChildB.const_get(:CS_CONST304).should == :const304_2
+ ensure
+ ConstantSpecs::ModuleA.send(:remove_const, :CS_CONST304)
+ ConstantSpecs::ModuleE.send(:remove_const, :CS_CONST304)
end
it "searches the superclass chain" do
ConstantSpecs::ModuleA::CS_CONST305 = :const305
ConstantSpecs::ContainerB::ChildB.const_get(:CS_CONST305).should == :const305
+ ensure
+ ConstantSpecs::ModuleA.send(:remove_const, :CS_CONST305)
end
it "returns a toplevel constant when the receiver is a Class" do
Object::CS_CONST306 = :const306
ConstantSpecs::ContainerB::ChildB.const_get(:CS_CONST306).should == :const306
+ ensure
+ Object.send(:remove_const, :CS_CONST306)
end
it "returns a toplevel constant when the receiver is a Module" do
Object::CS_CONST308 = :const308
ConstantSpecs.const_get(:CS_CONST308).should == :const308
ConstantSpecs::ModuleA.const_get(:CS_CONST308).should == :const308
+ ensure
+ Object.send(:remove_const, :CS_CONST308)
end
it "returns the updated value of a constant" do
@@ -246,6 +266,8 @@ describe "Module#const_get" do
ConstantSpecs::ClassB::CS_CONST309 = :const309_2
}.should complain(/already initialized constant/)
ConstantSpecs::ClassB.const_get(:CS_CONST309).should == :const309_2
+ ensure
+ ConstantSpecs::ClassB.send(:remove_const, :CS_CONST309)
end
end
end
diff --git a/spec/ruby/core/module/const_set_spec.rb b/spec/ruby/core/module/const_set_spec.rb
index 5bdfd7b68f..823768b882 100644
--- a/spec/ruby/core/module/const_set_spec.rb
+++ b/spec/ruby/core/module/const_set_spec.rb
@@ -8,16 +8,23 @@ describe "Module#const_set" do
ConstantSpecs.const_set "CS_CONST402", :const402
ConstantSpecs.const_get(:CS_CONST402).should == :const402
+ ensure
+ ConstantSpecs.send(:remove_const, :CS_CONST401)
+ ConstantSpecs.send(:remove_const, :CS_CONST402)
end
it "returns the value set" do
ConstantSpecs.const_set(:CS_CONST403, :const403).should == :const403
+ ensure
+ ConstantSpecs.send(:remove_const, :CS_CONST403)
end
it "sets the name of an anonymous module" do
m = Module.new
ConstantSpecs.const_set(:CS_CONST1000, m)
m.name.should == "ConstantSpecs::CS_CONST1000"
+ ensure
+ ConstantSpecs.send(:remove_const, :CS_CONST1000)
end
it "sets the name of a module scoped by an anonymous module" do
@@ -38,6 +45,8 @@ describe "Module#const_set" do
b.name.should == "ModuleSpecs_CS3::B"
c.name.should == "ModuleSpecs_CS3::B::C"
d.name.should == "ModuleSpecs_CS3::D"
+ ensure
+ Object.send(:remove_const, :ModuleSpecs_CS3)
end
it "raises a NameError if the name does not start with a capital letter" do
@@ -55,6 +64,8 @@ describe "Module#const_set" do
ConstantSpecs.const_set("CS_CONST404", :const404).should == :const404
-> { ConstantSpecs.const_set "Name=", 1 }.should raise_error(NameError)
-> { ConstantSpecs.const_set "Name?", 1 }.should raise_error(NameError)
+ ensure
+ ConstantSpecs.send(:remove_const, :CS_CONST404)
end
it "calls #to_str to convert the given name to a String" do
@@ -62,6 +73,8 @@ describe "Module#const_set" do
name.should_receive(:to_str).and_return("CS_CONST405")
ConstantSpecs.const_set(name, :const405).should == :const405
ConstantSpecs::CS_CONST405.should == :const405
+ ensure
+ ConstantSpecs.send(:remove_const, :CS_CONST405)
end
it "raises a TypeError if conversion to a String by calling #to_str fails" do
diff --git a/spec/ruby/core/module/const_source_location_spec.rb b/spec/ruby/core/module/const_source_location_spec.rb
index c194c9113f..06b3b215c2 100644
--- a/spec/ruby/core/module/const_source_location_spec.rb
+++ b/spec/ruby/core/module/const_source_location_spec.rb
@@ -19,40 +19,60 @@ describe "Module#const_source_location" do
ConstantSpecs::ContainerA::ChildA::CSL_CONST301 = :const301_5
ConstantSpecs::ContainerA::ChildA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1]
+ ensure
+ ConstantSpecs::ClassA.send(:remove_const, :CSL_CONST301)
+ ConstantSpecs::ModuleA.send(:remove_const, :CSL_CONST301)
+ ConstantSpecs::ParentA.send(:remove_const, :CSL_CONST301)
+ ConstantSpecs::ContainerA::ChildA.send(:remove_const, :CSL_CONST301)
end
it "searches a path in a module included in the immediate class before the superclass" do
ConstantSpecs::ParentB::CSL_CONST302 = :const302_1
ConstantSpecs::ModuleF::CSL_CONST302 = :const302_2
ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST302).should == [__FILE__, __LINE__ - 1]
+ ensure
+ ConstantSpecs::ParentB.send(:remove_const, :CSL_CONST302)
+ ConstantSpecs::ModuleF.send(:remove_const, :CSL_CONST302)
end
it "searches a path in the superclass before a module included in the superclass" do
ConstantSpecs::ModuleE::CSL_CONST303 = :const303_1
ConstantSpecs::ParentB::CSL_CONST303 = :const303_2
ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST303).should == [__FILE__, __LINE__ - 1]
+ ensure
+ ConstantSpecs::ModuleE.send(:remove_const, :CSL_CONST303)
+ ConstantSpecs::ParentB.send(:remove_const, :CSL_CONST303)
end
it "searches a path in a module included in the superclass" do
ConstantSpecs::ModuleA::CSL_CONST304 = :const304_1
ConstantSpecs::ModuleE::CSL_CONST304 = :const304_2
ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST304).should == [__FILE__, __LINE__ - 1]
+ ensure
+ ConstantSpecs::ModuleA.send(:remove_const, :CSL_CONST304)
+ ConstantSpecs::ModuleE.send(:remove_const, :CSL_CONST304)
end
it "searches a path in the superclass chain" do
ConstantSpecs::ModuleA::CSL_CONST305 = :const305
ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST305).should == [__FILE__, __LINE__ - 1]
+ ensure
+ ConstantSpecs::ModuleA.send(:remove_const, :CSL_CONST305)
end
it "returns path to a toplevel constant when the receiver is a Class" do
Object::CSL_CONST306 = :const306
ConstantSpecs::ContainerB::ChildB.const_source_location(:CSL_CONST306).should == [__FILE__, __LINE__ - 1]
+ ensure
+ Object.send(:remove_const, :CSL_CONST306)
end
it "returns path to a toplevel constant when the receiver is a Module" do
Object::CSL_CONST308 = :const308
ConstantSpecs.const_source_location(:CSL_CONST308).should == [__FILE__, __LINE__ - 1]
ConstantSpecs::ModuleA.const_source_location(:CSL_CONST308).should == [__FILE__, __LINE__ - 2]
+ ensure
+ Object.send(:remove_const, :CSL_CONST308)
end
it "returns path to the updated value of a constant" do
@@ -63,6 +83,8 @@ describe "Module#const_source_location" do
ConstantSpecs::ClassB::CSL_CONST309 = :const309_2
}.should complain(/already initialized constant/)
ConstantSpecs::ClassB.const_source_location(:CSL_CONST309).should == [__FILE__, __LINE__ - 2]
+ ensure
+ ConstantSpecs::ClassB.send(:remove_const, :CSL_CONST309)
end
end
@@ -207,7 +229,7 @@ describe "Module#const_source_location" do
end
it "does search private constants path" do
- ConstantSpecs.const_source_location(:CS_PRIVATE).should == [@constants_fixture_path, ConstantSpecs::CS_PRIVATE_LINE]
+ ConstantSpecs.const_source_location(:CS_PRIVATE).should == [@constants_fixture_path, ConstantSpecs::CS_PRIVATE_LINE]
end
it "works for eval with a given line" do
diff --git a/spec/ruby/core/module/define_method_spec.rb b/spec/ruby/core/module/define_method_spec.rb
index e04bb87ceb..c5dfc53764 100644
--- a/spec/ruby/core/module/define_method_spec.rb
+++ b/spec/ruby/core/module/define_method_spec.rb
@@ -476,6 +476,9 @@ describe "Module#define_method" do
ChildClass = Class.new(ParentClass) { define_method(:foo) { :baz } }
ParentClass.send :define_method, :foo, ChildClass.instance_method(:foo)
}.should raise_error(TypeError, /bind argument must be a subclass of ChildClass/)
+ ensure
+ Object.send(:remove_const, :ParentClass)
+ Object.send(:remove_const, :ChildClass)
end
it "raises a TypeError when an UnboundMethod from one class is defined on an unrelated class" do
diff --git a/spec/ruby/core/module/include_spec.rb b/spec/ruby/core/module/include_spec.rb
index 862c6976e1..a1bfd3a6f5 100644
--- a/spec/ruby/core/module/include_spec.rb
+++ b/spec/ruby/core/module/include_spec.rb
@@ -44,7 +44,11 @@ describe "Module#include" do
end
it "does not raise a TypeError when the argument is an instance of a subclass of Module" do
- -> { ModuleSpecs::SubclassSpec.include(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
+ class ModuleSpecs::SubclassSpec::AClass
+ end
+ -> { ModuleSpecs::SubclassSpec::AClass.include(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
+ ensure
+ ModuleSpecs::SubclassSpec.send(:remove_const, :AClass)
end
ruby_version_is ""..."3.2" do
@@ -427,6 +431,8 @@ describe "Module#include" do
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdated)
end
it "updates the constant when a module included after a call is later updated" do
@@ -453,6 +459,8 @@ describe "Module#include" do
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstLaterUpdated)
end
it "updates the constant when a module included in another module after a call is later updated" do
@@ -479,6 +487,8 @@ describe "Module#include" do
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstModuleLaterUpdated)
end
it "updates the constant when a nested included module is updated" do
@@ -507,6 +517,8 @@ describe "Module#include" do
N.const_set(:FOO, 'n')
B.foo.should == 'n'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatedNestedIncludeUpdated)
end
it "updates the constant when a new module is included" do
@@ -531,6 +543,8 @@ describe "Module#include" do
B.include(M)
B.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatedNewInclude)
end
it "updates the constant when a new module with nested module is included" do
@@ -559,6 +573,8 @@ describe "Module#include" do
B.include M
B.foo.should == 'n'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatedNestedIncluded)
end
it "overrides a previous super method call" do
diff --git a/spec/ruby/core/module/module_function_spec.rb b/spec/ruby/core/module/module_function_spec.rb
index 1c3ec5471b..51f647142e 100644
--- a/spec/ruby/core/module/module_function_spec.rb
+++ b/spec/ruby/core/module/module_function_spec.rb
@@ -38,22 +38,11 @@ describe "Module#module_function with specific method names" do
m.respond_to?(:test3).should == false
end
- ruby_version_is ""..."3.1" do
- it "returns self" do
- Module.new do
- def foo; end
- module_function(:foo).should equal(self)
- end
- end
- end
-
- ruby_version_is "3.1" do
- it "returns argument or arguments if given" do
- Module.new do
- def foo; end
- module_function(:foo).should equal(:foo)
- module_function(:foo, :foo).should == [:foo, :foo]
- end
+ it "returns argument or arguments if given" do
+ Module.new do
+ def foo; end
+ module_function(:foo).should equal(:foo)
+ module_function(:foo, :foo).should == [:foo, :foo]
end
end
@@ -216,19 +205,9 @@ describe "Module#module_function as a toggle (no arguments) in a Module body" do
m.respond_to?(:test2).should == true
end
- ruby_version_is ""..."3.1" do
- it "returns self" do
- Module.new do
- module_function.should equal(self)
- end
- end
- end
-
- ruby_version_is "3.1" do
- it "returns nil" do
- Module.new do
- module_function.should equal(nil)
- end
+ it "returns nil" do
+ Module.new do
+ module_function.should equal(nil)
end
end
diff --git a/spec/ruby/core/module/name_spec.rb b/spec/ruby/core/module/name_spec.rb
index 33e8400e88..b5c1f771f8 100644
--- a/spec/ruby/core/module/name_spec.rb
+++ b/spec/ruby/core/module/name_spec.rb
@@ -30,6 +30,8 @@ describe "Module#name" do
m::N.name.should =~ /\A#<Module:0x\h+>::N\z/
ModuleSpecs::Anonymous::WasAnnon = m::N
m::N.name.should == "ModuleSpecs::Anonymous::WasAnnon"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :WasAnnon)
end
it "may be the repeated in different module objects" do
@@ -76,12 +78,16 @@ describe "Module#name" do
m = Module.new
ModuleSpecs::Anonymous::A = m
m.name.should == "ModuleSpecs::Anonymous::A"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :A)
end
it "is set when assigning to a constant (constant path does not match outer module name)" do
m = Module.new
ModuleSpecs::Anonymous::SameChild::A = m
m.name.should == "ModuleSpecs::Anonymous::Child::A"
+ ensure
+ ModuleSpecs::Anonymous::SameChild.send(:remove_const, :A)
end
it "is not modified when assigning to a new constant after it has been accessed" do
@@ -90,6 +96,9 @@ describe "Module#name" do
m.name.should == "ModuleSpecs::Anonymous::B"
ModuleSpecs::Anonymous::C = m
m.name.should == "ModuleSpecs::Anonymous::B"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :B)
+ ModuleSpecs::Anonymous.send(:remove_const, :C)
end
it "is not modified when assigned to a different anonymous module" do
@@ -125,6 +134,8 @@ describe "Module#name" do
m::N = Module.new
ModuleSpecs::Anonymous::E = m
m::N.name.should == "ModuleSpecs::Anonymous::E::N"
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :E)
end
# https://bugs.ruby-lang.org/issues/19681
@@ -138,6 +149,8 @@ describe "Module#name" do
"ModuleSpecs::Anonymous::StoredInMultiplePlaces::O"
]
valid_names.should include(m::N.name) # You get one of the two, but you don't know which one.
+ ensure
+ ModuleSpecs::Anonymous.send(:remove_const, :StoredInMultiplePlaces)
end
ruby_version_is "3.2" do
diff --git a/spec/ruby/core/module/prepend_spec.rb b/spec/ruby/core/module/prepend_spec.rb
index b40d12f0de..9508fbf182 100644
--- a/spec/ruby/core/module/prepend_spec.rb
+++ b/spec/ruby/core/module/prepend_spec.rb
@@ -261,6 +261,8 @@ describe "Module#prepend" do
B.prepend M
B.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatePrepended)
end
it "updates the constant when a prepended module is updated" do
@@ -281,6 +283,8 @@ describe "Module#prepend" do
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstPrependedUpdated)
end
it "updates the constant when there is a base included constant and the prepended module overrides it" do
@@ -302,6 +306,8 @@ describe "Module#prepend" do
A.prepend M
A.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstIncludedPrependedOverride)
end
it "updates the constant when there is a base included constant and the prepended module is later updated" do
@@ -325,6 +331,8 @@ describe "Module#prepend" do
M.const_set(:FOO, 'm')
A.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstIncludedPrependedLaterUpdated)
end
it "updates the constant when a module prepended after a constant is later updated" do
@@ -348,6 +356,8 @@ describe "Module#prepend" do
M.const_set(:FOO, 'm')
B.foo.should == 'm'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatedPrependedAfterLaterUpdated)
end
it "updates the constant when a module is prepended after another and the constant is defined later on that module" do
@@ -372,6 +382,8 @@ describe "Module#prepend" do
N.const_set(:FOO, 'n')
A.foo.should == 'n'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatedPrependedAfterConstDefined)
end
it "updates the constant when a module is included in a prepended module and the constant is defined later" do
@@ -399,6 +411,8 @@ describe "Module#prepend" do
N.const_set(:FOO, 'n')
A.foo.should == 'n'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatedIncludedInPrependedConstDefinedLater)
end
it "updates the constant when a new module with an included module is prepended" do
@@ -425,6 +439,8 @@ describe "Module#prepend" do
B.prepend M
B.foo.should == 'n'
end
+ ensure
+ ModuleSpecs.send(:remove_const, :ConstUpdatedNewModuleIncludedPrepended)
end
it "raises a TypeError when the argument is not a Module" do
@@ -432,7 +448,11 @@ describe "Module#prepend" do
end
it "does not raise a TypeError when the argument is an instance of a subclass of Module" do
- -> { ModuleSpecs::SubclassSpec.prepend(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
+ class ModuleSpecs::SubclassSpec::AClass
+ end
+ -> { ModuleSpecs::SubclassSpec::AClass.prepend(ModuleSpecs::Subclass.new) }.should_not raise_error(TypeError)
+ ensure
+ ModuleSpecs::SubclassSpec.send(:remove_const, :AClass)
end
ruby_version_is ""..."3.2" do
@@ -787,34 +807,17 @@ describe "Module#prepend" do
# https://bugs.ruby-lang.org/issues/17423
describe "when module already exists in ancestor chain" do
- ruby_version_is ""..."3.1" do
- it "does not modify the ancestor chain" do
- m = Module.new do; end
- a = Module.new do; end
- b = Class.new do; end
-
- b.include(a)
- a.prepend(m)
- b.ancestors.take(4).should == [b, m, a, Object]
+ it "modifies the ancestor chain" do
+ m = Module.new do; end
+ a = Module.new do; end
+ b = Class.new do; end
- b.prepend(m)
- b.ancestors.take(4).should == [b, m, a, Object]
- end
- end
+ b.include(a)
+ a.prepend(m)
+ b.ancestors.take(4).should == [b, m, a, Object]
- ruby_version_is "3.1" do
- it "modifies the ancestor chain" do
- m = Module.new do; end
- a = Module.new do; end
- b = Class.new do; end
-
- b.include(a)
- a.prepend(m)
- b.ancestors.take(4).should == [b, m, a, Object]
-
- b.prepend(m)
- b.ancestors.take(5).should == [m, b, m, a, Object]
- end
+ b.prepend(m)
+ b.ancestors.take(5).should == [m, b, m, a, Object]
end
end
diff --git a/spec/ruby/core/module/private_spec.rb b/spec/ruby/core/module/private_spec.rb
index ead806637c..9e1a297eea 100644
--- a/spec/ruby/core/module/private_spec.rb
+++ b/spec/ruby/core/module/private_spec.rb
@@ -38,25 +38,13 @@ describe "Module#private" do
:module_specs_public_method_on_object_for_kernel_private)
end
- ruby_version_is ""..."3.1" do
- it "returns self" do
- (class << Object.new; self; end).class_eval do
- def foo; end
- private(:foo).should equal(self)
- private.should equal(self)
- end
- end
- end
-
- ruby_version_is "3.1" do
- it "returns argument or arguments if given" do
- (class << Object.new; self; end).class_eval do
- def foo; end
- private(:foo).should equal(:foo)
- private([:foo, :foo]).should == [:foo, :foo]
- private(:foo, :foo).should == [:foo, :foo]
- private.should equal(nil)
- end
+ it "returns argument or arguments if given" do
+ (class << Object.new; self; end).class_eval do
+ def foo; end
+ private(:foo).should equal(:foo)
+ private([:foo, :foo]).should == [:foo, :foo]
+ private(:foo, :foo).should == [:foo, :foo]
+ private.should equal(nil)
end
end
diff --git a/spec/ruby/core/module/protected_spec.rb b/spec/ruby/core/module/protected_spec.rb
index 058d49d751..9e37223e18 100644
--- a/spec/ruby/core/module/protected_spec.rb
+++ b/spec/ruby/core/module/protected_spec.rb
@@ -39,25 +39,13 @@ describe "Module#protected" do
:module_specs_public_method_on_object_for_kernel_protected)
end
- ruby_version_is ""..."3.1" do
- it "returns self" do
- (class << Object.new; self; end).class_eval do
- def foo; end
- protected(:foo).should equal(self)
- protected.should equal(self)
- end
- end
- end
-
- ruby_version_is "3.1" do
- it "returns argument or arguments if given" do
- (class << Object.new; self; end).class_eval do
- def foo; end
- protected(:foo).should equal(:foo)
- protected([:foo, :foo]).should == [:foo, :foo]
- protected(:foo, :foo).should == [:foo, :foo]
- protected.should equal(nil)
- end
+ it "returns argument or arguments if given" do
+ (class << Object.new; self; end).class_eval do
+ def foo; end
+ protected(:foo).should equal(:foo)
+ protected([:foo, :foo]).should == [:foo, :foo]
+ protected(:foo, :foo).should == [:foo, :foo]
+ protected.should equal(nil)
end
end
diff --git a/spec/ruby/core/module/public_spec.rb b/spec/ruby/core/module/public_spec.rb
index e3b183f228..ce31eb5d0e 100644
--- a/spec/ruby/core/module/public_spec.rb
+++ b/spec/ruby/core/module/public_spec.rb
@@ -27,25 +27,13 @@ describe "Module#public" do
:module_specs_private_method_on_object_for_kernel_public)
end
- ruby_version_is ""..."3.1" do
- it "returns self" do
- (class << Object.new; self; end).class_eval do
- def foo; end
- public(:foo).should equal(self)
- public.should equal(self)
- end
- end
- end
-
- ruby_version_is "3.1" do
- it "returns argument or arguments if given" do
- (class << Object.new; self; end).class_eval do
- def foo; end
- public(:foo).should equal(:foo)
- public([:foo, :foo]).should == [:foo, :foo]
- public(:foo, :foo).should == [:foo, :foo]
- public.should equal(nil)
- end
+ it "returns argument or arguments if given" do
+ (class << Object.new; self; end).class_eval do
+ def foo; end
+ public(:foo).should equal(:foo)
+ public([:foo, :foo]).should == [:foo, :foo]
+ public(:foo, :foo).should == [:foo, :foo]
+ public.should equal(nil)
end
end
diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb
index 8b9ea5eca8..7a5d607c4f 100644
--- a/spec/ruby/core/module/refine_spec.rb
+++ b/spec/ruby/core/module/refine_spec.rb
@@ -272,7 +272,7 @@ describe "Module#refine" do
it "looks in later included modules of the refined module first" do
a = Module.new do
def foo
- "foo from A"
+ "foo from A"
end
end
@@ -300,67 +300,6 @@ describe "Module#refine" do
result.should == "foo from IncludeMeLater"
end
- ruby_version_is ""..."3.1" do
- it "looks in prepended modules from the refinement first" do
- refined_class = ModuleSpecs.build_refined_class
-
- refinement = Module.new do
- refine refined_class do
- include ModuleSpecs::IncludedModule
- prepend ModuleSpecs::PrependedModule
-
- def foo; "foo from refinement"; end
- end
- end
-
- result = nil
- Module.new do
- using refinement
- result = refined_class.new.foo
- end
-
- result.should == "foo from prepended module"
- end
-
- it "looks in refinement then" do
- refined_class = ModuleSpecs.build_refined_class
-
- refinement = Module.new do
- refine(refined_class) do
- include ModuleSpecs::IncludedModule
-
- def foo; "foo from refinement"; end
- end
- end
-
- result = nil
- Module.new do
- using refinement
- result = refined_class.new.foo
- end
-
- result.should == "foo from refinement"
- end
-
- it "looks in included modules from the refinement then" do
- refined_class = ModuleSpecs.build_refined_class
-
- refinement = Module.new do
- refine refined_class do
- include ModuleSpecs::IncludedModule
- end
- end
-
- result = nil
- Module.new do
- using refinement
- result = refined_class.new.foo
- end
-
- result.should == "foo from included module"
- end
- end
-
it "looks in the class then" do
refined_class = ModuleSpecs.build_refined_class
@@ -606,30 +545,6 @@ describe "Module#refine" do
end
context "when super is called in a refinement" do
- ruby_version_is ""..."3.1" do
- it "looks in the included to refinery module" do
- refined_class = ModuleSpecs.build_refined_class
-
- refinement = Module.new do
- refine refined_class do
- include ModuleSpecs::IncludedModule
-
- def foo
- super
- end
- end
- end
-
- result = nil
- Module.new do
- using refinement
- result = refined_class.new.foo
- end
-
- result.should == "foo from included module"
- end
- end
-
it "looks in the refined class" do
refined_class = ModuleSpecs.build_refined_class
@@ -650,59 +565,6 @@ describe "Module#refine" do
result.should == "foo"
end
- ruby_version_is ""..."3.1" do
- it "looks in the refined class from included module" do
- refined_class = ModuleSpecs.build_refined_class(for_super: true)
-
- a = Module.new do
- def foo
- [:A] + super
- end
- end
-
- refinement = Module.new do
- refine refined_class do
- include a
- end
- end
-
- result = nil
- Module.new do
- using refinement
-
- result = refined_class.new.foo
- end
-
- result.should == [:A, :C]
- end
-
- it "looks in the refined ancestors from included module" do
- refined_class = ModuleSpecs.build_refined_class(for_super: true)
- subclass = Class.new(refined_class)
-
- a = Module.new do
- def foo
- [:A] + super
- end
- end
-
- refinement = Module.new do
- refine refined_class do
- include a
- end
- end
-
- result = nil
- Module.new do
- using refinement
-
- result = subclass.new.foo
- end
-
- result.should == [:A, :C]
- end
- end
-
# super in a method of a refinement invokes the method in the refined
# class even if there is another refinement which has been activated
# in the same context.
@@ -763,179 +625,6 @@ describe "Module#refine" do
}.should raise_error(NoMethodError)
end
end
-
- ruby_version_is ""..."3.1" do
- it "does't have access to active refinements for C from included module" do
- refined_class = ModuleSpecs.build_refined_class
-
- a = Module.new do
- def foo
- super + bar
- end
- end
-
- refinement = Module.new do
- refine refined_class do
- include a
-
- def bar
- "bar is not seen from A methods"
- end
- end
- end
-
- Module.new do
- using refinement
- -> {
- refined_class.new.foo
- }.should raise_error(NameError) { |e| e.name.should == :bar }
- end
- end
-
- it "does't have access to other active refinements from included module" do
- refined_class = ModuleSpecs.build_refined_class
-
- refinement_integer = Module.new do
- refine Integer do
- def bar
- "bar is not seen from A methods"
- end
- end
- end
-
- a = Module.new do
- def foo
- super + 1.bar
- end
- end
-
- refinement = Module.new do
- refine refined_class do
- include a
- end
- end
-
- Module.new do
- using refinement
- using refinement_integer
- -> {
- refined_class.new.foo
- }.should raise_error(NameError) { |e| e.name.should == :bar }
- end
- end
-
- # https://bugs.ruby-lang.org/issues/16977
- it "looks in the another active refinement if super called from included modules" do
- refined_class = ModuleSpecs.build_refined_class(for_super: true)
-
- a = Module.new do
- def foo
- [:A] + super
- end
- end
-
- b = Module.new do
- def foo
- [:B] + super
- end
- end
-
- refinement_a = Module.new do
- refine refined_class do
- include a
- end
- end
-
- refinement_b = Module.new do
- refine refined_class do
- include b
- end
- end
-
- result = nil
- Module.new do
- using refinement_a
- using refinement_b
- result = refined_class.new.foo
- end
-
- result.should == [:B, :A, :C]
- end
-
- it "looks in the current active refinement from included modules" do
- refined_class = ModuleSpecs.build_refined_class(for_super: true)
-
- a = Module.new do
- def foo
- [:A] + super
- end
- end
-
- b = Module.new do
- def foo
- [:B] + super
- end
- end
-
- refinement = Module.new do
- refine refined_class do
- def foo
- [:LAST] + super
- end
- end
- end
-
- refinement_a_b = Module.new do
- refine refined_class do
- include a
- include b
- end
- end
-
- result = nil
- Module.new do
- using refinement
- using refinement_a_b
- result = refined_class.new.foo
- end
-
- result.should == [:B, :A, :LAST, :C]
- end
-
- it "looks in the lexical scope refinements before other active refinements" do
- refined_class = ModuleSpecs.build_refined_class(for_super: true)
-
- refinement_local = Module.new do
- refine refined_class do
- def foo
- [:LOCAL] + super
- end
- end
- end
-
- a = Module.new do
- using refinement_local
-
- def foo
- [:A] + super
- end
- end
-
- refinement = Module.new do
- refine refined_class do
- include a
- end
- end
-
- result = nil
- Module.new do
- using refinement
- result = refined_class.new.foo
- end
-
- result.should == [:A, :LOCAL, :C]
- end
- end
end
it 'and alias aliases a method within a refinement module, but not outside it' do
diff --git a/spec/ruby/core/module/remove_const_spec.rb b/spec/ruby/core/module/remove_const_spec.rb
index 0ac23f05a5..35a9d65105 100644
--- a/spec/ruby/core/module/remove_const_spec.rb
+++ b/spec/ruby/core/module/remove_const_spec.rb
@@ -101,5 +101,7 @@ describe "Module#remove_const" do
A.send(:remove_const,:FOO)
A.foo.should == 'm'
end
+ ensure
+ ConstantSpecs.send(:remove_const, :RemovedConstantUpdate)
end
end
diff --git a/spec/ruby/core/module/to_s_spec.rb b/spec/ruby/core/module/to_s_spec.rb
index 6b1a615ef9..83c0ae0825 100644
--- a/spec/ruby/core/module/to_s_spec.rb
+++ b/spec/ruby/core/module/to_s_spec.rb
@@ -51,6 +51,8 @@ describe "Module#to_s" do
ModuleSpecs::RefinementInspect::R.name.should == 'ModuleSpecs::RefinementInspect::R'
ModuleSpecs::RefinementInspect::R.to_s.should == '#<refinement:String@ModuleSpecs::RefinementInspect>'
+ ensure
+ ModuleSpecs.send(:remove_const, :RefinementInspect)
end
it 'does not call #inspect or #to_s for singleton classes' do
diff --git a/spec/ruby/core/numeric/shared/imag.rb b/spec/ruby/core/numeric/shared/imag.rb
index ac2da40a3b..4f117e243a 100644
--- a/spec/ruby/core/numeric/shared/imag.rb
+++ b/spec/ruby/core/numeric/shared/imag.rb
@@ -19,8 +19,8 @@ describe :numeric_imag, shared: true do
end
it "raises an ArgumentError if given any arguments" do
- @numbers.each do |number|
- -> { number.send(@method, number) }.should raise_error(ArgumentError)
- end
+ @numbers.each do |number|
+ -> { number.send(@method, number) }.should raise_error(ArgumentError)
+ end
end
end
diff --git a/spec/ruby/core/numeric/shared/rect.rb b/spec/ruby/core/numeric/shared/rect.rb
index 9cde19a398..120a69b1c4 100644
--- a/spec/ruby/core/numeric/shared/rect.rb
+++ b/spec/ruby/core/numeric/shared/rect.rb
@@ -25,24 +25,24 @@ describe :numeric_rect, shared: true do
end
it "returns self as the first element" do
- @numbers.each do |number|
- if Float === number and number.nan?
- number.send(@method).first.nan?.should be_true
- else
- number.send(@method).first.should == number
- end
- end
+ @numbers.each do |number|
+ if Float === number and number.nan?
+ number.send(@method).first.nan?.should be_true
+ else
+ number.send(@method).first.should == number
+ end
+ end
end
it "returns 0 as the last element" do
- @numbers.each do |number|
- number.send(@method).last.should == 0
- end
+ @numbers.each do |number|
+ number.send(@method).last.should == 0
+ end
end
it "raises an ArgumentError if given any arguments" do
- @numbers.each do |number|
- -> { number.send(@method, number) }.should raise_error(ArgumentError)
- end
+ @numbers.each do |number|
+ -> { number.send(@method, number) }.should raise_error(ArgumentError)
+ end
end
end
diff --git a/spec/ruby/core/objectspace/define_finalizer_spec.rb b/spec/ruby/core/objectspace/define_finalizer_spec.rb
index 329f8e1f30..0f4b54c345 100644
--- a/spec/ruby/core/objectspace/define_finalizer_spec.rb
+++ b/spec/ruby/core/objectspace/define_finalizer_spec.rb
@@ -193,25 +193,23 @@ describe "ObjectSpace.define_finalizer" do
ret[1].should.equal?(p)
end
- ruby_version_is "3.1" do
- describe "when $VERBOSE is not nil" do
- it "warns if an exception is raised in finalizer" do
- code = <<-RUBY
- ObjectSpace.define_finalizer(Object.new) { raise "finalizing" }
- RUBY
-
- ruby_exe(code, args: "2>&1").should include("warning: Exception in finalizer", "finalizing")
- end
+ describe "when $VERBOSE is not nil" do
+ it "warns if an exception is raised in finalizer" do
+ code = <<-RUBY
+ ObjectSpace.define_finalizer(Object.new) { raise "finalizing" }
+ RUBY
+
+ ruby_exe(code, args: "2>&1").should include("warning: Exception in finalizer", "finalizing")
end
+ end
- describe "when $VERBOSE is nil" do
- it "does not warn even if an exception is raised in finalizer" do
- code = <<-RUBY
- ObjectSpace.define_finalizer(Object.new) { raise "finalizing" }
- RUBY
+ describe "when $VERBOSE is nil" do
+ it "does not warn even if an exception is raised in finalizer" do
+ code = <<-RUBY
+ ObjectSpace.define_finalizer(Object.new) { raise "finalizing" }
+ RUBY
- ruby_exe(code, args: "2>&1", options: "-W0").should == ""
- end
+ ruby_exe(code, args: "2>&1", options: "-W0").should == ""
end
end
end
diff --git a/spec/ruby/core/objectspace/weakkeymap/clear_spec.rb b/spec/ruby/core/objectspace/weakkeymap/clear_spec.rb
new file mode 100644
index 0000000000..8050e2c307
--- /dev/null
+++ b/spec/ruby/core/objectspace/weakkeymap/clear_spec.rb
@@ -0,0 +1,27 @@
+require_relative '../../../spec_helper'
+
+ruby_version_is '3.3' do
+ describe "ObjectSpace::WeakKeyMap#clear" do
+ it "removes all the entries" do
+ m = ObjectSpace::WeakKeyMap.new
+
+ key = Object.new
+ value = Object.new
+ m[key] = value
+
+ key2 = Object.new
+ value2 = Object.new
+ m[key2] = value2
+
+ m.clear
+
+ m.key?(key).should == false
+ m.key?(key2).should == false
+ end
+
+ it "returns self" do
+ m = ObjectSpace::WeakKeyMap.new
+ m.clear.should.equal?(m)
+ end
+ end
+end
diff --git a/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb b/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb
index 6e534b8ea8..3cd61355d6 100644
--- a/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb
+++ b/spec/ruby/core/objectspace/weakkeymap/delete_spec.rb
@@ -33,8 +33,19 @@ ruby_version_is '3.3' do
end
it "returns nil if the key is not found when no block is given" do
- m = ObjectSpace::WeakMap.new
+ m = ObjectSpace::WeakKeyMap.new
m.delete(Object.new).should == nil
end
+
+ it "returns nil when a key cannot be garbage collected" do
+ map = ObjectSpace::WeakKeyMap.new
+
+ map.delete(1).should == nil
+ map.delete(1.0).should == nil
+ map.delete(:a).should == nil
+ map.delete(true).should == nil
+ map.delete(false).should == nil
+ map.delete(nil).should == nil
+ end
end
end
diff --git a/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb b/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb
index 862480cd02..51368e8d3b 100644
--- a/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb
+++ b/spec/ruby/core/objectspace/weakkeymap/element_reference_spec.rb
@@ -1,4 +1,5 @@
require_relative '../../../spec_helper'
+require_relative 'fixtures/classes'
ruby_version_is "3.3" do
describe "ObjectSpace::WeakKeyMap#[]" do
@@ -15,12 +16,92 @@ ruby_version_is "3.3" do
map[key2].should == ref2
end
- it "matches using equality semantics" do
+ it "compares keys with #eql? semantics" do
+ map = ObjectSpace::WeakKeyMap.new
+ key = [1.0]
+ map[key] = "x"
+ map[[1]].should == nil
+ map[[1.0]].should == "x"
+ key.should == [1.0] # keep the key alive until here to keep the map entry
+
+ map = ObjectSpace::WeakKeyMap.new
+ key = [1]
+ map[key] = "x"
+ map[[1.0]].should == nil
+ map[[1]].should == "x"
+ key.should == [1] # keep the key alive until here to keep the map entry
+
map = ObjectSpace::WeakKeyMap.new
key1, key2 = %w[a a].map(&:upcase)
ref = "x"
map[key1] = ref
map[key2].should == ref
end
+
+ it "compares key via #hash first" do
+ x = mock('0')
+ x.should_receive(:hash).and_return(0)
+
+ map = ObjectSpace::WeakKeyMap.new
+ key = 'foo'
+ map[key] = :bar
+ map[x].should == nil
+ end
+
+ it "does not compare keys with different #hash values via #eql?" do
+ x = mock('x')
+ x.should_not_receive(:eql?)
+ x.stub!(:hash).and_return(0)
+
+ y = mock('y')
+ y.should_not_receive(:eql?)
+ y.stub!(:hash).and_return(1)
+
+ map = ObjectSpace::WeakKeyMap.new
+ map[y] = 1
+ map[x].should == nil
+ end
+
+ it "compares keys with the same #hash value via #eql?" do
+ x = mock('x')
+ x.should_receive(:eql?).and_return(true)
+ x.stub!(:hash).and_return(42)
+
+ y = mock('y')
+ y.should_not_receive(:eql?)
+ y.stub!(:hash).and_return(42)
+
+ map = ObjectSpace::WeakKeyMap.new
+ map[y] = 1
+ map[x].should == 1
+ end
+
+ it "finds a value via an identical key even when its #eql? isn't reflexive" do
+ x = mock('x')
+ x.should_receive(:hash).at_least(1).and_return(42)
+ x.stub!(:eql?).and_return(false) # Stubbed for clarity and latitude in implementation; not actually sent by MRI.
+
+ map = ObjectSpace::WeakKeyMap.new
+ map[x] = :x
+ map[x].should == :x
+ end
+
+ it "supports keys with private #hash method" do
+ key = WeakKeyMapSpecs::KeyWithPrivateHash.new
+ map = ObjectSpace::WeakKeyMap.new
+ map[key] = 42
+ map[key].should == 42
+ end
+
+ it "returns nil and does not raise error when a key cannot be garbage collected" do
+ map = ObjectSpace::WeakKeyMap.new
+
+ map[1].should == nil
+ map[1.0].should == nil
+ map[:a].should == nil
+ map[true].should == nil
+ map[false].should == nil
+ map[nil].should == nil
+ end
end
end
diff --git a/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb b/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb
index c427e01ca5..8db8d780c7 100644
--- a/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb
+++ b/spec/ruby/core/objectspace/weakkeymap/element_set_spec.rb
@@ -8,10 +8,6 @@ ruby_version_is "3.3" do
map[key].should == value
end
- def should_not_accept(map, key, value)
- -> { map[key] = value }.should raise_error(ArgumentError)
- end
-
it "is correct" do
map = ObjectSpace::WeakKeyMap.new
key1, key2 = %w[a b].map(&:upcase)
@@ -40,32 +36,47 @@ ruby_version_is "3.3" do
should_accept(map, y, x)
end
- it "rejects symbols as keys" do
+ it "does not duplicate and freeze String keys (like Hash#[]= does)" do
map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, :foo, true)
- should_not_accept(map, rand.to_s.to_sym, true)
- end
+ key = +"a"
+ map[key] = 1
- it "rejects integers as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, 42, true)
- should_not_accept(map, 2 ** 68, true)
- end
+ map.getkey("a").should.equal? key
+ map.getkey("a").should_not.frozen?
- it "rejects floats as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, 4.2, true)
+ key.should == "a" # keep the key alive until here to keep the map entry
end
- it "rejects booleans as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, true, true)
- should_not_accept(map, false, true)
- end
+ context "a key cannot be garbage collected" do
+ it "raises ArgumentError when Integer is used as a key" do
+ map = ObjectSpace::WeakKeyMap.new
+ -> { map[1] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
+ end
- it "rejects nil as keys" do
- map = ObjectSpace::WeakKeyMap.new
- should_not_accept(map, nil, true)
+ it "raises ArgumentError when Float is used as a key" do
+ map = ObjectSpace::WeakKeyMap.new
+ -> { map[1.0] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
+ end
+
+ it "raises ArgumentError when Symbol is used as a key" do
+ map = ObjectSpace::WeakKeyMap.new
+ -> { map[:a] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
+ end
+
+ it "raises ArgumentError when true is used as a key" do
+ map = ObjectSpace::WeakKeyMap.new
+ -> { map[true] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
+ end
+
+ it "raises ArgumentError when false is used as a key" do
+ map = ObjectSpace::WeakKeyMap.new
+ -> { map[false] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
+ end
+
+ it "raises ArgumentError when nil is used as a key" do
+ map = ObjectSpace::WeakKeyMap.new
+ -> { map[nil] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
+ end
end
end
end
diff --git a/spec/ruby/core/objectspace/weakkeymap/fixtures/classes.rb b/spec/ruby/core/objectspace/weakkeymap/fixtures/classes.rb
new file mode 100644
index 0000000000..0fd04551b5
--- /dev/null
+++ b/spec/ruby/core/objectspace/weakkeymap/fixtures/classes.rb
@@ -0,0 +1,5 @@
+module WeakKeyMapSpecs
+ class KeyWithPrivateHash
+ private :hash
+ end
+end
diff --git a/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb b/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb
index 3af0186f27..8a2dbf809d 100644
--- a/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb
+++ b/spec/ruby/core/objectspace/weakkeymap/getkey_spec.rb
@@ -9,6 +9,20 @@ ruby_version_is "3.3" do
map[key1] = true
map.getkey(key2).should equal(key1)
map.getkey("X").should == nil
+
+ key1.should == "A" # keep the key alive until here to keep the map entry
+ key2.should == "A" # keep the key alive until here to keep the map entry
+ end
+
+ it "returns nil when a key cannot be garbage collected" do
+ map = ObjectSpace::WeakKeyMap.new
+
+ map.getkey(1).should == nil
+ map.getkey(1.0).should == nil
+ map.getkey(:a).should == nil
+ map.getkey(true).should == nil
+ map.getkey(false).should == nil
+ map.getkey(nil).should == nil
end
end
end
diff --git a/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb b/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb
index 557fbc8733..319f050970 100644
--- a/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb
+++ b/spec/ruby/core/objectspace/weakkeymap/inspect_spec.rb
@@ -12,6 +12,10 @@ ruby_version_is "3.3" do
map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=2>\z/
map[key3] = 3
map.inspect.should =~ /\A\#<ObjectSpace::WeakKeyMap:0x\h+ size=2>\z/
+
+ key1.should == "foo" # keep the key alive until here to keep the map entry
+ key2.should == "bar" # keep the key alive until here to keep the map entry
+ key3.should == "bar" # keep the key alive until here to keep the map entry
end
end
end
diff --git a/spec/ruby/core/objectspace/weakkeymap/key_spec.rb b/spec/ruby/core/objectspace/weakkeymap/key_spec.rb
index 2af9c2b8e7..a9a2e12432 100644
--- a/spec/ruby/core/objectspace/weakkeymap/key_spec.rb
+++ b/spec/ruby/core/objectspace/weakkeymap/key_spec.rb
@@ -29,5 +29,16 @@ ruby_version_is "3.3" do
map[key] = nil
map.key?(key).should == true
end
+
+ it "returns false when a key cannot be garbage collected" do
+ map = ObjectSpace::WeakKeyMap.new
+
+ map.key?(1).should == false
+ map.key?(1.0).should == false
+ map.key?(:a).should == false
+ map.key?(true).should == false
+ map.key?(false).should == false
+ map.key?(nil).should == false
+ end
end
end
diff --git a/spec/ruby/core/proc/parameters_spec.rb b/spec/ruby/core/proc/parameters_spec.rb
index 972596d2ea..7a2723487d 100644
--- a/spec/ruby/core/proc/parameters_spec.rb
+++ b/spec/ruby/core/proc/parameters_spec.rb
@@ -64,7 +64,7 @@ describe "Proc#parameters" do
end
it "regards keyword parameters in lambdas as required" do
- eval("lambda {|x:| }").parameters.first.first.should == :keyreq
+ -> x: { }.parameters.first.first.should == :keyreq
end
it "sets the first element of each sub-Array to :rest for parameters prefixed with asterisks" do
@@ -130,10 +130,8 @@ describe "Proc#parameters" do
end
end
- ruby_version_is '3.1' do
- it "adds block arg with name & for anonymous block argument" do
- eval('-> & {}.parameters').should == [[:block, :&]]
- end
+ it "adds block arg with name & for anonymous block argument" do
+ -> & {}.parameters.should == [[:block, :&]]
end
it "does not add locals as block options with a block and splat" do
diff --git a/spec/ruby/core/process/_fork_spec.rb b/spec/ruby/core/process/_fork_spec.rb
index 6f711ad2dd..8e907f54bb 100644
--- a/spec/ruby/core/process/_fork_spec.rb
+++ b/spec/ruby/core/process/_fork_spec.rb
@@ -1,24 +1,22 @@
require_relative '../../spec_helper'
-ruby_version_is "3.1" do
- describe "Process._fork" do
- it "for #respond_to? returns the same as Process.respond_to?(:fork)" do
- Process.respond_to?(:_fork).should == Process.respond_to?(:fork)
- end
+describe "Process._fork" do
+ it "for #respond_to? returns the same as Process.respond_to?(:fork)" do
+ Process.respond_to?(:_fork).should == Process.respond_to?(:fork)
+ end
- guard_not -> { Process.respond_to?(:fork) } do
- it "raises a NotImplementedError when called" do
- -> { Process._fork }.should raise_error(NotImplementedError)
- end
+ guard_not -> { Process.respond_to?(:fork) } do
+ it "raises a NotImplementedError when called" do
+ -> { Process._fork }.should raise_error(NotImplementedError)
end
+ end
- guard -> { Process.respond_to?(:fork) } do
- it "is called by Process#fork" do
- Process.should_receive(:_fork).once.and_return(42)
+ guard -> { Process.respond_to?(:fork) } do
+ it "is called by Process#fork" do
+ Process.should_receive(:_fork).once.and_return(42)
- pid = Process.fork {}
- pid.should equal(42)
- end
+ pid = Process.fork {}
+ pid.should equal(42)
end
end
end
diff --git a/spec/ruby/core/process/gid_spec.rb b/spec/ruby/core/process/gid_spec.rb
index 07221da420..ca935ed520 100644
--- a/spec/ruby/core/process/gid_spec.rb
+++ b/spec/ruby/core/process/gid_spec.rb
@@ -3,8 +3,8 @@ require_relative '../../spec_helper'
describe "Process.gid" do
platform_is_not :windows do
it "returns the correct gid for the user executing this process" do
- current_gid_according_to_unix = `id -gr`.to_i
- Process.gid.should == current_gid_according_to_unix
+ current_gid_according_to_unix = `id -gr`.to_i
+ Process.gid.should == current_gid_according_to_unix
end
end
diff --git a/spec/ruby/core/process/tms/cstime_spec.rb b/spec/ruby/core/process/tms/cstime_spec.rb
new file mode 100644
index 0000000000..9c2d9e8632
--- /dev/null
+++ b/spec/ruby/core/process/tms/cstime_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+describe "Process::Tms#cstime" do
+ it "returns cstime attribute" do
+ cstime = Object.new
+ Process::Tms.new(nil, nil, nil, cstime).cstime.should == cstime
+ end
+end
+
+describe "Process::Tms#cstime=" do
+ it "assigns a value to the cstime attribute" do
+ cstime = Object.new
+ tms = Process::Tms.new
+ tms.cstime = cstime
+ tms.cstime.should == cstime
+ end
+end
diff --git a/spec/ruby/core/process/tms/cutime_spec.rb b/spec/ruby/core/process/tms/cutime_spec.rb
new file mode 100644
index 0000000000..0ac3ff1964
--- /dev/null
+++ b/spec/ruby/core/process/tms/cutime_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+describe "Process::Tms#cutime" do
+ it "returns cutime attribute" do
+ cutime = Object.new
+ Process::Tms.new(nil, nil, cutime, nil).cutime.should == cutime
+ end
+end
+
+describe "Process::Tms#cutime=" do
+ it "assigns a value to the cutime attribute" do
+ cutime = Object.new
+ tms = Process::Tms.new
+ tms.cutime = cutime
+ tms.cutime.should == cutime
+ end
+end
diff --git a/spec/ruby/core/process/tms/stime_spec.rb b/spec/ruby/core/process/tms/stime_spec.rb
new file mode 100644
index 0000000000..1e8371475f
--- /dev/null
+++ b/spec/ruby/core/process/tms/stime_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+describe "Process::Tms#stime" do
+ it "returns stime attribute" do
+ stime = Object.new
+ Process::Tms.new(nil, stime, nil, nil).stime.should == stime
+ end
+end
+
+describe "Process::Tms#stime=" do
+ it "assigns a value to the stime attribute" do
+ stime = Object.new
+ tms = Process::Tms.new
+ tms.stime = stime
+ tms.stime.should == stime
+ end
+end
diff --git a/spec/ruby/core/process/tms/utime_spec.rb b/spec/ruby/core/process/tms/utime_spec.rb
new file mode 100644
index 0000000000..403a31e2e6
--- /dev/null
+++ b/spec/ruby/core/process/tms/utime_spec.rb
@@ -0,0 +1,17 @@
+require_relative '../../../spec_helper'
+
+describe "Process::Tms#utime" do
+ it "returns utime attribute" do
+ utime = Object.new
+ Process::Tms.new(utime, nil, nil, nil).utime.should == utime
+ end
+end
+
+describe "Process::Tms#utime=" do
+ it "assigns a value to the ctime attribute" do
+ utime = Object.new
+ tms = Process::Tms.new
+ tms.utime = utime
+ tms.utime.should == utime
+ end
+end
diff --git a/spec/ruby/core/queue/initialize_spec.rb b/spec/ruby/core/queue/initialize_spec.rb
index c6c1ae63c5..592fbe2487 100644
--- a/spec/ruby/core/queue/initialize_spec.rb
+++ b/spec/ruby/core/queue/initialize_spec.rb
@@ -11,9 +11,21 @@ describe "Queue#initialize" do
Queue.private_instance_methods.include?(:initialize).should == true
end
- ruby_version_is '3.1' do
- it "adds all elements of the passed Enumerable to self" do
- q = Queue.new([1, 2, 3])
+ it "adds all elements of the passed Enumerable to self" do
+ q = Queue.new([1, 2, 3])
+ q.size.should == 3
+ q.should_not.empty?
+ q.pop.should == 1
+ q.pop.should == 2
+ q.pop.should == 3
+ q.should.empty?
+ end
+
+ describe "converts the given argument to an Array using #to_a" do
+ it "uses #to_a on the provided Enumerable" do
+ enumerable = MockObject.new('mock-enumerable')
+ enumerable.should_receive(:to_a).and_return([1, 2, 3])
+ q = Queue.new(enumerable)
q.size.should == 3
q.should_not.empty?
q.pop.should == 1
@@ -22,41 +34,27 @@ describe "Queue#initialize" do
q.should.empty?
end
- describe "converts the given argument to an Array using #to_a" do
- it "uses #to_a on the provided Enumerable" do
- enumerable = MockObject.new('mock-enumerable')
- enumerable.should_receive(:to_a).and_return([1, 2, 3])
- q = Queue.new(enumerable)
- q.size.should == 3
- q.should_not.empty?
- q.pop.should == 1
- q.pop.should == 2
- q.pop.should == 3
- q.should.empty?
- end
-
- it "raises a TypeError if the given argument can't be converted to an Array" do
- -> { Queue.new(42) }.should raise_error(TypeError)
- -> { Queue.new(:abc) }.should raise_error(TypeError)
- end
-
- it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to an Array" do
- enumerable = MockObject.new('mock-enumerable')
- enumerable.should_receive(:to_a).and_raise(NoMethodError)
- -> { Queue.new(enumerable) }.should raise_error(NoMethodError)
- end
+ it "raises a TypeError if the given argument can't be converted to an Array" do
+ -> { Queue.new(42) }.should raise_error(TypeError)
+ -> { Queue.new(:abc) }.should raise_error(TypeError)
end
- it "raises TypeError if the provided Enumerable does not respond to #to_a" do
+ it "raises a NoMethodError if the given argument raises a NoMethodError during type coercion to an Array" do
enumerable = MockObject.new('mock-enumerable')
- -> { Queue.new(enumerable) }.should raise_error(TypeError, "can't convert MockObject into Array")
+ enumerable.should_receive(:to_a).and_raise(NoMethodError)
+ -> { Queue.new(enumerable) }.should raise_error(NoMethodError)
end
+ end
- it "raises TypeError if #to_a does not return Array" do
- enumerable = MockObject.new('mock-enumerable')
- enumerable.should_receive(:to_a).and_return("string")
+ it "raises TypeError if the provided Enumerable does not respond to #to_a" do
+ enumerable = MockObject.new('mock-enumerable')
+ -> { Queue.new(enumerable) }.should raise_error(TypeError, "can't convert MockObject into Array")
+ end
- -> { Queue.new(enumerable) }.should raise_error(TypeError, "can't convert MockObject to Array (MockObject#to_a gives String)")
- end
+ it "raises TypeError if #to_a does not return Array" do
+ enumerable = MockObject.new('mock-enumerable')
+ enumerable.should_receive(:to_a).and_return("string")
+
+ -> { Queue.new(enumerable) }.should raise_error(TypeError, "can't convert MockObject to Array (MockObject#to_a gives String)")
end
end
diff --git a/spec/ruby/core/range/each_spec.rb b/spec/ruby/core/range/each_spec.rb
index ecae17c881..f10330d61d 100644
--- a/spec/ruby/core/range/each_spec.rb
+++ b/spec/ruby/core/range/each_spec.rb
@@ -40,21 +40,21 @@ describe "Range#each" do
it "works with endless ranges" do
a = []
- eval("(-2..)").each { |x| break if x > 2; a << x }
+ (-2..).each { |x| break if x > 2; a << x }
a.should == [-2, -1, 0, 1, 2]
a = []
- eval("(-2...)").each { |x| break if x > 2; a << x }
+ (-2...).each { |x| break if x > 2; a << x }
a.should == [-2, -1, 0, 1, 2]
end
it "works with String endless ranges" do
a = []
- eval("('A'..)").each { |x| break if x > "D"; a << x }
+ ('A'..).each { |x| break if x > "D"; a << x }
a.should == ["A", "B", "C", "D"]
a = []
- eval("('A'...)").each { |x| break if x > "D"; a << x }
+ ('A'...).each { |x| break if x > "D"; a << x }
a.should == ["A", "B", "C", "D"]
end
@@ -82,27 +82,14 @@ describe "Range#each" do
enum.to_a.should == [1, 2, 3]
end
- ruby_version_is "3.1" do
- it "supports Time objects that respond to #succ" do
- t = Time.utc(1970)
- def t.succ; self + 1 end
- t_succ = t.succ
- def t_succ.succ; self + 1; end
+ it "supports Time objects that respond to #succ" do
+ t = Time.utc(1970)
+ def t.succ; self + 1 end
+ t_succ = t.succ
+ def t_succ.succ; self + 1; end
- (t..t_succ).to_a.should == [Time.utc(1970), Time.utc(1970, nil, nil, nil, nil, 1)]
- (t...t_succ).to_a.should == [Time.utc(1970)]
- end
- end
-
- ruby_version_is ""..."3.1" do
- it "raises a TypeError if the first element is a Time object even if it responds to #succ" do
- t = Time.utc(1970)
- def t.succ; self + 1 end
- t_succ = t.succ
- def t_succ.succ; self + 1; end
-
- -> { (t..t_succ).each { |i| i } }.should raise_error(TypeError)
- end
+ (t..t_succ).to_a.should == [Time.utc(1970), Time.utc(1970, nil, nil, nil, nil, 1)]
+ (t...t_succ).to_a.should == [Time.utc(1970)]
end
it "passes each Symbol element by using #succ" do
diff --git a/spec/ruby/core/range/shared/cover_and_include.rb b/spec/ruby/core/range/shared/cover_and_include.rb
index f36a2cef8b..cd2b3621bb 100644
--- a/spec/ruby/core/range/shared/cover_and_include.rb
+++ b/spec/ruby/core/range/shared/cover_and_include.rb
@@ -20,8 +20,8 @@ describe :range_cover_and_include, shared: true do
end
it "returns true if other is an element of self for endless ranges" do
- eval("(1..)").send(@method, 2.4).should == true
- eval("(0.5...)").send(@method, 2.4).should == true
+ (1..).send(@method, 2.4).should == true
+ (0.5...).send(@method, 2.4).should == true
end
it "returns true if other is an element of self for beginless ranges" do
@@ -29,6 +29,17 @@ describe :range_cover_and_include, shared: true do
(...10.5).send(@method, 2.4).should == true
end
+ it "returns false if values are not comparable" do
+ (1..10).send(@method, nil).should == false
+ (1...10).send(@method, nil).should == false
+
+ (..10).send(@method, nil).should == false
+ (...10).send(@method, nil).should == false
+
+ (1..).send(@method, nil).should == false
+ (1...).send(@method, nil).should == false
+ end
+
it "compares values using <=>" do
rng = (1..5)
m = mock("int")
diff --git a/spec/ruby/core/range/step_spec.rb b/spec/ruby/core/range/step_spec.rb
index 31cfd400cc..0d0caf746d 100644
--- a/spec/ruby/core/range/step_spec.rb
+++ b/spec/ruby/core/range/step_spec.rb
@@ -322,13 +322,11 @@ describe "Range#step" do
ScratchPad.recorded.should eql([1.0, 2.8, 4.6])
end
- ruby_version_is '3.1' do
- it "correctly handles values near the upper limit" do # https://bugs.ruby-lang.org/issues/16612
- (1.0...55.6).step(18.2) { |x| ScratchPad << x }
- ScratchPad.recorded.should eql([1.0, 19.2, 37.4, 55.599999999999994])
+ it "correctly handles values near the upper limit" do # https://bugs.ruby-lang.org/issues/16612
+ (1.0...55.6).step(18.2) { |x| ScratchPad << x }
+ ScratchPad.recorded.should eql([1.0, 19.2, 37.4, 55.599999999999994])
- (1.0...55.6).step(18.2).size.should == 4
- end
+ (1.0...55.6).step(18.2).size.should == 4
end
it "handles infinite values at either end" do
@@ -408,108 +406,108 @@ describe "Range#step" do
describe "with an endless range" do
describe "and Integer values" do
it "yield Integer values incremented by 1 when not passed a step" do
- eval("(-2..)").step { |x| break if x > 2; ScratchPad << x }
+ (-2..).step { |x| break if x > 2; ScratchPad << x }
ScratchPad.recorded.should eql([-2, -1, 0, 1, 2])
ScratchPad.record []
- eval("(-2...)").step { |x| break if x > 2; ScratchPad << x }
+ (-2...).step { |x| break if x > 2; ScratchPad << x }
ScratchPad.recorded.should eql([-2, -1, 0, 1, 2])
end
it "yields Integer values incremented by an Integer step" do
- eval("(-5..)").step(2) { |x| break if x > 3; ScratchPad << x }
+ (-5..).step(2) { |x| break if x > 3; ScratchPad << x }
ScratchPad.recorded.should eql([-5, -3, -1, 1, 3])
ScratchPad.record []
- eval("(-5...)").step(2) { |x| break if x > 3; ScratchPad << x }
+ (-5...).step(2) { |x| break if x > 3; ScratchPad << x }
ScratchPad.recorded.should eql([-5, -3, -1, 1, 3])
end
it "yields Float values incremented by a Float step" do
- eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x }
+ (-2..).step(1.5) { |x| break if x > 1.0; ScratchPad << x }
ScratchPad.recorded.should eql([-2.0, -0.5, 1.0])
ScratchPad.record []
- eval("(-2..)").step(1.5) { |x| break if x > 1.0; ScratchPad << x }
+ (-2..).step(1.5) { |x| break if x > 1.0; ScratchPad << x }
ScratchPad.recorded.should eql([-2.0, -0.5, 1.0])
end
end
describe "and Float values" do
it "yields Float values incremented by 1 and less than end when not passed a step" do
- eval("(-2.0..)").step { |x| break if x > 1.5; ScratchPad << x }
+ (-2.0..).step { |x| break if x > 1.5; ScratchPad << x }
ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0])
ScratchPad.record []
- eval("(-2.0...)").step { |x| break if x > 1.5; ScratchPad << x }
+ (-2.0...).step { |x| break if x > 1.5; ScratchPad << x }
ScratchPad.recorded.should eql([-2.0, -1.0, 0.0, 1.0])
end
it "yields Float values incremented by an Integer step" do
- eval("(-5.0..)").step(2) { |x| break if x > 3.5; ScratchPad << x }
+ (-5.0..).step(2) { |x| break if x > 3.5; ScratchPad << x }
ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0])
ScratchPad.record []
- eval("(-5.0...)").step(2) { |x| break if x > 3.5; ScratchPad << x }
+ (-5.0...).step(2) { |x| break if x > 3.5; ScratchPad << x }
ScratchPad.recorded.should eql([-5.0, -3.0, -1.0, 1.0, 3.0])
end
it "yields Float values incremented by a Float step" do
- eval("(-1.0..)").step(0.5) { |x| break if x > 0.6; ScratchPad << x }
+ (-1.0..).step(0.5) { |x| break if x > 0.6; ScratchPad << x }
ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5])
ScratchPad.record []
- eval("(-1.0...)").step(0.5) { |x| break if x > 0.6; ScratchPad << x }
+ (-1.0...).step(0.5) { |x| break if x > 0.6; ScratchPad << x }
ScratchPad.recorded.should eql([-1.0, -0.5, 0.0, 0.5])
end
it "handles infinite values at the start" do
- eval("(-Float::INFINITY..)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
+ (-Float::INFINITY..).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY])
ScratchPad.record []
- eval("(-Float::INFINITY...)").step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
+ (-Float::INFINITY...).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
ScratchPad.recorded.should eql([-Float::INFINITY, -Float::INFINITY, -Float::INFINITY])
end
end
describe "and String values" do
it "yields String values incremented by #succ and less than or equal to end when not passed a step" do
- eval("('A'..)").step { |x| break if x > "D"; ScratchPad << x }
+ ('A'..).step { |x| break if x > "D"; ScratchPad << x }
ScratchPad.recorded.should == ["A", "B", "C", "D"]
ScratchPad.record []
- eval("('A'...)").step { |x| break if x > "D"; ScratchPad << x }
+ ('A'...).step { |x| break if x > "D"; ScratchPad << x }
ScratchPad.recorded.should == ["A", "B", "C", "D"]
end
it "yields String values incremented by #succ called Integer step times" do
- eval("('A'..)").step(2) { |x| break if x > "F"; ScratchPad << x }
+ ('A'..).step(2) { |x| break if x > "F"; ScratchPad << x }
ScratchPad.recorded.should == ["A", "C", "E"]
ScratchPad.record []
- eval("('A'...)").step(2) { |x| break if x > "F"; ScratchPad << x }
+ ('A'...).step(2) { |x| break if x > "F"; ScratchPad << x }
ScratchPad.recorded.should == ["A", "C", "E"]
end
it "raises a TypeError when passed a Float step" do
- -> { eval("('A'..)").step(2.0) { } }.should raise_error(TypeError)
- -> { eval("('A'...)").step(2.0) { } }.should raise_error(TypeError)
+ -> { ('A'..).step(2.0) { } }.should raise_error(TypeError)
+ -> { ('A'...).step(2.0) { } }.should raise_error(TypeError)
end
ruby_version_is "3.4" do
it "yields String values adjusted by step" do
- eval("('A'..)").step("A") { |x| break if x > "AAA"; ScratchPad << x }
+ ('A'..).step("A") { |x| break if x > "AAA"; ScratchPad << x }
ScratchPad.recorded.should == ["A", "AA", "AAA"]
ScratchPad.record []
- eval("('A'...)").step("A") { |x| break if x > "AAA"; ScratchPad << x }
+ ('A'...).step("A") { |x| break if x > "AAA"; ScratchPad << x }
ScratchPad.recorded.should == ["A", "AA", "AAA"]
end
it "raises a TypeError when passed an incompatible type step" do
- -> { eval("('A'..)").step([]) { } }.should raise_error(TypeError)
- -> { eval("('A'...)").step([]) { } }.should raise_error(TypeError)
+ -> { ('A'..).step([]) { } }.should raise_error(TypeError)
+ -> { ('A'...).step([]) { } }.should raise_error(TypeError)
end
end
end
diff --git a/spec/ruby/core/refinement/import_methods_spec.rb b/spec/ruby/core/refinement/import_methods_spec.rb
index 614c54dff8..13c0b1004c 100644
--- a/spec/ruby/core/refinement/import_methods_spec.rb
+++ b/spec/ruby/core/refinement/import_methods_spec.rb
@@ -2,137 +2,76 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "Refinement#import_methods" do
- ruby_version_is "3.1" do
- context "when methods are defined in Ruby code" do
- it "imports methods" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils
- "foo".indent(3).should == " foo"
- end
+ context "when methods are defined in Ruby code" do
+ it "imports methods" do
+ str_utils = Module.new do
+ def indent(level)
+ " " * level + self
end
end
- it "throws an exception when argument is not a module" do
- Module.new do
- refine String do
- -> {
- import_methods Integer
- }.should raise_error(TypeError, "wrong argument type Class (expected Module)")
- end
+ Module.new do
+ refine String do
+ import_methods str_utils
+ "foo".indent(3).should == " foo"
end
end
+ end
- it "imports methods from multiple modules" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- str_utils_fancy = Module.new do
- def indent_star(level)
- "*" * level + self
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils, str_utils_fancy
- "foo".indent(3).should == " foo"
- "foo".indent_star(3).should == "***foo"
- end
+ it "throws an exception when argument is not a module" do
+ Module.new do
+ refine String do
+ -> {
+ import_methods Integer
+ }.should raise_error(TypeError, "wrong argument type Class (expected Module)")
end
end
+ end
- it "imports a method defined in the last module if method with same name is defined in multiple modules" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- str_utils_fancy = Module.new do
- def indent(level)
- "*" * level + self
- end
- end
-
- Module.new do
- refine String do
- import_methods str_utils, str_utils_fancy
- "foo".indent(3).should == "***foo"
- end
+ it "imports methods from multiple modules" do
+ str_utils = Module.new do
+ def indent(level)
+ " " * level + self
end
end
- it "still imports methods of modules listed before a module that contains method not defined in Ruby" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
- end
-
- string_refined = Module.new do
- refine String do
- -> {
- import_methods str_utils, Kernel
- }.should raise_error(ArgumentError)
- end
+ str_utils_fancy = Module.new do
+ def indent_star(level)
+ "*" * level + self
end
+ end
- Module.new do
- using string_refined
+ Module.new do
+ refine String do
+ import_methods str_utils, str_utils_fancy
"foo".indent(3).should == " foo"
+ "foo".indent_star(3).should == "***foo"
end
end
end
- it "warns if a module includes/prepends some other module" do
- module1 = Module.new do
- end
-
- module2 = Module.new do
- include module1
- end
-
- Module.new do
- refine String do
- -> {
- import_methods module2
- }.should complain(/warning: #<Module:\w*> has ancestors, but Refinement#import_methods doesn't import their methods/)
+ it "imports a method defined in the last module if method with same name is defined in multiple modules" do
+ str_utils = Module.new do
+ def indent(level)
+ " " * level + self
end
end
- Module.new do
- refine String do
- -> {
- import_methods RefinementSpec::ModuleWithAncestors
- }.should complain(/warning: RefinementSpec::ModuleWithAncestors has ancestors, but Refinement#import_methods doesn't import their methods/)
+ str_utils_fancy = Module.new do
+ def indent(level)
+ "*" * level + self
end
end
- end
- it "doesn't import methods from included/prepended modules" do
Module.new do
refine String do
- suppress_warning { import_methods RefinementSpec::ModuleWithAncestors }
+ import_methods str_utils, str_utils_fancy
+ "foo".indent(3).should == "***foo"
end
-
- using self
- -> {
- "foo".indent(3)
- }.should raise_error(NoMethodError, /undefined method [`']indent' for ("foo":String|an instance of String)/)
end
end
- it "doesn't import any methods if one of the arguments is not a module" do
+ it "still imports methods of modules listed before a module that contains method not defined in Ruby" do
str_utils = Module.new do
def indent(level)
" " * level + self
@@ -142,126 +81,185 @@ describe "Refinement#import_methods" do
string_refined = Module.new do
refine String do
-> {
- import_methods str_utils, Integer
- }.should raise_error(TypeError)
+ import_methods str_utils, Kernel
+ }.should raise_error(ArgumentError)
end
end
Module.new do
using string_refined
+ "foo".indent(3).should == " foo"
+ end
+ end
+ end
+
+ it "warns if a module includes/prepends some other module" do
+ module1 = Module.new do
+ end
+
+ module2 = Module.new do
+ include module1
+ end
+
+ Module.new do
+ refine String do
-> {
- "foo".indent(3)
- }.should raise_error(NoMethodError)
+ import_methods module2
+ }.should complain(/warning: #<Module:\w*> has ancestors, but Refinement#import_methods doesn't import their methods/)
end
end
- it "imports methods from multiple modules so that methods see other's module's methods" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
+ Module.new do
+ refine String do
+ -> {
+ import_methods RefinementSpec::ModuleWithAncestors
+ }.should complain(/warning: RefinementSpec::ModuleWithAncestors has ancestors, but Refinement#import_methods doesn't import their methods/)
+ end
+ end
+ end
+
+ it "doesn't import methods from included/prepended modules" do
+ Module.new do
+ refine String do
+ suppress_warning { import_methods RefinementSpec::ModuleWithAncestors }
end
- str_utils_normal = Module.new do
- def indent_normal(level)
- self.indent(level)
- end
+ using self
+ -> {
+ "foo".indent(3)
+ }.should raise_error(NoMethodError, /undefined method [`']indent' for ("foo":String|an instance of String)/)
+ end
+ end
+
+ it "doesn't import any methods if one of the arguments is not a module" do
+ str_utils = Module.new do
+ def indent(level)
+ " " * level + self
end
+ end
- Module.new do
- refine String do
- import_methods str_utils, str_utils_normal
- end
+ string_refined = Module.new do
+ refine String do
+ -> {
+ import_methods str_utils, Integer
+ }.should raise_error(TypeError)
+ end
+ end
- using self
- "foo".indent_normal(3).should == " foo"
+ Module.new do
+ using string_refined
+ -> {
+ "foo".indent(3)
+ }.should raise_error(NoMethodError)
+ end
+ end
+
+ it "imports methods from multiple modules so that methods see other's module's methods" do
+ str_utils = Module.new do
+ def indent(level)
+ " " * level + self
end
end
- it "imports methods from module so that methods can see each other" do
- str_utils = Module.new do
- def indent(level)
- " " * level + self
- end
+ str_utils_normal = Module.new do
+ def indent_normal(level)
+ self.indent(level)
+ end
+ end
- def indent_with_dot(level)
- self.indent(level) + "."
- end
+ Module.new do
+ refine String do
+ import_methods str_utils, str_utils_normal
end
- Module.new do
- refine String do
- import_methods str_utils
- end
+ using self
+ "foo".indent_normal(3).should == " foo"
+ end
+ end
- using self
- "foo".indent_with_dot(3).should == " foo."
+ it "imports methods from module so that methods can see each other" do
+ str_utils = Module.new do
+ def indent(level)
+ " " * level + self
+ end
+
+ def indent_with_dot(level)
+ self.indent(level) + "."
end
end
- it "doesn't import module's class methods" do
- str_utils = Module.new do
- def self.indent(level)
- " " * level + self
- end
+ Module.new do
+ refine String do
+ import_methods str_utils
end
- Module.new do
- refine String do
- import_methods str_utils
- end
+ using self
+ "foo".indent_with_dot(3).should == " foo."
+ end
+ end
- using self
- -> {
- String.indent(3)
- }.should raise_error(NoMethodError, /undefined method [`']indent' for (String:Class|class String)/)
+ it "doesn't import module's class methods" do
+ str_utils = Module.new do
+ def self.indent(level)
+ " " * level + self
end
end
- it "imports module methods with super" do
- class_to_refine = Class.new do
- def foo(number)
- 2 * number
- end
+ Module.new do
+ refine String do
+ import_methods str_utils
end
- extension = Module.new do
- def foo(number)
- super * 2
- end
+ using self
+ -> {
+ String.indent(3)
+ }.should raise_error(NoMethodError, /undefined method [`']indent' for (String:Class|class String)/)
+ end
+ end
+
+ it "imports module methods with super" do
+ class_to_refine = Class.new do
+ def foo(number)
+ 2 * number
end
+ end
- refinement = Module.new do
- refine class_to_refine do
- import_methods extension
- end
+ extension = Module.new do
+ def foo(number)
+ super * 2
end
+ end
- Module.new do
- using refinement
- class_to_refine.new.foo(2).should == 8
+ refinement = Module.new do
+ refine class_to_refine do
+ import_methods extension
end
end
- context "when methods are not defined in Ruby code" do
- it "raises ArgumentError" do
- Module.new do
- refine String do
- -> {
- import_methods Kernel
- }.should raise_error(ArgumentError)
- end
+ Module.new do
+ using refinement
+ class_to_refine.new.foo(2).should == 8
+ end
+ end
+
+ context "when methods are not defined in Ruby code" do
+ it "raises ArgumentError" do
+ Module.new do
+ refine String do
+ -> {
+ import_methods Kernel
+ }.should raise_error(ArgumentError)
end
end
+ end
- it "raises ArgumentError when importing methods from C extension" do
- require 'zlib'
- Module.new do
- refine String do
- -> {
- import_methods Zlib
- }.should raise_error(ArgumentError, /Can't import method which is not defined with Ruby code: Zlib#*/)
- end
+ it "raises ArgumentError when importing methods from C extension" do
+ require 'zlib'
+ Module.new do
+ refine String do
+ -> {
+ import_methods Zlib
+ }.should raise_error(ArgumentError, /Can't import method which is not defined with Ruby code: Zlib#*/)
end
end
end
diff --git a/spec/ruby/core/refinement/include_spec.rb b/spec/ruby/core/refinement/include_spec.rb
index 25a53f0ec7..d20ab47e33 100644
--- a/spec/ruby/core/refinement/include_spec.rb
+++ b/spec/ruby/core/refinement/include_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
describe "Refinement#include" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "warns about deprecation" do
Module.new do
refine String do
diff --git a/spec/ruby/core/refinement/prepend_spec.rb b/spec/ruby/core/refinement/prepend_spec.rb
index 27b70d392a..5d66766689 100644
--- a/spec/ruby/core/refinement/prepend_spec.rb
+++ b/spec/ruby/core/refinement/prepend_spec.rb
@@ -1,7 +1,7 @@
require_relative '../../spec_helper'
describe "Refinement#prepend" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "warns about deprecation" do
Module.new do
refine String do
diff --git a/spec/ruby/core/string/byterindex_spec.rb b/spec/ruby/core/string/byterindex_spec.rb
index 150f709b90..34ecbfbd21 100644
--- a/spec/ruby/core/string/byterindex_spec.rb
+++ b/spec/ruby/core/string/byterindex_spec.rb
@@ -352,8 +352,8 @@ describe "String#byterindex with Regexp" do
end
it "returns the character index before the finish" do
- "ありがりがとう".byterindex("が", 9).should == 6
- "ありがりがとう".byterindex(/が/, 9).should == 6
+ "ありがりがとう".byterindex("が", 9).should == 6
+ "ありがりがとう".byterindex(/が/, 9).should == 6
end
end
end
diff --git a/spec/ruby/core/string/chilled_string_spec.rb b/spec/ruby/core/string/chilled_string_spec.rb
index b8fb6eedc9..968e4ec1f0 100644
--- a/spec/ruby/core/string/chilled_string_spec.rb
+++ b/spec/ruby/core/string/chilled_string_spec.rb
@@ -64,7 +64,7 @@ describe "chilled String" do
input.freeze
-> {
-> {
- input << "mutated"
+ input << "mutated"
}.should raise_error(FrozenError)
}.should_not complain(/literal string will be frozen in the future/)
end
@@ -133,7 +133,7 @@ describe "chilled String" do
input.freeze
-> {
-> {
- input << "mutated"
+ input << "mutated"
}.should raise_error(FrozenError)
}.should_not complain(/string returned by :chilled\.to_s will be frozen in the future/)
end
diff --git a/spec/ruby/core/string/lstrip_spec.rb b/spec/ruby/core/string/lstrip_spec.rb
index 99bab6f349..c83650207e 100644
--- a/spec/ruby/core/string/lstrip_spec.rb
+++ b/spec/ruby/core/string/lstrip_spec.rb
@@ -7,11 +7,11 @@ describe "String#lstrip" do
it_behaves_like :string_strip, :lstrip
it "returns a copy of self with leading whitespace removed" do
- " hello ".lstrip.should == "hello "
- " hello world ".lstrip.should == "hello world "
- "\n\r\t\n\v\r hello world ".lstrip.should == "hello world "
- "hello".lstrip.should == "hello"
- " こにちわ".lstrip.should == "こにちわ"
+ " hello ".lstrip.should == "hello "
+ " hello world ".lstrip.should == "hello world "
+ "\n\r\t\n\v\r hello world ".lstrip.should == "hello world "
+ "hello".lstrip.should == "hello"
+ " こにちわ".lstrip.should == "こにちわ"
end
it "works with lazy substrings" do
@@ -22,8 +22,8 @@ describe "String#lstrip" do
end
it "strips leading \\0" do
- "\x00hello".lstrip.should == "hello"
- "\000 \000hello\000 \000".lstrip.should == "hello\000 \000"
+ "\x00hello".lstrip.should == "hello"
+ "\000 \000hello\000 \000".lstrip.should == "hello\000 \000"
end
end
diff --git a/spec/ruby/core/string/rindex_spec.rb b/spec/ruby/core/string/rindex_spec.rb
index 88ce733583..0863a9c3be 100644
--- a/spec/ruby/core/string/rindex_spec.rb
+++ b/spec/ruby/core/string/rindex_spec.rb
@@ -371,8 +371,8 @@ describe "String#rindex with Regexp" do
end
it "returns the character index before the finish" do
- "ありがりがとう".rindex("が", 3).should == 2
- "ありがりがとう".rindex(/が/, 3).should == 2
+ "ありがりがとう".rindex("が", 3).should == 2
+ "ありがりがとう".rindex(/が/, 3).should == 2
end
it "raises an Encoding::CompatibilityError if the encodings are incompatible" do
diff --git a/spec/ruby/core/string/scan_spec.rb b/spec/ruby/core/string/scan_spec.rb
index 70c3b7fb7b..bbe843b591 100644
--- a/spec/ruby/core/string/scan_spec.rb
+++ b/spec/ruby/core/string/scan_spec.rb
@@ -103,11 +103,11 @@ describe "String#scan with pattern and block" do
offsets = []
str.scan(/([aeiou])/) do
- md = $~
- md.string.should == str
- matches << md.to_a
- offsets << md.offset(0)
- str
+ md = $~
+ md.string.should == str
+ matches << md.to_a
+ offsets << md.offset(0)
+ str
end
matches.should == [["e", "e"], ["o", "o"]]
@@ -117,11 +117,11 @@ describe "String#scan with pattern and block" do
offsets = []
str.scan("l") do
- md = $~
- md.string.should == str
- matches << md.to_a
- offsets << md.offset(0)
- str
+ md = $~
+ md.string.should == str
+ matches << md.to_a
+ offsets << md.offset(0)
+ str
end
matches.should == [["l"], ["l"]]
diff --git a/spec/ruby/core/string/shared/slice.rb b/spec/ruby/core/string/shared/slice.rb
index 2f69b9ddce..7b9b9f6a14 100644
--- a/spec/ruby/core/string/shared/slice.rb
+++ b/spec/ruby/core/string/shared/slice.rb
@@ -119,6 +119,18 @@ describe :string_slice_index_length, shared: true do
"hello there".send(@method, -4,-3).should == nil
end
+ platform_is pointer_size: 64 do
+ it "returns nil if the length is negative big value" do
+ "hello there".send(@method, 4, -(1 << 31)).should == nil
+
+ # by some reason length < -(1 << 31) on CI on Windows leads to
+ # 'RangeError: bignum too big to convert into `long'' error
+ platform_is_not :windows do
+ "hello there".send(@method, 4, -(1 << 63)).should == nil
+ end
+ end
+ end
+
it "calls to_int on the given index and the given length" do
"hello".send(@method, 0.5, 1).should == "h"
"hello".send(@method, 0.5, 2.5).should == "he"
@@ -152,6 +164,11 @@ describe :string_slice_index_length, shared: true do
-> { "hello".send(@method, 0, bignum_value) }.should raise_error(RangeError)
end
+ it "raises a RangeError if the index or length is too small" do
+ -> { "hello".send(@method, -bignum_value, 1) }.should raise_error(RangeError)
+ -> { "hello".send(@method, 0, -bignum_value) }.should raise_error(RangeError)
+ end
+
it "returns String instances" do
s = StringSpecs::MyString.new("hello")
s.send(@method, 0,0).should be_an_instance_of(String)
diff --git a/spec/ruby/core/string/sub_spec.rb b/spec/ruby/core/string/sub_spec.rb
index 4f9f87a433..6ff28ec851 100644
--- a/spec/ruby/core/string/sub_spec.rb
+++ b/spec/ruby/core/string/sub_spec.rb
@@ -232,10 +232,10 @@ describe "String#sub with pattern and block" do
offsets = []
str.sub(/([aeiou])/) do
- md = $~
- md.string.should == str
- offsets << md.offset(0)
- str
+ md = $~
+ md.string.should == str
+ offsets << md.offset(0)
+ str
end.should == "hhellollo"
offsets.should == [[1, 2]]
@@ -339,10 +339,10 @@ describe "String#sub! with pattern and block" do
offsets = []
str.dup.sub!(/([aeiou])/) do
- md = $~
- md.string.should == str
- offsets << md.offset(0)
- str
+ md = $~
+ md.string.should == str
+ offsets << md.offset(0)
+ str
end.should == "hhellollo"
offsets.should == [[1, 2]]
diff --git a/spec/ruby/core/string/swapcase_spec.rb b/spec/ruby/core/string/swapcase_spec.rb
index 7f4c68366d..011a213501 100644
--- a/spec/ruby/core/string/swapcase_spec.rb
+++ b/spec/ruby/core/string/swapcase_spec.rb
@@ -5,9 +5,9 @@ require_relative 'fixtures/classes'
describe "String#swapcase" do
it "returns a new string with all uppercase chars from self converted to lowercase and vice versa" do
- "Hello".swapcase.should == "hELLO"
- "cYbEr_PuNk11".swapcase.should == "CyBeR_pUnK11"
- "+++---111222???".swapcase.should == "+++---111222???"
+ "Hello".swapcase.should == "hELLO"
+ "cYbEr_PuNk11".swapcase.should == "CyBeR_pUnK11"
+ "+++---111222???".swapcase.should == "+++---111222???"
end
it "returns a String in the same encoding as self" do
diff --git a/spec/ruby/core/string/to_c_spec.rb b/spec/ruby/core/string/to_c_spec.rb
index 9d24f1f56c..4864a98e39 100644
--- a/spec/ruby/core/string/to_c_spec.rb
+++ b/spec/ruby/core/string/to_c_spec.rb
@@ -18,13 +18,17 @@ describe "String#to_c" do
end
end
- it "understands Float::INFINITY" do
- 'Infinity'.to_c.should == Complex(0, 1)
- '-Infinity'.to_c.should == Complex(0, -1)
- end
+ context "it treats special float value strings as characters" do
+ it "parses any string that starts with 'I' as 1i" do
+ 'Infinity'.to_c.should == Complex(0, 1)
+ '-Infinity'.to_c.should == Complex(0, -1)
+ 'Insecure'.to_c.should == Complex(0, 1)
+ '-Insecure'.to_c.should == Complex(0, -1)
+ end
- it "understands Float::NAN" do
- 'NaN'.to_c.should == Complex(0, 0)
+ it "does not parse any numeric information in 'NaN'" do
+ 'NaN'.to_c.should == Complex(0, 0)
+ end
end
it "allows null-byte" do
diff --git a/spec/ruby/core/string/to_f_spec.rb b/spec/ruby/core/string/to_f_spec.rb
index cf64ecfc5d..72e2a90b13 100644
--- a/spec/ruby/core/string/to_f_spec.rb
+++ b/spec/ruby/core/string/to_f_spec.rb
@@ -5,16 +5,15 @@ require_relative 'fixtures/classes'
describe "String#to_f" do
it "treats leading characters of self as a floating point number" do
- "123.45e1".to_f.should == 1234.5
- "45.67 degrees".to_f.should == 45.67
- "0".to_f.should == 0.0
- "123.45e1".to_f.should == 1234.5
+ "123.45e1".to_f.should == 1234.5
+ "45.67 degrees".to_f.should == 45.67
+ "0".to_f.should == 0.0
- ".5".to_f.should == 0.5
- ".5e1".to_f.should == 5.0
- "5.".to_f.should == 5.0
- "5e".to_f.should == 5.0
- "5E".to_f.should == 5.0
+ ".5".to_f.should == 0.5
+ ".5e1".to_f.should == 5.0
+ "5.".to_f.should == 5.0
+ "5e".to_f.should == 5.0
+ "5E".to_f.should == 5.0
end
it "treats special float value strings as characters" do
@@ -43,18 +42,39 @@ describe "String#to_f" do
"1_234_567.890_1".to_f.should == 1_234_567.890_1
end
- it "returns 0 for strings with any non-digit in them" do
- "blah".to_f.should == 0
- "0b5".to_f.should == 0
- "0d5".to_f.should == 0
- "0o5".to_f.should == 0
- "0xx5".to_f.should == 0
- end
-
it "returns 0 for strings with leading underscores" do
"_9".to_f.should == 0
end
+ it "stops if the underscore is not followed or preceded by a number" do
+ "1__2".to_f.should == 1.0
+ "1_.2".to_f.should == 1.0
+ "1._2".to_f.should == 1.0
+ "1.2_e2".to_f.should == 1.2
+ "1.2e_2".to_f.should == 1.2
+ "1_x2".to_f.should == 1.0
+ "1x_2".to_f.should == 1.0
+ "+_1".to_f.should == 0.0
+ "-_1".to_f.should == 0.0
+ end
+
+ it "does not allow prefixes to autodetect the base" do
+ "0b10".to_f.should == 0
+ "010".to_f.should == 10
+ "0o10".to_f.should == 0
+ "0d10".to_f.should == 0
+ "0x10".to_f.should == 0
+ end
+
+ it "treats any non-numeric character other than '.', 'e' and '_' as terminals" do
+ "blah".to_f.should == 0
+ "1b5".to_f.should == 1
+ "1d5".to_f.should == 1
+ "1o5".to_f.should == 1
+ "1xx5".to_f.should == 1
+ "x5".to_f.should == 0
+ end
+
it "takes an optional sign" do
"-45.67 degrees".to_f.should == -45.67
"+45.67 degrees".to_f.should == 45.67
@@ -63,8 +83,48 @@ describe "String#to_f" do
(1.0 / "-0".to_f).to_s.should == "-Infinity"
end
+ it "treats a second 'e' as terminal" do
+ "1.234e1e2".to_f.should == 1.234e1
+ end
+
+ it "treats a second '.' as terminal" do
+ "1.2.3".to_f.should == 1.2
+ end
+
+ it "treats a '.' after an 'e' as terminal" do
+ "1.234e1.9".to_f.should == 1.234e1
+ end
+
it "returns 0.0 if the conversion fails" do
"bad".to_f.should == 0.0
"thx1138".to_f.should == 0.0
end
+
+ it "ignores leading and trailing whitespace" do
+ " 1.2".to_f.should == 1.2
+ "1.2 ".to_f.should == 1.2
+ " 1.2 ".to_f.should == 1.2
+ "\t1.2".to_f.should == 1.2
+ "\n1.2".to_f.should == 1.2
+ "\v1.2".to_f.should == 1.2
+ "\f1.2".to_f.should == 1.2
+ "\r1.2".to_f.should == 1.2
+ end
+
+ it "treats non-printable ASCII characters as terminals" do
+ "\0001.2".to_f.should == 0
+ "\0011.2".to_f.should == 0
+ "\0371.2".to_f.should == 0
+ "\1771.2".to_f.should == 0
+ "\2001.2".b.to_f.should == 0
+ "\3771.2".b.to_f.should == 0
+ end
+
+ ruby_version_is "3.2" do
+ it "raises Encoding::CompatibilityError if String is in not ASCII-compatible encoding" do
+ -> {
+ '1.2'.encode("UTF-16").to_f
+ }.should raise_error(Encoding::CompatibilityError, "ASCII incompatible encoding: UTF-16")
+ end
+ end
end
diff --git a/spec/ruby/core/string/to_i_spec.rb b/spec/ruby/core/string/to_i_spec.rb
index 9931502baa..39f69acda3 100644
--- a/spec/ruby/core/string/to_i_spec.rb
+++ b/spec/ruby/core/string/to_i_spec.rb
@@ -10,7 +10,7 @@ describe "String#to_i" do
"1_2_3asdf".to_i.should == 123
end
- it "ignores multiple non-consecutive underscoes when the first digit is 0" do
+ it "ignores multiple non-consecutive underscores when the first digit is 0" do
(2..16).each do |base|
"0_0_010".to_i(base).should == base;
end
diff --git a/spec/ruby/core/string/to_r_spec.rb b/spec/ruby/core/string/to_r_spec.rb
index 7e1d635d3b..4ffbb10d98 100644
--- a/spec/ruby/core/string/to_r_spec.rb
+++ b/spec/ruby/core/string/to_r_spec.rb
@@ -33,6 +33,10 @@ describe "String#to_r" do
"-20".to_r.should == Rational(-20, 1)
end
+ it "accepts leading plus signs" do
+ "+20".to_r.should == Rational(20, 1)
+ end
+
it "does not treat a leading period without a numeric prefix as a decimal point" do
".9".to_r.should_not == Rational(8106479329266893, 9007199254740992)
end
diff --git a/spec/ruby/core/string/unpack1_spec.rb b/spec/ruby/core/string/unpack1_spec.rb
index df830916a3..3b3b879f75 100644
--- a/spec/ruby/core/string/unpack1_spec.rb
+++ b/spec/ruby/core/string/unpack1_spec.rb
@@ -8,29 +8,27 @@ describe "String#unpack1" do
"A".unpack1("B*").should == "01000001"
end
- ruby_version_is "3.1" do
- it "starts unpacking from the given offset" do
- "ZZABCD".unpack1('x3C', offset: 2).should == "ABCD".unpack('x3C')[0]
- "ZZZZaG9nZWZ1Z2E=".unpack1("m", offset: 4).should == "hogefuga"
- "ZA".unpack1("B*", offset: 1).should == "01000001"
- end
+ it "starts unpacking from the given offset" do
+ "ZZABCD".unpack1('x3C', offset: 2).should == "ABCD".unpack('x3C')[0]
+ "ZZZZaG9nZWZ1Z2E=".unpack1("m", offset: 4).should == "hogefuga"
+ "ZA".unpack1("B*", offset: 1).should == "01000001"
+ end
- it "traits offset as a bytes offset" do
- "؈".unpack("CC").should == [216, 136]
- "؈".unpack1("C").should == 216
- "؈".unpack1("C", offset: 1).should == 136
- end
+ it "traits offset as a bytes offset" do
+ "؈".unpack("CC").should == [216, 136]
+ "؈".unpack1("C").should == 216
+ "؈".unpack1("C", offset: 1).should == 136
+ end
- it "raises an ArgumentError when the offset is negative" do
- -> { "a".unpack1("C", offset: -1) }.should raise_error(ArgumentError, "offset can't be negative")
- end
+ it "raises an ArgumentError when the offset is negative" do
+ -> { "a".unpack1("C", offset: -1) }.should raise_error(ArgumentError, "offset can't be negative")
+ end
- it "returns nil if the offset is at the end of the string" do
- "a".unpack1("C", offset: 1).should == nil
- end
+ it "returns nil if the offset is at the end of the string" do
+ "a".unpack1("C", offset: 1).should == nil
+ end
- it "raises an ArgumentError when the offset is larger than the string bytesize" do
- -> { "a".unpack1("C", offset: 2) }.should raise_error(ArgumentError, "offset outside of string")
- end
+ it "raises an ArgumentError when the offset is larger than the string bytesize" do
+ -> { "a".unpack1("C", offset: 2) }.should raise_error(ArgumentError, "offset outside of string")
end
end
diff --git a/spec/ruby/core/string/unpack_spec.rb b/spec/ruby/core/string/unpack_spec.rb
index 52b4af3a95..083484ebe9 100644
--- a/spec/ruby/core/string/unpack_spec.rb
+++ b/spec/ruby/core/string/unpack_spec.rb
@@ -9,26 +9,24 @@ describe "String#unpack" do
-> { "abc".unpack(1) }.should raise_error(TypeError)
end
- ruby_version_is "3.1" do
- it "starts unpacking from the given offset" do
- "abc".unpack("CC", offset: 1).should == [98, 99]
- end
+ it "starts unpacking from the given offset" do
+ "abc".unpack("CC", offset: 1).should == [98, 99]
+ end
- it "traits offset as a bytes offset" do
- "؈".unpack("CC").should == [216, 136]
- "؈".unpack("CC", offset: 1).should == [136, nil]
- end
+ it "traits offset as a bytes offset" do
+ "؈".unpack("CC").should == [216, 136]
+ "؈".unpack("CC", offset: 1).should == [136, nil]
+ end
- it "raises an ArgumentError when the offset is negative" do
- -> { "a".unpack("C", offset: -1) }.should raise_error(ArgumentError, "offset can't be negative")
- end
+ it "raises an ArgumentError when the offset is negative" do
+ -> { "a".unpack("C", offset: -1) }.should raise_error(ArgumentError, "offset can't be negative")
+ end
- it "returns nil if the offset is at the end of the string" do
- "a".unpack("C", offset: 1).should == [nil]
- end
+ it "returns nil if the offset is at the end of the string" do
+ "a".unpack("C", offset: 1).should == [nil]
+ end
- it "raises an ArgumentError when the offset is larget than the string" do
- -> { "a".unpack("C", offset: 2) }.should raise_error(ArgumentError, "offset outside of string")
- end
+ it "raises an ArgumentError when the offset is larget than the string" do
+ -> { "a".unpack("C", offset: 2) }.should raise_error(ArgumentError, "offset outside of string")
end
end
diff --git a/spec/ruby/core/struct/deconstruct_keys_spec.rb b/spec/ruby/core/struct/deconstruct_keys_spec.rb
index b4c84c49df..cd05aee056 100644
--- a/spec/ruby/core/struct/deconstruct_keys_spec.rb
+++ b/spec/ruby/core/struct/deconstruct_keys_spec.rb
@@ -40,6 +40,14 @@ describe "Struct#deconstruct_keys" do
s.deconstruct_keys([0, 1, 2]).should == {0 => 10, 1 => 20, 2 => 30}
s.deconstruct_keys([0, 1] ).should == {0 => 10, 1 => 20}
s.deconstruct_keys([0] ).should == {0 => 10}
+ s.deconstruct_keys([-1] ).should == {-1 => 30}
+ end
+
+ it "support mixing attribute names and argument position numbers" do
+ struct = Struct.new(:x, :y)
+ s = struct.new(1, 2)
+
+ s.deconstruct_keys([0, :x]).should == {0 => 1, :x => 1}
end
it "returns an empty hash when there are more keys than attributes" do
@@ -57,6 +65,14 @@ describe "Struct#deconstruct_keys" do
s.deconstruct_keys([:x, :a]).should == {x: 1}
end
+ it "returns at first not existing argument position number" do
+ struct = Struct.new(:x, :y)
+ s = struct.new(1, 2)
+
+ s.deconstruct_keys([3, 0]).should == {}
+ s.deconstruct_keys([0, 3]).should == {0 => 1}
+ end
+
it "accepts nil argument and return all the attributes" do
struct = Struct.new(:x, :y)
obj = struct.new(1, 2)
@@ -64,6 +80,15 @@ describe "Struct#deconstruct_keys" do
obj.deconstruct_keys(nil).should == {x: 1, y: 2}
end
+ it "raises TypeError if index is not a String, a Symbol and not convertible to Integer " do
+ struct = Struct.new(:x, :y)
+ s = struct.new(1, 2)
+
+ -> {
+ s.deconstruct_keys([0, []])
+ }.should raise_error(TypeError, "no implicit conversion of Array into Integer")
+ end
+
it "raise TypeError if passed anything except nil or array" do
struct = Struct.new(:x, :y)
s = struct.new(1, 2)
diff --git a/spec/ruby/core/struct/fixtures/classes.rb b/spec/ruby/core/struct/fixtures/classes.rb
index bf838d05df..7b80b814ef 100644
--- a/spec/ruby/core/struct/fixtures/classes.rb
+++ b/spec/ruby/core/struct/fixtures/classes.rb
@@ -29,4 +29,6 @@ module StructClasses
super
end
end
+
+ class StructSubclass < Struct; end
end
diff --git a/spec/ruby/core/struct/initialize_spec.rb b/spec/ruby/core/struct/initialize_spec.rb
index a5ebe9551c..1861bcafb0 100644
--- a/spec/ruby/core/struct/initialize_spec.rb
+++ b/spec/ruby/core/struct/initialize_spec.rb
@@ -41,7 +41,7 @@ describe "Struct#initialize" do
StructClasses::SubclassX.new(:y).new.key.should == :value
end
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "warns about passing only keyword arguments" do
-> {
StructClasses::Ruby.new(version: "3.1", platform: "OS")
diff --git a/spec/ruby/core/struct/keyword_init_spec.rb b/spec/ruby/core/struct/keyword_init_spec.rb
index 8de4c14351..536b82041a 100644
--- a/spec/ruby/core/struct/keyword_init_spec.rb
+++ b/spec/ruby/core/struct/keyword_init_spec.rb
@@ -1,40 +1,45 @@
require_relative '../../spec_helper'
+require_relative 'fixtures/classes'
-ruby_version_is "3.1" do
- # See https://bugs.ruby-lang.org/issues/18008
- describe "StructClass#keyword_init?" do
- it "returns true for a struct that accepts keyword arguments to initialize" do
- struct = Struct.new(:arg, keyword_init: true)
- struct.keyword_init?.should be_true
- end
+# See https://bugs.ruby-lang.org/issues/18008
+describe "StructClass#keyword_init?" do
+ it "returns true for a struct that accepts keyword arguments to initialize" do
+ struct = Struct.new(:arg, keyword_init: true)
+ struct.keyword_init?.should be_true
+ end
- it "returns false for a struct that does not accept keyword arguments to initialize" do
- struct = Struct.new(:arg, keyword_init: false)
- struct.keyword_init?.should be_false
- end
+ it "returns false for a struct that does not accept keyword arguments to initialize" do
+ struct = Struct.new(:arg, keyword_init: false)
+ struct.keyword_init?.should be_false
+ end
- it "returns nil for a struct that did not explicitly specify keyword_init" do
- struct = Struct.new(:arg)
- struct.keyword_init?.should be_nil
- end
+ it "returns nil for a struct that did not explicitly specify keyword_init" do
+ struct = Struct.new(:arg)
+ struct.keyword_init?.should be_nil
+ end
- it "returns nil for a struct that does specify keyword_init to be nil" do
- struct = Struct.new(:arg, keyword_init: nil)
- struct.keyword_init?.should be_nil
- end
+ it "returns nil for a struct that does specify keyword_init to be nil" do
+ struct = Struct.new(:arg, keyword_init: nil)
+ struct.keyword_init?.should be_nil
+ end
- it "returns true for any truthy value, not just for true" do
- struct = Struct.new(:arg, keyword_init: 1)
- struct.keyword_init?.should be_true
+ it "returns true for any truthy value, not just for true" do
+ struct = Struct.new(:arg, keyword_init: 1)
+ struct.keyword_init?.should be_true
- struct = Struct.new(:arg, keyword_init: "")
- struct.keyword_init?.should be_true
+ struct = Struct.new(:arg, keyword_init: "")
+ struct.keyword_init?.should be_true
- struct = Struct.new(:arg, keyword_init: [])
- struct.keyword_init?.should be_true
+ struct = Struct.new(:arg, keyword_init: [])
+ struct.keyword_init?.should be_true
+
+ struct = Struct.new(:arg, keyword_init: {})
+ struct.keyword_init?.should be_true
+ end
- struct = Struct.new(:arg, keyword_init: {})
- struct.keyword_init?.should be_true
+ context "class inheriting Struct" do
+ it "isn't available in a subclass" do
+ StructClasses::StructSubclass.should_not.respond_to?(:keyword_init?)
end
end
end
diff --git a/spec/ruby/core/struct/members_spec.rb b/spec/ruby/core/struct/members_spec.rb
index 1f2ff950d9..1ff7b9387a 100644
--- a/spec/ruby/core/struct/members_spec.rb
+++ b/spec/ruby/core/struct/members_spec.rb
@@ -11,3 +11,15 @@ describe "Struct#members" do
it_behaves_like :struct_accessor, :members
end
+
+describe "StructClass#members" do
+ it "returns an array of attribute names" do
+ StructClasses::Car.members.should == [:make, :model, :year]
+ end
+
+ context "class inheriting Struct" do
+ it "isn't available in a subclass" do
+ StructClasses::StructSubclass.should_not.respond_to?(:members)
+ end
+ end
+end
diff --git a/spec/ruby/core/struct/new_spec.rb b/spec/ruby/core/struct/new_spec.rb
index a94eb852e1..73e88a81c1 100644
--- a/spec/ruby/core/struct/new_spec.rb
+++ b/spec/ruby/core/struct/new_spec.rb
@@ -6,6 +6,8 @@ describe "Struct.new" do
struct = Struct.new('Animal', :name, :legs, :eyeballs)
struct.should == Struct::Animal
struct.name.should == "Struct::Animal"
+ ensure
+ Struct.send(:remove_const, :Animal)
end
it "overwrites previously defined constants with string as first argument" do
@@ -19,6 +21,8 @@ describe "Struct.new" do
second.should == Struct::Person
first.members.should_not == second.members
+ ensure
+ Struct.send(:remove_const, :Person)
end
it "calls to_str on its first argument (constant name)" do
@@ -27,6 +31,8 @@ describe "Struct.new" do
struct = Struct.new(obj)
struct.should == Struct::Foo
struct.name.should == "Struct::Foo"
+ ensure
+ Struct.send(:remove_const, :Foo)
end
it "creates a new anonymous class with nil first argument" do
@@ -138,6 +144,8 @@ describe "Struct.new" do
it "creates a constant in subclass' namespace" do
struct = StructClasses::Apple.new('Computer', :size)
struct.should == StructClasses::Apple::Computer
+ ensure
+ StructClasses::Apple.send(:remove_const, :Computer)
end
it "creates an instance" do
@@ -158,19 +166,6 @@ describe "Struct.new" do
-> { StructClasses::Ruby.new('2.0', 'i686', true) }.should raise_error(ArgumentError)
end
- ruby_version_is ''...'3.1' do
- it "passes a hash as a normal argument" do
- type = Struct.new(:args)
-
- obj = suppress_warning {type.new(keyword: :arg)}
- obj2 = type.new(*[{keyword: :arg}])
-
- obj.should == obj2
- obj.args.should == {keyword: :arg}
- obj2.args.should == {keyword: :arg}
- end
- end
-
ruby_version_is '3.2' do
it "accepts keyword arguments to initialize" do
type = Struct.new(:args)
diff --git a/spec/ruby/core/symbol/shared/slice.rb b/spec/ruby/core/symbol/shared/slice.rb
index 0df87e183d..d3d4aad617 100644
--- a/spec/ruby/core/symbol/shared/slice.rb
+++ b/spec/ruby/core/symbol/shared/slice.rb
@@ -7,7 +7,7 @@ describe :symbol_slice, shared: true do
end
it "returns nil if the index starts from the end and is greater than the length" do
- :symbol.send(@method, -10).should be_nil
+ :symbol.send(@method, -10).should be_nil
end
it "returns nil if the index is greater than the length" do
diff --git a/spec/ruby/core/thread/abort_on_exception_spec.rb b/spec/ruby/core/thread/abort_on_exception_spec.rb
index 34b648ca0f..49be84ea9f 100644
--- a/spec/ruby/core/thread/abort_on_exception_spec.rb
+++ b/spec/ruby/core/thread/abort_on_exception_spec.rb
@@ -72,7 +72,7 @@ describe "Thread.abort_on_exception" do
end
after do
- Thread.abort_on_exception = @abort_on_exception
+ Thread.abort_on_exception = @abort_on_exception
end
it "is false by default" do
diff --git a/spec/ruby/core/thread/backtrace/limit_spec.rb b/spec/ruby/core/thread/backtrace/limit_spec.rb
index 26a87a806c..b55ca67ea0 100644
--- a/spec/ruby/core/thread/backtrace/limit_spec.rb
+++ b/spec/ruby/core/thread/backtrace/limit_spec.rb
@@ -1,15 +1,13 @@
require_relative '../../../spec_helper'
-ruby_version_is "3.1" do
- describe "Thread::Backtrace.limit" do
- it "returns maximum backtrace length set by --backtrace-limit command-line option" do
- out = ruby_exe("print Thread::Backtrace.limit", options: "--backtrace-limit=2")
- out.should == "2"
- end
+describe "Thread::Backtrace.limit" do
+ it "returns maximum backtrace length set by --backtrace-limit command-line option" do
+ out = ruby_exe("print Thread::Backtrace.limit", options: "--backtrace-limit=2")
+ out.should == "2"
+ end
- it "returns -1 when --backtrace-limit command-line option is not set" do
- out = ruby_exe("print Thread::Backtrace.limit")
- out.should == "-1"
- end
+ it "returns -1 when --backtrace-limit command-line option is not set" do
+ out = ruby_exe("print Thread::Backtrace.limit")
+ out.should == "-1"
end
end
diff --git a/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb b/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb
index 6e381e4868..68a69049d9 100644
--- a/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb
+++ b/spec/ruby/core/thread/backtrace/location/absolute_path_spec.rb
@@ -27,20 +27,11 @@ describe 'Thread::Backtrace::Location#absolute_path' do
end
context "when used in eval with a given filename" do
- code = "caller_locations(0)[0].absolute_path"
+ it "returns nil with absolute_path" do
+ code = "caller_locations(0)[0].absolute_path"
- ruby_version_is ""..."3.1" do
- it "returns filename with absolute_path" do
- eval(code, nil, "foo.rb").should == "foo.rb"
- eval(code, nil, "foo/bar.rb").should == "foo/bar.rb"
- end
- end
-
- ruby_version_is "3.1" do
- it "returns nil with absolute_path" do
- eval(code, nil, "foo.rb").should == nil
- eval(code, nil, "foo/bar.rb").should == nil
- end
+ eval(code, nil, "foo.rb").should == nil
+ eval(code, nil, "foo/bar.rb").should == nil
end
end
diff --git a/spec/ruby/core/thread/native_thread_id_spec.rb b/spec/ruby/core/thread/native_thread_id_spec.rb
index 17a08c8a15..374cc59279 100644
--- a/spec/ruby/core/thread/native_thread_id_spec.rb
+++ b/spec/ruby/core/thread/native_thread_id_spec.rb
@@ -1,37 +1,35 @@
require_relative '../../spec_helper'
-ruby_version_is "3.1" do
- platform_is :linux, :darwin, :windows, :freebsd do
- describe "Thread#native_thread_id" do
- it "returns an integer when the thread is alive" do
- Thread.current.native_thread_id.should be_kind_of(Integer)
- end
+platform_is :linux, :darwin, :windows, :freebsd do
+ describe "Thread#native_thread_id" do
+ it "returns an integer when the thread is alive" do
+ Thread.current.native_thread_id.should be_kind_of(Integer)
+ end
- it "returns nil when the thread is not running" do
- t = Thread.new {}
- t.join
- t.native_thread_id.should == nil
- end
+ it "returns nil when the thread is not running" do
+ t = Thread.new {}
+ t.join
+ t.native_thread_id.should == nil
+ end
- it "each thread has different native thread id" do
- t = Thread.new { sleep }
- Thread.pass until t.stop?
- main_thread_id = Thread.current.native_thread_id
- t_thread_id = t.native_thread_id
+ it "each thread has different native thread id" do
+ t = Thread.new { sleep }
+ Thread.pass until t.stop?
+ main_thread_id = Thread.current.native_thread_id
+ t_thread_id = t.native_thread_id
- if ruby_version_is "3.3"
- # native_thread_id can be nil on a M:N scheduler
- t_thread_id.should be_kind_of(Integer) if t_thread_id != nil
- else
- t_thread_id.should be_kind_of(Integer)
- end
+ if ruby_version_is "3.3"
+ # native_thread_id can be nil on a M:N scheduler
+ t_thread_id.should be_kind_of(Integer) if t_thread_id != nil
+ else
+ t_thread_id.should be_kind_of(Integer)
+ end
- main_thread_id.should_not == t_thread_id
+ main_thread_id.should_not == t_thread_id
- t.run
- t.join
- t.native_thread_id.should == nil
- end
+ t.run
+ t.join
+ t.native_thread_id.should == nil
end
end
end
diff --git a/spec/ruby/core/time/at_spec.rb b/spec/ruby/core/time/at_spec.rb
index 85bb6d7ebf..97906b8c8c 100644
--- a/spec/ruby/core/time/at_spec.rb
+++ b/spec/ruby/core/time/at_spec.rb
@@ -102,8 +102,8 @@ describe "Time.at" do
it "needs for the argument to respond to #to_int too" do
o = mock('rational-but-no-to_int')
- o.should_receive(:to_r).and_return(Rational(5, 2))
- -> { Time.at(o) }.should raise_error(TypeError)
+ def o.to_r; Rational(5, 2) end
+ -> { Time.at(o) }.should raise_error(TypeError, "can't convert MockObject into an exact number")
end
end
end
@@ -288,39 +288,19 @@ describe "Time.at" do
end
it "raises ArgumentError if hours greater than 23" do # TODO
- ruby_version_is ""..."3.1" do
- -> { Time.at(@epoch_time, in: "+24:00") }.should raise_error(ArgumentError, 'utc_offset out of range')
- -> { Time.at(@epoch_time, in: "+2400") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
-
- -> { Time.at(@epoch_time, in: "+99:00") }.should raise_error(ArgumentError, 'utc_offset out of range')
- -> { Time.at(@epoch_time, in: "+9900") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- end
+ -> { Time.at(@epoch_time, in: "+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.at(@epoch_time, in: "+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
- ruby_version_is "3.1" do
- -> { Time.at(@epoch_time, in: "+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.at(@epoch_time, in: "+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
-
- -> { Time.at(@epoch_time, in: "+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.at(@epoch_time, in: "+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
- end
+ -> { Time.at(@epoch_time, in: "+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.at(@epoch_time, in: "+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
end
it "raises ArgumentError if minutes greater than 59" do # TODO
- ruby_version_is ""..."3.1" do
- -> { Time.at(@epoch_time, in: "+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- -> { Time.at(@epoch_time, in: "+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
+ -> { Time.at(@epoch_time, in: "+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
+ -> { Time.at(@epoch_time, in: "+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
- -> { Time.at(@epoch_time, in: "+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- -> { Time.at(@epoch_time, in: "+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- end
-
- ruby_version_is "3.1" do
- -> { Time.at(@epoch_time, in: "+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
- -> { Time.at(@epoch_time, in: "+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
-
- -> { Time.at(@epoch_time, in: "+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
- -> { Time.at(@epoch_time, in: "+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
- end
+ -> { Time.at(@epoch_time, in: "+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
+ -> { Time.at(@epoch_time, in: "+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
end
ruby_bug '#20797', ''...'3.4' do
diff --git a/spec/ruby/core/time/getlocal_spec.rb b/spec/ruby/core/time/getlocal_spec.rb
index ff3e3d8dd1..398596f400 100644
--- a/spec/ruby/core/time/getlocal_spec.rb
+++ b/spec/ruby/core/time/getlocal_spec.rb
@@ -14,6 +14,7 @@ describe "Time#getlocal" do
t = Time.gm(2007, 1, 9, 12, 0, 0).getlocal(3630)
t.should == Time.new(2007, 1, 9, 13, 0, 30, 3630)
t.utc_offset.should == 3630
+ t.zone.should be_nil
end
platform_is_not :windows do
@@ -110,39 +111,19 @@ describe "Time#getlocal" do
end
it "raises ArgumentError if String argument and hours greater than 23" do
- ruby_version_is ""..."3.1" do
- -> { Time.now.getlocal("+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.getlocal("+2400") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
+ -> { Time.now.getlocal("+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.now.getlocal("+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.getlocal("+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.getlocal("+9900") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- end
-
- ruby_version_is "3.1" do
- -> { Time.now.getlocal("+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.getlocal("+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
-
- -> { Time.now.getlocal("+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.getlocal("+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
- end
+ -> { Time.now.getlocal("+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.now.getlocal("+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
end
it "raises ArgumentError if String argument and minutes greater than 59" do
- ruby_version_is ""..."3.1" do
- -> { Time.now.getlocal("+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- -> { Time.now.getlocal("+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
+ -> { Time.now.getlocal("+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
+ -> { Time.now.getlocal("+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
- -> { Time.now.getlocal("+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- -> { Time.now.getlocal("+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- end
-
- ruby_version_is "3.1" do
- -> { Time.now.getlocal("+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
- -> { Time.now.getlocal("+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
-
- -> { Time.now.getlocal("+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
- -> { Time.now.getlocal("+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
- end
+ -> { Time.now.getlocal("+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
+ -> { Time.now.getlocal("+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
end
ruby_bug '#20797', ''...'3.4' do
diff --git a/spec/ruby/core/time/localtime_spec.rb b/spec/ruby/core/time/localtime_spec.rb
index 5badba9fb2..71c0dfebde 100644
--- a/spec/ruby/core/time/localtime_spec.rb
+++ b/spec/ruby/core/time/localtime_spec.rb
@@ -106,39 +106,19 @@ describe "Time#localtime" do
end
it "raises ArgumentError if String argument and hours greater than 23" do
- ruby_version_is ""..."3.1" do
- -> { Time.now.localtime("+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.localtime("+2400") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
+ -> { Time.now.localtime("+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.now.localtime("+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.localtime("+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.localtime("+9900") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- end
-
- ruby_version_is "3.1" do
- -> { Time.now.localtime("+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.localtime("+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
-
- -> { Time.now.localtime("+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now.localtime("+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
- end
+ -> { Time.now.localtime("+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.now.localtime("+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
end
it "raises ArgumentError if String argument and minutes greater than 59" do
- ruby_version_is ""..."3.1" do
- -> { Time.now.localtime("+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- -> { Time.now.localtime("+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
+ -> { Time.now.localtime("+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
+ -> { Time.now.localtime("+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
- -> { Time.now.localtime("+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- -> { Time.now.localtime("+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset')
- end
-
- ruby_version_is "3.1" do
- -> { Time.now.localtime("+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
- -> { Time.now.localtime("+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
-
- -> { Time.now.localtime("+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
- -> { Time.now.localtime("+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
- end
+ -> { Time.now.localtime("+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
+ -> { Time.now.localtime("+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
end
ruby_bug '#20797', ''...'3.4' do
@@ -188,6 +168,17 @@ describe "Time#localtime" do
end
end
+ describe "with an argument that responds to #utc_to_local" do
+ it "coerces using #utc_to_local" do
+ o = mock('string')
+ o.should_receive(:utc_to_local).and_return(Time.new(2007, 1, 9, 13, 0, 0, 3600))
+ t = Time.gm(2007, 1, 9, 12, 0, 0)
+ t.localtime(o)
+ t.should == Time.new(2007, 1, 9, 13, 0, 0, 3600)
+ t.utc_offset.should == 3600
+ end
+ end
+
it "raises ArgumentError if the String argument is not of the form (+|-)HH:MM" do
t = Time.now
-> { t.localtime("3600") }.should raise_error(ArgumentError)
diff --git a/spec/ruby/core/time/new_spec.rb b/spec/ruby/core/time/new_spec.rb
index 1a743b485e..0fd48640d4 100644
--- a/spec/ruby/core/time/new_spec.rb
+++ b/spec/ruby/core/time/new_spec.rb
@@ -58,30 +58,28 @@ describe "Time.new with a utc_offset argument" do
Time.new(2000, 1, 1, 0, 0, 0, "-04:10:43").utc_offset.should == -15043
end
- ruby_bug '#13669', ''...'3.1' do
- it "returns a Time with a UTC offset specified as +HH" do
- Time.new(2000, 1, 1, 0, 0, 0, "+05").utc_offset.should == 3600 * 5
- end
+ it "returns a Time with a UTC offset specified as +HH" do
+ Time.new(2000, 1, 1, 0, 0, 0, "+05").utc_offset.should == 3600 * 5
+ end
- it "returns a Time with a UTC offset specified as -HH" do
- Time.new(2000, 1, 1, 0, 0, 0, "-05").utc_offset.should == -3600 * 5
- end
+ it "returns a Time with a UTC offset specified as -HH" do
+ Time.new(2000, 1, 1, 0, 0, 0, "-05").utc_offset.should == -3600 * 5
+ end
- it "returns a Time with a UTC offset specified as +HHMM" do
- Time.new(2000, 1, 1, 0, 0, 0, "+0530").utc_offset.should == 19800
- end
+ it "returns a Time with a UTC offset specified as +HHMM" do
+ Time.new(2000, 1, 1, 0, 0, 0, "+0530").utc_offset.should == 19800
+ end
- it "returns a Time with a UTC offset specified as -HHMM" do
- Time.new(2000, 1, 1, 0, 0, 0, "-0530").utc_offset.should == -19800
- end
+ it "returns a Time with a UTC offset specified as -HHMM" do
+ Time.new(2000, 1, 1, 0, 0, 0, "-0530").utc_offset.should == -19800
+ end
- it "returns a Time with a UTC offset specified as +HHMMSS" do
- Time.new(2000, 1, 1, 0, 0, 0, "+053037").utc_offset.should == 19837
- end
+ it "returns a Time with a UTC offset specified as +HHMMSS" do
+ Time.new(2000, 1, 1, 0, 0, 0, "+053037").utc_offset.should == 19837
+ end
- it "returns a Time with a UTC offset specified as -HHMMSS" do
- Time.new(2000, 1, 1, 0, 0, 0, "-053037").utc_offset.should == -19837
- end
+ it "returns a Time with a UTC offset specified as -HHMMSS" do
+ Time.new(2000, 1, 1, 0, 0, 0, "-053037").utc_offset.should == -19837
end
describe "with an argument that responds to #to_str" do
@@ -129,18 +127,9 @@ describe "Time.new with a utc_offset argument" do
end
end
- ruby_version_is ""..."3.1" do
- it "raises ArgumentError if the string argument is J" do
- message = '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset'
- -> { Time.new(2000, 1, 1, 0, 0, 0, "J") }.should raise_error(ArgumentError, message)
- end
- end
-
- ruby_version_is "3.1" do
- it "raises ArgumentError if the string argument is J" do
- message = '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: J'
- -> { Time.new(2000, 1, 1, 0, 0, 0, "J") }.should raise_error(ArgumentError, message)
- end
+ it "raises ArgumentError if the string argument is J" do
+ message = '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: J'
+ -> { Time.new(2000, 1, 1, 0, 0, 0, "J") }.should raise_error(ArgumentError, message)
end
it "returns a local Time if the argument is nil" do
@@ -193,6 +182,7 @@ describe "Time.new with a utc_offset argument" do
end
end
+# The method #local_to_utc is tested only here because Time.new is the only method that calls #local_to_utc.
describe "Time.new with a timezone argument" do
it "returns a Time in the timezone" do
zone = TimeSpecs::Timezone.new(offset: (5*3600+30*60))
@@ -213,9 +203,7 @@ describe "Time.new with a timezone argument" do
time
end
- -> {
- Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
- }.should_not raise_error
+ Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
end
it "raises TypeError if timezone does not implement #local_to_utc method" do
@@ -226,7 +214,7 @@ describe "Time.new with a timezone argument" do
-> {
Time.new(2000, 1, 1, 12, 0, 0, zone)
- }.should raise_error(TypeError, /can't convert \w+ into an exact number/)
+ }.should raise_error(TypeError, /can't convert Object into an exact number/)
end
it "does not raise exception if timezone does not implement #utc_to_local method" do
@@ -235,51 +223,48 @@ describe "Time.new with a timezone argument" do
time
end
- -> {
- Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
- }.should_not raise_error
+ Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
end
# The result also should be a Time or Time-like object (not necessary to be the same class)
- # The zone of the result is just ignored
+ # or respond to #to_int method. The zone of the result is just ignored.
describe "returned value by #utc_to_local and #local_to_utc methods" do
it "could be Time instance" do
zone = Object.new
def zone.local_to_utc(t)
- Time.utc(t.year, t.mon, t.day, t.hour - 1, t.min, t.sec)
+ time = Time.utc(t.year, t.mon, t.day, t.hour, t.min, t.sec)
+ time - 60 * 60 # - 1 hour
end
- -> {
- Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
- Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60
- }.should_not raise_error
+ Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
+ Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60
end
it "could be Time subclass instance" do
zone = Object.new
def zone.local_to_utc(t)
- Class.new(Time).utc(t.year, t.mon, t.day, t.hour - 1, t.min, t.sec)
+ time = Time.utc(t.year, t.mon, t.day, t.hour, t.min, t.sec)
+ time -= 60 * 60 # - 1 hour
+ Class.new(Time).utc(time.year, time.mon, time.day, time.hour, t.min, t.sec)
end
- -> {
- Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
- Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60
- }.should_not raise_error
+ Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
+ Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60
end
it "could be any object with #to_i method" do
zone = Object.new
def zone.local_to_utc(time)
- Struct.new(:to_i).new(time.to_i - 60*60)
+ obj = Object.new
+ obj.singleton_class.define_method(:to_i) { time.to_i - 60*60 }
+ obj
end
- -> {
- Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
- Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60
- }.should_not raise_error
+ Time.new(2000, 1, 1, 12, 0, 0, zone).should be_kind_of(Time)
+ Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 60*60
end
- it "could have any #zone and #utc_offset because they are ignored" do
+ it "could have any #zone and #utc_offset because they are ignored if it isn't an instance of Time" do
zone = Object.new
def zone.local_to_utc(time)
Struct.new(:to_i, :zone, :utc_offset).new(time.to_i, 'America/New_York', -5*60*60)
@@ -293,7 +278,15 @@ describe "Time.new with a timezone argument" do
Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 0
end
- it "leads to raising Argument error if difference between argument and result is too large" do
+ it "cannot have arbitrary #utc_offset if it is an instance of Time" do
+ zone = Object.new
+ def zone.local_to_utc(t)
+ Time.new(t.year, t.mon, t.mday, t.hour, t.min, t.sec, 9*60*60)
+ end
+ Time.new(2000, 1, 1, 12, 0, 0, zone).utc_offset.should == 9*60*60
+ end
+
+ it "raises ArgumentError if difference between argument and result is too large" do
zone = Object.new
def zone.local_to_utc(t)
Time.utc(t.year, t.mon, t.day + 1, t.hour, t.min, t.sec)
@@ -318,12 +311,9 @@ describe "Time.new with a timezone argument" do
end
it "implements subset of Time methods" do
+ # List only methods that are explicitly documented.
[
- :year, :mon, :month, :mday, :hour, :min, :sec,
- :tv_sec, :tv_usec, :usec, :tv_nsec, :nsec, :subsec,
- :to_i, :to_f, :to_r, :+, :-,
- :isdst, :dst?, :zone, :gmtoff, :gmt_offset, :utc_offset, :utc?, :gmt?,
- :to_s, :inspect, :to_a, :to_time,
+ :year, :mon, :mday, :hour, :min, :sec, :to_i, :isdst
].each do |name|
@obj.respond_to?(name).should == true
end
@@ -403,79 +393,77 @@ describe "Time.new with a timezone argument" do
end
end
- ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/17485
- describe ":in keyword argument" do
- it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
- time = Time.new(2000, 1, 1, 12, 0, 0, in: "+05:00")
+ describe ":in keyword argument" do
+ it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
+ time = Time.new(2000, 1, 1, 12, 0, 0, in: "+05:00")
- time.utc_offset.should == 5*60*60
- time.zone.should == nil
+ time.utc_offset.should == 5*60*60
+ time.zone.should == nil
- time = Time.new(2000, 1, 1, 12, 0, 0, in: "-09:00")
+ time = Time.new(2000, 1, 1, 12, 0, 0, in: "-09:00")
- time.utc_offset.should == -9*60*60
- time.zone.should == nil
+ time.utc_offset.should == -9*60*60
+ time.zone.should == nil
- time = Time.new(2000, 1, 1, 12, 0, 0, in: "-09:00:01")
+ time = Time.new(2000, 1, 1, 12, 0, 0, in: "-09:00:01")
- time.utc_offset.should == -(9*60*60 + 1)
- time.zone.should == nil
- end
+ time.utc_offset.should == -(9*60*60 + 1)
+ time.zone.should == nil
+ end
- it "could be UTC offset as a number of seconds" do
- time = Time.new(2000, 1, 1, 12, 0, 0, in: 5*60*60)
+ it "could be UTC offset as a number of seconds" do
+ time = Time.new(2000, 1, 1, 12, 0, 0, in: 5*60*60)
- time.utc_offset.should == 5*60*60
- time.zone.should == nil
+ time.utc_offset.should == 5*60*60
+ time.zone.should == nil
- time = Time.new(2000, 1, 1, 12, 0, 0, in: -9*60*60)
+ time = Time.new(2000, 1, 1, 12, 0, 0, in: -9*60*60)
- time.utc_offset.should == -9*60*60
- time.zone.should == nil
- end
+ time.utc_offset.should == -9*60*60
+ time.zone.should == nil
+ end
- it "returns a Time with UTC offset specified as a single letter military timezone" do
- Time.new(2000, 1, 1, 0, 0, 0, in: "W").utc_offset.should == 3600 * -10
- end
+ it "returns a Time with UTC offset specified as a single letter military timezone" do
+ Time.new(2000, 1, 1, 0, 0, 0, in: "W").utc_offset.should == 3600 * -10
+ end
- it "could be a timezone object" do
- zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
- time = Time.new(2000, 1, 1, 12, 0, 0, in: zone)
+ it "could be a timezone object" do
+ zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
+ time = Time.new(2000, 1, 1, 12, 0, 0, in: zone)
- time.utc_offset.should == 5*3600+30*60
- time.zone.should == zone
+ time.utc_offset.should == 5*3600+30*60
+ time.zone.should == zone
- zone = TimeSpecs::TimezoneWithName.new(name: "PST")
- time = Time.new(2000, 1, 1, 12, 0, 0, in: zone)
+ zone = TimeSpecs::TimezoneWithName.new(name: "PST")
+ time = Time.new(2000, 1, 1, 12, 0, 0, in: zone)
- time.utc_offset.should == -9*60*60
- time.zone.should == zone
- end
+ time.utc_offset.should == -9*60*60
+ time.zone.should == zone
+ end
- it "allows omitting minor arguments" do
- Time.new(2000, 1, 1, 12, 1, 1, in: "+05:00").should == Time.new(2000, 1, 1, 12, 1, 1, "+05:00")
- Time.new(2000, 1, 1, 12, 1, in: "+05:00").should == Time.new(2000, 1, 1, 12, 1, 0, "+05:00")
- Time.new(2000, 1, 1, 12, in: "+05:00").should == Time.new(2000, 1, 1, 12, 0, 0, "+05:00")
- Time.new(2000, 1, 1, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
- Time.new(2000, 1, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
- Time.new(2000, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
- Time.new(in: "+05:00").should be_close(Time.now.getlocal("+05:00"), TIME_TOLERANCE)
- end
+ it "allows omitting minor arguments" do
+ Time.new(2000, 1, 1, 12, 1, 1, in: "+05:00").should == Time.new(2000, 1, 1, 12, 1, 1, "+05:00")
+ Time.new(2000, 1, 1, 12, 1, in: "+05:00").should == Time.new(2000, 1, 1, 12, 1, 0, "+05:00")
+ Time.new(2000, 1, 1, 12, in: "+05:00").should == Time.new(2000, 1, 1, 12, 0, 0, "+05:00")
+ Time.new(2000, 1, 1, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
+ Time.new(2000, 1, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
+ Time.new(2000, in: "+05:00").should == Time.new(2000, 1, 1, 0, 0, 0, "+05:00")
+ Time.new(in: "+05:00").should be_close(Time.now.getlocal("+05:00"), TIME_TOLERANCE)
+ end
- it "converts to a provided timezone if all the positional arguments are omitted" do
- Time.new(in: "+05:00").utc_offset.should == 5*3600
- end
+ it "converts to a provided timezone if all the positional arguments are omitted" do
+ Time.new(in: "+05:00").utc_offset.should == 5*3600
+ end
- it "raises ArgumentError if format is invalid" do
- -> { Time.new(2000, 1, 1, 12, 0, 0, in: "+09:99") }.should raise_error(ArgumentError)
- -> { Time.new(2000, 1, 1, 12, 0, 0, in: "ABC") }.should raise_error(ArgumentError)
- end
+ it "raises ArgumentError if format is invalid" do
+ -> { Time.new(2000, 1, 1, 12, 0, 0, in: "+09:99") }.should raise_error(ArgumentError)
+ -> { Time.new(2000, 1, 1, 12, 0, 0, in: "ABC") }.should raise_error(ArgumentError)
+ end
- it "raises ArgumentError if two offset arguments are given" do
- -> {
- Time.new(2000, 1, 1, 12, 0, 0, "+05:00", in: "+05:00")
- }.should raise_error(ArgumentError, "timezone argument given as positional and keyword arguments")
- end
+ it "raises ArgumentError if two offset arguments are given" do
+ -> {
+ Time.new(2000, 1, 1, 12, 0, 0, "+05:00", in: "+05:00")
+ }.should raise_error(ArgumentError, "timezone argument given as positional and keyword arguments")
end
end
diff --git a/spec/ruby/core/time/now_spec.rb b/spec/ruby/core/time/now_spec.rb
index 7c2425411a..f19e015461 100644
--- a/spec/ruby/core/time/now_spec.rb
+++ b/spec/ruby/core/time/now_spec.rb
@@ -4,83 +4,178 @@ require_relative 'shared/now'
describe "Time.now" do
it_behaves_like :time_now, :now
- ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/17485
- describe ":in keyword argument" do
- it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
- time = Time.now(in: "+05:00")
+ describe ":in keyword argument" do
+ it "could be UTC offset as a String in '+HH:MM or '-HH:MM' format" do
+ time = Time.now(in: "+05:00")
- time.utc_offset.should == 5*60*60
- time.zone.should == nil
+ time.utc_offset.should == 5*60*60
+ time.zone.should == nil
- time = Time.now(in: "-09:00")
+ time = Time.now(in: "-09:00")
- time.utc_offset.should == -9*60*60
- time.zone.should == nil
+ time.utc_offset.should == -9*60*60
+ time.zone.should == nil
- time = Time.now(in: "-09:00:01")
+ time = Time.now(in: "-09:00:01")
- time.utc_offset.should == -(9*60*60 + 1)
- time.zone.should == nil
- end
+ time.utc_offset.should == -(9*60*60 + 1)
+ time.zone.should == nil
+ end
- it "could be UTC offset as a number of seconds" do
- time = Time.now(in: 5*60*60)
+ it "could be UTC offset as a number of seconds" do
+ time = Time.now(in: 5*60*60)
- time.utc_offset.should == 5*60*60
- time.zone.should == nil
+ time.utc_offset.should == 5*60*60
+ time.zone.should == nil
- time = Time.now(in: -9*60*60)
+ time = Time.now(in: -9*60*60)
- time.utc_offset.should == -9*60*60
- time.zone.should == nil
- end
+ time.utc_offset.should == -9*60*60
+ time.zone.should == nil
+ end
- it "returns a Time with UTC offset specified as a single letter military timezone" do
- Time.now(in: "W").utc_offset.should == 3600 * -10
- end
+ it "returns a Time with UTC offset specified as a single letter military timezone" do
+ Time.now(in: "W").utc_offset.should == 3600 * -10
+ end
- it "could be a timezone object" do
- zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
- time = Time.now(in: zone)
+ it "could be a timezone object" do
+ zone = TimeSpecs::TimezoneWithName.new(name: "Asia/Colombo")
+ time = Time.now(in: zone)
- time.utc_offset.should == 5*3600+30*60
- time.zone.should == zone
+ time.utc_offset.should == 5*3600+30*60
+ time.zone.should == zone
- zone = TimeSpecs::TimezoneWithName.new(name: "PST")
- time = Time.now(in: zone)
+ zone = TimeSpecs::TimezoneWithName.new(name: "PST")
+ time = Time.now(in: zone)
- time.utc_offset.should == -9*60*60
- time.zone.should == zone
- end
+ time.utc_offset.should == -9*60*60
+ time.zone.should == zone
+ end
+
+ it "raises ArgumentError if format is invalid" do
+ -> { Time.now(in: "+09:99") }.should raise_error(ArgumentError)
+ -> { Time.now(in: "ABC") }.should raise_error(ArgumentError)
+ end
+
+ it "raises ArgumentError if String argument and hours greater than 23" do
+ -> { Time.now(in: "+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.now(in: "+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
+
+ -> { Time.now(in: "+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> { Time.now(in: "+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
+ end
+
+ it "raises ArgumentError if String argument and minutes greater than 59" do
+ -> { Time.now(in: "+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
+ -> { Time.now(in: "+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
+
+ -> { Time.now(in: "+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
+ -> { Time.now(in: "+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
+ end
- it "raises ArgumentError if format is invalid" do
- -> { Time.now(in: "+09:99") }.should raise_error(ArgumentError)
- -> { Time.now(in: "ABC") }.should raise_error(ArgumentError)
+ ruby_bug '#20797', ''...'3.4' do
+ it "raises ArgumentError if String argument and seconds greater than 59" do
+ -> { Time.now(in: "+00:00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:00:60')
+ -> { Time.now(in: "+000060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +000060')
+
+ -> { Time.now(in: "+00:00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:00:99')
+ -> { Time.now(in: "+000099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +000099')
end
+ end
+ end
- it "raises ArgumentError if String argument and hours greater than 23" do
- -> { Time.now(in: "+24:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now(in: "+2400") }.should raise_error(ArgumentError, "utc_offset out of range")
+ ruby_version_is '3.1' do # https://bugs.ruby-lang.org/issues/17485
+ describe "Timezone object" do
+ it "raises TypeError if timezone does not implement #utc_to_local method" do
+ zone = Object.new
+ def zone.local_to_utc(time)
+ time
+ end
- -> { Time.now(in: "+99:00") }.should raise_error(ArgumentError, "utc_offset out of range")
- -> { Time.now(in: "+9900") }.should raise_error(ArgumentError, "utc_offset out of range")
+ -> {
+ Time.now(in: zone)
+ }.should raise_error(TypeError, /can't convert Object into an exact number/)
end
- it "raises ArgumentError if String argument and minutes greater than 59" do
- -> { Time.now(in: "+00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:60')
- -> { Time.now(in: "+0060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0060')
+ it "does not raise exception if timezone does not implement #local_to_utc method" do
+ zone = Object.new
+ def zone.utc_to_local(time)
+ time
+ end
- -> { Time.now(in: "+00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:99')
- -> { Time.now(in: "+0099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +0099')
+ Time.now(in: zone).should be_kind_of(Time)
end
- ruby_bug '#20797', ''...'3.4' do
- it "raises ArgumentError if String argument and seconds greater than 59" do
- -> { Time.now(in: "+00:00:60") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:00:60')
- -> { Time.now(in: "+000060") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +000060')
+ # The result also should be a Time or Time-like object (not necessary to be the same class)
+ # or Integer. The zone of the result is just ignored.
+ describe "returned value by #utc_to_local and #local_to_utc methods" do
+ it "could be Time instance" do
+ zone = Object.new
+ def zone.utc_to_local(t)
+ time = Time.new(t.year, t.mon, t.day, t.hour, t.min, t.sec, t.utc_offset)
+ time + 60 * 60 # + 1 hour
+ end
+
+ Time.now(in: zone).should be_kind_of(Time)
+ Time.now(in: zone).utc_offset.should == 3600
+ end
+
+ it "could be Time subclass instance" do
+ zone = Object.new
+ def zone.utc_to_local(t)
+ time = Time.new(t.year, t.mon, t.day, t.hour, t.min, t.sec, t.utc_offset)
+ time += 60 * 60 # + 1 hour
+
+ Class.new(Time).new(time.year, time.mon, time.day, time.hour, time.min, time.sec, time.utc_offset)
+ end
+
+ Time.now(in: zone).should be_kind_of(Time)
+ Time.now(in: zone).utc_offset.should == 3600
+ end
+
+ it "could be Integer" do
+ zone = Object.new
+ def zone.utc_to_local(time)
+ time.to_i + 60*60
+ end
+
+ Time.now(in: zone).should be_kind_of(Time)
+ Time.now(in: zone).utc_offset.should == 60*60
+ end
+
+ it "could have any #zone and #utc_offset because they are ignored" do
+ zone = Object.new
+ def zone.utc_to_local(t)
+ Struct.new(:year, :mon, :mday, :hour, :min, :sec, :isdst, :to_i, :zone, :utc_offset) # rubocop:disable Lint/StructNewOverride
+ .new(t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.isdst, t.to_i, 'America/New_York', -5*60*60)
+ end
+ Time.now(in: zone).utc_offset.should == 0
+
+ zone = Object.new
+ def zone.utc_to_local(t)
+ Struct.new(:year, :mon, :mday, :hour, :min, :sec, :isdst, :to_i, :zone, :utc_offset) # rubocop:disable Lint/StructNewOverride
+ .new(t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.isdst, t.to_i, 'Asia/Tokyo', 9*60*60)
+ end
+ Time.now(in: zone).utc_offset.should == 0
+
+ zone = Object.new
+ def zone.utc_to_local(t)
+ Time.new(t.year, t.mon, t.mday, t.hour, t.min, t.sec, 9*60*60)
+ end
+ Time.now(in: zone).utc_offset.should == 0
+ end
- -> { Time.now(in: "+00:00:99") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +00:00:99')
- -> { Time.now(in: "+000099") }.should raise_error(ArgumentError, '"+HH:MM", "-HH:MM", "UTC" or "A".."I","K".."Z" expected for utc_offset: +000099')
+ it "raises ArgumentError if difference between argument and result is too large" do
+ zone = Object.new
+ def zone.utc_to_local(t)
+ time = Time.utc(t.year, t.mon, t.day, t.hour, t.min, t.sec, t.utc_offset)
+ time -= 24 * 60 * 60 # - 1 day
+ Time.utc(time.year, time.mon, time.day, time.hour, time.min, time.sec, time.utc_offset)
+ end
+
+ -> {
+ Time.now(in: zone)
+ }.should raise_error(ArgumentError, "utc_offset out of range")
end
end
end
diff --git a/spec/ruby/core/time/strftime_spec.rb b/spec/ruby/core/time/strftime_spec.rb
index 4cb300c916..fd233f3577 100644
--- a/spec/ruby/core/time/strftime_spec.rb
+++ b/spec/ruby/core/time/strftime_spec.rb
@@ -50,44 +50,42 @@ describe "Time#strftime" do
time.strftime("%::z").should == "+01:01:05"
end
- ruby_version_is "3.1" do
- it "supports RFC 3339 UTC for unknown offset local time, -0000, as %-z" do
- time = Time.gm(2022)
-
- time.strftime("%z").should == "+0000"
- time.strftime("%-z").should == "-0000"
- time.strftime("%-:z").should == "-00:00"
- time.strftime("%-::z").should == "-00:00:00"
- end
+ it "supports RFC 3339 UTC for unknown offset local time, -0000, as %-z" do
+ time = Time.gm(2022)
- it "applies '-' flag to UTC time" do
- time = Time.utc(2022)
- time.strftime("%-z").should == "-0000"
+ time.strftime("%z").should == "+0000"
+ time.strftime("%-z").should == "-0000"
+ time.strftime("%-:z").should == "-00:00"
+ time.strftime("%-::z").should == "-00:00:00"
+ end
- time = Time.gm(2022)
- time.strftime("%-z").should == "-0000"
+ it "applies '-' flag to UTC time" do
+ time = Time.utc(2022)
+ time.strftime("%-z").should == "-0000"
- time = Time.new(2022, 1, 1, 0, 0, 0, "Z")
- time.strftime("%-z").should == "-0000"
+ time = Time.gm(2022)
+ time.strftime("%-z").should == "-0000"
- time = Time.new(2022, 1, 1, 0, 0, 0, "-00:00")
- time.strftime("%-z").should == "-0000"
+ time = Time.new(2022, 1, 1, 0, 0, 0, "Z")
+ time.strftime("%-z").should == "-0000"
- time = Time.new(2022, 1, 1, 0, 0, 0, "+03:00").utc
- time.strftime("%-z").should == "-0000"
- end
+ time = Time.new(2022, 1, 1, 0, 0, 0, "-00:00")
+ time.strftime("%-z").should == "-0000"
- it "ignores '-' flag for non-UTC time" do
- time = Time.new(2022, 1, 1, 0, 0, 0, "+03:00")
- time.strftime("%-z").should == "+0300"
- end
+ time = Time.new(2022, 1, 1, 0, 0, 0, "+03:00").utc
+ time.strftime("%-z").should == "-0000"
+ end
- it "works correctly with width, _ and 0 flags, and :" do
- Time.now.utc.strftime("%-_10z").should == " -000"
- Time.now.utc.strftime("%-10z").should == "-000000000"
- Time.now.utc.strftime("%-010:z").should == "-000000:00"
- Time.now.utc.strftime("%-_10:z").should == " -0:00"
- Time.now.utc.strftime("%-_10::z").should == " -0:00:00"
- end
+ it "ignores '-' flag for non-UTC time" do
+ time = Time.new(2022, 1, 1, 0, 0, 0, "+03:00")
+ time.strftime("%-z").should == "+0300"
+ end
+
+ it "works correctly with width, _ and 0 flags, and :" do
+ Time.now.utc.strftime("%-_10z").should == " -000"
+ Time.now.utc.strftime("%-10z").should == "-000000000"
+ Time.now.utc.strftime("%-010:z").should == "-000000:00"
+ Time.now.utc.strftime("%-_10:z").should == " -0:00"
+ Time.now.utc.strftime("%-_10::z").should == " -0:00:00"
end
end
diff --git a/spec/ruby/core/time/utc_spec.rb b/spec/ruby/core/time/utc_spec.rb
index 566509fd33..3d36e13ccf 100644
--- a/spec/ruby/core/time/utc_spec.rb
+++ b/spec/ruby/core/time/utc_spec.rb
@@ -22,10 +22,8 @@ describe "Time#utc?" do
Time.now.localtime("UTC").utc?.should == true
Time.at(Time.now, in: 'UTC').utc?.should == true
- ruby_version_is "3.1" do
- Time.new(2022, 1, 1, 0, 0, 0, in: "UTC").utc?.should == true
- Time.now(in: "UTC").utc?.should == true
- end
+ Time.new(2022, 1, 1, 0, 0, 0, in: "UTC").utc?.should == true
+ Time.now(in: "UTC").utc?.should == true
end
it "does treat time with Z offset as UTC" do
@@ -33,18 +31,14 @@ describe "Time#utc?" do
Time.now.localtime("Z").utc?.should == true
Time.at(Time.now, in: 'Z').utc?.should == true
- ruby_version_is "3.1" do
- Time.new(2022, 1, 1, 0, 0, 0, in: "Z").utc?.should == true
- Time.now(in: "Z").utc?.should == true
- end
+ Time.new(2022, 1, 1, 0, 0, 0, in: "Z").utc?.should == true
+ Time.now(in: "Z").utc?.should == true
end
- ruby_version_is "3.1" do
- it "does treat time with -00:00 offset as UTC" do
- Time.new(2022, 1, 1, 0, 0, 0, "-00:00").utc?.should == true
- Time.now.localtime("-00:00").utc?.should == true
- Time.at(Time.now, in: '-00:00').utc?.should == true
- end
+ it "does treat time with -00:00 offset as UTC" do
+ Time.new(2022, 1, 1, 0, 0, 0, "-00:00").utc?.should == true
+ Time.now.localtime("-00:00").utc?.should == true
+ Time.at(Time.now, in: '-00:00').utc?.should == true
end
it "does not treat time with +00:00 offset as UTC" do
diff --git a/spec/ruby/core/time/zone_spec.rb b/spec/ruby/core/time/zone_spec.rb
index 63c92602d1..9a15bd569b 100644
--- a/spec/ruby/core/time/zone_spec.rb
+++ b/spec/ruby/core/time/zone_spec.rb
@@ -69,22 +69,18 @@ describe "Time#zone" do
Time.at(Time.now, in: 'UTC').zone.should == "UTC"
Time.at(Time.now, in: 'Z').zone.should == "UTC"
- ruby_version_is "3.1" do
- Time.new(2022, 1, 1, 0, 0, 0, "-00:00").zone.should == "UTC"
- Time.now.localtime("-00:00").zone.should == "UTC"
- Time.at(Time.now, in: '-00:00').zone.should == "UTC"
- end
+ Time.new(2022, 1, 1, 0, 0, 0, "-00:00").zone.should == "UTC"
+ Time.now.localtime("-00:00").zone.should == "UTC"
+ Time.at(Time.now, in: '-00:00').zone.should == "UTC"
- ruby_version_is "3.1" do
- Time.new(2022, 1, 1, 0, 0, 0, in: "UTC").zone.should == "UTC"
- Time.new(2022, 1, 1, 0, 0, 0, in: "Z").zone.should == "UTC"
+ Time.new(2022, 1, 1, 0, 0, 0, in: "UTC").zone.should == "UTC"
+ Time.new(2022, 1, 1, 0, 0, 0, in: "Z").zone.should == "UTC"
- Time.now(in: 'UTC').zone.should == "UTC"
- Time.now(in: 'Z').zone.should == "UTC"
+ Time.now(in: 'UTC').zone.should == "UTC"
+ Time.now(in: 'Z').zone.should == "UTC"
- Time.at(Time.now, in: 'UTC').zone.should == "UTC"
- Time.at(Time.now, in: 'Z').zone.should == "UTC"
- end
+ Time.at(Time.now, in: 'UTC').zone.should == "UTC"
+ Time.at(Time.now, in: 'Z').zone.should == "UTC"
end
platform_is_not :aix, :windows do
diff --git a/spec/ruby/core/tracepoint/allow_reentry_spec.rb b/spec/ruby/core/tracepoint/allow_reentry_spec.rb
index 6bff1bed76..75e9e859a9 100644
--- a/spec/ruby/core/tracepoint/allow_reentry_spec.rb
+++ b/spec/ruby/core/tracepoint/allow_reentry_spec.rb
@@ -1,32 +1,30 @@
require_relative '../../spec_helper'
require_relative 'fixtures/classes'
-ruby_version_is "3.1" do
- describe 'TracePoint.allow_reentry' do
- it 'allows the reentrance in a given block' do
- event_lines = []
- l1 = l2 = l3 = l4 = nil
- TracePoint.new(:line) do |tp|
- next unless TracePointSpec.target_thread?
+describe 'TracePoint.allow_reentry' do
+ it 'allows the reentrance in a given block' do
+ event_lines = []
+ l1 = l2 = l3 = l4 = nil
+ TracePoint.new(:line) do |tp|
+ next unless TracePointSpec.target_thread?
- event_lines << tp.lineno
- next if (__LINE__ + 2 .. __LINE__ + 4).cover?(tp.lineno)
- TracePoint.allow_reentry do
- a = 1; l3 = __LINE__
- b = 2; l4 = __LINE__
- end
- end.enable do
- c = 3; l1 = __LINE__
- d = 4; l2 = __LINE__
+ event_lines << tp.lineno
+ next if (__LINE__ + 2 .. __LINE__ + 4).cover?(tp.lineno)
+ TracePoint.allow_reentry do
+ a = 1; l3 = __LINE__
+ b = 2; l4 = __LINE__
end
-
- event_lines.should == [l1, l3, l4, l2, l3, l4]
+ end.enable do
+ c = 3; l1 = __LINE__
+ d = 4; l2 = __LINE__
end
- it 'raises RuntimeError when not called inside a TracePoint' do
- -> {
- TracePoint.allow_reentry{}
- }.should raise_error(RuntimeError)
- end
+ event_lines.should == [l1, l3, l4, l2, l3, l4]
+ end
+
+ it 'raises RuntimeError when not called inside a TracePoint' do
+ -> {
+ TracePoint.allow_reentry{}
+ }.should raise_error(RuntimeError)
end
end
diff --git a/spec/ruby/core/unboundmethod/private_spec.rb b/spec/ruby/core/unboundmethod/private_spec.rb
index 8ea50bb5d4..9a890db6fd 100644
--- a/spec/ruby/core/unboundmethod/private_spec.rb
+++ b/spec/ruby/core/unboundmethod/private_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "UnboundMethod#private?" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "returns false when the method is public" do
obj = UnboundMethodSpecs::Methods.new
obj.method(:my_public_method).unbind.private?.should == false
diff --git a/spec/ruby/core/unboundmethod/protected_spec.rb b/spec/ruby/core/unboundmethod/protected_spec.rb
index 0c215d8638..b79e2da63b 100644
--- a/spec/ruby/core/unboundmethod/protected_spec.rb
+++ b/spec/ruby/core/unboundmethod/protected_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "UnboundMethod#protected?" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "returns false when the method is public" do
obj = UnboundMethodSpecs::Methods.new
obj.method(:my_public_method).unbind.protected?.should == false
diff --git a/spec/ruby/core/unboundmethod/public_spec.rb b/spec/ruby/core/unboundmethod/public_spec.rb
index 552bbf6eab..c2a2795a84 100644
--- a/spec/ruby/core/unboundmethod/public_spec.rb
+++ b/spec/ruby/core/unboundmethod/public_spec.rb
@@ -2,7 +2,7 @@ require_relative '../../spec_helper'
require_relative 'fixtures/classes'
describe "UnboundMethod#public?" do
- ruby_version_is "3.1"..."3.2" do
+ ruby_version_is ""..."3.2" do
it "returns true when the method is public" do
obj = UnboundMethodSpecs::Methods.new
obj.method(:my_public_method).unbind.public?.should == true
diff --git a/spec/ruby/core/unboundmethod/source_location_spec.rb b/spec/ruby/core/unboundmethod/source_location_spec.rb
index 45bd69438c..2391d07d99 100644
--- a/spec/ruby/core/unboundmethod/source_location_spec.rb
+++ b/spec/ruby/core/unboundmethod/source_location_spec.rb
@@ -61,5 +61,5 @@ describe "UnboundMethod#source_location" do
ruby_version_is("3.5") do
location.should == ["foo", 100, 0, 100, 10]
end
- end
+ end
end