@Test
  public void shouldRunScenarioAndLifecycleStepsInCorrectOrderWithExamplesTable() throws Throwable {
    // Given
    ExamplesTable examplesTable = new ExamplesTable("|one|two|\n|1|2|\n");
    Map<String, String> tableRow = examplesTable.getRow(0);
    Scenario scenario1 =
        new Scenario(
            "my title 1",
            Meta.EMPTY,
            GivenStories.EMPTY,
            examplesTable,
            asList("step <one>", "step <two>"));
    Story story = new Story(new Description("my blurb"), Narrative.EMPTY, asList(scenario1));
    StoryReporter reporter = mock(ConcurrentStoryReporter.class);
    StepCollector collector = mock(StepCollector.class);
    FailureStrategy failureStrategy = mock(FailureStrategy.class);
    Configuration configuration = configurationWith(reporter, collector, failureStrategy);
    configuration.storyControls().doDryRun(true);
    CandidateSteps mySteps = new Steps(configuration);
    Step firstStep = mockSuccessfulStep("step <one>");
    Step secondStep = mockSuccessfulStep("step <two>");
    when(collector.collectScenarioSteps(asList(mySteps), scenario1, tableRow))
        .thenReturn(asList(firstStep, secondStep));
    boolean givenStory = false;
    givenStoryWithNoBeforeOrAfterSteps(story, givenStory, collector, mySteps);

    Step beforeExampleStep = mockSuccessfulStep("beforeExampleStep");
    Step afterExampleStep = mockSuccessfulStep("afterExampleStep");
    when(collector.collectBeforeOrAfterScenarioSteps(
            eq(asList(mySteps)), Matchers.<Meta>any(), eq(Stage.BEFORE), eq(ScenarioType.EXAMPLE)))
        .thenReturn(asList(beforeExampleStep));
    when(collector.collectBeforeOrAfterScenarioSteps(
            eq(asList(mySteps)), Matchers.<Meta>any(), eq(Stage.AFTER), eq(ScenarioType.EXAMPLE)))
        .thenReturn(asList(afterExampleStep));

    Step beforeStep = mockSuccessfulStep("lifecycleBeforeStep");
    Step afterStep = mockSuccessfulStep("lifecycleAfterStep");
    when(collector.collectLifecycleSteps(
            eq(asList(mySteps)), eq(Lifecycle.EMPTY), any(Meta.class), eq(Stage.BEFORE)))
        .thenReturn(asList(beforeStep));
    when(collector.collectLifecycleSteps(
            eq(asList(mySteps)), eq(Lifecycle.EMPTY), any(Meta.class), eq(Stage.AFTER)))
        .thenReturn(asList(afterStep));

    // When
    StoryRunner runner = new StoryRunner();
    runner.run(configuration, asList(mySteps), story);

    // Then
    InOrder inOrder = inOrder(reporter, failureStrategy);
    inOrder.verify(reporter).successful("beforeExampleStep");
    inOrder.verify(reporter).successful("lifecycleBeforeStep");
    inOrder.verify(reporter).successful("step <one>");
    inOrder.verify(reporter).successful("step <two>");
    inOrder.verify(reporter).successful("lifecycleAfterStep");
    inOrder.verify(reporter).successful("afterExampleStep");
  }
  @Test
  public void shouldAllowToSkipBeforeAndAfterScenarioStepsIfGivenStory() throws Throwable {
    // Given
    Scenario scenario1 = new Scenario("scenario 1", asList("successfulStep"));
    GivenStories givenStories = new GivenStories("/path/to/given/story1");
    Scenario scenario2 =
        new Scenario(
            "scenario 2",
            Meta.EMPTY,
            givenStories,
            ExamplesTable.EMPTY,
            asList("anotherSuccessfulStep"));
    Story story1 = new Story(new Description("story 1"), Narrative.EMPTY, asList(scenario1));
    Story story2 = new Story(new Description("story 2"), Narrative.EMPTY, asList(scenario2));

    Step step = mock(Step.class);
    StepResult result = mock(StepResult.class);
    when(step.perform(null)).thenReturn(result);

    StoryParser storyParser = mock(StoryParser.class);
    StoryLoader storyLoader = mock(StoryLoader.class);
    StoryReporter reporter = mock(ConcurrentStoryReporter.class);
    StepCollector collector = mock(StepCollector.class);
    CandidateSteps mySteps = new Steps();
    Step successfulStep = mockSuccessfulStep("successfulStep");
    Step anotherSuccessfulStep = mockSuccessfulStep("anotherSuccessfulStep");
    givenStoryWithNoBeforeOrAfterSteps(story1, false, collector, mySteps);
    when(collector.collectScenarioSteps(asList(mySteps), scenario1, parameters))
        .thenReturn(asList(successfulStep));
    givenStoryWithNoBeforeOrAfterSteps(story2, true, collector, mySteps);
    when(collector.collectScenarioSteps(asList(mySteps), scenario2, parameters))
        .thenReturn(asList(anotherSuccessfulStep));
    when(storyLoader.loadStoryAsText("/path/to/given/story1")).thenReturn("storyContent");
    when(storyParser.parseStory("storyContent", "/path/to/given/story1")).thenReturn(story1);
    FailureStrategy failureStrategy = mock(FailureStrategy.class);

    Step beforeStep = mockSuccessfulStep("SuccessfulBeforeScenarioStep");
    Step afterStep = mockSuccessfulStep("SuccessfulAfterScenarioStep");
    when(collector.collectBeforeOrAfterScenarioSteps(
            eq(asList(mySteps)), Matchers.<Meta>any(), eq(Stage.BEFORE), eq(ScenarioType.NORMAL)))
        .thenReturn(asList(beforeStep));
    when(collector.collectBeforeOrAfterScenarioSteps(
            eq(asList(mySteps)), Matchers.<Meta>any(), eq(Stage.AFTER), eq(ScenarioType.NORMAL)))
        .thenReturn(asList(afterStep));

    // When
    StoryRunner runner = new StoryRunner();
    Configuration configuration =
        configurationWith(storyParser, storyLoader, reporter, collector, failureStrategy);
    configuration.storyControls().doSkipBeforeAndAfterScenarioStepsIfGivenStory(true);
    runner.run(configuration, asList(mySteps), story2);

    // Then
    verify(collector).collectScenarioSteps(asList(mySteps), scenario1, parameters);
    verify(collector).collectScenarioSteps(asList(mySteps), scenario2, parameters);

    InOrder inOrder = inOrder(beforeStep, successfulStep, anotherSuccessfulStep, afterStep);

    inOrder.verify(beforeStep).perform(null);
    inOrder.verify(successfulStep).perform(null);
    inOrder.verify(anotherSuccessfulStep).perform(null);
    inOrder.verify(afterStep).perform(null);
  }