Title: [1488] trunk/core: start of optional DI extension for JB
Revision
1488
Author
paul
Date
2010-01-02 18:08:37 -0600 (Sat, 02 Jan 2010)

Log Message

start of optional DI extension for JB

Modified Paths


Added Paths

Diff

Modified: trunk/core/jbehave-core/src/behaviour/java/org/jbehave/scenario/steps/SomeSteps.java (1487 => 1488)

--- trunk/core/jbehave-core/src/behaviour/java/org/jbehave/scenario/steps/SomeSteps.java	2010-01-02 14:13:31 UTC (rev 1487)
+++ trunk/core/jbehave-core/src/behaviour/java/org/jbehave/scenario/steps/SomeSteps.java	2010-01-03 00:08:37 UTC (rev 1488)
@@ -10,8 +10,13 @@
 import org.jbehave.scenario.definition.ExamplesTable;
 
 public class SomeSteps extends Steps {
-    Object args;
 
+    public SomeSteps() {
+        System.out.println("");
+    }
+
+    public Object args;
+
     public void aMethod() {
 
     }

Modified: trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/CandidateStep.java (1487 => 1488)

--- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/CandidateStep.java	2010-01-02 14:13:31 UTC (rev 1487)
+++ trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/CandidateStep.java	2010-01-03 00:08:37 UTC (rev 1488)
@@ -34,7 +34,7 @@
     private final String patternAsString;
     private final StepType stepType;
     private final Method method;
-    private final CandidateSteps steps;
+    protected final CandidateSteps steps;
     private final ParameterConverters parameterConverters;
     private final Map<StepType, String> startingWordsByType;
     private final Pattern pattern;
@@ -64,6 +64,10 @@
         this.paranamer = paranamer;
     }
 
