Skip to content

Commit

Permalink
Ensure that after(:each) blocks are run, even if one fails.
Browse files Browse the repository at this point in the history
Closes rspec#60.
  • Loading branch information
dchelimsky committed Jul 9, 2010
1 parent ce9dfea commit d0ef7e6
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 4 deletions.
8 changes: 6 additions & 2 deletions lib/rspec/core/example.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def run(example_group_instance, reporter)
@in_block = true
with_pending_capture &@example_block
rescue Exception => e
@exception = e
set_exception(e)
ensure
@in_block = false
run_after_each
Expand All @@ -60,7 +60,7 @@ def run(example_group_instance, reporter)
end.call
end
rescue Exception => e
@exception ||= e
set_exception(e)
ensure
@example_group_instance.example = nil
assign_auto_description
Expand All @@ -69,6 +69,10 @@ def run(example_group_instance, reporter)
finish(reporter)
end

def set_exception(exception)
@exception ||= exception
end

private

def with_pending_capture
Expand Down
22 changes: 20 additions & 2 deletions lib/rspec/core/hooks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,30 @@ def to_proc
def call
@block.call
end
end

class BeforeHook < Hook
def run_in(example)
example ? example.instance_eval(&self) : call
end
end

class BeforeHook < Hook; end
class AfterHook < Hook; end
class AfterHook < Hook
def run_in(example)
if example
begin
example.instance_eval(&self)
rescue Exception => e
if example.respond_to?(:example)
example.example.set_exception(e)
end
end
else
call
end
end
end

class AroundHook < Hook
def call(wrapped_example)
@block.call(wrapped_example)
Expand All @@ -50,6 +66,7 @@ def run_all!(example)
shift.run_in(example) until empty?
end
end

class AfterHooks < HookCollection
def run_all(example)
reverse.each {|h| h.run_in(example) }
Expand All @@ -59,6 +76,7 @@ def run_all!(example)
pop.run_in(example) until empty?
end
end

class AroundHooks < HookCollection; end

def hooks
Expand Down
23 changes: 23 additions & 0 deletions spec/rspec/core/example_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,29 @@
after_run.should be_true, "expected after(:each) to be run"
end

context "with an after(:each) that raises" do
it "runs subsequent after(:each)'s" do
after_run = false
group = RSpec::Core::ExampleGroup.describe do
after(:each) { after_run = true }
after(:each) { raise "FOO" }
example('example') { 1.should == 1 }
end
group.run_all
after_run.should be_true, "expected after(:each) to be run"
end

it "stores the exception" do
group = RSpec::Core::ExampleGroup.describe
group.after(:each) { raise "FOO" }
example = group.example('example') { 1.should == 1 }

group.run_all

example.metadata[:execution_result][:exception_encountered].message.should == "FOO"
end
end

it "wraps before/after(:each) inside around" do
results = []
group = RSpec::Core::ExampleGroup.describe do
Expand Down

0 comments on commit d0ef7e6

Please sign in to comment.