Update to ruby/spec@5e579e2
This commit is contained in:
parent
53a930f157
commit
bac22c985e
Notes:
git
2025-03-27 10:09:42 +00:00
@ -30,8 +30,8 @@ ruby/spec is known to be tested in these implementations for every commit:
|
||||
* [Opal](https://github.com/opal/opal/tree/master/spec)
|
||||
* [Artichoke](https://github.com/artichoke/spec/tree/artichoke-vendor)
|
||||
|
||||
ruby/spec describes the behavior of Ruby 3.0 and more recent Ruby versions.
|
||||
More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (3.0.x, 3.1.x, 3.2.x, etc), and those are tested in CI.
|
||||
ruby/spec describes the behavior of Ruby 3.1 and more recent Ruby versions.
|
||||
More precisely, every latest stable MRI release should [pass](https://github.com/ruby/spec/actions/workflows/ci.yml) all specs of ruby/spec (3.1.x, 3.2.x, etc), and those are tested in CI.
|
||||
|
||||
### Synchronization with Ruby Implementations
|
||||
|
||||
@ -62,6 +62,7 @@ For older specs try these commits:
|
||||
* Ruby 2.5.9 - [Suite](https://github.com/ruby/spec/commit/c503335d3d9f6ec6ef24de60a0716c34af69b64f) using [MSpec](https://github.com/ruby/mspec/commit/0091e8a62e954717cd54641f935eaf1403692041)
|
||||
* Ruby 2.6.10 - [Suite](https://github.com/ruby/spec/commit/aaf998fb8c92c4e63ad423a2e7ca6e6921818c6e) using [MSpec](https://github.com/ruby/mspec/commit/5e36c684e9e2b92b1187589bba1df22c640a8661)
|
||||
* Ruby 2.7.8 - [Suite](https://github.com/ruby/spec/commit/93787e6035c925b593a9c0c6fb0e7e07a6f1df1f) using [MSpec](https://github.com/ruby/mspec/commit/1d8cf64722d8a7529f7cd205be5f16a89b7a67fd)
|
||||
* Ruby 3.0.7 - [Suite](https://github.com/ruby/spec/commit/affef93d9940f615e4836f64b011da211f570913) using [MSpec](https://github.com/ruby/mspec/commit/0aabb3e548eb5ea6cad0125f8f46cee34542b6b7)
|
||||
|
||||
### Running the specs
|
||||
|
||||
|
@ -2,7 +2,6 @@ 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
|
||||
@ -62,5 +61,4 @@ describe 'Array#intersect?' do
|
||||
[].intersect?([]).should == false
|
||||
[nil].intersect?([nil]).should == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -141,23 +141,12 @@ 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
|
||||
|
||||
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
|
||||
end
|
||||
|
||||
it "looks in the caller class next" do
|
||||
receiver = BasicObjectSpecs::InstEval::Constants::ConstantInCallerClass::ReceiverScope::Receiver.new
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,8 +1,7 @@
|
||||
require_relative '../../spec_helper'
|
||||
require_relative '../module/fixtures/classes'
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
describe "Class#subclasses" 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
|
||||
@ -83,5 +82,4 @@ ruby_version_is '3.1' do
|
||||
def assert_subclasses(mod,subclasses)
|
||||
mod.subclasses.sort_by(&:inspect).should == subclasses.sort_by(&:inspect)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
107
spec/ruby/core/data/deconstruct_keys_spec.rb
Normal file
107
spec/ruby/core/data/deconstruct_keys_spec.rb
Normal file
@ -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
|
10
spec/ruby/core/data/deconstruct_spec.rb
Normal file
10
spec/ruby/core/data/deconstruct_spec.rb
Normal file
@ -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
|
65
spec/ruby/core/data/eql_spec.rb
Normal file
65
spec/ruby/core/data/eql_spec.rb
Normal file
@ -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
|
65
spec/ruby/core/data/equal_value_spec.rb
Normal file
65
spec/ruby/core/data/equal_value_spec.rb
Normal file
@ -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
|
@ -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
|
||||
|
27
spec/ruby/core/data/hash_spec.rb
Normal file
27
spec/ruby/core/data/hash_spec.rb
Normal file
@ -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
|
8
spec/ruby/core/data/inspect_spec.rb
Normal file
8
spec/ruby/core/data/inspect_spec.rb
Normal file
@ -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
|
23
spec/ruby/core/data/members_spec.rb
Normal file
23
spec/ruby/core/data/members_spec.rb
Normal file
@ -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
|
54
spec/ruby/core/data/shared/inspect.rb
Normal file
54
spec/ruby/core/data/shared/inspect.rb
Normal file
@ -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
|
8
spec/ruby/core/data/to_s_spec.rb
Normal file
8
spec/ruby/core/data/to_s_spec.rb
Normal file
@ -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
|
@ -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')
|
||||
|
@ -89,21 +89,6 @@ 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/.
|
||||
@ -114,7 +99,6 @@ describe "Dir.glob" do
|
||||
|
||||
Dir.glob('nested/**/*', File::FNM_DOTMATCH).sort.should == expected.sort
|
||||
end
|
||||
end
|
||||
|
||||
# This is a separate case to check **/ coming after a constant
|
||||
# directory as well.
|
||||
@ -260,8 +244,6 @@ 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[
|
||||
.
|
||||
@ -288,7 +270,6 @@ describe "Dir.glob" do
|
||||
|
||||
Dir.glob('**/**', File::FNM_DOTMATCH, base: "deeply/nested").sort.should == expected
|
||||
end
|
||||
end
|
||||
|
||||
it "handles **/*pattern* with base keyword argument and FNM_DOTMATCH" do
|
||||
expected = %w[
|
||||
|
@ -42,26 +42,11 @@ 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
|
||||
end
|
||||
|
||||
it "matches non-dotfiles with '*'" do
|
||||
expected = %w[
|
||||
@ -151,17 +136,9 @@ 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
|
||||
end
|
||||
|
||||
it "matches non-dotfiles with '*<non-special characters>'" do
|
||||
Dir.send(@method, '*file').sort.should == %w|nondotfile|.sort
|
||||
@ -205,17 +182,9 @@ 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
|
||||
end
|
||||
|
||||
it "recursively matches any nondot subdirectories with '**/'" do
|
||||
expected = %w[
|
||||
@ -245,21 +214,11 @@ 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
|
||||
end
|
||||
end
|
||||
|
||||
it "matches a single character except leading '.' with '?'" do
|
||||
Dir.send(@method, '?ubdir_one').sort.should == %w|subdir_one|.sort
|
||||
|
@ -1,11 +1,9 @@
|
||||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
describe "Enumerable#compact" 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
|
||||
end
|
||||
end
|
||||
|
@ -56,11 +56,9 @@ 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
|
||||
end
|
||||
|
||||
describe "when no block is given" do
|
||||
it "returns an enumerator" do
|
||||
|
@ -57,11 +57,9 @@ 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
|
||||
end
|
||||
|
||||
it "gathers whole arrays as elements when each yields multiple" do
|
||||
multi = EnumerableSpecs::YieldsMulti.new
|
||||
|
@ -32,8 +32,7 @@ describe "Enumerable#tally" do
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "Enumerable#tally with a hash" do
|
||||
describe "Enumerable#tally with a hash" do
|
||||
before :each do
|
||||
ScratchPad.record []
|
||||
end
|
||||
@ -89,5 +88,4 @@ ruby_version_is "3.1" do
|
||||
enum = EnumerableSpecs::Numerous.new('foo')
|
||||
-> { enum.tally({ 'foo' => 'bar' }) }.should raise_error(TypeError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,8 +1,7 @@
|
||||
require_relative '../../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is '3.1' do
|
||||
describe "Enumerator::Lazy#compact" 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)
|
||||
@ -12,5 +11,4 @@ ruby_version_is '3.1' do
|
||||
it "sets #size to nil" do
|
||||
Enumerator::Lazy.new(Object.new, 100) {}.compact.size.should == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -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
|
||||
|
2
spec/ruby/core/env/dup_spec.rb
vendored
2
spec/ruby/core/env/dup_spec.rb
vendored
@ -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
|
||||
end
|
||||
end
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -1,7 +1,5 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
require 'fiber'
|
||||
|
||||
describe "Fiber#alive?" do
|
||||
it "returns true for a Fiber that hasn't had #resume called" do
|
||||
fiber = Fiber.new { true }
|
@ -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? }
|
||||
|
||||
|
@ -1,14 +1,6 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
require 'fiber'
|
||||
|
||||
describe "Fiber.current" do
|
||||
ruby_version_is "3.1" do
|
||||
it "is available without an extra require" do
|
||||
ruby_exe("print Fiber.current.class", options: '--disable-gems --disable-did-you-mean').should == "Fiber"
|
||||
end
|
||||
end
|
||||
|
||||
it "returns the root Fiber when called outside of a Fiber" do
|
||||
root = Fiber.current
|
||||
root.should be_an_instance_of(Fiber)
|
@ -1,5 +1,4 @@
|
||||
require_relative '../../spec_helper'
|
||||
require 'fiber'
|
||||
|
||||
describe "Fiber#inspect" do
|
||||
describe "status" do
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,7 +1,5 @@
|
||||
require_relative '../../spec_helper'
|
||||
require_relative '../../shared/fiber/resume'
|
||||
|
||||
require 'fiber'
|
||||
require_relative 'shared/resume'
|
||||
|
||||
describe "Fiber#transfer" do
|
||||
it_behaves_like :fiber_resume, :transfer
|
@ -11,7 +11,6 @@ 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 == '/'
|
||||
@ -40,7 +39,6 @@ describe "File.dirname" do
|
||||
File.dirname("/a/b/c/d", object).should == '/a/b'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "returns a String" do
|
||||
File.dirname("foo").should be_kind_of(String)
|
||||
|
@ -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
|
||||
|
@ -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 )
|
||||
|
@ -1,7 +1,6 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "GC.measure_total_time" do
|
||||
describe "GC.measure_total_time" do
|
||||
before :each do
|
||||
@default = GC.measure_total_time
|
||||
end
|
||||
@ -15,5 +14,4 @@ ruby_version_is "3.1" do
|
||||
GC.measure_total_time = !original
|
||||
GC.measure_total_time.should == !original
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,7 +1,6 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "GC.total_time" do
|
||||
describe "GC.total_time" do
|
||||
it "returns an Integer" do
|
||||
GC.total_time.should be_kind_of(Integer)
|
||||
end
|
||||
@ -11,5 +10,4 @@ ruby_version_is "3.1" do
|
||||
GC.start
|
||||
GC.total_time.should >= time_before
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -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
|
||||
|
||||
eval('{a:, b:}.should == { a: 1, b: 2 }')
|
||||
end
|
||||
{a:, b:}.should == { a: 1, b: 2 }
|
||||
end
|
||||
end
|
||||
|
@ -76,17 +76,6 @@ 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
|
||||
@ -94,7 +83,6 @@ describe "Hash#transform_keys!" do
|
||||
end
|
||||
@hash.should == { b: 1, c: 2, d: 4 }
|
||||
end
|
||||
end
|
||||
|
||||
it "keeps later pair if new keys conflict" do
|
||||
@hash.transform_keys! { |_| :a }.should == { a: 4 }
|
||||
|
@ -1,8 +1,7 @@
|
||||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "Integer.try_convert" 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)
|
||||
@ -46,5 +45,4 @@ ruby_version_is "3.1" do
|
||||
obj.should_receive(:to_int).and_raise(RuntimeError)
|
||||
-> { Integer.try_convert obj }.should raise_error(RuntimeError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -94,13 +94,11 @@ 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
|
||||
end
|
||||
|
||||
describe "with 'r' mode" do
|
||||
describe "when Encoding.default_internal is nil" do
|
||||
|
@ -113,13 +113,11 @@ 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
|
||||
end
|
||||
|
||||
describe "with 'r' mode" do
|
||||
it_behaves_like :io_internal_encoding, nil, "r"
|
||||
|
@ -93,13 +93,11 @@ 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
|
||||
end
|
||||
|
||||
it "preserves the encoding of the given buffer" do
|
||||
buffer = ''.encode(Encoding::ISO_8859_1)
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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')
|
||||
|
@ -165,7 +165,6 @@ 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
|
||||
@ -197,7 +196,6 @@ describe :kernel_load, shared: true do
|
||||
mod.private_instance_methods.include?(:load_wrap_specs_top_level_method).should == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "(shell expansion)" do
|
||||
before :each do
|
||||
|
@ -30,17 +30,9 @@ 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
|
||||
end
|
||||
|
||||
it "raises a NameError when at least one of given method names is undefined" do
|
||||
-> do
|
||||
|
@ -30,17 +30,9 @@ 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
|
||||
end
|
||||
|
||||
|
||||
it "raises a NameError when given an undefined name" do
|
||||
|
@ -599,7 +599,6 @@ 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
|
||||
@ -613,7 +612,6 @@ describe "Marshal.dump" do
|
||||
|
||||
Marshal.dump(h).should == "\x04\bC:\rUserHashC:\tHash{\x00"
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a TypeError with hash having default proc" do
|
||||
-> { Marshal.dump(Hash.new {}) }.should raise_error(TypeError, "can't dump hash with default proc")
|
||||
|
@ -23,7 +23,6 @@ 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)
|
||||
@ -222,10 +221,8 @@ describe :marshal_load, shared: true do
|
||||
end
|
||||
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|
|
||||
@ -241,7 +238,6 @@ describe :marshal_load, shared: true do
|
||||
string = Marshal.load(Marshal.dump("foo"), :freeze.to_proc)
|
||||
string.should.frozen?
|
||||
end
|
||||
end
|
||||
|
||||
ruby_bug "#19427", ""..."3.3" do
|
||||
it "call the proc with extended objects" do
|
||||
@ -255,7 +251,6 @@ describe :marshal_load, shared: true do
|
||||
Marshal.send(@method, Marshal.dump([1,2]), proc { [3,4] }).should == [3,4]
|
||||
end
|
||||
|
||||
ruby_bug "#18141", ""..."3.1" do
|
||||
it "calls the proc for recursively visited data" do
|
||||
a = [1]
|
||||
a << a
|
||||
@ -290,7 +285,6 @@ describe :marshal_load, shared: true do
|
||||
Struct.send(:remove_const, :Brittle)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "when called with nil for the proc argument" do
|
||||
it "behaves as if no proc argument was passed" do
|
||||
@ -364,7 +358,6 @@ 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 }
|
||||
@ -397,7 +390,6 @@ describe :marshal_load, shared: true do
|
||||
|
||||
arr.size.should == 6
|
||||
end
|
||||
end
|
||||
|
||||
it "assigns classes to nested subclasses of Array correctly" do
|
||||
arr = ArraySub.new(ArraySub.new)
|
||||
@ -526,7 +518,6 @@ 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
|
||||
@ -548,7 +539,6 @@ describe :marshal_load, shared: true do
|
||||
unmarshalled = Marshal.send(@method, Marshal.dump(h))
|
||||
unmarshalled.should_not.compare_by_identity?
|
||||
end
|
||||
end
|
||||
|
||||
it "allocates an instance of the proper class when Hash subclass with compare_by_identity behaviour" do
|
||||
h = UserHash.new({ a: 1 })
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "MatchData#match_length" do
|
||||
describe "MatchData#match_length" do
|
||||
it "returns the length of the corresponding match when given an Integer" do
|
||||
md = /(.)(.)(\d+)(\d)/.match("THX1138.")
|
||||
|
||||
@ -30,5 +29,4 @@ ruby_version_is "3.1" do
|
||||
md.match_length(:t).should == 1
|
||||
md.match_length(:a).should == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -2,8 +2,7 @@
|
||||
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "MatchData#match" do
|
||||
describe "MatchData#match" do
|
||||
it "returns the corresponding match when given an Integer" do
|
||||
md = /(.)(.)(\d+)(\d)/.match("THX1138.")
|
||||
|
||||
@ -30,5 +29,4 @@ ruby_version_is "3.1" do
|
||||
md.match(:t).should == 't'
|
||||
md.match(:a).should == nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -257,31 +257,18 @@ 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
|
||||
end
|
||||
|
||||
object.method(:foo).parameters.should == [[:block, :&]]
|
||||
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
|
||||
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
|
||||
end
|
||||
|
||||
it "returns the args and block for a splat and block argument" do
|
||||
m = MethodSpecs::Methods.new
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -486,7 +486,6 @@ 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 []
|
||||
@ -503,26 +502,6 @@ describe "Module#autoload" do
|
||||
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
|
||||
|
||||
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 have_constant(:O)
|
||||
ModuleSpecs::Autoload.autoload?(:O).should == nil
|
||||
-> { ModuleSpecs::Autoload.const_get(:O) }.should raise_error(NameError)
|
||||
end
|
||||
end
|
||||
|
||||
it "does not try to load the file again if the loaded file did not define the constant" do
|
||||
path = fixture(__FILE__, "autoload_o.rb")
|
||||
@ -654,7 +633,6 @@ 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
|
||||
@ -674,30 +652,6 @@ describe "Module#autoload" do
|
||||
DeclaredInCurrentDefinedInParent.should == :declared_in_current_defined_in_parent
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
it "in the included modules" do
|
||||
@remove << :DefinedInIncludedModule
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -38,16 +38,6 @@ 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
|
||||
@ -55,7 +45,6 @@ describe "Module#module_function with specific method names" do
|
||||
module_function(:foo, :foo).should == [:foo, :foo]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "creates an independent copy of the method, not a redirect" do
|
||||
module Mixin
|
||||
@ -216,21 +205,11 @@ 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
|
||||
end
|
||||
end
|
||||
|
||||
it "stops creating module functions if the body encounters another toggle " \
|
||||
"like public/protected/private without arguments" do
|
||||
|
@ -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
|
||||
|
@ -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,22 +807,6 @@ 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]
|
||||
|
||||
b.prepend(m)
|
||||
b.ancestors.take(4).should == [b, m, a, Object]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
it "modifies the ancestor chain" do
|
||||
m = Module.new do; end
|
||||
a = Module.new do; end
|
||||
@ -816,7 +820,6 @@ describe "Module#prepend" do
|
||||
b.ancestors.take(5).should == [m, b, m, a, Object]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "called on a module" do
|
||||
describe "included into a class"
|
||||
|
@ -38,17 +38,6 @@ 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
|
||||
@ -58,7 +47,6 @@ describe "Module#private" do
|
||||
private.should equal(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a NameError when given an undefined name" do
|
||||
-> do
|
||||
|
@ -39,17 +39,6 @@ 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
|
||||
@ -59,7 +48,6 @@ describe "Module#protected" do
|
||||
protected.should equal(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a NameError when given an undefined name" do
|
||||
-> do
|
||||
|
@ -27,17 +27,6 @@ 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
|
||||
@ -47,7 +36,6 @@ describe "Module#public" do
|
||||
public.should equal(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "raises a NameError when given an undefined name" do
|
||||
-> do
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -193,7 +193,6 @@ 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
|
||||
@ -213,5 +212,4 @@ describe "ObjectSpace.define_finalizer" do
|
||||
ruby_exe(code, args: "2>&1", options: "-W0").should == ""
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
27
spec/ruby/core/objectspace/weakkeymap/clear_spec.rb
Normal file
27
spec/ruby/core/objectspace/weakkeymap/clear_spec.rb
Normal file
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
key = +"a"
|
||||
map[key] = 1
|
||||
|
||||
map.getkey("a").should.equal? key
|
||||
map.getkey("a").should_not.frozen?
|
||||
|
||||
key.should == "a" # keep the key alive until here to keep the map entry
|
||||
end
|
||||
|
||||
it "rejects integers as keys" do
|
||||
context "a key cannot be garbage collected" do
|
||||
it "raises ArgumentError when Integer is used as a key" do
|
||||
map = ObjectSpace::WeakKeyMap.new
|
||||
should_not_accept(map, 42, true)
|
||||
should_not_accept(map, 2 ** 68, true)
|
||||
-> { map[1] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
|
||||
end
|
||||
|
||||
it "rejects floats as keys" do
|
||||
it "raises ArgumentError when Float is used as a key" do
|
||||
map = ObjectSpace::WeakKeyMap.new
|
||||
should_not_accept(map, 4.2, true)
|
||||
-> { map[1.0] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
|
||||
end
|
||||
|
||||
it "rejects booleans as keys" do
|
||||
it "raises ArgumentError when Symbol is used as a key" do
|
||||
map = ObjectSpace::WeakKeyMap.new
|
||||
should_not_accept(map, true, true)
|
||||
should_not_accept(map, false, true)
|
||||
-> { map[:a] = "x" }.should raise_error(ArgumentError, /WeakKeyMap (keys )?must be garbage collectable/)
|
||||
end
|
||||
|
||||
it "rejects nil as keys" do
|
||||
it "raises ArgumentError when true is used as a key" do
|
||||
map = ObjectSpace::WeakKeyMap.new
|
||||
should_not_accept(map, nil, true)
|
||||
-> { 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
|
||||
|
@ -0,0 +1,5 @@
|
||||
module WeakKeyMapSpecs
|
||||
class KeyWithPrivateHash
|
||||
private :hash
|
||||
end
|
||||
end
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
-> & {}.parameters.should == [[:block, :&]]
|
||||
end
|
||||
|
||||
it "does not add locals as block options with a block and splat" do
|
||||
|
@ -1,7 +1,6 @@
|
||||
require_relative '../../spec_helper'
|
||||
|
||||
ruby_version_is "3.1" do
|
||||
describe "Process._fork" 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
|
||||
@ -20,5 +19,4 @@ ruby_version_is "3.1" do
|
||||
pid.should equal(42)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
17
spec/ruby/core/process/tms/cstime_spec.rb
Normal file
17
spec/ruby/core/process/tms/cstime_spec.rb
Normal file
@ -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
|
17
spec/ruby/core/process/tms/cutime_spec.rb
Normal file
17
spec/ruby/core/process/tms/cutime_spec.rb
Normal file
@ -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
|
17
spec/ruby/core/process/tms/stime_spec.rb
Normal file
17
spec/ruby/core/process/tms/stime_spec.rb
Normal file
@ -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
|
17
spec/ruby/core/process/tms/utime_spec.rb
Normal file
17
spec/ruby/core/process/tms/utime_spec.rb
Normal file
@ -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
|
@ -11,7 +11,6 @@ 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])
|
||||
q.size.should == 3
|
||||
@ -58,5 +57,4 @@ describe "Queue#initialize" do
|
||||
|
||||
-> { Queue.new(enumerable) }.should raise_error(TypeError, "can't convert MockObject to Array (MockObject#to_a gives String)")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -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,7 +82,6 @@ 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
|
||||
@ -92,18 +91,6 @@ describe "Range#each" do
|
||||
(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
|
||||
end
|
||||
|
||||
it "passes each Symbol element by using #succ" do
|
||||
(:aa..:ac).each.to_a.should == [:aa, :ab, :ac]
|
||||
|
@ -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")
|
||||
|
@ -322,14 +322,12 @@ 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])
|
||||
|
||||
(1.0...55.6).step(18.2).size.should == 4
|
||||
end
|
||||
end
|
||||
|
||||
it "handles infinite values at either end" do
|
||||
(-Float::INFINITY...0.0).step(2) { |x| ScratchPad << x; break if ScratchPad.recorded.size == 3 }
|
||||
@ -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
|
||||
|
@ -2,7 +2,6 @@ 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
|
||||
@ -265,5 +264,4 @@ describe "Refinement#import_methods" do
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -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
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user