mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
238 lines
6.7 KiB
Ruby
238 lines
6.7 KiB
Ruby
require_relative '../../spec_helper'
|
|
require_relative 'fixtures/common'
|
|
|
|
describe "Proc.new with an associated block" do
|
|
it "returns a proc that represents the block" do
|
|
Proc.new { }.call.should == nil
|
|
Proc.new { "hello" }.call.should == "hello"
|
|
end
|
|
|
|
describe "called on a subclass of Proc" do
|
|
before :each do
|
|
@subclass = Class.new(Proc) do
|
|
attr_reader :ok
|
|
def initialize
|
|
@ok = true
|
|
super
|
|
end
|
|
end
|
|
end
|
|
|
|
it "returns an instance of the subclass" do
|
|
proc = @subclass.new {"hello"}
|
|
|
|
proc.class.should == @subclass
|
|
proc.call.should == "hello"
|
|
proc.ok.should == true
|
|
end
|
|
|
|
# JRUBY-5026
|
|
describe "using a reified block parameter" do
|
|
it "returns an instance of the subclass" do
|
|
cls = Class.new do
|
|
def self.subclass=(subclass)
|
|
@subclass = subclass
|
|
end
|
|
def self.foo(&block)
|
|
@subclass.new(&block)
|
|
end
|
|
end
|
|
cls.subclass = @subclass
|
|
proc = cls.foo {"hello"}
|
|
|
|
proc.class.should == @subclass
|
|
proc.call.should == "hello"
|
|
proc.ok.should == true
|
|
end
|
|
end
|
|
end
|
|
|
|
# JRUBY-5261; Proc sets up the block during .new, not in #initialize
|
|
describe "called on a subclass of Proc that does not 'super' in 'initialize'" do
|
|
before :each do
|
|
@subclass = Class.new(Proc) do
|
|
attr_reader :ok
|
|
def initialize
|
|
@ok = true
|
|
end
|
|
end
|
|
end
|
|
|
|
it "still constructs a functional proc" do
|
|
proc = @subclass.new {'ok'}
|
|
proc.call.should == 'ok'
|
|
proc.ok.should == true
|
|
end
|
|
end
|
|
|
|
it "raises a LocalJumpError when context of the block no longer exists" do
|
|
def some_method
|
|
Proc.new { return }
|
|
end
|
|
res = some_method()
|
|
|
|
-> { res.call }.should raise_error(LocalJumpError)
|
|
end
|
|
|
|
it "returns from within enclosing method when 'return' is used in the block" do
|
|
# we essentially verify that the created instance behaves like proc,
|
|
# not like lambda.
|
|
def some_method
|
|
Proc.new { return :proc_return_value }.call
|
|
:method_return_value
|
|
end
|
|
some_method.should == :proc_return_value
|
|
end
|
|
|
|
it "returns a subclass of Proc" do
|
|
obj = ProcSpecs::MyProc.new { }
|
|
obj.should be_kind_of(ProcSpecs::MyProc)
|
|
end
|
|
|
|
it "calls initialize on the Proc object" do
|
|
obj = ProcSpecs::MyProc2.new(:a, 2) { }
|
|
obj.first.should == :a
|
|
obj.second.should == 2
|
|
end
|
|
|
|
ruby_version_is ""..."2.7" do
|
|
it "returns a new Proc instance from the block passed to the containing method" do
|
|
prc = ProcSpecs.new_proc_in_method { "hello" }
|
|
prc.should be_an_instance_of(Proc)
|
|
prc.call.should == "hello"
|
|
end
|
|
|
|
it "returns a new Proc instance from the block passed to the containing method" do
|
|
prc = ProcSpecs.new_proc_subclass_in_method { "hello" }
|
|
prc.should be_an_instance_of(ProcSpecs::ProcSubclass)
|
|
prc.call.should == "hello"
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "Proc.new with a block argument" do
|
|
it "returns the passed proc created from a block" do
|
|
passed_prc = Proc.new { "hello".size }
|
|
prc = Proc.new(&passed_prc)
|
|
|
|
prc.should equal(passed_prc)
|
|
prc.call.should == 5
|
|
end
|
|
|
|
it "returns the passed proc created from a method" do
|
|
method = "hello".method(:size)
|
|
passed_prc = Proc.new(&method)
|
|
prc = Proc.new(&passed_prc)
|
|
|
|
prc.should equal(passed_prc)
|
|
prc.call.should == 5
|
|
end
|
|
|
|
it "returns the passed proc created from a symbol" do
|
|
passed_prc = Proc.new(&:size)
|
|
prc = Proc.new(&passed_prc)
|
|
|
|
prc.should equal(passed_prc)
|
|
prc.call("hello").should == 5
|
|
end
|
|
end
|
|
|
|
describe "Proc.new with a block argument called indirectly from a subclass" do
|
|
it "returns the passed proc created from a block" do
|
|
passed_prc = ProcSpecs::MyProc.new { "hello".size }
|
|
passed_prc.class.should == ProcSpecs::MyProc
|
|
prc = ProcSpecs::MyProc.new(&passed_prc)
|
|
|
|
prc.should equal(passed_prc)
|
|
prc.call.should == 5
|
|
end
|
|
|
|
it "returns the passed proc created from a method" do
|
|
method = "hello".method(:size)
|
|
passed_prc = ProcSpecs::MyProc.new(&method)
|
|
passed_prc.class.should == ProcSpecs::MyProc
|
|
prc = ProcSpecs::MyProc.new(&passed_prc)
|
|
|
|
prc.should equal(passed_prc)
|
|
prc.call.should == 5
|
|
end
|
|
|
|
it "returns the passed proc created from a symbol" do
|
|
passed_prc = ProcSpecs::MyProc.new(&:size)
|
|
passed_prc.class.should == ProcSpecs::MyProc
|
|
prc = ProcSpecs::MyProc.new(&passed_prc)
|
|
|
|
prc.should equal(passed_prc)
|
|
prc.call("hello").should == 5
|
|
end
|
|
end
|
|
|
|
describe "Proc.new without a block" do
|
|
it "raises an ArgumentError" do
|
|
-> { Proc.new }.should raise_error(ArgumentError)
|
|
end
|
|
|
|
it "raises an ArgumentError if invoked from within a method with no block" do
|
|
-> { ProcSpecs.new_proc_in_method }.should raise_error(ArgumentError)
|
|
end
|
|
|
|
it "raises an ArgumentError if invoked on a subclass from within a method with no block" do
|
|
-> { ProcSpecs.new_proc_subclass_in_method }.should raise_error(ArgumentError)
|
|
end
|
|
|
|
ruby_version_is ""..."2.7" do
|
|
it "uses the implicit block from an enclosing method" do
|
|
def some_method
|
|
Proc.new
|
|
end
|
|
|
|
prc = some_method { "hello" }
|
|
|
|
prc.call.should == "hello"
|
|
end
|
|
|
|
it "uses the implicit block from an enclosing method when called inside a block" do
|
|
def some_method
|
|
proc do |&block|
|
|
Proc.new
|
|
end.call { "failing" }
|
|
end
|
|
prc = some_method { "hello" }
|
|
|
|
prc.call.should == "hello"
|
|
end
|
|
end
|
|
|
|
ruby_version_is "2.7"..."3.0" do
|
|
it "can be created if invoked from within a method with a block" do
|
|
-> { ProcSpecs.new_proc_in_method { "hello" } }.should complain(/Capturing the given block using Proc.new is deprecated/)
|
|
end
|
|
|
|
it "can be created if invoked on a subclass from within a method with a block" do
|
|
-> { ProcSpecs.new_proc_subclass_in_method { "hello" } }.should complain(/Capturing the given block using Proc.new is deprecated/)
|
|
end
|
|
|
|
|
|
it "can be create when called with no block" do
|
|
def some_method
|
|
Proc.new
|
|
end
|
|
|
|
-> {
|
|
some_method { "hello" }
|
|
}.should complain(/Capturing the given block using Proc.new is deprecated/)
|
|
end
|
|
end
|
|
|
|
ruby_version_is "3.0" do
|
|
it "raises an ArgumentError when passed no block" do
|
|
def some_method
|
|
Proc.new
|
|
end
|
|
|
|
-> { ProcSpecs.new_proc_in_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
|
|
-> { ProcSpecs.new_proc_subclass_in_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
|
|
-> { some_method { "hello" } }.should raise_error(ArgumentError, 'tried to create Proc object without a block')
|
|
end
|
|
end
|
|
end
|