require 'cucumber/formatter/legacy_api/adapter' require 'cucumber/core' require 'cucumber/core/gherkin/writer' require 'cucumber/runtime/step_hooks' require 'cucumber/runtime/before_hooks' require 'cucumber/runtime/after_hooks' require 'cucumber/filters' module Cucumber module Formatter::LegacyApi describe Adapter do include Core::Gherkin::Writer include Core let(:report) { Adapter.new(formatter, runtime.results, runtime.support_code, runtime.configuration) } let(:formatter) { double('formatter').as_null_object } let(:runtime) { Runtime.new } Failure = Class.new(StandardError) class SimpleStepMatch def initialize(&block) @block = block end def activate(test_step) test_step.with_action &@block end end class SimpleStepDefinitions def find_match(test_step) if test_step.name =~ /pass/ return SimpleStepMatch.new {} end if test_step.name =~ /fail/ return SimpleStepMatch.new { raise Failure } end NoStepMatch.new test_step.source.last, test_step.name end end class AddBeforeAndAfterHooks < Core::Filter.new def test_case(test_case) steps = before_hooks(test_case.source) + test_case.test_steps + after_hooks(test_case.source) test_case.with_steps(steps).describe_to receiver end private def before_hooks(source) # The adapter is built on the assumption that each test case will have at least one step. This is annoying # for tests, but a safe assumption for production use as we always add one hook to initialize the world. [ Hooks.before_hook(source) {} ] end def after_hooks(source) # We add an after hook to make sure the adapter can cope with it [ Hooks.after_hook(source) {} ] end end context 'message order' do let(:formatter) { MessageSpy.new } it 'two features' do gherkin_docs = [ gherkin do feature do scenario do step 'passing' end end end, gherkin do feature do scenario do step 'passing' end end end, ] runner = Core::Test::Runner.new(report) compile gherkin_docs, runner, default_filters expect( formatter.legacy_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, :after_feature_element, :after_feature, :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, :after_feature_element, :after_feature, :after_features, ] end it 'a scenario with no steps' do execute_gherkin do feature do scenario end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_feature_element, :before_tags, :after_tags, :scenario_name, :after_feature_element, :after_feature, :after_features, ] end it 'a scenario with no steps coming after another scenario' do execute_gherkin do feature do scenario do step 'passing' end scenario end end expect( formatter.legacy_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, :after_feature_element, :before_feature_element, :before_tags, :after_tags, :scenario_name, :after_feature_element, :after_feature, :after_features, ] end it 'a scenario with one step' do execute_gherkin do feature do scenario do step 'passing' end end end expect( formatter.legacy_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, :after_feature_element, :after_feature, :after_features, ] end it 'a scenario with two steps, one of them failing' do execute_gherkin do feature do scenario do step 'passing' step 'failing' end end end expect( formatter.legacy_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, :before_step, :before_step_result, :step_name, :exception, :after_step_result, :after_step, :after_steps, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with two scenarios' do execute_gherkin do feature do scenario do step 'passing' end scenario do step 'passing' end end end expect( formatter.legacy_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, :after_feature_element, :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, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background and an empty scenario' do execute_gherkin do feature do background do step 'passing' end scenario end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :before_feature_element, :before_tags, :after_tags, :scenario_name, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background and two scenarios' do execute_gherkin do feature do background do step 'passing' end scenario do step 'passing' end scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :after_feature_element, :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, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background and one scenario and one scenario outline' do execute_gherkin do feature do background do step 'passing' end scenario do step 'passing' end scenario_outline do step 'ing' examples do row 'result' row 'pass' end end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :after_feature_element, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background and one scenario outline and one scenario' do execute_gherkin do feature do background do step 'passing' end scenario_outline do step 'ing' examples do row 'result' row 'pass' end end scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :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, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background and two scenario outlines' do execute_gherkin do feature do background do step 'passing' end scenario_outline do step 'ing' examples do row 'result' row 'pass' end end scenario_outline do step 'ing' examples do row 'result' row 'pass' end end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background and one scenario outline with two rows' do execute_gherkin do feature do background do step 'passing' end scenario_outline do step 'ing' examples do row 'result' row 'pass' row 'pass' end end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background and one scenario outline with two examples tables' do execute_gherkin do feature do background do step 'passing' end scenario_outline do step 'ing' examples do row 'result' row 'pass' end examples do row 'result' row 'pass' end end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background with two steps' do execute_gherkin do feature do background do step 'passing' step 'passing' end scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a background' do execute_gherkin do feature do background do step 'passing' end scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :after_feature_element, :after_feature, :after_features, ] end it 'scenario outline' do execute_gherkin do feature do scenario_outline do step 'ing' examples do row 'result' row 'pass' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'scenario outline after scenario' do execute_gherkin do feature do scenario do step 'passing' end scenario_outline do step 'ing' examples do row 'result' row 'pass' end end end end expect( formatter.legacy_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, :after_feature_element, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'scenario outline before scenario' do execute_gherkin do feature do scenario_outline do step 'ing' examples do row 'result' row 'pass' end end scenario do step 'passing' end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :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, :after_feature_element, :after_feature, :after_features, ] end it 'scenario outline two rows' do execute_gherkin do feature do scenario_outline do step 'ing' examples do row 'result' row 'pass' row 'pass' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'scenario outline two examples tables' do execute_gherkin do feature do scenario_outline do step 'ing' examples do row 'result' row 'pass' end examples do row 'result' row 'pass' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'two scenario outline' do execute_gherkin do feature do scenario_outline do step 'ing' examples do row 'result' row 'pass' end end scenario_outline do step 'ing' examples do row 'result' row 'pass' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'failing scenario outline' do execute_gherkin do feature do scenario_outline do step 'ing' examples do row 'result' row 'fail' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end it 'a feature with a failing background and two scenarios' do execute_gherkin do feature do background do step 'failing' end scenario do step 'passing' end scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq [ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :before_steps, :before_step, :before_step_result, :step_name, :exception, :after_step_result, :after_step, :after_steps, :after_background, :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, :after_feature_element, :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, :after_feature_element, :after_feature, :after_features, ] end context 'in expand mode' do let(:runtime) { Runtime.new expand: true } let(:formatter) { MessageSpy.new } it 'scenario outline two rows' do execute_gherkin do feature do scenario_outline do step 'ing' examples do row 'result' row 'pass' row 'pass' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :scenario_name, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :scenario_name, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ] end end context 'with exception in after step hook' do class FailingAfterStepHook def find_after_step_hooks(test_case) Runtime::StepHooks.new [-> { raise Failure }] end end it 'prints the exception within the step' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyAfterStepHooks.new(FailingAfterStepHook.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario do step 'passing' end end end expect( formatter.legacy_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, :exception, :after_steps, :after_feature_element, :after_feature, :after_features, ]) end end context 'with exception in a single before hook' do class FailingBeforeHook def apply_before_hooks(test_case) Runtime::BeforeHooks.new([proc { raise Failure }]).apply_to(test_case) end end it 'prints the exception after the scenario name' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyBeforeHooks.new(FailingBeforeHook.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq([ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_feature_element, :before_tags, :after_tags, :scenario_name, :exception, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_feature_element, :after_feature, :after_features, ]) end it 'prints the exception after the background name' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyBeforeHooks.new(FailingBeforeHook.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do background do step 'passing' end scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq([ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_background, :background_name, :exception, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_background, :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, :after_feature_element, :after_feature, :after_features, ]) end it 'prints the exception before the examples table row' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyBeforeHooks.new(FailingBeforeHook.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario_outline do step 'ing' examples do row 'status' row 'pass' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :exception, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ]) end end context 'with exception in the first of several before hooks' do # This proves that the second before hook's result doesn't overwrite # the result of the first one. class FailingAndPassingBeforeHooks def apply_before_hooks(test_case) Runtime::BeforeHooks.new([proc { raise Failure }, proc { }]).apply_to(test_case) end end it 'prints the exception after the scenario name' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyBeforeHooks.new(FailingAndPassingBeforeHooks.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario do step 'passing' end end end expect( formatter.legacy_messages ).to eq([ :before_features, :before_feature, :before_tags, :after_tags, :feature_name, :before_feature_element, :before_tags, :after_tags, :scenario_name, :exception, :before_steps, :before_step, :before_step_result, :step_name, :after_step_result, :after_step, :after_steps, :after_feature_element, :after_feature, :after_features, ]) end end context 'with exception in after hooks' do class FailingAfterHook def apply_after_hooks(test_case) Runtime::AfterHooks.new([proc { raise Failure }]).apply_to(test_case) end end it 'prints the exception after the steps' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyAfterHooks.new(FailingAfterHook.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario do step 'passing' end end end expect( formatter.legacy_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 it 'prints the exception after the examples table row' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyAfterHooks.new(FailingAfterHook.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario_outline do step 'ing' examples do row 'status' row 'pass' end end end end expect( formatter.legacy_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, :before_examples_array, :before_examples, :examples_name, :before_outline_table, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :before_table_row, :before_table_cell, :table_cell_value, :after_table_cell, :after_table_row, :exception, :after_outline_table, :after_examples, :after_examples_array, :after_feature_element, :after_feature, :after_features, ]) end end context 'with exception in the first of several after hooks' do class FailingThenPassingAfterHooks def apply_after_hooks(test_case) Runtime::AfterHooks.new([proc { raise Failure }, proc {}]).apply_to(test_case) end end it 'prints the exception after the steps' do filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyAfterHooks.new(FailingThenPassingAfterHooks.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario do step 'passing' end end end expect( formatter.legacy_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 filters = [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), Filters::ApplyAfterHooks.new(FailingAfterHook.new), AddBeforeAndAfterHooks.new ] execute_gherkin(filters) do feature do scenario do end end end expect( formatter.legacy_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 nil as the multiline arg when there is none' do expect(formatter).to receive(:after_step_result) do |keyword, step_match, multiline_arg, status, exception, source_indent, background, file_colon_line| expect(multiline_arg).to be_nil end execute_gherkin do feature do scenario do step 'passing' end end end end it 'passes an object responding to failed? with the after_feature_element message' do expect( formatter ).to receive(:after_feature_element) do |scenario| expect( scenario ).to be_failed end execute_gherkin do feature do scenario do step 'failing' end end end end context 'in strict mode' do let(:runtime) { Runtime.new strict: true } it 'passes an exception to the formatter for undefined steps' do expect( formatter ).to receive(:exception) do |exception| expect( exception.message ).to eq %{Undefined step: "this step is undefined"} end execute_gherkin do feature do scenario do step 'this step is undefined' end end end end end class MessageSpy attr_reader :messages def initialize @messages = [] end def legacy_messages @messages - [ :before_test_step, :before_test_case, :after_test_step, :after_test_case, :done ] end def method_missing(message, *args) @messages << message end def respond_to_missing?(name, include_private = false) true end end def execute_gherkin(filters = default_filters, &gherkin) runner = Core::Test::Runner.new(report) compile [gherkin(&gherkin)], runner, filters end def default_filters [ Filters::ActivateSteps.new(SimpleStepDefinitions.new), AddBeforeAndAfterHooks.new ] end end end end