Title: [892] trunk/jbehave-core/src/java/org/jbehave/scenario/steps: JBEHAVE-128: Refactored candidate step to use generic parameter types (of which Class is impl) to allow support for conversion of list objects.
Revision
892
Author
mauro
Date
2008-08-24 11:41:41 -0500 (Sun, 24 Aug 2008)

Log Message

JBEHAVE-128:  Refactored candidate step to use generic parameter types (of which Class is impl) to allow support for conversion of list objects.  Added support for list of strings.

Modified Paths

Diff

Modified: trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/CandidateStepBehaviour.java (891 => 892)

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/CandidateStepBehaviour.java	2008-08-24 16:12:59 UTC (rev 891)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/CandidateStepBehaviour.java	2008-08-24 16:41:41 UTC (rev 892)
@@ -1,11 +1,19 @@
 package org.jbehave.scenario.steps;
 
+import static java.util.Arrays.asList;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.jbehave.Ensure.ensureThat;
 import static org.jbehave.Ensure.not;
 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.List;
+
 import org.jbehave.scenario.parser.PrefixCapturingPatternBuilder;
 import org.jbehave.scenario.parser.StepPatternBuilder;
 import org.jbehave.scenario.reporters.ScenarioReporter;
@@ -21,14 +29,13 @@
     public void shouldMatchASimpleString() throws Exception {
         CandidateStep candidateStep = new CandidateStep("I laugh", SomeSteps.class.getMethod("aMethod"), null,
                 PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
-
         ensureThat(candidateStep.matches("Given I laugh"));
     }
 
     @Test
     public void shouldMatchAStringWithArguments() throws Exception {
-        CandidateStep candidateStep = new CandidateStep("windows on the $nth floor", SomeSteps.class.getMethod("aMethod"), null,
-                PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        CandidateStep candidateStep = new CandidateStep("windows on the $nth floor", SomeSteps.class
+                .getMethod("aMethod"), null, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         ensureThat(candidateStep.matches("When windows on the 1st floor"));
         ensureThat(not(candidateStep.matches("When windows on the 1st floor are open")));
     }
@@ -36,8 +43,8 @@
     @Test
     public void shouldProvideARealStepUsingTheMatchedString() throws Exception {
         SomeSteps someSteps = new SomeSteps();
-        CandidateStep candidateStep = new CandidateStep("I live on the $nth floor", SomeSteps.class.getMethod("aMethodWith",
-                String.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        CandidateStep candidateStep = new CandidateStep("I live on the $nth floor", SomeSteps.class.getMethod(
+                "aMethodWith", String.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         Step step = candidateStep.createFrom("Then I live on the 1st floor");
         step.perform();
         ensureThat((String) someSteps.args, equalTo("1st"));
@@ -45,31 +52,31 @@
 
     @Test
     public void shouldMatchMultilineStrings() throws Exception {
-        CandidateStep candidateStep = new CandidateStep("the grid should look like $grid", SomeSteps.class.getMethod("aMethod"),
-                null, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        CandidateStep candidateStep = new CandidateStep("the grid should look like $grid", SomeSteps.class
+                .getMethod("aMethod"), null, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         ensureThat(candidateStep.matches("Then the grid should look like " + NL + "...." + NL + "...." + NL));
     }
 
     @Test
     public void shouldConvertArgsToAppropriateNumbers() throws Exception {
         SomeSteps someSteps = new SomeSteps();
-        CandidateStep candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod("aMethodWith",
-                int.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        CandidateStep candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod(
+                "aMethodWith", int.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         candidateStep.createFrom("Then I should live in no. 14").perform();
         ensureThat((Integer) someSteps.args, equalTo(14));
 
-        candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod("aMethodWith", long.class),
-                someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod("aMethodWith",
+                long.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         candidateStep.createFrom("Then I should live in no. 14").perform();
         ensureThat((Long) someSteps.args, equalTo(14L));
 
-        candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod("aMethodWith", double.class),
-                someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod("aMethodWith",
+                double.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         candidateStep.createFrom("Then I should live in no. 14").perform();
         ensureThat((Double) someSteps.args, equalTo(14.0));
 
-        candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod("aMethodWith", float.class),
-                someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        candidateStep = new CandidateStep("I should live in no. $no", SomeSteps.class.getMethod("aMethodWith",
+                float.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         candidateStep.createFrom("Then I should live in no. 14").perform();
         ensureThat((Float) someSteps.args, equalTo(14.0f));
     }
@@ -78,38 +85,48 @@
     public void shouldProvideAStepWithADescriptionThatMatchesTheCandidateStep() throws Exception {
         ScenarioReporter reporter = mock(ScenarioReporter.class);
         SomeSteps someSteps = new SomeSteps();
-        CandidateStep candidateStep = new CandidateStep("I live on the $nth floor", SomeSteps.class.getMethod("aMethodWith",
-                String.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        CandidateStep candidateStep = new CandidateStep("I live on the $nth floor", SomeSteps.class.getMethod(
+                "aMethodWith", String.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
         Step step = candidateStep.createFrom("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
     public void shouldNotFailJustBecauseWeHaveDifferentNewlinesToTheOneTheScenarioWasWrittenIn() throws Exception {
         String windowsNewline = "\r\n";
         String unixNewline = "\n";
         String systemNewline = System.getProperty("line.separator");
-        
         SomeSteps someSteps = new SomeSteps();
-        CandidateStep candidateStep = new CandidateStep(
-                "the grid should look like $grid", 
-                SomeSteps.class.getMethod("aMethodWith", String.class), 
-                someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
-        Step step = candidateStep.createFrom(
-                "Then the grid should look like" + windowsNewline +
-                ".." + unixNewline +
-                ".." + windowsNewline);
-        
+        CandidateStep candidateStep = new CandidateStep("the grid should look like $grid", SomeSteps.class.getMethod(
+                "aMethodWith", String.class), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        Step step = candidateStep.createFrom("Then the grid should look like" + windowsNewline + ".." + unixNewline
+                + ".." + windowsNewline);
         step.perform();
-        ensureThat((String) someSteps.args, equalTo(
-                ".." + systemNewline +
-                ".." + systemNewline));
+        ensureThat((String) someSteps.args, equalTo(".." + systemNewline + ".." + systemNewline));
     }
 
+    @Test
+    public void shouldConvertArgsToListOfStrings() throws Exception {
+        SomeSteps someSteps = new SomeSteps();
+        CandidateStep candidateStep = new CandidateStep("windows on the $nth floors",
+                methodFor("aMethodWithListOfStrings"), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        candidateStep.createFrom("When windows on the 1,2,3 floors").perform();
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList("1","2","3").toString()));
+    }
+
+    public static Method methodFor(String methodName) throws IntrospectionException {
+        BeanInfo beanInfo = Introspector.getBeanInfo(SomeSteps.class);
+        for (MethodDescriptor md : beanInfo.getMethodDescriptors()) {
+            if (md.getMethod().getName().equals(methodName)) {
+                return md.getMethod();
+            }
+        }
+        return null;
+    }
+
     public class SomeSteps extends Steps {
         private Object args;
 
@@ -136,5 +153,9 @@
         public void aMethodWith(float args) {
             this.args = args;
         }
+
+        public void aMethodWithListOfStrings(List<String> args) {
+            this.args = args;
+        }
     }
 }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateStep.java (891 => 892)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateStep.java	2008-08-24 16:12:59 UTC (rev 891)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateStep.java	2008-08-24 16:41:41 UTC (rev 892)
@@ -1,7 +1,12 @@
 package org.jbehave.scenario.steps;
 
+import static java.util.Arrays.asList;
+
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -11,18 +16,20 @@
 
 public class CandidateStep {
 
+    private static final String NL = System.getProperty("line.separator");
+    private static final String COMMA = ",";
     private final Method method;
     private final Steps steps;
     private final StepMonitor monitor;
     private Pattern pattern;
     private String[] startingWords;
 
-    public CandidateStep(String matchThis, Method method, Steps steps, StepPatternBuilder patternConverter, StepMonitor monitor, String... startingWords) {
+    public CandidateStep(String matchThis, Method method, Steps steps, StepPatternBuilder patterBuilder, StepMonitor monitor, String... startingWords) {
         this.method = method;
         this.steps = steps;
         this.monitor = monitor;
         this.startingWords = startingWords;
-        pattern = patternConverter.buildPattern(matchThis);
+        pattern = patterBuilder.buildPattern(matchThis);
     }
 
     public boolean matches(String step) {
@@ -46,7 +53,7 @@
         final Object[] args = new Object[matcher.groupCount()];
         for (int group = 0; group < args.length; group++) {
             String arg = matcher.group(group + 1);
-            Object converted = convert(arg, method.getParameterTypes()[group]);
+            Object converted = convert(arg, method.getGenericParameterTypes()[group]);
             args[group] = converted;
         }
         return createStep(stepAsString, args);
@@ -91,22 +98,32 @@
         };
     }
 
-    private Object convert(String value, Class<?> clazz) {
-        if (clazz == Integer.class || clazz == int.class) {
+    private Object convert(String value, Type type) {
+        monitor.convertingValueOfType(value, type);
+        if (type == Integer.class || type == int.class) {
             return Integer.valueOf(value);
-        } else if (clazz == Long.class || clazz == long.class) {
+        } else if (type == Long.class || type == long.class) {
             return Long.valueOf(value);
-        } else if (clazz == Double.class || clazz == double.class) {
+        } else if (type == Double.class || type == double.class) {
             return Double.valueOf(value);
-        } else if (clazz == Float.class || clazz == float.class) {
+        } else if (type == Float.class || type == float.class) {
             return Float.valueOf(value);
-        } else if (clazz == String.class) {
+        } else if (type instanceof ParameterizedType ){
+            return listFor(value, (ParameterizedType)type);
+        } else if (type == String.class) {
             return replaceNewlinesWithSystemNewlines(value);
         }
         return value;
     }
 
+    private Object listFor(String value, ParameterizedType type) {
+        if ( List.class.isAssignableFrom((Class<?>)type.getRawType()) ){
+            return asList(value.split(COMMA));
+        }
+        return replaceNewlinesWithSystemNewlines(value);
+    }
+
     private Object replaceNewlinesWithSystemNewlines(String value) {
-        return value.replaceAll("(\n)|(\r\n)", System.getProperty("line.separator"));
+        return value.replaceAll("(\n)|(\r\n)", NL);
     }
 }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java (891 => 892)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java	2008-08-24 16:12:59 UTC (rev 891)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java	2008-08-24 16:41:41 UTC (rev 892)
@@ -3,6 +3,7 @@
 import static java.text.MessageFormat.format;
 
 import java.io.PrintStream;
+import java.lang.reflect.Type;
 
 public class PrintStreamStepMonitor implements StepMonitor {
     private final PrintStream output;
@@ -21,7 +22,13 @@
         print(output, message);
     }
 
+    public void convertingValueOfType(String value, Type type) {
+        String message = format("Converting value ''{0}'' of type ''{1}''", value, type);
+        print(output,message);
+    }
+    
     protected void print(PrintStream output, String message) {
         output.println(message);
     }
+
 }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepMonitor.java (891 => 892)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepMonitor.java	2008-08-24 16:12:59 UTC (rev 891)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepMonitor.java	2008-08-24 16:41:41 UTC (rev 892)
@@ -1,5 +1,7 @@
 package org.jbehave.scenario.steps;
 
+import java.lang.reflect.Type;
+
 /**
  * Interface to monitor step events
  * 
@@ -9,4 +11,6 @@
 
     void stepMatchesPattern(String string, boolean matches, String pattern);
 
+    void convertingValueOfType(String value, Type type);
+
 }


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to