Skip to content

Commit

Permalink
Better reporting of After hook exceptions
Browse files Browse the repository at this point in the history
Closes #723
  • Loading branch information
mattwynne committed Aug 29, 2014
1 parent f0ce241 commit 63c6694
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 18 deletions.
50 changes: 32 additions & 18 deletions lib/cucumber/reports/legacy_formatter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,14 @@ def after_test_case(*args)
end

def before_hook(location, result)
@before_hook_results << Legacy::Ast::BeforeHookResult.new(LegacyResultBuilder.new(result))
@before_hook_results << Legacy::Ast::HookResult.new(LegacyResultBuilder.new(result))
end

def after_hook(location, result)
return unless @child
@child.after_hook LegacyResultBuilder.new(result)
# if the scenario has no steps, we can hit this before we've created the scenario printer
# ideally we should call switch_step_container in before_step_step
switch_step_container if !@child
@child.after_hook Legacy::Ast::HookResult.new(LegacyResultBuilder.new(result))
end

def after_step_hook(hook, result)
Expand Down Expand Up @@ -378,6 +380,27 @@ def indented(nasty_old_conflation_of_name_and_description)

end

module PrintsAfterHooks
def after_hook_results
@after_hook_results ||= Legacy::Ast::NodeCollection.new
end

def after_hook(result)
after_hook_results << result
end
end

# Basic printer used by default
class AfterHookPrinter
include Cucumber.initializer(:formatter)

include PrintsAfterHooks

def after
after_hook_results.accept(formatter)
end
end

BackgroundPrinter = Struct.new(:formatter, :runtime, :node, :before_hook_results) do

def before
Expand Down Expand Up @@ -439,6 +462,7 @@ def after_test_case(*);end
end

ScenarioPrinter = Struct.new(:formatter, :runtime, :node, :before_hook_results) do
include PrintsAfterHooks

def before
formatter.before_feature_element(node)
Expand All @@ -454,10 +478,6 @@ def step_invocation(step_invocation, source)
@last_step_result = source.step_result
end

def after_hook(result)
@after_hook_result = result
end

def after_step_hook(result)
result.describe_exception_to formatter
end
Expand All @@ -472,7 +492,7 @@ def after
# TODO - the last step result might not accurately reflect the
# overall scenario result.
scenario = last_step_result.scenario(node.name, node.location)
@after_hook_result.describe_exception_to(formatter) if @after_hook_result
after_hook_results.accept(formatter)
formatter.after_feature_element(scenario)
@done = true
self
Expand Down Expand Up @@ -526,10 +546,6 @@ def before
self
end

def after_hook(result)
@child.after_hook(result)
end

def step_invocation(step_invocation, source)
node, result = source.step, source.step_result
@last_step_result = result
Expand Down Expand Up @@ -701,9 +717,7 @@ def char_length_of(cell)
end

class TableRowPrinterBase < Struct.new(:formatter, :runtime, :node, :before_hook_results)
def after_hook(result)
@after_hook_result = result
end
include PrintsAfterHooks

def after_step_hook(result)
@after_step_hook_result = result
Expand Down Expand Up @@ -772,7 +786,7 @@ def after
end
formatter.after_table_row(legacy_table_row)
@after_step_hook_result.describe_exception_to formatter if @after_step_hook_result
@after_hook_result.describe_exception_to(formatter) if @after_hook_result
after_hook_results.accept(formatter)
@done = true
self
end
Expand Down Expand Up @@ -807,7 +821,7 @@ def after
return if @done
@child.after if @child
@after_step_hook_result.describe_exception_to formatter if @after_step_hook_result
@after_hook_result.describe_exception_to(formatter) if @after_hook_result
after_hook_results.accept(formatter)
@done = true
self
end
Expand Down Expand Up @@ -1036,7 +1050,7 @@ def accept(formatter)
end
end

class BeforeHookResult
class HookResult
def initialize(result)
@result = result
@already_accepted = false
Expand Down
69 changes: 69 additions & 0 deletions spec/cucumber/reports/legacy_formatter_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1729,6 +1729,75 @@ module Cucumber
])
end
end

context 'with exception in the first of several after hooks' do
it 'prints the exception after the steps' do
define_steps do
After { raise 'an exception' }
After { }
end
execute_gherkin do
feature do
scenario do
step 'passing'
end
end
end

expect( formatter.messages ).to eq([
:before_features,
:before_feature,
:before_tags,
:after_tags,
:feature_name,
:before_feature_element,
:before_tags,
:after_tags,
:scenario_name,
:before_steps,
:before_step,
:before_step_result,
:step_name,
:after_step_result,
:after_step,
:after_steps,
:exception,
:after_feature_element,
:after_feature,
:after_features
])
end
end

context 'with an exception in an after hook but no steps' do
it 'prints the exception after the steps' do
define_steps do
After { fail }
end
execute_gherkin do
feature do
scenario do
end
end
end

expect( formatter.messages ).to eq([
:before_features,
:before_feature,
:before_tags,
:after_tags,
:feature_name,
:before_feature_element,
:before_tags,
:after_tags,
:scenario_name,
:exception,
:after_feature_element,
:after_feature,
:after_features
])
end
end
end

it 'passes an object responding to failed? with the after_feature_element message' do
Expand Down

0 comments on commit 63c6694

Please sign in to comment.