- Revision
- 1620
- Author
- mauro
- Date
- 2010-05-01 05:46:50 -0500 (Sat, 01 May 2010)
Log Message
JBEHAVE-278: Enhanced candidate step matching to be aware of the previous step type when matching AND steps.
Modified Paths
- trunk/core/jbehave-core/src/behaviour/java/org/jbehave/scenario/steps/CandidateStepBehaviour.java
- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/CandidateStep.java
- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java
- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/StepMonitor.java
- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/UnmatchedToPendingStepCreator.java
Added Paths
Diff
Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/scenarios/AndStep.java (0 => 1620)
--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/scenarios/AndStep.java (rev 0) +++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/scenarios/AndStep.java 2010-05-01 10:46:50 UTC (rev 1620) @@ -0,0 +1,52 @@ +package org.jbehave.examples.trader.scenarios; + +import org.jbehave.scenario.JUnitScenario; +import org.jbehave.scenario.MostUsefulConfiguration; +import org.jbehave.scenario.annotations.Given; +import org.jbehave.scenario.annotations.When; +import org.jbehave.scenario.parser.ClasspathScenarioDefiner; +import org.jbehave.scenario.parser.PatternScenarioParser; +import org.jbehave.scenario.parser.ScenarioDefiner; +import org.jbehave.scenario.parser.UnderscoredCamelCaseResolver; +import org.jbehave.scenario.reporters.PrintStreamScenarioReporter; +import org.jbehave.scenario.reporters.ScenarioReporter; +import org.jbehave.scenario.steps.PrintStreamStepMonitor; +import org.jbehave.scenario.steps.StepsConfiguration; +import org.jbehave.scenario.steps.StepsFactory; + +public class AndStep extends JUnitScenario { + + public AndStep() { + useConfiguration(new MostUsefulConfiguration() { + @Override + public ScenarioDefiner forDefiningScenarios() { + return new ClasspathScenarioDefiner( + new UnderscoredCamelCaseResolver(".scenario"), + new PatternScenarioParser(keywords())); + } + + @Override + public ScenarioReporter forReportingScenarios() { + return new PrintStreamScenarioReporter(); + } + + }); + + StepsConfiguration configuration = new StepsConfiguration(); + configuration.useMonitor(new PrintStreamStepMonitor()); + addSteps(new StepsFactory(configuration).createCandidateSteps(new AndSteps())); + } + + public static class AndSteps { + @Given("the wind blows") + public void givenWindBlows() { + System.err.println("given the wind blows"); + } + + @When("the wind blows") + public void whenWindBlows() { + System.err.println("when the wind blows"); + } + + } +}
Added: trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/scenarios/and_step.scenario (0 => 1620)
--- trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/scenarios/and_step.scenario (rev 0) +++ trunk/core/examples/trader/src/main/java/org/jbehave/examples/trader/scenarios/and_step.scenario 2010-05-01 10:46:50 UTC (rev 1620) @@ -0,0 +1,10 @@ +Scenario: An initial AND step should be marked as pending as there is not previous step + +And the wind blows + +Scenario: AND steps should match the previous step type + +Given the wind blows +And the wind blows +When the wind blows +And the wind blows \ No newline at end of file
Modified: trunk/core/jbehave-core/src/behaviour/java/org/jbehave/scenario/steps/CandidateStepBehaviour.java (1619 => 1620)
--- trunk/core/jbehave-core/src/behaviour/java/org/jbehave/scenario/steps/CandidateStepBehaviour.java 2010-04-27 22:13:11 UTC (rev 1619) +++ trunk/core/jbehave-core/src/behaviour/java/org/jbehave/scenario/steps/CandidateStepBehaviour.java 2010-05-01 10:46:50 UTC (rev 1620) @@ -5,6 +5,7 @@ import static org.hamcrest.CoreMatchers.nullValue; import static org.jbehave.Ensure.ensureThat; import static org.jbehave.Ensure.not; +import static org.jbehave.scenario.steps.StepType.AND; import static org.jbehave.scenario.steps.StepType.GIVEN; import static org.jbehave.scenario.steps.StepType.THEN; import static org.jbehave.scenario.steps.StepType.WHEN; @@ -46,18 +47,19 @@ map.put(GIVEN, "Given"); map.put(WHEN, "When"); map.put(THEN, "Then"); + map.put(AND, "And"); return map; } @Test - public void shouldMatchASimpleString() throws Exception { + public void shouldMatchAStepWithoutArguments() throws Exception { CandidateStep candidateStep = new CandidateStep("I laugh", DEFAULT_PRIORITY, GIVEN, SomeSteps.class.getMethod("aMethod"), null, PATTERN_BUILDER, new ParameterConverters(), startingWords); ensureThat(candidateStep.matches("Given I laugh")); } @Test - public void shouldMatchAStringWithArguments() throws Exception { + public void shouldMatchAStepWithArguments() throws Exception { CandidateStep candidateStep = new CandidateStep("windows on the $nth floor", DEFAULT_PRIORITY, WHEN, SomeSteps.class .getMethod("aMethod"), null, PATTERN_BUILDER, new ParameterConverters(), startingWords); ensureThat(candidateStep.matches("When windows on the 1st floor")); @@ -65,6 +67,14 @@ } @Test + public void shouldMatchAndStepsOnlyWithPreviousStep() throws Exception { + CandidateStep candidateStep = new CandidateStep("windows on the $nth floor", DEFAULT_PRIORITY, WHEN, SomeSteps.class + .getMethod("aMethod"), null, PATTERN_BUILDER, new ParameterConverters(), startingWords); + ensureThat(not(candidateStep.matches("And windows on the 1st floor"))); + ensureThat(candidateStep.matches("And windows on the 1st floor", "When windows on the 1st floor")); + } + + @Test public void shouldProvideARealStepUsingTheMatchedString() throws Exception { SomeSteps someSteps = new SomeSteps(); CandidateStep candidateStep = new CandidateStep("I live on the $nth floor", DEFAULT_PRIORITY, THEN, SomeSteps.class.getMethod( @@ -270,9 +280,13 @@ CandidateStep[] candidateSteps = steps.getSteps(); ensureThat(candidateSteps.length, equalTo(2)); candidateSteps[0].createFrom(tableRow, "Given foo named xyz").perform(); + candidateSteps[0].createFrom(tableRow, "And foo named xyz").perform(); candidateSteps[1].createFrom(tableRow, "When foo named Bar").perform(); + candidateSteps[1].createFrom(tableRow, "And foo named Bar").perform(); ensureThat(steps.givenName, equalTo("xyz")); + ensureThat(steps.givenTimes, equalTo(2)); ensureThat(steps.whenName, equalTo("Bar")); + ensureThat(steps.whenTimes, equalTo(2)); } @Test(expected=StartingWordNotFound.class) @@ -289,15 +303,19 @@ static class NamedTypeSteps extends Steps { String givenName; String whenName; + int givenTimes; + int whenTimes; @Given("foo named $name") public void givenFoo(String name) { givenName = name; + givenTimes++; } @When("foo named $name") public void whenFoo(String name) { whenName = name; + whenTimes++; } }
Modified: trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/CandidateStep.java (1619 => 1620)
--- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/CandidateStep.java 2010-04-27 22:13:11 UTC (rev 1619) +++ trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/CandidateStep.java 2010-05-01 10:46:50 UTC (rev 1620) @@ -90,16 +90,34 @@ } public boolean matches(String stepAsString) { + return matches(stepAsString, null); + } + + public boolean matches(String stepAsString, String previousAsString) { try { - Matcher matcher = matcherForStep(stepAsString); - boolean matches = matcher.matches(); - stepMonitor.stepMatchesPattern(stepAsString, matches, pattern.pattern()); - return matches; + boolean matchesType = true; + if ( isAndStep(stepAsString) ){ + if ( previousAsString == null ){ + matchesType = false; // cannot handle AND step with no previous step + } else { + // previous step type should match candidate step type + matchesType = startingWordFor(stepType).equals(findStartingWord(previousAsString)); + } + } + stepMonitor.stepMatchesType(stepAsString, previousAsString, matchesType, stepType); + boolean matchesPattern = matcherForStep(stepAsString).matches(); + stepMonitor.stepMatchesPattern(stepAsString, matchesPattern, pattern.pattern()); + // must match both type and pattern + return matchesType && matchesPattern; } catch (StartingWordNotFound e) { return false; } } + private boolean isAndStep(String stepAsString) { + return stepAsString.startsWith(startingWordFor(StepType.AND)); + } + private String trimStartingWord(String word, String step) { return step.substring(word.length() + 1); // 1 for the space after }
Modified: trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java (1619 => 1620)
--- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java 2010-04-27 22:13:11 UTC (rev 1619) +++ trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java 2010-05-01 10:46:50 UTC (rev 1620) @@ -10,8 +10,9 @@ * {...@link System.out}. */ public class PrintStreamStepMonitor implements StepMonitor { - + private static final String CONVERTED_VALUE_OF_TYPE = "Converted value ''{0}'' of type ''{1}'' to ''{2}'' with converter ''{3}''"; + private static final String STEP_MATCHES_TYPE = "Step ''{0}'' (with previous step ''{1}'') ''{2}'' type ''{3}''"; private static final String STEP_MATCHES_PATTERN = "Step ''{0}'' {1} pattern ''{2}''"; private static final String MATCHES = "matches"; private static final String DOES_NOT_MATCH = "does not match"; @@ -33,6 +34,13 @@ this.output = output; } + public void stepMatchesType(String step, String previous, boolean matches, + StepType stepType) { + String message = format(STEP_MATCHES_TYPE, step, previous, + (matches ? MATCHES : DOES_NOT_MATCH), stepType); + print(output, message); + } + public void stepMatchesPattern(String step, boolean matches, String pattern) { String message = format(STEP_MATCHES_PATTERN, step, (matches ? MATCHES : DOES_NOT_MATCH), pattern); @@ -57,32 +65,33 @@ public void usingParameterNameForArg(String name, int position) { String message = format(USING_NAME_FOR_ARG, PARAMETER, name, position); - print(output, message); + print(output, message); } public void usingTableAnnotatedNameForArg(String name, int position) { - String message = format(USING_NAME_FOR_ARG, TABLE_ANNOTATED, name, position); - print(output, message); + String message = format(USING_NAME_FOR_ARG, TABLE_ANNOTATED, name, + position); + print(output, message); } public void usingTableParameterNameForArg(String name, int position) { - String message = format(USING_NAME_FOR_ARG, TABLE_PARAMETER, name, position); - print(output, message); + String message = format(USING_NAME_FOR_ARG, TABLE_PARAMETER, name, + position); + print(output, message); } public void usingNaturalOrderForArg(int position) { String message = format(USING_NATURAL_ORDER_FOR_ARG, position); - print(output, message); + print(output, message); } public void foundArg(String arg, int position) { String message = format(FOUND_ARG, arg, position); - print(output, message); + print(output, message); } - + protected void print(PrintStream output, String message) { output.println(message); } - }
Modified: trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/StepMonitor.java (1619 => 1620)
--- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/StepMonitor.java 2010-04-27 22:13:11 UTC (rev 1619) +++ trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/StepMonitor.java 2010-05-01 10:46:50 UTC (rev 1620) @@ -9,8 +9,11 @@ */ public interface StepMonitor { - void stepMatchesPattern(String step, boolean matches, String pattern); + void stepMatchesType(String stepAsString, String previousAsString, + boolean matchesType, StepType stepType); + void stepMatchesPattern(String step, boolean matches, String pattern); + void convertedValueOfType(String value, Type type, Object converted, Class<?> converterClass); void performing(String step); @@ -26,4 +29,5 @@ void usingNaturalOrderForArg(int position); void foundArg(String arg, int position); + }
Modified: trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/UnmatchedToPendingStepCreator.java (1619 => 1620)
--- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/UnmatchedToPendingStepCreator.java 2010-04-27 22:13:11 UTC (rev 1619) +++ trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/UnmatchedToPendingStepCreator.java 2010-05-01 10:46:50 UTC (rev 1620) @@ -56,7 +56,8 @@ private void addMatchedScenarioSteps(ScenarioDefinition scenarioDefinition, List<Step> steps, Map<String, String> tableRow, CandidateSteps... candidateSteps) { List<CandidateStep> prioritised = prioritise(candidateSteps); - for (String stringStep : scenarioDefinition.getSteps()) { + String previousStep = null; + for (String stringStep : scenarioDefinition.getSteps()) { Step step = new PendingStep(stringStep); for (CandidateStep candidate : prioritised) { if (candidate.ignore(stringStep)) { // ignorable steps are added @@ -64,15 +65,24 @@ step = new IgnorableStep(stringStep); break; } - if (candidate.matches(stringStep)) { + if (matchesCandidate(stringStep, previousStep, candidate)) { step = candidate.createFrom(tableRow, stringStep); break; } } steps.add(step); + previousStep = stringStep; } } + private boolean matchesCandidate(String stringStep, String previousStep, + CandidateStep candidate) { + if ( previousStep != null ){ + return candidate.matches(stringStep, previousStep); + } + return candidate.matches(stringStep); + } + private List<CandidateStep> prioritise(CandidateSteps[] candidateSteps) { List<CandidateStep> steps = new ArrayList<CandidateStep>(); for (CandidateSteps candidates : candidateSteps) {
To unsubscribe from this list please visit:
