mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Update to ruby/spec@b0b7f53
This commit is contained in:
parent
acbe7aa197
commit
6d05967468
27 changed files with 703 additions and 76 deletions
|
@ -113,6 +113,9 @@ Lint/Debugger:
|
|||
Exclude:
|
||||
- 'core/binding/fixtures/irb.rb'
|
||||
|
||||
Lint/Loop:
|
||||
Enabled: false
|
||||
|
||||
Style/Lambda:
|
||||
Enabled: true
|
||||
EnforcedStyle: literal
|
||||
|
|
|
@ -76,12 +76,6 @@ Lint/LiteralInInterpolation:
|
|||
- 'language/undef_spec.rb'
|
||||
- 'library/net/ftp/connect_spec.rb'
|
||||
|
||||
# Offense count: 16
|
||||
Lint/Loop:
|
||||
Exclude:
|
||||
- 'language/until_spec.rb'
|
||||
- 'language/while_spec.rb'
|
||||
|
||||
# Offense count: 8
|
||||
# Cop supports --auto-correct.
|
||||
Lint/MultipleComparison:
|
||||
|
|
|
@ -90,7 +90,7 @@ describe "Array#flatten" do
|
|||
ArraySpecs::MyArray[].flatten.should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, 2, 3].flatten.should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, [2], 3].flatten.should be_an_instance_of(Array)
|
||||
ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == Array[1, 2, 3, 4]
|
||||
ArraySpecs::MyArray[1, [2, 3], 4].flatten.should == [1, 2, 3, 4]
|
||||
[ArraySpecs::MyArray[1, 2, 3]].flatten.should be_an_instance_of(Array)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,4 +47,12 @@ describe "Errno::ENOTSUP" do
|
|||
it "is defined" do
|
||||
Errno.should have_constant(:ENOTSUP)
|
||||
end
|
||||
|
||||
it "is the same class as Errno::EOPNOTSUPP if they represent the same errno value" do
|
||||
if Errno::ENOTSUP::Errno == Errno::EOPNOTSUPP::Errno
|
||||
Errno::ENOTSUP.should == Errno::EOPNOTSUPP
|
||||
else
|
||||
Errno::ENOTSUP.should_not == Errno::EOPNOTSUPP
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
17
spec/ruby/core/exception/system_exit_spec.rb
Normal file
17
spec/ruby/core/exception/system_exit_spec.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
describe "SystemExit" do
|
||||
it "sets the exit status and exits silently when raised" do
|
||||
code = 'raise SystemExit.new(7)'
|
||||
result = ruby_exe(code, args: "2>&1")
|
||||
result.should == ""
|
||||
$?.exitstatus.should == 7
|
||||
end
|
||||
|
||||
it "sets the exit status and exits silently when raised when subclassed" do
|
||||
code = 'class CustomExit < SystemExit; end; raise CustomExit.new(8)'
|
||||
result = ruby_exe(code, args: "2>&1")
|
||||
result.should == ""
|
||||
$?.exitstatus.should == 8
|
||||
end
|
||||
end
|
12
spec/ruby/core/fiber/fixtures/classes.rb
Normal file
12
spec/ruby/core/fiber/fixtures/classes.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
module FiberSpecs
|
||||
|
||||
class NewFiberToRaise
|
||||
def self.raise(*args)
|
||||
fiber = Fiber.new { Fiber.yield }
|
||||
fiber.resume
|
||||
fiber.raise(*args)
|
||||
end
|
||||
end
|
||||
|
||||
class CustomError < StandardError; end
|
||||
end
|
76
spec/ruby/core/fiber/raise_spec.rb
Normal file
76
spec/ruby/core/fiber/raise_spec.rb
Normal file
|
@ -0,0 +1,76 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative 'fixtures/classes'
|
||||
require_relative '../../shared/kernel/raise'
|
||||
|
||||
ruby_version_is "2.7" do
|
||||
describe "Fiber#raise" do
|
||||
it_behaves_like :kernel_raise, :raise, FiberSpecs::NewFiberToRaise
|
||||
end
|
||||
|
||||
describe "Fiber#raise" do
|
||||
it 'raises RuntimeError by default' do
|
||||
-> { FiberSpecs::NewFiberToRaise.raise }.should raise_error(RuntimeError)
|
||||
end
|
||||
|
||||
it "raises FiberError if Fiber is not born" do
|
||||
fiber = Fiber.new { true }
|
||||
-> { fiber.raise }.should raise_error(FiberError, "cannot raise exception on unborn fiber")
|
||||
end
|
||||
|
||||
it "raises FiberError if Fiber is dead" do
|
||||
fiber = Fiber.new { true }
|
||||
fiber.resume
|
||||
-> { fiber.raise }.should raise_error(FiberError, /dead fiber called|attempt to resume a terminated fiber/)
|
||||
end
|
||||
|
||||
it 'accepts error class' do
|
||||
-> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError }.should raise_error(FiberSpecs::CustomError)
|
||||
end
|
||||
|
||||
it 'accepts error message' do
|
||||
-> { FiberSpecs::NewFiberToRaise.raise "error message" }.should raise_error(RuntimeError, "error message")
|
||||
end
|
||||
|
||||
it 'does not accept array of backtrace information only' do
|
||||
-> { FiberSpecs::NewFiberToRaise.raise ['foo'] }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it 'does not accept integer' do
|
||||
-> { FiberSpecs::NewFiberToRaise.raise 100 }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it 'accepts error class with error message' do
|
||||
-> { FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error' }.should raise_error(FiberSpecs::CustomError, 'test error')
|
||||
end
|
||||
|
||||
it 'accepts error class with with error message and backtrace information' do
|
||||
-> {
|
||||
FiberSpecs::NewFiberToRaise.raise FiberSpecs::CustomError, 'test error', ['foo', 'boo']
|
||||
}.should raise_error(FiberSpecs::CustomError) { |e|
|
||||
e.message.should == 'test error'
|
||||
e.backtrace.should == ['foo', 'boo']
|
||||
}
|
||||
end
|
||||
|
||||
it 'does not accept only error message and backtrace information' do
|
||||
-> { FiberSpecs::NewFiberToRaise.raise 'test error', ['foo', 'boo'] }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "raises a FiberError if invoked from a different Thread" do
|
||||
fiber = Fiber.new { Fiber.yield }
|
||||
fiber.resume
|
||||
Thread.new do
|
||||
-> {
|
||||
fiber.raise
|
||||
}.should raise_error(FiberError, "fiber called across threads")
|
||||
end.join
|
||||
end
|
||||
|
||||
it "kills Fiber" do
|
||||
fiber = Fiber.new { Fiber.yield :first; :second }
|
||||
fiber.resume
|
||||
-> { fiber.raise }.should raise_error
|
||||
-> { fiber.resume }.should raise_error(FiberError, /dead fiber called|attempt to resume a terminated fiber/)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -12,6 +12,16 @@ describe "File.extname" do
|
|||
File.extname(".app.conf").should == ".conf"
|
||||
end
|
||||
|
||||
it "returns unfrozen strings" do
|
||||
File.extname("foo.rb").frozen?.should == false
|
||||
File.extname("/foo/bar.rb").frozen?.should == false
|
||||
File.extname("/foo.rb/bar.c").frozen?.should == false
|
||||
File.extname("bar").frozen?.should == false
|
||||
File.extname(".bashrc").frozen?.should == false
|
||||
File.extname("/foo.bar/baz").frozen?.should == false
|
||||
File.extname(".app.conf").frozen?.should == false
|
||||
end
|
||||
|
||||
it "returns the extension for edge cases" do
|
||||
File.extname("").should == ""
|
||||
File.extname(".").should == ""
|
||||
|
|
|
@ -1,27 +1,5 @@
|
|||
require_relative '../fixtures/classes'
|
||||
|
||||
describe :integer_comparison_coerce_rescue, shared: true do
|
||||
it "rescues exception (StandardError and subclasses) raised in other#coerce and raises ArgumentError" do
|
||||
b = mock("numeric with failed #coerce")
|
||||
b.should_receive(:coerce).and_raise(IntegerSpecs::CoerceError)
|
||||
|
||||
# e.g. 1 > b
|
||||
-> {
|
||||
-> { 1.send(@method, b) }.should raise_error(ArgumentError, /comparison of Integer with MockObject failed/)
|
||||
}.should complain(/Numerical comparison operators will no more rescue exceptions of #coerce/)
|
||||
end
|
||||
|
||||
it "does not rescue Exception and StandardError siblings raised in other#coerce" do
|
||||
[Exception, NoMemoryError].each do |exception|
|
||||
b = mock("numeric with failed #coerce")
|
||||
b.should_receive(:coerce).and_raise(exception)
|
||||
|
||||
# e.g. 1 > b
|
||||
-> { 1.send(@method, b) }.should raise_error(exception)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe :integer_comparison_coerce_not_rescue, shared: true do
|
||||
it "does not rescue exception raised in other#coerce" do
|
||||
b = mock("numeric with failed #coerce")
|
||||
|
|
57
spec/ruby/core/io/set_encoding_by_bom_spec.rb
Normal file
57
spec/ruby/core/io/set_encoding_by_bom_spec.rb
Normal file
|
@ -0,0 +1,57 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
describe "IO#set_encoding_by_bom" do
|
||||
before :each do
|
||||
@name = tmp('io_set_encoding_by_bom.txt')
|
||||
touch(@name)
|
||||
@io = new_io(@name, 'rb')
|
||||
end
|
||||
|
||||
after :each do
|
||||
@io.close unless @io.closed?
|
||||
rm_r @name
|
||||
end
|
||||
|
||||
ruby_version_is "2.7" do
|
||||
it "returns the result encoding if found BOM UTF-8 sequence" do
|
||||
File.binwrite(@name, "\u{FEFF}abc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_8
|
||||
@io.external_encoding.should == Encoding::UTF_8
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_16LE sequence" do
|
||||
File.binwrite(@name, "\xFF\xFEabc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16LE
|
||||
@io.external_encoding.should == Encoding::UTF_16LE
|
||||
end
|
||||
|
||||
it "returns the result encoding if found BOM UTF_16BE sequence" do
|
||||
File.binwrite(@name, "\xFE\xFFabc")
|
||||
|
||||
@io.set_encoding_by_bom.should == Encoding::UTF_16BE
|
||||
@io.external_encoding.should == Encoding::UTF_16BE
|
||||
end
|
||||
|
||||
it "returns nil if found BOM sequence not provided" do
|
||||
File.write(@name, "abc")
|
||||
|
||||
@io.set_encoding_by_bom.should == nil
|
||||
end
|
||||
|
||||
it 'returns exception if io not in binary mode' do
|
||||
not_binary_io = new_io(@name, 'r')
|
||||
|
||||
-> { not_binary_io.set_encoding_by_bom }.should raise_error(ArgumentError, 'ASCII incompatible encoding needs binmode')
|
||||
ensure
|
||||
not_binary_io.close
|
||||
end
|
||||
|
||||
it 'returns exception if encoding already set' do
|
||||
@io.set_encoding("utf-8")
|
||||
|
||||
-> { @io.set_encoding_by_bom }.should raise_error(ArgumentError, 'encoding is set to UTF-8 already')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -25,7 +25,7 @@ describe "Kernel#respond_to?" do
|
|||
end
|
||||
|
||||
it "throws a type error if argument can't be coerced into a Symbol" do
|
||||
-> { @a.respond_to?(Object.new) }.should raise_error(TypeError)
|
||||
-> { @a.respond_to?(Object.new) }.should raise_error(TypeError, /is not a symbol nor a string/)
|
||||
end
|
||||
|
||||
it "returns false if obj responds to the given protected method" do
|
||||
|
@ -69,5 +69,4 @@ describe "Kernel#respond_to?" do
|
|||
KernelSpecs::Foo.new.respond_to?(:bar).should == true
|
||||
KernelSpecs::Foo.new.respond_to?(:invalid_and_silly_method_name).should == false
|
||||
end
|
||||
|
||||
end
|
||||
|
|
220
spec/ruby/core/module/const_source_location_spec.rb
Normal file
220
spec/ruby/core/module/const_source_location_spec.rb
Normal file
|
@ -0,0 +1,220 @@
|
|||
require_relative '../../spec_helper'
|
||||
require_relative '../../fixtures/constants'
|
||||
|
||||
describe "Module#const_source_location" do
|
||||
before do
|
||||
@constants_fixture_path = File.expand_path('../../fixtures/constants.rb', __dir__)
|
||||
end
|
||||
|
||||
ruby_version_is "2.7" do
|
||||
describe "with dynamically assigned constants" do
|
||||
it "searches a path in the immediate class or module first" do
|
||||
ConstantSpecs::ClassA::CSL_CONST301 = :const301_1
|
||||
ConstantSpecs::ClassA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1]
|
||||
|
||||
ConstantSpecs::ModuleA::CSL_CONST301 = :const301_2
|
||||
ConstantSpecs::ModuleA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1]
|
||||
|
||||
ConstantSpecs::ParentA::CSL_CONST301 = :const301_3
|
||||
ConstantSpecs::ParentA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1]
|
||||
|
||||
ConstantSpecs::ContainerA::ChildA::CSL_CONST301 = :const301_5
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CSL_CONST301).should == [__FILE__, __LINE__ - 1]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
end
|
||||
|
||||
it "returns path to the updated value of a constant" do
|
||||
ConstantSpecs::ClassB::CSL_CONST309 = :const309_1
|
||||
ConstantSpecs::ClassB.const_source_location(:CSL_CONST309).should == [__FILE__, __LINE__ - 1]
|
||||
|
||||
-> {
|
||||
ConstantSpecs::ClassB::CSL_CONST309 = :const309_2
|
||||
}.should complain(/already initialized constant/)
|
||||
ConstantSpecs::ClassB.const_source_location(:CSL_CONST309).should == [__FILE__, __LINE__ - 2]
|
||||
end
|
||||
end
|
||||
|
||||
describe "with statically assigned constants" do
|
||||
it "searches location path the immediate class or module first" do
|
||||
ConstantSpecs::ClassA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE]
|
||||
ConstantSpecs::ModuleA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST10_LINE]
|
||||
ConstantSpecs::ParentA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST10_LINE]
|
||||
ConstantSpecs::ContainerA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ContainerA::CS_CONST10_LINE]
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST10).should == [@constants_fixture_path, ConstantSpecs::ContainerA::ChildA::CS_CONST10_LINE]
|
||||
end
|
||||
|
||||
it "searches location path a module included in the immediate class before the superclass" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST15).should == [@constants_fixture_path, ConstantSpecs::ModuleC::CS_CONST15_LINE]
|
||||
end
|
||||
|
||||
it "searches location path the superclass before a module included in the superclass" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST11).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST11_LINE]
|
||||
end
|
||||
|
||||
it "searches location path a module included in the superclass" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST12).should == [@constants_fixture_path, ConstantSpecs::ModuleB::CS_CONST12_LINE]
|
||||
end
|
||||
|
||||
it "searches location path the superclass chain" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST13).should == [@constants_fixture_path, ConstantSpecs::ModuleA::CS_CONST13_LINE]
|
||||
end
|
||||
|
||||
it "returns location path a toplevel constant when the receiver is a Class" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE]
|
||||
end
|
||||
|
||||
it "returns location path a toplevel constant when the receiver is a Module" do
|
||||
ConstantSpecs.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE]
|
||||
ConstantSpecs::ModuleA.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE]
|
||||
end
|
||||
end
|
||||
|
||||
it "return empty path if constant defined in C code" do
|
||||
Object.const_source_location(:String).should == []
|
||||
end
|
||||
|
||||
it "accepts a String or Symbol name" do
|
||||
Object.const_source_location(:CS_CONST1).should == [@constants_fixture_path, CS_CONST1_LINE]
|
||||
Object.const_source_location("CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE]
|
||||
end
|
||||
|
||||
it "returns nil if no constant is defined in the search path" do
|
||||
ConstantSpecs.const_source_location(:CS_CONSTX).should == nil
|
||||
end
|
||||
|
||||
it "raises a NameError if the name does not start with a capital letter" do
|
||||
-> { ConstantSpecs.const_source_location "name" }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "raises a NameError if the name starts with a non-alphabetic character" do
|
||||
-> { ConstantSpecs.const_source_location "__CONSTX__" }.should raise_error(NameError)
|
||||
-> { ConstantSpecs.const_source_location "@CS_CONST1" }.should raise_error(NameError)
|
||||
-> { ConstantSpecs.const_source_location "!CS_CONST1" }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "raises a NameError if the name contains non-alphabetic characters except '_'" do
|
||||
Object.const_source_location("CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE]
|
||||
-> { ConstantSpecs.const_source_location "CS_CONST1=" }.should raise_error(NameError)
|
||||
-> { ConstantSpecs.const_source_location "CS_CONST1?" }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "calls #to_str to convert the given name to a String" do
|
||||
name = mock("ClassA")
|
||||
name.should_receive(:to_str).and_return("ClassA")
|
||||
ConstantSpecs.const_source_location(name).should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CLASS_A_LINE]
|
||||
end
|
||||
|
||||
it "raises a TypeError if conversion to a String by calling #to_str fails" do
|
||||
name = mock('123')
|
||||
-> { ConstantSpecs.const_source_location(name) }.should raise_error(TypeError)
|
||||
|
||||
name.should_receive(:to_str).and_return(123)
|
||||
-> { ConstantSpecs.const_source_location(name) }.should raise_error(TypeError)
|
||||
end
|
||||
|
||||
it "does not search the singleton class of a Class or Module" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST14).should == nil
|
||||
ConstantSpecs.const_source_location(:CS_CONST14).should == nil
|
||||
end
|
||||
|
||||
it "does not search the containing scope" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST20).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST20_LINE]
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST5) == nil
|
||||
end
|
||||
|
||||
it "returns nil if the constant is defined in the receiver's superclass and the inherit flag is false" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST4, false).should == nil
|
||||
end
|
||||
|
||||
it "searches into the receiver superclasses if the inherit flag is true" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST4, true).should == [@constants_fixture_path, ConstantSpecs::ParentA::CS_CONST4_LINE]
|
||||
end
|
||||
|
||||
it "returns nil when the receiver is a Module, the constant is defined at toplevel and the inherit flag is false" do
|
||||
ConstantSpecs::ModuleA.const_source_location(:CS_CONST1, false).should == nil
|
||||
end
|
||||
|
||||
it "returns nil when the receiver is a Class, the constant is defined at toplevel and the inherit flag is false" do
|
||||
ConstantSpecs::ContainerA::ChildA.const_source_location(:CS_CONST1, false).should == nil
|
||||
end
|
||||
|
||||
it "accepts a toplevel scope qualifier" do
|
||||
ConstantSpecs.const_source_location("::CS_CONST1").should == [@constants_fixture_path, CS_CONST1_LINE]
|
||||
end
|
||||
|
||||
it "accepts a scoped constant name" do
|
||||
ConstantSpecs.const_source_location("ClassA::CS_CONST10").should == [@constants_fixture_path, ConstantSpecs::ClassA::CS_CONST10_LINE]
|
||||
end
|
||||
|
||||
it "raises a NameError if the name includes two successive scope separators" do
|
||||
-> { ConstantSpecs.const_source_location("ClassA::::CS_CONST10") }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "raises a NameError if only '::' is passed" do
|
||||
-> { ConstantSpecs.const_source_location("::") }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "raises a NameError if a Symbol has a toplevel scope qualifier" do
|
||||
-> { ConstantSpecs.const_source_location(:'::CS_CONST1') }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "raises a NameError if a Symbol is a scoped constant name" do
|
||||
-> { ConstantSpecs.const_source_location(:'ClassA::CS_CONST10') }.should raise_error(NameError)
|
||||
end
|
||||
|
||||
it "does search private constants path" do
|
||||
ConstantSpecs.const_source_location(:CS_PRIVATE).should == [@constants_fixture_path, ConstantSpecs::CS_PRIVATE_LINE]
|
||||
end
|
||||
|
||||
context 'autoload' do
|
||||
before :all do
|
||||
ConstantSpecs.autoload :CSL_CONST1, "#{__dir__}/notexisting.rb"
|
||||
@line = __LINE__ - 1
|
||||
end
|
||||
|
||||
it 'returns the autoload location while not resolved' do
|
||||
ConstantSpecs.const_source_location('CSL_CONST1').should == [__FILE__, @line]
|
||||
end
|
||||
|
||||
it 'returns where the constant was resolved when resolved' do
|
||||
file = fixture(__FILE__, 'autoload_location.rb')
|
||||
ConstantSpecs.autoload :CONST_LOCATION, file
|
||||
line = ConstantSpecs::CONST_LOCATION
|
||||
ConstantSpecs.const_source_location('CONST_LOCATION').should == [file, line]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -43,31 +43,31 @@ end
|
|||
describe "Module#constants" do
|
||||
it "returns an array of Symbol names of all constants defined in the module and all included modules" do
|
||||
ConstantSpecs::ContainerA.constants.sort.should == [
|
||||
:CS_CONST10, :CS_CONST23, :CS_CONST24, :CS_CONST5, :ChildA
|
||||
:CS_CONST10, :CS_CONST10_LINE, :CS_CONST23, :CS_CONST24, :CS_CONST5, :ChildA
|
||||
]
|
||||
end
|
||||
|
||||
it "returns all constants including inherited when passed true" do
|
||||
ConstantSpecs::ContainerA.constants(true).sort.should == [
|
||||
:CS_CONST10, :CS_CONST23, :CS_CONST24, :CS_CONST5, :ChildA
|
||||
:CS_CONST10, :CS_CONST10_LINE, :CS_CONST23, :CS_CONST24, :CS_CONST5, :ChildA
|
||||
]
|
||||
end
|
||||
|
||||
it "returns all constants including inherited when passed some object" do
|
||||
ConstantSpecs::ContainerA.constants(Object.new).sort.should == [
|
||||
:CS_CONST10, :CS_CONST23, :CS_CONST24, :CS_CONST5, :ChildA
|
||||
:CS_CONST10, :CS_CONST10_LINE, :CS_CONST23, :CS_CONST24, :CS_CONST5, :ChildA
|
||||
]
|
||||
end
|
||||
|
||||
it "doesn't returns inherited constants when passed false" do
|
||||
ConstantSpecs::ContainerA.constants(false).sort.should == [
|
||||
:CS_CONST10, :CS_CONST23, :CS_CONST5, :ChildA
|
||||
:CS_CONST10, :CS_CONST10_LINE, :CS_CONST23, :CS_CONST5, :ChildA
|
||||
]
|
||||
end
|
||||
|
||||
it "doesn't returns inherited constants when passed nil" do
|
||||
ConstantSpecs::ContainerA.constants(nil).sort.should == [
|
||||
:CS_CONST10, :CS_CONST23, :CS_CONST5, :ChildA
|
||||
:CS_CONST10, :CS_CONST10_LINE, :CS_CONST23, :CS_CONST5, :ChildA
|
||||
]
|
||||
end
|
||||
|
||||
|
|
3
spec/ruby/core/module/fixtures/autoload_location.rb
Normal file
3
spec/ruby/core/module/fixtures/autoload_location.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
module ConstantSpecs
|
||||
CONST_LOCATION = __LINE__
|
||||
end
|
|
@ -193,9 +193,11 @@ describe "Process.exec" do
|
|||
map_fd_fixture = fixture __FILE__, "map_fd.rb"
|
||||
cmd = <<-EOC
|
||||
f = File.open(#{@name.inspect}, "w+")
|
||||
child_fd = f.fileno + 1
|
||||
File.open(#{@child_fd_file.inspect}, "w") { |io| io.print child_fd }
|
||||
Process.exec "#{ruby_cmd(map_fd_fixture)} \#{child_fd}", { child_fd => f }
|
||||
File.open(#{__FILE__.inspect}, "r") do |io|
|
||||
child_fd = io.fileno
|
||||
File.open(#{@child_fd_file.inspect}, "w") { |io| io.print child_fd }
|
||||
Process.exec "#{ruby_cmd(map_fd_fixture)} \#{child_fd}", { child_fd => f }
|
||||
end
|
||||
EOC
|
||||
|
||||
ruby_exe(cmd, escape: true)
|
||||
|
|
|
@ -706,13 +706,15 @@ describe "Process.spawn" do
|
|||
end
|
||||
|
||||
it "maps the key to a file descriptor in the child that inherits the file descriptor from the parent specified by the value" do
|
||||
child_fd = find_unused_fd
|
||||
args = ruby_cmd(fixture(__FILE__, "map_fd.rb"), args: [child_fd.to_s])
|
||||
pid = Process.spawn(*args, { child_fd => @io })
|
||||
Process.waitpid pid
|
||||
@io.rewind
|
||||
File.open(__FILE__, "r") do |f|
|
||||
child_fd = f.fileno
|
||||
args = ruby_cmd(fixture(__FILE__, "map_fd.rb"), args: [child_fd.to_s])
|
||||
pid = Process.spawn(*args, { child_fd => @io })
|
||||
Process.waitpid pid
|
||||
@io.rewind
|
||||
|
||||
@io.read.should == "writing to fd: #{child_fd}"
|
||||
@io.read.should == "writing to fd: #{child_fd}"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
170
spec/ruby/core/range/minmax_spec.rb
Normal file
170
spec/ruby/core/range/minmax_spec.rb
Normal file
|
@ -0,0 +1,170 @@
|
|||
require_relative '../../spec_helper'
|
||||
|
||||
# These specs use Range.new instead of the literal notation so they parse fine on Ruby < 2.6
|
||||
describe 'Range#minmax' do
|
||||
before(:each) do
|
||||
@x = mock('x')
|
||||
@y = mock('y')
|
||||
|
||||
@x.should_receive(:<=>).with(@y).any_number_of_times.and_return(-1) # x < y
|
||||
@x.should_receive(:<=>).with(@x).any_number_of_times.and_return(0) # x == x
|
||||
@y.should_receive(:<=>).with(@x).any_number_of_times.and_return(1) # y > x
|
||||
@y.should_receive(:<=>).with(@y).any_number_of_times.and_return(0) # y == y
|
||||
end
|
||||
|
||||
describe 'on an inclusive range' do
|
||||
ruby_version_is '2.6'...'2.7' do
|
||||
it 'should try to iterate endlessly on an endless range' do
|
||||
@x.should_receive(:succ).once.and_return(@y)
|
||||
range = Range.new(@x, nil)
|
||||
|
||||
-> { range.minmax }.should raise_error(NoMethodError, /^undefined method `succ' for/)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '2.7' do
|
||||
it 'should raise RangeError on an endless range without iterating the range' do
|
||||
@x.should_not_receive(:succ)
|
||||
|
||||
range = Range.new(@x, nil)
|
||||
|
||||
-> { range.minmax }.should raise_error(RangeError, 'cannot get the maximum of endless range')
|
||||
end
|
||||
|
||||
it 'raises RangeError or ArgumentError on a beginless range' do
|
||||
range = Range.new(nil, @x)
|
||||
|
||||
-> { range.minmax }.should raise_error(StandardError) { |e|
|
||||
if RangeError === e
|
||||
# error from #min
|
||||
-> { raise e }.should raise_error(RangeError, 'cannot get the minimum of beginless range')
|
||||
else
|
||||
# error from #max
|
||||
-> { raise e }.should raise_error(ArgumentError, 'comparison of NilClass with MockObject failed')
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return begining of range if beginning and end are equal without iterating the range' do
|
||||
@x.should_not_receive(:succ)
|
||||
|
||||
(@x..@x).minmax.should == [@x, @x]
|
||||
end
|
||||
|
||||
it 'should return nil pair if beginning is greater than end without iterating the range' do
|
||||
@y.should_not_receive(:succ)
|
||||
|
||||
(@y..@x).minmax.should == [nil, nil]
|
||||
end
|
||||
|
||||
ruby_version_is ''...'2.7' do
|
||||
it 'should return the minimum and maximum values for a non-numeric range by iterating the range' do
|
||||
@x.should_receive(:succ).once.and_return(@y)
|
||||
|
||||
(@x..@y).minmax.should == [@x, @y]
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '2.7' do
|
||||
it 'should return the minimum and maximum values for a non-numeric range without iterating the range' do
|
||||
@x.should_not_receive(:succ)
|
||||
|
||||
(@x..@y).minmax.should == [@x, @y]
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return the minimum and maximum values for a numeric range' do
|
||||
(1..3).minmax.should == [1, 3]
|
||||
end
|
||||
|
||||
ruby_version_is '2.7' do
|
||||
it 'should return the minimum and maximum values for a numeric range without iterating the range' do
|
||||
# We cannot set expectations on integers,
|
||||
# so we "prevent" iteration by picking a value that would iterate until the spec times out.
|
||||
range_end = Float::INFINITY
|
||||
|
||||
(1..range_end).minmax.should == [1, range_end]
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return the minimum and maximum values according to the provided block by iterating the range' do
|
||||
@x.should_receive(:succ).once.and_return(@y)
|
||||
|
||||
(@x..@y).minmax { |x, y| - (x <=> y) }.should == [@y, @x]
|
||||
end
|
||||
end
|
||||
|
||||
describe 'on an exclusive range' do
|
||||
ruby_version_is '2.6'...'2.7' do
|
||||
# Endless ranges introduced in 2.6
|
||||
it 'should try to iterate endlessly on an endless range' do
|
||||
@x.should_receive(:succ).once.and_return(@y)
|
||||
range = Range.new(@x, nil, true)
|
||||
|
||||
-> { range.minmax }.should raise_error(NoMethodError, /^undefined method `succ' for/)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is '2.7' do
|
||||
it 'should raise RangeError on an endless range' do
|
||||
@x.should_not_receive(:succ)
|
||||
range = Range.new(@x, nil, true)
|
||||
|
||||
-> { range.minmax }.should raise_error(RangeError, 'cannot get the maximum of endless range')
|
||||
end
|
||||
|
||||
it 'should raise RangeError on a beginless range' do
|
||||
range = Range.new(nil, @x, true)
|
||||
|
||||
-> { range.minmax }.should raise_error(RangeError,
|
||||
/cannot get the maximum of beginless range with custom comparison method|cannot get the minimum of beginless range/)
|
||||
end
|
||||
end
|
||||
|
||||
ruby_bug "#17014", "2.7.0"..."2.8" do
|
||||
it 'should return nil pair if beginning and end are equal without iterating the range' do
|
||||
@x.should_not_receive(:succ)
|
||||
|
||||
(@x...@x).minmax.should == [nil, nil]
|
||||
end
|
||||
|
||||
it 'should return nil pair if beginning is greater than end without iterating the range' do
|
||||
@y.should_not_receive(:succ)
|
||||
|
||||
(@y...@x).minmax.should == [nil, nil]
|
||||
end
|
||||
|
||||
it 'should return the minimum and maximum values for a non-numeric range by iterating the range' do
|
||||
@x.should_receive(:succ).once.and_return(@y)
|
||||
|
||||
(@x...@y).minmax.should == [@x, @x]
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return the minimum and maximum values for a numeric range' do
|
||||
(1...3).minmax.should == [1, 2]
|
||||
end
|
||||
|
||||
ruby_version_is '2.7' do
|
||||
it 'should return the minimum and maximum values for a numeric range without iterating the range' do
|
||||
# We cannot set expectations on integers,
|
||||
# so we "prevent" iteration by picking a value that would iterate until the spec times out.
|
||||
range_end = bignum_value
|
||||
|
||||
(1...range_end).minmax.should == [1, range_end - 1]
|
||||
end
|
||||
|
||||
it 'raises TypeError if the end value is not an integer' do
|
||||
range = (0...Float::INFINITY)
|
||||
-> { range.minmax }.should raise_error(TypeError, 'cannot exclude non Integer end value')
|
||||
end
|
||||
end
|
||||
|
||||
it 'should return the minimum and maximum values according to the provided block by iterating the range' do
|
||||
@x.should_receive(:succ).once.and_return(@y)
|
||||
|
||||
(@x...@y).minmax { |x, y| - (x <=> y) }.should == [@x, @x]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -55,6 +55,10 @@ describe "String#chomp" do
|
|||
$/ = "cdef"
|
||||
"abcdef".chomp.should == "ab"
|
||||
end
|
||||
|
||||
it "removes one trailing newline for string with invalid encoding" do
|
||||
"\xa0\xa1\n".chomp.should == "\xa0\xa1"
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed nil" do
|
||||
|
@ -108,6 +112,10 @@ describe "String#chomp" do
|
|||
it "returns an empty String when self is empty" do
|
||||
"".chomp("").should == ""
|
||||
end
|
||||
|
||||
it "removes one trailing newline for string with invalid encoding" do
|
||||
"\xa0\xa1\n".chomp("").should == "\xa0\xa1"
|
||||
end
|
||||
end
|
||||
|
||||
describe "when passed '\\n'" do
|
||||
|
|
|
@ -43,11 +43,11 @@ describe "Thread.list" do
|
|||
end
|
||||
end
|
||||
|
||||
while spawner.alive?
|
||||
begin
|
||||
Thread.list.each { |th|
|
||||
th.should be_kind_of(Thread)
|
||||
}
|
||||
end
|
||||
end while spawner.alive?
|
||||
|
||||
threads = spawner.value
|
||||
threads.each(&:join)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Contains all static code examples of all constants behavior in language and
|
||||
# library specs. The specs include language/constants_spec.rb and the specs
|
||||
# for Module#const_defined?, Module#const_get, Module#const_set,
|
||||
# Module#remove_const, Module#const_missing and Module#constants.
|
||||
# for Module#const_defined?, Module#const_get, Module#const_set, Module#remove_const,
|
||||
# Module#const_source_location, Module#const_missing and Module#constants.
|
||||
#
|
||||
# Rather than defining a class structure for each example, a canonical set of
|
||||
# classes is used along with numerous constants, in most cases, a unique
|
||||
|
@ -28,14 +28,17 @@
|
|||
# for completeness. No other constant of this name should be defined in the
|
||||
# specs.
|
||||
CS_CONST1 = :const1 # only defined here
|
||||
CS_CONST1_LINE = __LINE__ - 1
|
||||
|
||||
module ConstantSpecs
|
||||
|
||||
# Included at toplevel
|
||||
module ModuleA
|
||||
CS_CONST10 = :const10_1
|
||||
CS_CONST10_LINE = __LINE__ - 1
|
||||
CS_CONST12 = :const12_2
|
||||
CS_CONST13 = :const13
|
||||
CS_CONST13_LINE = __LINE__ - 1
|
||||
CS_CONST21 = :const21_2
|
||||
end
|
||||
|
||||
|
@ -44,12 +47,14 @@ module ConstantSpecs
|
|||
CS_CONST10 = :const10_9
|
||||
CS_CONST11 = :const11_2
|
||||
CS_CONST12 = :const12_1
|
||||
CS_CONST12_LINE = __LINE__ - 1
|
||||
end
|
||||
|
||||
# Included in ChildA
|
||||
module ModuleC
|
||||
CS_CONST10 = :const10_4
|
||||
CS_CONST15 = :const15_1
|
||||
CS_CONST15_LINE = __LINE__ - 1
|
||||
end
|
||||
|
||||
# Included in ChildA metaclass
|
||||
|
@ -75,7 +80,9 @@ module ConstantSpecs
|
|||
# are run.
|
||||
|
||||
class ClassA
|
||||
CS_CLASS_A_LINE = __LINE__ - 1
|
||||
CS_CONST10 = :const10_10
|
||||
CS_CONST10_LINE = __LINE__ - 1
|
||||
CS_CONST16 = :const16
|
||||
CS_CONST17 = :const17_2
|
||||
CS_CONST22 = :const22_1
|
||||
|
@ -97,10 +104,14 @@ module ConstantSpecs
|
|||
include ModuleB
|
||||
|
||||
CS_CONST4 = :const4
|
||||
CS_CONST4_LINE = __LINE__ - 1
|
||||
CS_CONST10 = :const10_5
|
||||
CS_CONST10_LINE = __LINE__ - 1
|
||||
CS_CONST11 = :const11_1
|
||||
CS_CONST11_LINE = __LINE__ - 1
|
||||
CS_CONST15 = :const15_2
|
||||
CS_CONST20 = :const20_2
|
||||
CS_CONST20_LINE = __LINE__ - 1
|
||||
CS_CONST21 = :const21_1
|
||||
CS_CONST22 = :const22_2
|
||||
|
||||
|
@ -118,6 +129,7 @@ module ConstantSpecs
|
|||
|
||||
CS_CONST5 = :const5
|
||||
CS_CONST10 = :const10_2
|
||||
CS_CONST10_LINE = __LINE__ - 1
|
||||
CS_CONST23 = :const23
|
||||
|
||||
class ChildA < ParentA
|
||||
|
@ -135,6 +147,7 @@ module ConstantSpecs
|
|||
|
||||
CS_CONST6 = :const6
|
||||
CS_CONST10 = :const10_3
|
||||
CS_CONST10_LINE = __LINE__ - 1
|
||||
CS_CONST19 = :const19_2
|
||||
|
||||
def self.const10; CS_CONST10; end
|
||||
|
@ -282,6 +295,7 @@ module ConstantSpecs
|
|||
end
|
||||
|
||||
CS_PRIVATE = :cs_private
|
||||
CS_PRIVATE_LINE = __LINE__ - 1
|
||||
private_constant :CS_PRIVATE
|
||||
end
|
||||
|
||||
|
|
|
@ -1254,3 +1254,25 @@ describe "The predefined global constant" do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
ruby_version_is "2.7" do
|
||||
describe "$LOAD_PATH.resolve_feature_path" do
|
||||
it "returns what will be loaded without actual loading, .rb file" do
|
||||
extension, path = $LOAD_PATH.resolve_feature_path('set')
|
||||
extension.should == :rb
|
||||
path.should.end_with?('/set.rb')
|
||||
end
|
||||
|
||||
it "returns what will be loaded without actual loading, .so file" do
|
||||
require 'rbconfig'
|
||||
|
||||
extension, path = $LOAD_PATH.resolve_feature_path('etc')
|
||||
extension.should == :so
|
||||
path.should.end_with?("/etc.#{RbConfig::CONFIG['DLEXT']}")
|
||||
end
|
||||
|
||||
it "raises LoadError if feature cannot be found" do
|
||||
-> { $LOAD_PATH.resolve_feature_path('noop') }.should raise_error(LoadError)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,16 +34,10 @@ describe 'Socket#listen' do
|
|||
@server.close
|
||||
end
|
||||
|
||||
platform_is_not :android do
|
||||
it 'raises Errno::EOPNOTSUPP' do
|
||||
-> { @server.listen(1) }.should raise_error(Errno::EOPNOTSUPP)
|
||||
end
|
||||
end
|
||||
|
||||
platform_is :android do
|
||||
it 'raises Errno::EOPNOTSUPP or Errno::EACCES' do
|
||||
-> { @server.listen(1) }.should raise_error(-> exc { Errno::EACCES === exc || Errno::EOPNOTSUPP === exc })
|
||||
end
|
||||
it 'raises Errno::EOPNOTSUPP or Errno::EACCES' do
|
||||
-> { @server.listen(1) }.should raise_error { |e|
|
||||
[Errno::EOPNOTSUPP, Errno::EACCES].should.include?(e.class)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -396,12 +396,20 @@ describe "C-API Kernel function" do
|
|||
proc = -> x { x }
|
||||
arg_error_proc = -> *_ { raise ArgumentError, '' }
|
||||
run_error_proc = -> *_ { raise RuntimeError, '' }
|
||||
type_error_proc = -> *_ { raise TypeError, '' }
|
||||
type_error_proc = -> *_ { raise Exception, 'custom error' }
|
||||
@s.rb_rescue2(arg_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError).should == :exc
|
||||
@s.rb_rescue2(run_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError).should == :exc
|
||||
-> {
|
||||
@s.rb_rescue2(type_error_proc, :no_exc, proc, :exc, ArgumentError, RuntimeError)
|
||||
}.should raise_error(TypeError)
|
||||
}.should raise_error(Exception, 'custom error')
|
||||
end
|
||||
|
||||
ruby_bug "#17305", ""..."2.7" do
|
||||
it "raises TypeError if one of the passed exceptions is not a Module" do
|
||||
-> {
|
||||
@s.rb_rescue2(-> *_ { raise RuntimeError, "foo" }, :no_exc, -> x { x }, :exc, Object.new, 42)
|
||||
}.should raise_error(TypeError, /class or module required/)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -135,7 +135,7 @@ describe "CApiModule" do
|
|||
end
|
||||
|
||||
it "returns a constant defined at toplevel" do
|
||||
@m.rb_const_get(CApiModuleSpecs::A, :Fixnum).should == Fixnum
|
||||
@m.rb_const_get(CApiModuleSpecs::A, :Integer).should == Integer
|
||||
end
|
||||
|
||||
it "returns a constant defined in a superclass" do
|
||||
|
@ -176,8 +176,8 @@ describe "CApiModule" do
|
|||
end
|
||||
|
||||
it "calls #const_missing if the constant is not defined in the class or ancestors" do
|
||||
CApiModuleSpecs::M.should_receive(:const_missing).with(:Fixnum)
|
||||
@m.rb_const_get_from(CApiModuleSpecs::M, :Fixnum)
|
||||
CApiModuleSpecs::M.should_receive(:const_missing).with(:Integer)
|
||||
@m.rb_const_get_from(CApiModuleSpecs::M, :Integer)
|
||||
end
|
||||
|
||||
it "resolves autoload constants" do
|
||||
|
|
|
@ -62,7 +62,7 @@ describe "C-API Struct function" do
|
|||
end
|
||||
|
||||
describe "C-API Struct function" do
|
||||
before :each do
|
||||
before :all do
|
||||
@s = CApiStructSpecs.new
|
||||
@struct = @s.rb_struct_define_under(CApiStructSpecs, "CAPIStructUnder", "a", "b", "c")
|
||||
end
|
||||
|
|
|
@ -12,6 +12,13 @@ describe :enum_for, shared: true do
|
|||
enum.map { |v| v }.should == [1,2].each { |v| v }
|
||||
end
|
||||
|
||||
it "sets regexp matches in the caller" do
|
||||
"wawa".send(@method, :scan, /./).map {|o| $& }.should == ["w", "a", "w", "a"]
|
||||
a = []
|
||||
"wawa".send(@method, :scan, /./).each {|o| a << $& }
|
||||
a.should == ["w", "a", "w", "a"]
|
||||
end
|
||||
|
||||
it "exposes multi-arg yields as an array" do
|
||||
o = Object.new
|
||||
def o.each
|
||||
|
|
|
@ -50,20 +50,43 @@ describe :kernel_raise, shared: true do
|
|||
end
|
||||
|
||||
it "re-raises a previously rescued exception without overwriting the backtrace" do
|
||||
begin
|
||||
initial_raise_line = __LINE__; @object.raise 'raised'
|
||||
rescue => raised
|
||||
begin
|
||||
raise_again_line = __LINE__; @object.raise raised
|
||||
rescue => raised_again
|
||||
# This spec is written using #backtrace and matching the line number
|
||||
# from the string, as backtrace_locations is a more advanced
|
||||
# method that is not always supported by implementations.
|
||||
# This spec is written using #backtrace and matching the line number
|
||||
# from the string, as backtrace_locations is a more advanced
|
||||
# method that is not always supported by implementations.
|
||||
#
|
||||
initial_raise_line = nil
|
||||
raise_again_line = nil
|
||||
raised_again = nil
|
||||
|
||||
raised_again.backtrace.first.should include("#{__FILE__}:#{initial_raise_line}:")
|
||||
raised_again.backtrace.first.should_not include("#{__FILE__}:#{raise_again_line}:")
|
||||
if defined?(FiberSpecs::NewFiberToRaise) and @object == FiberSpecs::NewFiberToRaise
|
||||
fiber = Fiber.new do
|
||||
begin
|
||||
initial_raise_line = __LINE__; Fiber.yield
|
||||
rescue => raised
|
||||
begin
|
||||
raise_again_line = __LINE__; Fiber.yield raised
|
||||
rescue => raised_again
|
||||
raised_again
|
||||
end
|
||||
end
|
||||
end
|
||||
fiber.resume
|
||||
raised = fiber.raise 'raised'
|
||||
raised_again = fiber.raise raised
|
||||
else
|
||||
begin
|
||||
initial_raise_line = __LINE__; @object.raise 'raised'
|
||||
rescue => raised
|
||||
begin
|
||||
raise_again_line = __LINE__; @object.raise raised
|
||||
rescue => raised_again
|
||||
raised_again
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
raised_again.backtrace.first.should include("#{__FILE__}:#{initial_raise_line}:")
|
||||
raised_again.backtrace.first.should_not include("#{__FILE__}:#{raise_again_line}:")
|
||||
end
|
||||
|
||||
it "allows Exception, message, and backtrace parameters" do
|
||||
|
|
Loading…
Reference in a new issue