+    protected Paranamer getParanamer() {
+        return paranamer;
+    }
+
     public boolean matches(String stepAsString) {
         try {
             Matcher matcher = matcherForStep(stepAsString);
@@ -82,12 +86,7 @@
     public Step createFrom(Map<String, String> tableRow, final String stepAsString) {
         Matcher matcher = matcherForStep(stepAsString);
         matcher.find();
-        Type[] types = method.getGenericParameterTypes();
-        String[] annotationNames = annotatedParameterNames();
-        String[] parameterNames = paranamer.lookupParameterNames(method, false);
-        Object[] args = argsForStep(tableRow, matcher, types, annotationNames, parameterNames);
-        String translatedStep = translatedStep(stepAsString, tableRow, types, annotationNames, parameterNames);
-        return createStep(stepAsString, args, translatedStep);
+        return createStep(stepAsString, tableRow, matcher, method, stepMonitor, groupNames);
     }
 
     private Matcher matcherForStep(final String stepAsString) {
@@ -96,7 +95,7 @@
         return pattern.matcher(trimmed);
     }
 
-    private Object[] argsForStep(Map<String, String> tableRow, Matcher matcher, Type[] types, String[] annotationNames,
+    protected Object[] argsForStep(Map<String, String> tableRow, Matcher matcher, Type[] types, String[] annotationNames,
             String[] parameterNames) {
         final Object[] args = new Object[types.length];
         for (int position = 0; position < types.length; position++) {
@@ -106,7 +105,7 @@
         return args;
     }
 
-    private String translatedStep(String stepAsString, Map<String, String> tableRow, Type[] types, String[] annotationNames,
+    protected String translatedStep(String stepAsString, Map<String, String> tableRow, Type[] types, String[] annotationNames,
             String[] parameterNames) {
         String replacedStepText = stepAsString;
         for (int position = 0; position < types.length; position++) {
@@ -173,7 +172,7 @@
         return tableRow.get(name) != null;
     }
 
-    private String getGroup(Matcher matcher, String name) {
+    protected String getGroup(Matcher matcher, String name) {
         for (int i = 0; i < groupNames.length; i++) {
             String groupName = groupNames[i];
             if (name.equals(groupName)) {
@@ -212,7 +211,7 @@
      * @return An array of annotated parameter names, which <b>may</b> include
      *         <code>null</code> values for parameters that are not annotated
      */
-    private String[] annotatedParameterNames() {
+    protected String[] annotatedParameterNames() {
         Annotation[][] parameterAnnotations = method.getParameterAnnotations();
         String[] names = new String[parameterAnnotations.length];
         for (int x = 0; x < parameterAnnotations.length; x++) {
@@ -247,7 +246,13 @@
         return startingWord;
     }
 
-    private Step createStep(final String stepAsString, final Object[] args, final String translatedStep) {
+    protected Step createStep(final String stepAsString, Map<String, String> tableRow, Matcher matcher,
+                              final Method method, final StepMonitor stepMonitor, String[] groupNames) {
+        Type[] types = method.getGenericParameterTypes();
+        String[] annotationNames = annotatedParameterNames();
+        String[] parameterNames = paranamer.lookupParameterNames(method, false);
+        final String translatedStep = translatedStep(stepAsString, tableRow, types, annotationNames, parameterNames);
+        final Object[] args = argsForStep(tableRow, matcher, types, annotationNames, parameterNames);
         return new Step() {
             public StepResult perform() {
                 try {

Modified: trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/Steps.java (1487 => 1488)

--- trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/Steps.java	2010-01-02 14:13:31 UTC (rev 1487)
+++ trunk/core/jbehave-core/src/main/java/org/jbehave/scenario/steps/Steps.java	2010-01-03 00:08:37 UTC (rev 1488)
@@ -157,16 +157,20 @@
 	private void createCandidateStep(List<CandidateStep> steps, Method method,
 			StepType stepType, String stepPatternAsString) {
 		checkForDuplicateCandidateSteps(steps, stepType, stepPatternAsString);
-		CandidateStep step = new CandidateStep(stepPatternAsString, stepType, method,
-				this, configuration.getPatternBuilder(), configuration
-						.getParameterConverters(), configuration
-						.getStartingWordsByType());
-		step.useStepMonitor(configuration.getMonitor());
+        CandidateStep step = createCandidateStep(method, stepType, stepPatternAsString, configuration);
+        step.useStepMonitor(configuration.getMonitor());
 		step.useParanamer(configuration.getParanamer());
 		steps.add(step);
 	}
 
-	private void checkForDuplicateCandidateSteps(List<CandidateStep> steps,
+    protected CandidateStep createCandidateStep(Method method, StepType stepType, String stepPatternAsString,  StepsConfiguration configuration) {
+        return new CandidateStep(stepPatternAsString, stepType, method,
+                this, configuration.getPatternBuilder(), configuration
+                        .getParameterConverters(), configuration
+                        .getStartingWordsByType());
+    }
+
+    private void checkForDuplicateCandidateSteps(List<CandidateStep> steps,
 			StepType stepType, String patternAsString) {
 		for (CandidateStep step : steps) {
 			if (step.getStepType() == stepType && step.getPatternAsString().equals(patternAsString)) {

Added: trunk/core/jbehave-pico/pom.xml (0 => 1488)

--- trunk/core/jbehave-pico/pom.xml	                        (rev 0)
+++ trunk/core/jbehave-pico/pom.xml	2010-01-03 00:08:37 UTC (rev 1488)
@@ -0,0 +1,34 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.jbehave</groupId>
+    <artifactId>jbehave</artifactId>
+    <version>2.4-SNAPSHOT</version>
+  </parent>
+  <artifactId>jbehave-pico</artifactId>
+  <name>JBehave PicoContainer Extension</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.jbehave</groupId>
+      <artifactId>jbehave-core</artifactId>
+      <version>${pom.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>org.picocontainer</groupId>
+      <artifactId>picocontainer</artifactId>
+      <version>2.10-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>javax.inject</groupId>
+      <artifactId>javax.inject</artifactId>
+      <version>1</version>
+      <optional>true</optional>
+    </dependency>
+  </dependencies>
+
+  <build>
+    <sourceDirectory>src/main/java</sourceDirectory>
+    <testSourceDirectory>src/behaviour/java</testSourceDirectory>
+  </build>
+</project>

Added: trunk/core/jbehave-pico/src/behaviour/java/org/jbehave/scenario/steps/pico/PicoEnabledCandidateStepBehaviour.java (0 => 1488)

--- trunk/core/jbehave-pico/src/behaviour/java/org/jbehave/scenario/steps/pico/PicoEnabledCandidateStepBehaviour.java	                        (rev 0)
+++ trunk/core/jbehave-pico/src/behaviour/java/org/jbehave/scenario/steps/pico/PicoEnabledCandidateStepBehaviour.java	2010-01-03 00:08:37 UTC (rev 1488)
@@ -0,0 +1,351 @@
+package org.jbehave.scenario.steps.pico;
+
+import org.jbehave.scenario.annotations.Given;
+import org.jbehave.scenario.annotations.When;
+import org.jbehave.scenario.parser.PrefixCapturingPatternBuilder;
+import org.jbehave.scenario.parser.StepPatternBuilder;
+import org.jbehave.scenario.reporters.ScenarioReporter;
+import org.jbehave.scenario.steps.*;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.picocontainer.Characteristics;
+import org.picocontainer.DefaultPicoContainer;
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.behaviors.Caching;
+import org.picocontainer.containers.EmptyPicoContainer;
+import org.picocontainer.injectors.ConstructorInjection;
+
+import javax.inject.Named;
+
+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 static java.util.Arrays.asList;
+import static org.hamcrest.CoreMatchers.equalTo;
+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.GIVEN;
+import static org.jbehave.scenario.steps.StepType.THEN;
+import static org.jbehave.scenario.steps.StepType.WHEN;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class PicoEnabledCandidateStepBehaviour {
+
+    private static final StepPatternBuilder PATTERN_BUILDER = new PrefixCapturingPatternBuilder();
+    private static final String NL = System.getProperty("line.separator");
+	private Map<String, String> tableRow = new HashMap<String, String>();
+	private Map<StepType, String> startingWords = startingWords();
+    private MutablePicoContainer parent;
+
+	private Map<StepType, String> startingWords() {
+		Map<StepType, String> map = new HashMap<StepType, String>();
+		map.put(GIVEN, "Given");
+		map.put(WHEN, "When");
+		map.put(THEN, "Then");
+		return map;
+	}
+
+    @Before
+    public void setup() {
+        parent = new DefaultPicoContainer(new Caching().wrap(new ConstructorInjection()));
+    }
+
+
+    @Test
+    public void shouldMatchASimpleString() throws Exception {
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I laugh", GIVEN, SomeSteps2.class.getMethod("aMethod"),
+                null, PATTERN_BUILDER, new ParameterConverters(), startingWords, new EmptyPicoContainer());
+        ensureThat(candidateStep.matches("Given I laugh"));
+    }
+
+    @Test
+    public void shouldMatchAStringWithArguments() throws Exception {
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("windows on the $nth floor", WHEN, SomeSteps2.class
+				        .getMethod("aMethod"), null, PATTERN_BUILDER, new ParameterConverters(), startingWords, new EmptyPicoContainer());
+        ensureThat(candidateStep.matches("When windows on the 1st floor"));
+        ensureThat(not(candidateStep.matches("When windows on the 1st floor are open")));
+    }
+
+    @Test
+    public void shouldProvideARealStepUsingTheMatchedString() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(SomeSteps2.class);
+        SomeSteps2 someSteps = parent.getComponent(SomeSteps2.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I live on the $args floor", THEN, SomeSteps2.class.getMethod(
+				        "aMethodWith", String.class), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        Step step = candidateStep.createFrom(tableRow, "Then I live on the 1st floor");
+        step.perform();
+        ensureThat((String) someSteps.args, equalTo("1st"));
+    }
+
+    @Test
+    public void shouldMatchMultilineStrings() throws Exception {
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("the grid should look like $grid", THEN, SomeSteps2.class
+				        .getMethod("aMethod"), null, PATTERN_BUILDER, new ParameterConverters(), startingWords, new EmptyPicoContainer());
+        ensureThat(candidateStep.matches("Then the grid should look like " + NL + "...." + NL + "...." + NL));
+    }
+
+    @Test
+    public void shouldConvertArgsToAppropriateNumbers() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(SomeSteps2.class);
+        SomeSteps2 someSteps = parent.getComponent(SomeSteps2.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I should live in no. $args", THEN, SomeSteps2.class.getMethod(
+				        "aMethodWith", int.class), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "Then I should live in no. 14").perform();
+        ensureThat((Integer) someSteps.args, equalTo(14));
+
+        candidateStep = new PicoEnabledCandidateStep("I should live in no. $args", THEN, SomeSteps2.class.getMethod("aMethodWith",
+				        long.class), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "Then I should live in no. 14").perform();
+        ensureThat((Long) someSteps.args, equalTo(14L));
+
+        candidateStep = new PicoEnabledCandidateStep("I should live in no. $args", THEN, SomeSteps2.class.getMethod("aMethodWith",
+				        double.class), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "Then I should live in no. 14").perform();
+        ensureThat((Double) someSteps.args, equalTo(14.0));
+
+        candidateStep = new PicoEnabledCandidateStep("I should live in no. $args", THEN, SomeSteps2.class.getMethod("aMethodWith",
+				        float.class), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "Then I should live in no. 14").perform();
+        ensureThat((Float) someSteps.args, equalTo(14.0f));
+    }
+
+    @Test
+    public void shouldProvideAStepWithADescriptionThatMatchesTheCandidateStep() throws Exception {
+        ScenarioReporter reporter = mock(ScenarioReporter.class);
+        parent.as(Characteristics.USE_NAMES).addComponent(SomeSteps2.class);
+        SomeSteps2 someSteps = parent.getComponent(SomeSteps2.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I live on the $nth floor", THEN, SomeSteps2.class.getMethod(
+				        "aMethodWith", String.class), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        Step step = candidateStep.createFrom(tableRow, "Then I live on the 1st floor");
+
+        StepResult result = step.perform();
+        result.describeTo(reporter);
+        verify(reporter).successful("Then I live on the 1st floor");
+    }
+
+    @Test
+    @Ignore()    
+    public void shouldNotFailJustBecauseWeHaveDifferentNewlinesToTheOneTheScenarioWasWrittenIn() throws Exception {
+        String windowsNewline = "\r\n";
+        String unixNewline = "\n";
+        String systemNewline = System.getProperty("line.separator");
+        parent.as(Characteristics.USE_NAMES).addComponent(SomeSteps2.class);
+        SomeSteps2 someSteps = parent.getComponent(SomeSteps2.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("the grid should look like $grid", THEN, SomeSteps2.class.getMethod(
+				        "aMethodWith", String.class), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        Step step = candidateStep.createFrom(tableRow, "Then the grid should look like" + windowsNewline + ".." + unixNewline
+                + ".." + windowsNewline);
+        step.perform();
+        ensureThat((String) someSteps.args, equalTo(".." + systemNewline + ".." + systemNewline));
+    }
+
+    @Test
+    @Ignore
+    public void shouldConvertArgsToListOfNumbers() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(SomeSteps2.class);
+        SomeSteps2 someSteps = parent.getComponent(SomeSteps2.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("windows on the $nth floors",
+        		WHEN, SomeSteps2.methodFor("aMethodWithListOfLongs"), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When windows on the 1L,2L,3L floors").perform();
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList(1L, 2L, 3L).toString()));
+
+        candidateStep = new PicoEnabledCandidateStep("windows on the $nth floors", WHEN,
+                SomeSteps2.methodFor("aMethodWithListOfIntegers"), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When windows on the 1,2,3 floors").perform();
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList(1, 2, 3).toString()));
+
+        candidateStep = new PicoEnabledCandidateStep("windows on the $nth floors", WHEN,
+                SomeSteps2.methodFor("aMethodWithListOfDoubles"), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When windows on the 1.1,2.2,3.3 floors").perform();
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList(1.1, 2.2, 3.3).toString()));
+
+        candidateStep = new PicoEnabledCandidateStep("windows on the $nth floors", WHEN,
+                SomeSteps2.methodFor("aMethodWithListOfFloats"), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When windows on the 1.1f,2.2f,3.3f floors").perform();
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList(1.1f, 2.2f, 3.3f).toString()));
+
+    }
+
+    @Test
+    @Ignore
+    public void shouldConvertArgsToListOfStrings() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(SomeSteps2.class);
+        SomeSteps2 someSteps = parent.getComponent(SomeSteps2.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("windows on the $nth floors",
+        		WHEN, SomeSteps2.methodFor("aMethodWithListOfStrings"), someSteps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When windows on the 1,2,3 floors").perform();
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList("1", "2", "3").toString()));
+    }
+
+    @Test
+    public void shouldMatchMethodParametersByAnnotatedNamesInNaturalOrder() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(AnnotationNamedParameterSteps.class);
+        AnnotationNamedParameterSteps steps = parent.getComponent(AnnotationNamedParameterSteps.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I live on the $ith floor but some call it the $nth",
+        		WHEN, stepMethodFor("methodWithNamedParametersInNaturalOrder", AnnotationNamedParameterSteps.class), steps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When I live on the first floor but some call it the ground").perform();
+        ensureThat(steps.ith, equalTo("first"));
+        ensureThat(steps.nth, equalTo("ground"));
+    }
+
+    @Test
+    public void shouldMatchMethodParametersByAnnotatedNamesInverseOrder() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(AnnotationNamedParameterSteps.class);
+        AnnotationNamedParameterSteps steps = parent.getComponent(AnnotationNamedParameterSteps.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I live on the $ith floor but some call it the $nth",
+        		WHEN, stepMethodFor("methodWithNamedParametersInInverseOrder", AnnotationNamedParameterSteps.class), steps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When I live on the first floor but some call it the ground").perform();
+        ensureThat(steps.ith, equalTo("first"));
+        ensureThat(steps.nth, equalTo("ground"));
+    }
+
+    @Test
+    @Ignore
+    public void shouldCreateStepFromTableValuesViaAnnotations() throws Exception {
+    	AnnotationNamedParameterSteps steps = new AnnotationNamedParameterSteps();
+    	tableRow.put("ith", "first");
+    	tableRow.put("nth", "ground");
+        CandidateStep candidateStep = new CandidateStep("I live on the ith floor but some call it the nth",
+        		WHEN, stepMethodFor("methodWithNamedParametersInNaturalOrder", AnnotationNamedParameterSteps.class), steps, PATTERN_BUILDER, new ParameterConverters(), startingWords);
+        candidateStep.createFrom(tableRow, "When I live on the <ith> floor but some call it the <nth>").perform();
+        ensureThat(steps.ith, equalTo("first"));
+        ensureThat(steps.nth, equalTo("ground"));
+    }
+
+    @Test
+    public void shouldMatchMethodParametersByParanamerNamesInNaturalOrder() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(ParanamerNamedParameterSteps.class);
+        ParanamerNamedParameterSteps steps = parent.getComponent(ParanamerNamedParameterSteps.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I live on the $ith floor but some call it the $nth",
+        		WHEN, stepMethodFor("methodWithNamedParametersInNaturalOrder", ParanamerNamedParameterSteps.class), steps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        Step step = candidateStep.createFrom(tableRow, "When I live on the first floor but some call it the ground");
+        step.perform();
+        ensureThat(steps.ith, equalTo("first"));
+        ensureThat(steps.nth, equalTo("ground"));
+    }
+
+    @Test
+    public void shouldMatchMethodParametersByParanamerInverseOrder() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(ParanamerNamedParameterSteps.class);
+        ParanamerNamedParameterSteps steps = parent.getComponent(ParanamerNamedParameterSteps.class);
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I live on the $ith floor but some call it the $nth",
+        		WHEN, stepMethodFor("methodWithNamedParametersInInverseOrder", ParanamerNamedParameterSteps.class), steps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When I live on the first floor but some call it the ground").perform();
+        ensureThat(steps.ith, equalTo("first"));
+        ensureThat(steps.nth, equalTo("ground"));
+    }
+
+    @Test
+    public void shouldCreateStepFromTableValuesViaParanamer() throws Exception {
+        parent.as(Characteristics.USE_NAMES).addComponent(ParanamerNamedParameterSteps.class);
+        ParanamerNamedParameterSteps steps = parent.getComponent(ParanamerNamedParameterSteps.class);
+    	tableRow.put("ith", "first");
+    	tableRow.put("nth", "ground");
+        PicoEnabledCandidateStep candidateStep = new PicoEnabledCandidateStep("I live on the ith floor but some call it the nth",
+        		WHEN, stepMethodFor("methodWithNamedParametersInNaturalOrder", ParanamerNamedParameterSteps.class), steps, PATTERN_BUILDER, new ParameterConverters(), startingWords, parent);
+        candidateStep.createFrom(tableRow, "When I live on the <ith> floor but some call it the <nth>").perform();
+        ensureThat(steps.ith, equalTo("first"));
+        ensureThat(steps.nth, equalTo("ground"));
+    }
+
+    @Test
+    public void shouldCreateStepsOfDifferentTypesWithSameMatchingPattern() throws Throwable {
+        parent.addComponent(NamedTypeSteps.class);
+        NamedTypeSteps steps = parent.getComponent(NamedTypeSteps.class);
+        steps.withPicoContainer(parent);
+        CandidateStep[] candidateSteps = steps.getSteps();
+        ensureThat(candidateSteps.length, equalTo(2));
+        guard(candidateSteps[0].createFrom(tableRow, "Given foo named xyz").perform());
+        guard(candidateSteps[1].createFrom(tableRow, "When foo named Bar").perform());
+        ensureThat(steps.givenName, equalTo("xyz"));
+        ensureThat(steps.whenName, equalTo("Bar"));
+    }
+
+    private StepResult guard(StepResult result) throws Throwable {
+        if (result instanceof StepResult.Failed) {
+            throw result.getThrowable();
+        }
+        return result;
+    }
+
+	@Test(expected= CandidateStep.StartingWordNotFound.class)
+    public void shouldNotCreateStepOfWrongType() {
+        parent.addComponent(NamedTypeSteps.class);
+        NamedTypeSteps steps = parent.getComponent(NamedTypeSteps.class);
+        steps.withPicoContainer(parent);
+        CandidateStep[] candidateSteps = steps.getSteps();
+        ensureThat(candidateSteps.length, equalTo(2));
+        candidateSteps[0].createFrom(tableRow, "Given foo named xyz").perform();
+        ensureThat(steps.givenName, equalTo("xyz"));
+        ensureThat(steps.whenName, nullValue());
+        candidateSteps[0].createFrom(tableRow, "Then foo named xyz").perform();
+    }
+
+    public static class NamedTypeSteps extends PicoEnabledSteps {
+        String givenName;
+        String whenName;
+
+        @Given("foo named $name")
+        public void givenFoo(String name) {
+        	givenName = name;
+        }
+
+        @When("foo named $name")
+        public void whenFoo(String name) {
+        	whenName = name;
+        }
+
+    }
+
+    public static class AnnotationNamedParameterSteps extends PicoEnabledSteps {
+    	String ith;
+        String nth;
+
+        public void methodWithNamedParametersInNaturalOrder(@Named("ith") String ithName, @Named("nth") String nthName){
+    		this.ith = ithName;
+    		this.nth = nthName;
+        }
+
+        public void methodWithNamedParametersInInverseOrder(@Named("nth") String nthName, @Named("ith") String ithName){
+    		this.ith = ithName;
+    		this.nth = nthName;
+        }
+
+    }
+
+    public static class ParanamerNamedParameterSteps extends PicoEnabledSteps {
+    	String ith;
+        String nth;
+
+        public void methodWithNamedParametersInNaturalOrder(String ith, String nth){
+    		this.ith = ith;
+    		this.nth = nth;
+        }
+
+        public void methodWithNamedParametersInInverseOrder(String nth, String ith){
+    		this.ith = ith;
+    		this.nth = nth;
+        }
+
+    }
+
+    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;
+    }
+
+}

Added: trunk/core/jbehave-pico/src/behaviour/java/org/jbehave/scenario/steps/pico/SomeSteps2.java (0 => 1488)

--- trunk/core/jbehave-pico/src/behaviour/java/org/jbehave/scenario/steps/pico/SomeSteps2.java	                        (rev 0)
+++ trunk/core/jbehave-pico/src/behaviour/java/org/jbehave/scenario/steps/pico/SomeSteps2.java	2010-01-03 00:08:37 UTC (rev 1488)
@@ -0,0 +1,83 @@
+package org.jbehave.scenario.steps.pico;
+
+import org.jbehave.scenario.definition.ExamplesTable;
+import org.jbehave.scenario.steps.Steps;
+
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.MethodDescriptor;
+import java.lang.reflect.Method;
+import java.util.List;
+
+public class SomeSteps2 extends Steps {
+
+    public SomeSteps2() {
+        System.out.println("");
+    }
+
+    public Object args;
+
+    public void aMethod() {
+
+    }
+
+    public void aMethodWith(String args) {
+        this.args = args;
+    }
+
+    public void aMethodWith(double args) {
+        this.args = args;
+    }
+
+    public void aMethodWith(long args) {
+        this.args = args;
+    }
+
+    public void aMethodWith(int args) {
+        this.args = args;
+    }
+
+    public void aMethodWith(float args) {
+        this.args = args;
+    }
+
+    public void aMethodWithListOfStrings(List<String> args) {
+        this.args = args;
+    }
+
+    public void aMethodWithListOfLongs(List<Long> args) {
+        this.args = args;
+    }
+
+    public void aMethodWithListOfIntegers(List<Integer> args) {
+        this.args = args;
+    }
+
+    public void aMethodWithListOfDoubles(List<Double> args) {
+        this.args = args;
+    }
+
+    public void aMethodWithListOfFloats(List<Float> args) {
+        this.args = args;
+    }
+
+    public void aMethodWithListOfNumbers(List<Number> args) {
+        this.args = args;
+    }
+
+    public void aMethodWithExamplesTable(ExamplesTable args) {
+        this.args = args;
+    }
+
+    public static Method methodFor(String methodName) throws IntrospectionException {
+        BeanInfo beanInfo = Introspector.getBeanInfo(SomeSteps2.class);
+        for (MethodDescriptor md : beanInfo.getMethodDescriptors()) {
+            if (md.getMethod().getName().equals(methodName)) {
+                return md.getMethod();
+            }
+        }
+        return null;
+    }
+
+}

Added: trunk/core/jbehave-pico/src/main/java/org/jbehave/scenario/steps/pico/PicoEnabledCandidateStep.java (0 => 1488)

--- trunk/core/jbehave-pico/src/main/java/org/jbehave/scenario/steps/pico/PicoEnabledCandidateStep.java	                        (rev 0)
+++ trunk/core/jbehave-pico/src/main/java/org/jbehave/scenario/steps/pico/PicoEnabledCandidateStep.java	2010-01-03 00:08:37 UTC (rev 1488)
@@ -0,0 +1,81 @@
+package org.jbehave.scenario.steps.pico;
+
+import org.jbehave.scenario.errors.PendingError;
+import org.jbehave.scenario.parser.StepPatternBuilder;
+import org.jbehave.scenario.steps.*;
+import org.picocontainer.Characteristics;
+import org.picocontainer.DefaultPicoContainer;
+import org.picocontainer.MutablePicoContainer;
+import org.picocontainer.PicoContainer;
+import org.picocontainer.injectors.MethodInjection;
+import org.picocontainer.injectors.Reinjection;
+import org.picocontainer.injectors.Reinjector;
+import org.picocontainer.lifecycle.NullLifecycleStrategy;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.regex.Matcher;
+
+public class PicoEnabledCandidateStep extends CandidateStep {
+
+    private PicoContainer parent;
+
+    public PicoEnabledCandidateStep(String patternAsString, StepType stepType, Method method, CandidateSteps steps,
+                                    StepPatternBuilder patternBuilder, ParameterConverters parameterConverters,
+                                    Map<StepType, String> startingWords, PicoContainer parent) {
+        super(patternAsString, stepType, method, steps, patternBuilder, parameterConverters, startingWords);
+        this.parent = parent;
+    }
+
+    @Override
+    protected Step createStep(final String stepAsString, Map<String, String> tableRow, Matcher matcher, final Method method,
+                              final StepMonitor stepMonitor, String[] groupNames) {
+
+        final MutablePicoContainer tempContainer = new DefaultPicoContainer(new Reinjection(new MethodInjection(method), parent), new NullLifecycleStrategy(), parent);
+
+        // populate named entries from tableRow
+        Set<String> keys = tableRow.keySet();
+        for (String key : keys) {
+            tempContainer.addConfig(key, tableRow.get(key));
+        }
+
+        // populate named entries from regex
+        for (String groupName : groupNames) {
+            String val = getGroup(matcher, groupName);
+            tempContainer.addConfig(groupName, val);
+        }
+
+        return new Step() {
+            public StepResult perform() {
+                try {
+                    stepMonitor.performing(stepAsString);
+                    tempContainer.as(Characteristics.USE_NAMES).addComponent(method.getDeclaringClass());
+                    tempContainer.getComponent(method.getDeclaringClass());
+                    return StepResult.success(stepAsString);
+                } catch (Throwable t) {
+                    return failureWithOriginalException(stepAsString, t);
+                }
+            }
+
+            private StepResult failureWithOriginalException(final String stepAsString, Throwable t) {
+                if (t instanceof InvocationTargetException && t.getCause() != null) {
+                    if (t.getCause() instanceof PendingError) {
+                        return StepResult.pending(stepAsString, (PendingError) t.getCause());
+                    } else {
+                        return StepResult.failure(stepAsString, t.getCause());
+                    }
+                }
+                return StepResult.failure(stepAsString, t);
+            }
+
+            public StepResult doNotPerform() {
+                return StepResult.notPerformed(stepAsString);
+            }
+
+        };
+    }
+}

Added: trunk/core/jbehave-pico/src/main/java/org/jbehave/scenario/steps/pico/PicoEnabledSteps.java (0 => 1488)

--- trunk/core/jbehave-pico/src/main/java/org/jbehave/scenario/steps/pico/PicoEnabledSteps.java	                        (rev 0)
+++ trunk/core/jbehave-pico/src/main/java/org/jbehave/scenario/steps/pico/PicoEnabledSteps.java	2010-01-03 00:08:37 UTC (rev 1488)
@@ -0,0 +1,45 @@
+package org.jbehave.scenario.steps.pico;
+
+import org.jbehave.scenario.definition.KeyWords;
+import org.jbehave.scenario.steps.*;
+import org.picocontainer.PicoContainer;
+
+import java.lang.reflect.Method;
+
+public class PicoEnabledSteps extends Steps {
+
+    private PicoContainer parent;
+
+    public PicoEnabledSteps() {
+    }
+
+    public PicoEnabledSteps withPicoContainer(PicoContainer parent) {
+        this.parent = parent;
+        return this;
+    }
+
+    public PicoEnabledSteps(KeyWords keywords) {
+        super(keywords);
+    }
+
+    public PicoEnabledSteps(ParameterConverters converters) {
+        super(converters);
+    }
+
+
+    public PicoEnabledSteps(StepsConfiguration configuration) {
+        super(configuration);
+    }
+
+    protected CandidateStep createCandidateStep(Method method, StepType stepType, String stepPatternAsString, StepsConfiguration configuration) {
+        if (parent == null) {
+            throw new NullPointerException("parent should be passed in via usePicoContainer(..)");
+        }
+        return new PicoEnabledCandidateStep(stepPatternAsString, stepType, method,
+                this, configuration.getPatternBuilder(),
+                configuration.getParameterConverters(),
+                configuration.getStartingWordsByType(), parent);
+    }
+
+
+}

Modified: trunk/core/pom.xml (1487 => 1488)

--- trunk/core/pom.xml	2010-01-02 14:13:31 UTC (rev 1487)
+++ trunk/core/pom.xml	2010-01-03 00:08:37 UTC (rev 1488)
@@ -13,6 +13,7 @@
     <module>jbehave-core</module>
     <module>jbehave-ant</module>
     <module>jbehave-maven-plugin</module>
+    <module>jbehave-pico</module>
   </modules>
 
   <dependencyManagement>


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to