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.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.jbehave.core.steps.StepCreator.PARAMETER_VALUE_END;
import static org.jbehave.core.steps.StepCreator.PARAMETER_VALUE_START;
import static org.jbehave.core.steps.StepType.GIVEN;
import static org.jbehave.core.steps.StepType.IGNORABLE;
import static org.jbehave.core.steps.StepType.THEN;
import static org.jbehave.core.steps.StepType.WHEN;
import static org.junit.Assert.fail;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.MethodDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hamcrest.Matchers;
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Pending;
import org.jbehave.core.annotations.When;
import org.jbehave.core.configuration.Configuration;
import org.jbehave.core.configuration.Keywords;
import org.jbehave.core.configuration.Keywords.StartingWordNotFound;
import org.jbehave.core.configuration.MostUsefulConfiguration;
import org.jbehave.core.failures.RestartingScenarioFailure;
import org.jbehave.core.failures.UUIDExceptionWrapper;
import org.jbehave.core.i18n.LocalizedKeywords;
import org.jbehave.core.model.OutcomesTable;
import org.jbehave.core.model.TableTransformers;
import org.jbehave.core.model.OutcomesTable.OutcomesFailed;
import org.jbehave.core.parsers.RegexPrefixCapturingPatternParser;
import org.jbehave.core.reporters.StoryReporter;
import org.jbehave.core.steps.AbstractStepResult.NotPerformed;
import org.jbehave.core.steps.context.StepsContext;
import org.junit.Test;
import com.thoughtworks.paranamer.BytecodeReadingParanamer;
import com.thoughtworks.paranamer.CachingParanamer;
import com.thoughtworks.paranamer.Paranamer;
public class StepCandidateBehaviour {
private Map<String, String> namedParameters = new HashMap<String, String>();
private Paranamer paranamer = new CachingParanamer(new BytecodeReadingParanamer());
private Keywords keywords = new LocalizedKeywords();
private StepCandidate candidateWith(String patternAsString, StepType stepType, Method method, Object instance) {
return candidateWith(patternAsString, stepType, method, instance, new ParameterControls());
}
private StepCandidate candidateWith(String patternAsString, StepType stepType, Method method, Object instance, ParameterControls parameterControls) {
Class<?> stepsType = instance.getClass();
MostUsefulConfiguration configuration = new MostUsefulConfiguration();
InjectableStepsFactory stepsFactory = new InstanceStepsFactory(configuration, instance);
return new StepCandidate(patternAsString, 0, stepType, method, stepsType, stepsFactory, new StepsContext(),
keywords, new RegexPrefixCapturingPatternParser(), configuration.parameterConverters(),
parameterControls);
}
@Test
public void shouldMatchStepWithoutParameters() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
StepCandidate candidate = candidateWith("I laugh", GIVEN, method, new SomeSteps());
assertThat(candidate.matches("Given I laugh"), is(true));
}
@Test
public void shouldMatchStepWithParameters() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
StepCandidate candidate = candidateWith("windows on the $nth floor", WHEN, method, new SomeSteps());
assertThat(candidate.matches("When windows on the 1st floor"), is(true));
assertThat(candidate.matches("When windows on the 1st floor are open"), is(not(true)));
}
@Test
public void shouldMatchAndStepOnlyWithPreviousStep() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
StepCandidate candidate = candidateWith("windows on the $nth floor", WHEN, method, new SomeSteps());
assertThat(candidate.matches("And windows on the 1st floor"), is(not(true)));
assertThat(candidate.matches("And windows on the 1st floor", "When windows on the 1st floor"), is(true));
}
@Test
public void shouldMatchMultilineStep() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
StepCandidate candidate = candidateWith("the grid should look like $grid", THEN, method, new SomeSteps());
assertThat(candidate.matches("Then the grid should look like \n....\n....\n"), is(true));
}
@Test
public void shouldMatchStepWithEmptyParameters() throws Exception {
Method method = SomeSteps.class.getMethod("aMethodWith", String.class);
SomeSteps someSteps = new SomeSteps();
StepCandidate candidate = candidateWith("windows on the $nth floor", WHEN, method, someSteps);
String stepAsString = "When windows on the floor";
assertThat(candidate.matches(stepAsString), is(true));
Step step = candidate.createMatchedStep(stepAsString, new HashMap<String, String>());
step.perform(null);
Object args = someSteps.args;
assertThat(args, instanceOf(String.class));
assertThat(((String)args), Matchers.equalTo(""));
}
@Test
public void shouldIgnoreStep() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
StepCandidate candidate = candidateWith("", IGNORABLE, method, new SomeSteps());
assertThat(candidate.ignore("!-- Then ignore me"), is(true));
}
@Test
public void shouldComment() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
StepCandidate candidate = candidateWith("", IGNORABLE, method, new SomeSteps());
assertThat(candidate.comment("!-- comment"), is(true));
}
@Test
public void shouldNotMatchOrIgnoreStepWhenStartingWordNotFound() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
Keywords keywords = new LocalizedKeywords(){
@Override
public String startingWordFor(StepType stepType) {
throw new StartingWordNotFound(stepType, new HashMap<StepType, String>());
}
};
StepCandidate candidate = new StepCandidate("windows on the $nth floor", 0, WHEN, method, null, null,
new StepsContext(), keywords, new RegexPrefixCapturingPatternParser(),
new ParameterConverters(new TableTransformers()), new ParameterControls());
assertThat(candidate.matches("When windows on the 1st floor"), is(false));
assertThat(candidate.ignore("!-- windows on the 1st floor"), is(false));
}
@Test
public void shouldProvideStepPriority() throws Exception {
Method method = SomeSteps.class.getMethod("aMethod");
StepCandidate candidate = candidateWith("I laugh", GIVEN, method, new SomeSteps());
assertThat(candidate.getPriority(), equalTo(0));
}
@Test
public void shouldCreatePerformableStepUsingTheMatchedString() throws Exception {
SomeSteps someSteps = new SomeSteps();
Method method = SomeSteps.class.getMethod("aMethodWith", String.class);
StepCandidate candidate = candidateWith("I live on the $nth floor", THEN, method, someSteps);
candidate.createMatchedStep("Then I live on the 1st floor", namedParameters).perform(null);
assertThat((String) someSteps.args, equalTo("1st"));
}
@Test
public void shouldCreatePerformableStepWithResultThatDescribesTheStepPerformed() throws Exception {
StoryReporter reporter = mock(StoryReporter.class);
SomeSteps someSteps = new SomeSteps();
Method method = SomeSteps.class.getMethod("aMethodWith", String.class);
StepCandidate candidate = candidateWith("I live on the $nth floor", THEN, method, someSteps);
StepResult result = candidate.createMatchedStep("Then I live on the 1st floor", namedParameters).perform(null);
result.describeTo(reporter);
verify(reporter).successful(
"Then I live on the " + PARAMETER_VALUE_START + "1st" + PARAMETER_VALUE_END + " floor");
}
@Test
public void shouldConvertStringParameterValueToUseSystemNewline() throws Exception {
String windowsNewline = "\r\n";
String unixNewline = "\n";
String systemNewline = System.getProperty("line.separator");
SomeSteps someSteps = new SomeSteps();
Method method = SomeSteps.class.getMethod("aMethodWith", String.class);
StepCandidate candidate = candidateWith("the grid should look like $grid", THEN, method, someSteps);
candidate.createMatchedStep(
"Then the grid should look like" + windowsNewline + ".." + unixNewline + ".." + windowsNewline,
namedParameters).perform(null);
assertThat((String) someSteps.args, equalTo(".." + systemNewline + ".." + systemNewline));
}
@Test
public void shouldConvertParameterToNumber() throws Exception {
assertThatNumberIsConverted("I should live in no. $no", int.class, new Integer(14));
assertThatNumberIsConverted("I should live in no. $no", long.class, new Long(14L));
assertThatNumberIsConverted("I should live in no. $no", float.class, new Float(14f));
assertThatNumberIsConverted("I should live in no. $no", double.class, new Double(14d));
}
@SuppressWarnings("unchecked")
private <T> void assertThatNumberIsConverted(String patternAsString, Class<T> type, T number) throws Exception {
SomeSteps someSteps = new SomeSteps();
Method method = SomeSteps.class.getMethod("aMethodWith", type);
StepCandidate candidate = candidateWith(patternAsString, THEN, method, someSteps);
candidate.createMatchedStep("Then I should live in no. 14", namedParameters).perform(null);
assertThat((T) someSteps.args, equalTo(number));
}
@Test
public void shouldConvertParameterToListOfNumbersOrStrings() throws Exception {
assertThatListIsConverted("windows on the $nth floors", "aMethodWithListOfIntegers", int.class, "1,2,3",
asList(1, 2, 3));
assertThatListIsConverted("windows on the $nth floors", "aMethodWithListOfLongs", long.class, "1,2,3", asList(
1L, 2L, 3L));
assertThatListIsConverted("windows on the $nth floors", "aMethodWithListOfFloats", float.class, "1.1,2.2,3.3",
asList(1.1f, 2.2f, 3.3f));
assertThatListIsConverted("windows on the $nth floors", "aMethodWithListOfDoubles", double.class,
"1.1,2.2,3.3", asList(1.1d, 2.2d, 3.3d));
assertThatListIsConverted("windows on the $nth floors", "aMethodWithListOfStrings", String.class, "1,2,3",
asList("1", "2", "3"));
}
@SuppressWarnings("unchecked")
private <T> void assertThatListIsConverted(String patternAsString, String methodName, Class<T> type, String csv,
List<T> numbers) throws Exception {
SomeSteps someSteps = new SomeSteps();
Method method = SomeSteps.methodFor(methodName);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, someSteps);
candidate.createMatchedStep("When windows on the " + csv + " floors", namedParameters).perform(null);
assertThat((List<T>) someSteps.args, equalTo(numbers));
}
@Test
public void shouldMatchMethodParametersByAnnotatedNamesInNaturalOrder() throws Exception {
AnnotationNamedParameterSteps steps = new AnnotationNamedParameterSteps();
String patternAsString = "I live on the $ith floor but some call it the $nth";
Method method = stepMethodFor("methodWithNamedParametersInNaturalOrder", AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
candidate.createMatchedStep("When I live on the first floor but some call it the ground", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
}
@Test
public void shouldMatchMethodParametersByAnnotatedNamesInverseOrder() throws Exception {
AnnotationNamedParameterSteps steps = new AnnotationNamedParameterSteps();
String patternAsString = "I live on the $ith floor but some call it the $nth";
Method method = stepMethodFor("methodWithNamedParametersInInverseOrder", AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
candidate.createMatchedStep("When I live on the first floor but some call it the ground", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
}
@Test
public void shouldCreateStepFromTableValuesViaAnnotations() throws Exception {
StoryReporter reporter = mock(StoryReporter.class);
AnnotationNamedParameterSteps steps = new AnnotationNamedParameterSteps();
namedParameters.put("ith", "first");
namedParameters.put("nth", "ground");
String patternAsString = "I live on the ith floor but some call it the nth";
Method method = stepMethodFor("methodWithNamedParametersInNaturalOrder", AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
StepResult result =candidate.createMatchedStep("When I live on the <ith> floor but some call it the <nth>", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
result.describeTo(reporter);
verify(reporter).successful(
"When I live on the " + PARAMETER_VALUE_START + "first" + PARAMETER_VALUE_END + " floor but some call it the " + PARAMETER_VALUE_START + "ground" + PARAMETER_VALUE_END );
}
@Test
public void shouldCreateStepFromTableValuesViaAnnotationsWithCustomParameterDelimiters() throws Exception {
StoryReporter reporter = mock(StoryReporter.class);
AnnotationNamedParameterSteps steps = new AnnotationNamedParameterSteps();
namedParameters.put("ith", "first");
namedParameters.put("nth", "ground");
String patternAsString = "I live on the ith floor but some call it the nth";
Method method = stepMethodFor("methodWithNamedParametersInNaturalOrder", AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps, new ParameterControls().useNameDelimiterLeft("[").useNameDelimiterRight("]"));
StepResult result = candidate.createMatchedStep("When I live on the [ith] floor but some call it the [nth]", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
result.describeTo(reporter);
verify(reporter).successful(
"When I live on the " + PARAMETER_VALUE_START + "first" + PARAMETER_VALUE_END + " floor but some call it the " + PARAMETER_VALUE_START + "ground" + PARAMETER_VALUE_END );
}
@Test
public void shouldMatchMethodParametersByAnnotatedNamesInNaturalOrderForJsr330Named() throws Exception {
Jsr330AnnotationNamedParameterSteps steps = new Jsr330AnnotationNamedParameterSteps();
String patternAsString = "I live on the $ith floor but some call it the $nth";
Method method = stepMethodFor("methodWithNamedParametersInNaturalOrder",
Jsr330AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
candidate.createMatchedStep("When I live on the first floor but some call it the ground", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
}
@Test
public void shouldMatchMethodParametersByAnnotatedNamesInverseOrderForJsr330Named() throws Exception {
Jsr330AnnotationNamedParameterSteps steps = new Jsr330AnnotationNamedParameterSteps();
String patternAsString = "I live on the $ith floor but some call it the $nth";
Method method = stepMethodFor("methodWithNamedParametersInInverseOrder",
Jsr330AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
candidate.createMatchedStep("When I live on the first floor but some call it the ground", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
}
@Test
public void shouldCreateStepFromTableValuesViaAnnotationsForJsr330Named() throws Exception {
Jsr330AnnotationNamedParameterSteps steps = new Jsr330AnnotationNamedParameterSteps();
namedParameters.put("ith", "first");
namedParameters.put("nth", "ground");
String patternAsString = "I live on the ith floor but some call it the nth";
Method method = stepMethodFor("methodWithNamedParametersInNaturalOrder",
Jsr330AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
candidate.createMatchedStep("When I live on the <ith> floor but some call it the <nth>", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
}
@Test
public void shouldMatchMethodParametersByParanamerNamesInNaturalOrder() throws Exception {
shouldMatchMethodParametersByParanamerSomeOrder("methodWithNamedParametersInNaturalOrder");
}
@Test
public void shouldMatchMethodParametersByParanamerInverseOrder() throws Exception {
shouldMatchMethodParametersByParanamerSomeOrder("methodWithNamedParametersInInverseOrder");
}
private void shouldMatchMethodParametersByParanamerSomeOrder(String methodName) throws IntrospectionException {
ParanamerNamedParameterSteps steps = new ParanamerNamedParameterSteps();
String patternAsString = "I live on the $ith floor but some call it the $nth";
Method method = stepMethodFor(methodName, ParanamerNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
candidate.useParanamer(paranamer);
candidate.createMatchedStep("When I live on the first floor but some call it the ground", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
}
@Test
public void shouldCreateStepFromTableValuesViaParanamer() throws Exception {
ParanamerNamedParameterSteps steps = new ParanamerNamedParameterSteps();
namedParameters.put("ith", "first");
namedParameters.put("nth", "ground");
String patternAsString = "I live on the ith floor but some call it the nth";
Method method = stepMethodFor("methodWithNamedParametersInNaturalOrder", ParanamerNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
candidate.useParanamer(paranamer);
candidate.createMatchedStep("When I live on the <ith> floor but some call it the <nth>", namedParameters)
.perform(null);
assertThat(steps.ith, equalTo("first"));
assertThat(steps.nth, equalTo("ground"));
}
@Test
public void shouldCreateStepFromTableValuesWhenHeadersDoNotMatchParameterNames() throws Exception {
AnnotationNamedParameterSteps steps = new AnnotationNamedParameterSteps();
// I speak LolCatz and mispell headerz
namedParameters.put("itz", "first");
namedParameters.put("ntz", "ground");
String patternAsString = "I live on the ith floor but some call it the nth";
Method method = stepMethodFor("methodWithNamedParametersInNaturalOrder", AnnotationNamedParameterSteps.class);
StepCandidate candidate = candidateWith(patternAsString, WHEN, method, steps);
String stepAsString = "When I live on the <ith> floor but some call it the <nth>";
Step step = candidate.createMatchedStep(stepAsString, namedParameters);
StepResult perform = step.perform(null);
assertThat(perform, instanceOf(AbstractStepResult.Pending.class));
assertThat(perform.parametrisedStep(), equalTo(stepAsString));
StepResult doNotPerform = step.doNotPerform(null);
assertThat(doNotPerform, instanceOf(NotPerformed.class));
assertThat(doNotPerform.parametrisedStep(), equalTo(stepAsString));
}
@Test
public void shouldCreateStepsOfDifferentTypesWithSameMatchingPattern() {
NamedTypeSteps steps = new NamedTypeSteps();
List<StepCandidate> candidates = steps.listCandidates();
assertThat(candidates.size(), equalTo(2));
StepCandidate step0 = candidateMatchingStep(candidates, "Given foo named $name");
performStep(step0, "Given foo named xyz");
performStep(step0, "And foo named xyz");
StepCandidate step1 = candidateMatchingStep(candidates, "When foo named $name");
performStep(step1, "When foo named Bar");
performStep(step1, "And foo named Bar");
assertThat(steps.givenName, equalTo("xyz"));
assertThat(steps.givenTimes, equalTo(2));
assertThat(steps.whenName, equalTo("Bar"));
assertThat(steps.whenTimes, equalTo(2));
}
private void performStep(StepCandidate candidate, String step) {
candidate.createMatchedStep(step, namedParameters).perform(null);
}
@Test
public void shouldCaptureOutcomeFailures() {
FailingSteps steps = new FailingSteps();
List<StepCandidate> candidates = steps.listCandidates();
assertThat(candidates.size(), equalTo(1));
String stepAsString = "When outcome fails for Bar upon verification";
StepResult stepResult = candidates.get(0).createMatchedStep(stepAsString,
namedParameters).perform(null);
UUIDExceptionWrapper failure = stepResult.getFailure();
assertThat(failure.getCause(), instanceOf(OutcomesFailed.class));
assertThat(failure.getMessage(), equalTo(stepAsString));
}
@Test
public void shouldRestart() {
RestartingSteps steps = new RestartingSteps();
List<StepCandidate> candidates = steps.listCandidates();
assertThat(candidates.size(), equalTo(1));
try {
candidates.get(0).createMatchedStep("When blah Bar blah", namedParameters).perform(null);
fail("should have barfed");
} catch (RestartingScenarioFailure e) {
assertThat(e.getMessage(), is(equalTo("Bar restarting")));
}
}
@Test
public void shouldPerformStepsInDryRunMode() {
Configuration configuration = new MostUsefulConfiguration();
configuration.storyControls().doDryRun(true);
NamedTypeSteps steps = new NamedTypeSteps(configuration);
List<StepCandidate> candidates = steps.listCandidates();
assertThat(candidates.size(), equalTo(2));
StepCandidate step0 = candidateMatchingStep(candidates, "Given foo named $name");
step0.createMatchedStep("Given foo named xyz", namedParameters).perform(null);
step0.createMatchedStep("And foo named xyz", namedParameters).perform(null);
StepCandidate step1 = candidateMatchingStep(candidates, "When foo named $name");
step1.createMatchedStep("When foo named Bar", namedParameters).perform(null);
step1.createMatchedStep("And foo named Bar", namedParameters).perform(null);
assertThat(steps.givenName, nullValue());
assertThat(steps.givenTimes, equalTo(0));
assertThat(steps.whenName, nullValue());
assertThat(steps.whenTimes, equalTo(0));
}
@Test
public void shouldMatchAndIdentifyPendingAnnotatedSteps() {
PendingSteps steps = new PendingSteps();
List<StepCandidate> candidates = steps.listCandidates();
assertThat(candidates.size(), equalTo(2));
StepCandidate pending = candidateMatchingStep(candidates, "Given a pending step");
assertThat(pending, notNullValue());
assertThat(pending.isPending(), is(true));
StepCandidate nonPending = candidateMatchingStep(candidates, "Given a non pending step");
assertThat(nonPending, notNullValue());
assertThat(nonPending.isPending(), is(false));
}
@Test(expected = StartingWordNotFound.class)
public void shouldNotCreateStepOfWrongType() {
NamedTypeSteps steps = new NamedTypeSteps();
List<StepCandidate> candidates = steps.listCandidates();
assertThat(candidates.size(), equalTo(2));
StepCandidate step = candidateMatchingStep(candidates, "Given foo named $name");
step.createMatchedStep("Given foo named xyz", namedParameters).perform(null);
assertThat(steps.givenName, equalTo("xyz"));
assertThat(steps.whenName, nullValue());
step.createMatchedStep("Then foo named xyz", namedParameters).perform(null);
}
static class NamedTypeSteps extends Steps {
String givenName;
String whenName;
int givenTimes;
int whenTimes;
public NamedTypeSteps() {
this(new MostUsefulConfiguration());
}
public NamedTypeSteps(Configuration configuration) {
super(configuration);
}
@Given("foo named $name")
public void givenFoo(String name) {
givenName = name;
givenTimes++;
}
@When("foo named $name")
public void whenFoo(String name) {
whenName = name;
whenTimes++;
}
}
static class FailingSteps extends Steps {
@When("outcome fails for $name upon verification")
public void whenOutcomeFails(String name) {
OutcomesTable outcomes = new OutcomesTable();
outcomes.addOutcome("failing", name, equalTo(""));
outcomes.verify();
}
}
static class RestartingSteps extends Steps {
@When("blah $name blah")
public void whenOutcomeFails(String name) {
throw new RestartingScenarioFailure(name + " restarting");
}
}
static class PendingSteps extends Steps {
@Given("a pending step")
@Pending
public void aPendingStep() {
}
@Given("a non pending step")
public void aNonPendingStep() {
}
}
static StepCandidate candidateMatchingStep(List<StepCandidate> candidates, String stepAsString) {
for (StepCandidate candidate : candidates) {
if (candidate.matches(stepAsString)){
return candidate ;
}
}
return null;
}
static Method stepMethodFor(String methodName, Class<? extends Steps> stepsClass) throws IntrospectionException {
BeanInfo beanInfo = Introspector.getBeanInfo(stepsClass);
for (MethodDescriptor md : beanInfo.getMethodDescriptors()) {
if (md.getMethod().getName().equals(methodName)) {
return md.getMethod();
}
}
return null;
}
}