Permalink
Fetching contributors…
Cannot retrieve contributors at this time
111 lines (102 sloc) 2.99 KB
# only passing a block works.
# Procs always LocalJumpError on break
# Lambdas either LocalJumpError or ignore it completely, depending on how they're called
class EachWithBlock
include Enumerable
attr_reader :times_around, :after_called
def initialize
@after_called = false
@times_around = 0
end
def each &call_me
raise ArgumentError.new("bad, dont call this again") if @times_around != 0
for i in 1..3 do
call_me.call i
@times_around += 1
end
@after_called = true
@times_around
end
end
class EachWithYield
include Enumerable
attr_reader :times_around, :after_called
def initialize
@after_called = false
end
def each
@times_around = 0
for i in 1..3 do
yield i
@times_around += 1
end
@after_called = true
@times_around
end
end
describe "break" do
let(:cwb) { EachWithBlock.new }
let(:cwy) { EachWithYield.new }
describe "block that uses break" do
it "breaks when called with yield" do
t = cwy
(t.each { |i| break "stuff #{i}" if (i > 1)}).should == "stuff 2"
t.after_called.should be_false
t.times_around.should == 1
end
it "breaks when called with block" do
t = cwb
(t.each { |i| break "stuff #{i}" }).should == "stuff 1"
t.after_called.should be_false
t.times_around.should == 0
end
it "Returns and skips the statements after if called inside a lambda" do
t = cwb
lambda { t.each { |i| break "stuff #{i}"}}.call.should == "stuff 1"
t.after_called.should be_false
t.times_around.should == 0
end
end
describe "proc that uses break" do
let(:p) { Proc.new { break "stuff"}}
it "throws LocalJumpError when called with yield in a proc" do
t = cwy
Proc.new { t.each &p }.should raise_error(LocalJumpError)
t.after_called.should be_false
t.times_around.should == 0
end
it "throws LocalJumpError when called with block in a proc" do
t = cwb
Proc.new { t.each &p }.should raise_error(LocalJumpError)
t.after_called.should be_false
t.times_around.should == 0
end
it "throws LocalJumpError even when called inside a lambda" do
t = cwb
lambda { t.each &p }.should raise_error(LocalJumpError)
t.after_called.should be_false
t.times_around.should == 0
end
end
describe "rspec" do
it "works on a lambda break; it's using block.call" do
lambda { break "stuff"}.should_not raise_error(LocalJumpError)
end
end
describe "lambda" do
#interesting: lambda checks argument times_around, the others don't care
let(:lam) { lambda { |i| break "stuff"}}
it "has no effect when called with block" do
t=cwb
t.each(&lam).should == 3
t.times_around.should == 3
t.after_called.should be_true
end
it "LocalJumpErrors when called with yield" do
t = cwy
Proc.new { t.each(&lam) }.should raise_error(LocalJumpError)
t.after_called.should be_false
t.times_around.should == 0
end
end
end