1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00
ruby--ruby/spec/ruby/core/proc/new_spec.rb
2020-09-15 21:56:00 +02:00

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