package org.jbehave.core.steps;
import static java.util.Arrays.asList;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.lessThan;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.hamcrest.Matchers;
import org.jbehave.core.annotations.AfterScenario;
import org.jbehave.core.annotations.AfterScenario.Outcome;
import org.jbehave.core.annotations.AfterStory;
import org.jbehave.core.annotations.BeforeScenario;
import org.jbehave.core.annotations.BeforeStory;
import org.jbehave.core.annotations.Named;
import org.jbehave.core.annotations.ScenarioType;
import org.jbehave.core.failures.PendingStepFound;
import org.jbehave.core.failures.UUIDExceptionWrapper;
import org.jbehave.core.model.Lifecycle;
import org.jbehave.core.model.Meta;
import org.jbehave.core.model.Scenario;
import org.jbehave.core.model.Story;
import org.jbehave.core.steps.AbstractStepResult.Ignorable;
import org.jbehave.core.steps.AbstractStepResult.Comment;
import org.jbehave.core.steps.StepCollector.Stage;
import org.jbehave.core.steps.StepCreator.PendingStep;
import org.jbehave.core.steps.StepFinder.ByLevenshteinDistance;
import org.junit.Test;
import com.thoughtworks.xstream.XStream;
public class MarkUnmatchedStepsAsPendingBehaviour {
private MarkUnmatchedStepsAsPending stepCollector = new MarkUnmatchedStepsAsPending();
private Map<String, String> parameters = new HashMap<String, String>();
@Test
public void shouldCreateExecutableStepsWhenCandidatesAreMatched() {
// Given
StepCandidate candidate = mock(StepCandidate.class);
Step executableStep = mock(Step.class);
String stepAsString = "my step";
when(candidate.matches(stepAsString)).thenReturn(true);
when(candidate.createMatchedStep(stepAsString, parameters)).thenReturn(executableStep);
List<CandidateSteps> steps = mockCandidateSteps(candidate);
// When
List<Step> executableSteps = stepCollector.collectScenarioSteps(steps, createScenario(stepAsString),
parameters);
// Then
assertThat(executableSteps.size(), equalTo(1));
assertThat(executableSteps.get(0), equalTo(executableStep));
}
@Test
public void shouldCreateExecutableStepsOnlyFromPreviousNonAndStep() {
// Given
StepCandidate candidate = mock(StepCandidate.class, "candidate");
StepCandidate andCandidate = mock(StepCandidate.class, "andCandidate");
Step step = mock(Step.class);
Step andStep = mock(Step.class);
String myStep = "my step";
when(candidate.matches(myStep)).thenReturn(true);
when(candidate.createMatchedStep(myStep, parameters)).thenReturn(step);
when(andCandidate.isAndStep(myStep)).thenReturn(false);
String myAndStep = "my And step";
when(andCandidate.matches(myAndStep)).thenReturn(true);
when(andCandidate.isAndStep(myAndStep)).thenReturn(true);
when(andCandidate.createMatchedStep(myAndStep, parameters)).thenReturn(andStep);
List<CandidateSteps> steps = mockCandidateSteps(candidate, andCandidate);
// When
List<Step> executableSteps = stepCollector.collectScenarioSteps(steps,
createScenario(myStep, myAndStep), parameters);
// Then
assertThat(executableSteps.size(), equalTo(2));
}
@Test
public void shouldCreateExecutableStepsUponOutcome() {
// Given
StepCandidate anyCandidate = mock(StepCandidate.class, "anyCandidate");
StepCandidate successCandidate = mock(StepCandidate.class, "successCandidate");
StepCandidate failureCandidate = mock(StepCandidate.class, "failureCandidate");
Step anyStep = mock(Step.class, "anyStep");
Step successStep = mock(Step.class, "successStep");
Step failureStep = mock(Step.class, "failureStep");
String myAnyStep = "my any step";
when(anyCandidate.matches(myAnyStep)).thenReturn(true);
when(anyCandidate.createMatchedStepUponOutcome(myAnyStep, parameters, Outcome.ANY)).thenReturn(anyStep);
when(successCandidate.isAndStep(myAnyStep)).thenReturn(false);
String mySuccessStep = "my success step";
when(successCandidate.matches(mySuccessStep)).thenReturn(true);
when(successCandidate.isAndStep(mySuccessStep)).thenReturn(false);
when(successCandidate.createMatchedStepUponOutcome(mySuccessStep, parameters, Outcome.SUCCESS)).thenReturn(successStep);
String myFailureStep = "my failure step";
when(successCandidate.matches(myFailureStep)).thenReturn(true);
when(successCandidate.isAndStep(myFailureStep)).thenReturn(false);
when(successCandidate.createMatchedStepUponOutcome(myFailureStep, parameters, Outcome.FAILURE)).thenReturn(failureStep);
List<CandidateSteps> steps = mockCandidateSteps(anyCandidate, successCandidate, failureCandidate);
Lifecycle lifecycle = new Lifecycle(
org.jbehave.core.model.Lifecycle.Steps.EMPTY,
new org.jbehave.core.model.Lifecycle.Steps(Outcome.ANY, asList(myAnyStep)),
new org.jbehave.core.model.Lifecycle.Steps(Outcome.SUCCESS, asList(mySuccessStep)),
new org.jbehave.core.model.Lifecycle.Steps(Outcome.FAILURE, asList(myFailureStep)));
// When
List<Step> executableSteps = stepCollector.collectLifecycleSteps(steps, lifecycle, Meta.EMPTY, Stage.AFTER);
// Then
assertThat(executableSteps.size(), equalTo(3));
assertThat(executableSteps.get(0), equalTo(anyStep));
assertThat(executableSteps.get(1), equalTo(successStep));
assertThat(executableSteps.get(2), equalTo(failureStep));
}
@Test
public void shouldAddComposedStepsWhenACompositeStepIsMatched() {
// Given
StepCandidate compositeCandidate = mock(StepCandidate.class, "compositeCandidate");
StepCandidate composedCandidate1 = mock(StepCandidate.class, "composedCandidate1");
StepCandidate composedCandidate2 = mock(StepCandidate.class, "composedCandidate2");
Step executableCompositeStep = mock(Step.class, "composite");
List<CandidateSteps> steps = mockCandidateSteps(compositeCandidate, composedCandidate1, composedCandidate2);
String compositeStepAsString = "my composite step";
when(compositeCandidate.matches(compositeStepAsString)).thenReturn(true);
when(compositeCandidate.isComposite()).thenReturn(true);
when(compositeCandidate.createMatchedStep(compositeStepAsString, parameters)).thenReturn(
executableCompositeStep);
// When
stepCollector.collectScenarioSteps(steps, createScenario(compositeStepAsString), parameters);
// Then
verify(compositeCandidate, times(1)).
addComposedSteps(new ArrayList<Step>(), compositeStepAsString, parameters,
asList(compositeCandidate, composedCandidate1, composedCandidate2));
}
@Test
public void shouldCreatePendingStepsWhenCandidatesAreNotFound() {
// Given
String givenPendingStep = "Given a pending step";
String andGivenPendingStep = "And a given pending step";
String whenPendingStep = "When yet another pending step";
String andWhenPendingStep = "And a when pending step";
List<CandidateSteps> steps = mockCandidateSteps();
// When
List<Step> executableSteps = stepCollector.collectScenarioSteps(steps,
createScenario(givenPendingStep, andGivenPendingStep, whenPendingStep, andWhenPendingStep),
parameters);
// Then
assertThat(executableSteps.size(), equalTo(4));
assertIsPending(executableSteps.get(0), givenPendingStep, null);
assertIsPending(executableSteps.get(1), andGivenPendingStep, givenPendingStep);
assertIsPending(executableSteps.get(2), whenPendingStep, givenPendingStep);
assertIsPending(executableSteps.get(3), andWhenPendingStep, whenPendingStep);
}
@Test
public void shouldCreatePendingStepsWhenCandidatesAreNotMatched() {
// Given
String givenPendingStep = "Given a pending step";
String andGivenPendingStep = "And a given pending step";
String whenPendingStep = "When yet another pending step";
String andWhenPendingStep = "And a when pending step";
StepCandidate firstCandidate = mock(StepCandidate.class, "firstCandidate");
when(firstCandidate.matches(givenPendingStep)).thenReturn(false);
when(firstCandidate.isAndStep(givenPendingStep)).thenReturn(false);
StepCandidate secondCandidate = mock(StepCandidate.class, "secondCandidate");
when(secondCandidate.matches(andGivenPendingStep)).thenReturn(false);
when(secondCandidate.isAndStep(andGivenPendingStep)).thenReturn(true);
StepCandidate thirdCandidate = mock(StepCandidate.class, "thirdCandidate");
when(thirdCandidate.matches(whenPendingStep)).thenReturn(false);
when(thirdCandidate.isAndStep(whenPendingStep)).thenReturn(false);
StepCandidate fourthCandidate = mock(StepCandidate.class, "fourthCandidate");
when(fourthCandidate.matches(andWhenPendingStep)).thenReturn(false);
when(fourthCandidate.isAndStep(andWhenPendingStep)).thenReturn(true);
List<CandidateSteps> steps = mockCandidateSteps(firstCandidate, secondCandidate, thirdCandidate, fourthCandidate);
// When
List<Step> executableSteps = stepCollector.collectScenarioSteps(steps,
createScenario(givenPendingStep, andGivenPendingStep, whenPendingStep, andWhenPendingStep),
parameters);
// Then
assertThat(executableSteps.size(), equalTo(4));
assertIsPending(executableSteps.get(0), givenPendingStep, null);
assertIsPending(executableSteps.get(1), andGivenPendingStep, givenPendingStep);
assertIsPending(executableSteps.get(2), whenPendingStep, givenPendingStep);
assertIsPending(executableSteps.get(3), andWhenPendingStep, whenPendingStep);
}
private void assertIsPending(Step step, String stepAsString, String previousNonAndStep) {
assertThat(step, instanceOf(PendingStep.class));
PendingStep pendingStep = (PendingStep) step;
assertThat(pendingStep.stepAsString(), equalTo(stepAsString));
assertThat(pendingStep.previousNonAndStepAsString(), equalTo(previousNonAndStep));
Throwable throwable = step.perform(null).getFailure();
assertThat(throwable, instanceOf(PendingStepFound.class));
assertThat(throwable.getMessage(), equalTo(stepAsString));
}
@Test
public void shouldCreateIgnorableSteps() {
// Given
StepCandidate candidate = mock(StepCandidate.class);
String stepAsString = "my ignorable step";
when(candidate.ignore(stepAsString)).thenReturn(true);
List<CandidateSteps> steps = mockCandidateSteps(candidate);
// When
List<Step> executableSteps = stepCollector.collectScenarioSteps(steps, createScenario(stepAsString), parameters);
// Then
assertThat(executableSteps.size(), equalTo(1));
StepResult result = executableSteps.get(0).perform(null);
assertThat(result, Matchers.instanceOf(Ignorable.class));
}
@Test
public void shouldCreateComment() {
// Given
StepCandidate candidate = mock(StepCandidate.class);
String stepAsString = "comment";
when(candidate.comment(stepAsString)).thenReturn(true);
List<CandidateSteps> steps = mockCandidateSteps(candidate);
// When
List<Step> executableSteps = stepCollector.collectScenarioSteps(steps, createScenario(stepAsString), parameters);
// Then
assertThat(executableSteps.size(), equalTo(1));
StepResult result = executableSteps.get(0).perform(null);
assertThat(result, Matchers.instanceOf(Comment.class));
}
@Test
public void shouldCollectBeforeAndAfterScenarioAnnotatedSteps() {
assertThatBeforeAndAfterScenarioAnnotatedStepsCanBeCollectedForGivenType(ScenarioType.NORMAL);
assertThatBeforeAndAfterScenarioAnnotatedStepsCanBeCollectedForGivenType(ScenarioType.EXAMPLE);
assertThatBeforeAndAfterScenarioAnnotatedStepsCanBeCollectedForGivenType(ScenarioType.ANY);
}
private void assertThatBeforeAndAfterScenarioAnnotatedStepsCanBeCollectedForGivenType(ScenarioType scenarioType) {
// Given some candidate steps classes with before and after scenario
// methods
Meta storyAndScenarioMeta = mock(Meta.class);
CandidateSteps steps1 = mock(Steps.class);
CandidateSteps steps2 = mock(Steps.class);
BeforeOrAfterStep bafStep11 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep12 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep21 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep22 = mock(BeforeOrAfterStep.class);
Step stepBefore1 = mock(Step.class);
Step stepBefore2 = mock(Step.class);
Step stepAfter1 = mock(Step.class);
Step stepAfter2 = mock(Step.class);
when(bafStep11.getStage()).thenReturn(Stage.BEFORE);
when(bafStep11.createStepWith(storyAndScenarioMeta)).thenReturn(stepBefore1);
when(bafStep12.getStage()).thenReturn(Stage.BEFORE);
when(bafStep12.createStepWith(storyAndScenarioMeta)).thenReturn(stepBefore2);
when(bafStep21.getStage()).thenReturn(Stage.AFTER);
when(bafStep21.createStepUponOutcome(storyAndScenarioMeta)).thenReturn(stepAfter1);
when(bafStep22.getStage()).thenReturn(Stage.AFTER);
when(bafStep22.createStepUponOutcome(storyAndScenarioMeta)).thenReturn(stepAfter2);
when(steps1.listBeforeOrAfterScenario(scenarioType)).thenReturn(asList(bafStep11, bafStep12));
when(steps2.listBeforeOrAfterScenario(scenarioType)).thenReturn(asList(bafStep21, bafStep22));
// When we collect the list of steps
List<Step> beforeSteps = stepCollector.collectBeforeOrAfterScenarioSteps(asList(steps1, steps2),
storyAndScenarioMeta, Stage.BEFORE, scenarioType);
List<Step> afterSteps = stepCollector.collectBeforeOrAfterScenarioSteps(asList(steps1, steps2),
storyAndScenarioMeta, Stage.AFTER, scenarioType);
// Then all before and after steps should be added
assertThat(beforeSteps, equalTo(asList(stepBefore1, stepBefore2)));
assertThat(afterSteps, equalTo(asList(stepAfter1, stepAfter2)));
}
@Test
public void shouldCollectBeforeAndAfterStoryAnnotatedSteps() {
// Given some candidate steps classes with before and after story
// methods
Story story = new Story();
Meta storyMeta = story.getMeta();
CandidateSteps steps1 = mock(Steps.class);
CandidateSteps steps2 = mock(Steps.class);
BeforeOrAfterStep bafStep11 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep21 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep12 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep22 = mock(BeforeOrAfterStep.class);
Step stepBefore1 = mock(Step.class);
Step stepBefore2 = mock(Step.class);
Step stepAfter1 = mock(Step.class);
Step stepAfter2 = mock(Step.class);
boolean givenStory = false;
when(bafStep11.getStage()).thenReturn(Stage.BEFORE);
when(bafStep11.createStepWith(storyMeta)).thenReturn(stepBefore1);
when(bafStep21.getStage()).thenReturn(Stage.BEFORE);
when(bafStep21.createStepWith(storyMeta)).thenReturn(stepBefore2);
when(bafStep12.getStage()).thenReturn(Stage.AFTER);
when(bafStep12.createStepWith(storyMeta)).thenReturn(stepAfter1);
when(bafStep22.getStage()).thenReturn(Stage.AFTER);
when(bafStep22.createStepWith(storyMeta)).thenReturn(stepAfter2);
when(steps1.listBeforeOrAfterStory(givenStory)).thenReturn(asList(bafStep11, bafStep12));
when(steps2.listBeforeOrAfterStory(givenStory)).thenReturn(asList(bafStep21, bafStep22));
// When we collect the list of steps
List<Step> beforeSteps = stepCollector.collectBeforeOrAfterStorySteps(asList(steps1, steps2), story,
Stage.BEFORE, givenStory);
List<Step> afterSteps = stepCollector.collectBeforeOrAfterStorySteps(asList(steps1, steps2), story,
Stage.AFTER, givenStory);
// Then all before and after steps should be added
assertThat(beforeSteps, equalTo(asList(stepBefore1, stepBefore2)));
assertThat(afterSteps, equalTo(asList(stepAfter1, stepAfter2)));
}
@Test
public void shouldCollectBeforeAndAfterStoriesAnnotatedSteps() {
// Given some candidate steps classes with before and after stories
// methods
CandidateSteps steps1 = mock(Steps.class);
CandidateSteps steps2 = mock(Steps.class);
BeforeOrAfterStep bafStep11 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep21 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep12 = mock(BeforeOrAfterStep.class);
BeforeOrAfterStep bafStep22 = mock(BeforeOrAfterStep.class);
Step stepBefore1 = mock(Step.class);
Step stepBefore2 = mock(Step.class);
Step stepAfter1 = mock(Step.class);
Step stepAfter2 = mock(Step.class);
when(bafStep11.getStage()).thenReturn(Stage.BEFORE);
when(bafStep11.createStep()).thenReturn(stepBefore1);
when(bafStep21.getStage()).thenReturn(Stage.BEFORE);
when(bafStep21.createStep()).thenReturn(stepBefore2);
when(bafStep12.getStage()).thenReturn(Stage.AFTER);
when(bafStep12.createStep()).thenReturn(stepAfter1);
when(bafStep22.getStage()).thenReturn(Stage.AFTER);
when(bafStep22.createStep()).thenReturn(stepAfter2);
when(steps1.listBeforeOrAfterStories()).thenReturn(asList(bafStep11, bafStep12));
when(steps2.listBeforeOrAfterStories()).thenReturn(asList(bafStep21, bafStep22));
// When we collect the list of steps
List<Step> beforeSteps = stepCollector.collectBeforeOrAfterStoriesSteps(asList(steps1, steps2), Stage.BEFORE);
List<Step> afterSteps = stepCollector.collectBeforeOrAfterStoriesSteps(asList(steps1, steps2), Stage.AFTER);
// Then all before and after steps should be added
assertThat(beforeSteps, equalTo(asList(stepBefore1, stepBefore2)));
assertThat(afterSteps, equalTo(asList(stepAfter1, stepAfter2)));
}
@Test
public void shouldSortCandidateStepsByPriorityByDefault() {
// Given some candidate steps classes
// and some methods split across them
CandidateSteps steps1 = mock(Steps.class);
CandidateSteps steps2 = mock(Steps.class);
StepCandidate candidate1 = mock(StepCandidate.class);
StepCandidate candidate2 = mock(StepCandidate.class);
StepCandidate candidate3 = mock(StepCandidate.class);
StepCandidate candidate4 = mock(StepCandidate.class);
Step step1 = mock(Step.class);
Step step2 = mock(Step.class);
Step step3 = mock(Step.class);
Step step4 = mock(Step.class);
when(steps1.listCandidates()).thenReturn(asList(candidate1, candidate2));
when(steps2.listCandidates()).thenReturn(asList(candidate3, candidate4));
// all matching the same step string with different priorities
String stepAsString = "Given a step";
when(candidate1.matches(stepAsString)).thenReturn(true);
when(candidate2.matches(stepAsString)).thenReturn(true);
when(candidate3.matches(stepAsString)).thenReturn(true);
when(candidate4.matches(stepAsString)).thenReturn(true);
when(candidate1.getPriority()).thenReturn(1);
when(candidate2.getPriority()).thenReturn(2);
when(candidate3.getPriority()).thenReturn(3);
when(candidate4.getPriority()).thenReturn(4);
when(candidate1.createMatchedStep(stepAsString, parameters)).thenReturn(step1);
when(candidate2.createMatchedStep(stepAsString, parameters)).thenReturn(step2);
when(candidate3.createMatchedStep(stepAsString, parameters)).thenReturn(step3);
when(candidate4.createMatchedStep(stepAsString, parameters)).thenReturn(step4);
// When we collect the list of steps
List<Step> steps = stepCollector.collectScenarioSteps(asList(steps1, steps2), createScenario(stepAsString), parameters);
// Then the step with highest priority is returned
assertThat(step4, equalTo(steps.get(0)));
}
@Test
public void shouldPrioritiseCandidateStepsByInjectableStrategy() {
// Given some candidate steps classes
// and some methods split across them
CandidateSteps steps1 = mock(Steps.class);
CandidateSteps steps2 = mock(Steps.class);
StepCandidate candidate1 = mock(StepCandidate.class);
StepCandidate candidate2 = mock(StepCandidate.class);
StepCandidate candidate3 = mock(StepCandidate.class);
StepCandidate candidate4 = mock(StepCandidate.class);
Step step1 = mock(Step.class);
Step step2 = mock(Step.class);
Step step3 = mock(Step.class);
Step step4 = mock(Step.class);
when(steps1.listCandidates()).thenReturn(asList(candidate1, candidate2));
when(steps2.listCandidates()).thenReturn(asList(candidate3, candidate4));
// all matching the same step string with different priorities
String stepAsString = "Given a step";
when(candidate1.matches(stepAsString)).thenReturn(true);
when(candidate2.matches(stepAsString)).thenReturn(true);
when(candidate3.matches(stepAsString)).thenReturn(true);
when(candidate4.matches(stepAsString)).thenReturn(true);
when(candidate1.getPatternAsString()).thenReturn("Given I do something");
when(candidate2.getPatternAsString()).thenReturn("When I do something ");
when(candidate3.getPatternAsString()).thenReturn("Then I do something");
when(candidate4.getPatternAsString()).thenReturn("And I do something");
when(candidate1.createMatchedStep(stepAsString, parameters)).thenReturn(step1);
when(candidate2.createMatchedStep(stepAsString, parameters)).thenReturn(step2);
when(candidate3.createMatchedStep(stepAsString, parameters)).thenReturn(step3);
when(candidate4.createMatchedStep(stepAsString, parameters)).thenReturn(step4);
StepCollector stepCollector = new MarkUnmatchedStepsAsPending(new StepFinder(new ByLevenshteinDistance()));
List<Step> steps = stepCollector.collectScenarioSteps(asList(steps1, steps2), createScenario(stepAsString), parameters);
// Then the step with highest priority is returned
assertThat(step4, equalTo(steps.get(0)));
}
@Test
public void afterScenarioStepsShouldBeInReverseOrder() throws Throwable {
List<CandidateSteps> steps = new ArrayList<CandidateSteps>();
steps.add(new ClassWithMethodsAandB());
steps.add(new ClassWithMethodsCandD());
String stepsAsString = steps.toString(); // includes object ID numbers
// from JVM
XStream xs = new XStream();
ScenarioType scenarioType = ScenarioType.NORMAL;
List<Step> subset = stepCollector.collectBeforeOrAfterScenarioSteps(steps, null, Stage.BEFORE, scenarioType);
String subsetAsXML = xs.toXML(subset);
assertThat(subsetAsXML.indexOf("<name>a</name>"), greaterThan(-1)); // there
assertThat(subsetAsXML.indexOf("<name>b</name>"), equalTo(-1)); // not there
assertThat(subsetAsXML.indexOf("<name>c</name>"), greaterThan(-1)); // there
assertThat(subsetAsXML.indexOf("<name>d</name>"), equalTo(-1)); // not there
assertThat(subsetAsXML.indexOf("<name>a</name>"), lessThan(subsetAsXML.indexOf("<name>c</name>"))); // there
assertThat(stepsAsString, equalTo(steps.toString())); // steps have not been mutated.
subset = stepCollector.collectBeforeOrAfterScenarioSteps(steps, null, Stage.AFTER, scenarioType);
subsetAsXML = xs.toXML(subset);
assertThat(subsetAsXML.indexOf("<name>a</name>"), equalTo(-1)); // not there
assertThat(subsetAsXML.indexOf("<name>b</name>"), greaterThan(-1)); // there
assertThat(subsetAsXML.indexOf("<name>c</name>"), equalTo(-1)); // not there
assertThat(subsetAsXML.indexOf("<name>d</name>"), greaterThan(-1)); // there
assertThat(subsetAsXML.indexOf("<name>d</name>"), lessThan(subsetAsXML.indexOf("<name>b</name>"))); // reverse order
}
@Test
public void shouldInvokeBeforeOrAfterScenarioWithParameter() throws Exception {
BeforeOrAfterScenarioWithParameterSteps steps = new BeforeOrAfterScenarioWithParameterSteps();
Meta meta = beforeAndAfterMeta();
ScenarioType scenarioType = ScenarioType.NORMAL;
List<Step> beforeSteps = stepCollector.collectBeforeOrAfterScenarioSteps(asList((CandidateSteps) steps), meta,
Stage.BEFORE, scenarioType);
beforeSteps.get(0).perform(null);
assertThat(steps.value, equalTo("before"));
List<Step> afterSteps = stepCollector.collectBeforeOrAfterScenarioSteps(asList((CandidateSteps) steps), meta,
Stage.AFTER, scenarioType);
afterSteps.get(0).perform(null);
assertThat(steps.value, equalTo("after"));
}
@Test
public void shouldInvokeBeforeOrAfterScenarioWithParameterAndException() throws Exception {
BeforeOrAfterScenarioWithParameterAndExceptionSteps steps = new BeforeOrAfterScenarioWithParameterAndExceptionSteps();
Meta meta = beforeAndAfterMeta();
UUIDExceptionWrapper failureOccurred = new UUIDExceptionWrapper();
ScenarioType scenarioType = ScenarioType.NORMAL;
List<Step> beforeSteps = stepCollector.collectBeforeOrAfterScenarioSteps(asList((CandidateSteps) steps), meta,
Stage.BEFORE, scenarioType);
beforeSteps.get(0).doNotPerform(failureOccurred);
assertThat(steps.value, equalTo("before"));
assertThat(steps.exception, equalTo(failureOccurred));
List<Step> afterSteps = stepCollector.collectBeforeOrAfterScenarioSteps(asList((CandidateSteps) steps), meta,
Stage.AFTER, scenarioType);
failureOccurred = new UUIDExceptionWrapper();
afterSteps.get(0).doNotPerform(failureOccurred);
assertThat(steps.value, equalTo("after"));
assertThat(steps.exception, equalTo(failureOccurred));
}
@Test
public void shouldInvokeBeforeOrAfterStoryWithParameter() throws Exception {
BeforeOrAfterStoryWithParameter steps = new BeforeOrAfterStoryWithParameter();
Story story = mock(Story.class);
when(story.getMeta()).thenReturn(beforeAndAfterMeta());
List<Step> beforeSteps = stepCollector.collectBeforeOrAfterStorySteps(asList((CandidateSteps) steps), story,
Stage.BEFORE, false);
beforeSteps.get(0).perform(null);
assertThat(steps.value, equalTo("before"));
List<Step> afterSteps = stepCollector.collectBeforeOrAfterStorySteps(asList((CandidateSteps) steps), story,
Stage.AFTER, false);
afterSteps.get(0).perform(null);
assertThat(steps.value, equalTo("after"));
}
@Test
public void shouldInvokeBeforeOrAfterStoryWithParameterAndException() throws Exception {
BeforeOrAfterStoryWithParameterAndExceptionSteps steps = new BeforeOrAfterStoryWithParameterAndExceptionSteps();
Story story = mock(Story.class);
when(story.getMeta()).thenReturn(beforeAndAfterMeta());
List<Step> beforeSteps = stepCollector.collectBeforeOrAfterStorySteps(asList((CandidateSteps) steps), story,
Stage.BEFORE, false);
UUIDExceptionWrapper failureOccurred = new UUIDExceptionWrapper();
beforeSteps.get(0).doNotPerform(failureOccurred);
assertThat(steps.value, equalTo("before"));
assertThat(steps.exception, equalTo(failureOccurred));
List<Step> afterSteps = stepCollector.collectBeforeOrAfterStorySteps(asList((CandidateSteps) steps), story,
Stage.AFTER, false);
failureOccurred = new UUIDExceptionWrapper();
afterSteps.get(0).doNotPerform(failureOccurred);
assertThat(steps.value, equalTo("after"));
assertThat(steps.exception, equalTo(failureOccurred));
}
private List<CandidateSteps> mockCandidateSteps(StepCandidate... candidate) {
CandidateSteps steps = mock(Steps.class);
when(steps.listCandidates()).thenReturn(asList(candidate));
return Collections.singletonList(steps);
}
private Scenario createScenario(String... stepsAsStrings) {
return new Scenario(asList(stepsAsStrings));
}
private Meta beforeAndAfterMeta() {
Properties properties = new Properties();
properties.put("before", "before");
properties.put("after", "after");
return new Meta(properties);
}
public static class ClassWithMethodsAandB extends Steps {
@BeforeScenario
public void a() {
}
@AfterScenario
public void b() {
}
}
public static class ClassWithMethodsCandD extends Steps {
@BeforeScenario
public void c() {
}
@AfterScenario
public void d() {
}
}
public static class BeforeOrAfterScenarioWithParameterSteps extends Steps {
private String value;
@BeforeScenario
public void beforeScenario(@Named("before") String before) {
this.value = before;
}
@AfterScenario
public void afterScenario(@Named("after") String after) {
this.value = after;
}
}
public static class BeforeOrAfterScenarioWithParameterAndExceptionSteps extends Steps {
private String value;
private UUIDExceptionWrapper exception;
@BeforeScenario
public void beforeScenario(@Named("before") String before, UUIDExceptionWrapper exception) {
this.value = before;
this.exception = exception;
}
@AfterScenario
public void afterScenario(@Named("after") String after, UUIDExceptionWrapper exception) {
this.value = after;
this.exception = exception;
}
}
public static class BeforeOrAfterStoryWithParameter extends Steps {
private String value;
@BeforeStory
public void beforeStory(@Named("before") String before) {
this.value = before;
}
@AfterStory
public void afterStory(@Named("after") String after) {
this.value = after;
}
}
public static class BeforeOrAfterStoryWithParameterAndExceptionSteps extends Steps {
private String value;
private UUIDExceptionWrapper exception;
@BeforeStory
public void beforeStory(@Named("before") String before, UUIDExceptionWrapper exception) {
this.value = before;
this.exception = exception;
}
@AfterStory
public void afterStory(@Named("after") String after, UUIDExceptionWrapper exception) {
this.value = after;
this.exception = exception;
}
}
}