Title: [893] trunk/jbehave-core/src/java/org/jbehave/scenario/steps: JBEHAVE-128: Refactored candidate step argument converters.

Diff

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

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/CandidateStepBehaviour.java	2008-08-24 16:41:41 UTC (rev 892)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/CandidateStepBehaviour.java	2008-08-25 17:34:58 UTC (rev 893)
@@ -109,12 +109,37 @@
     }
 
     @Test
+    public void shouldConvertArgsToListOfNumbers() throws Exception {
+        SomeSteps someSteps = new SomeSteps();
+        CandidateStep candidateStep = new CandidateStep("windows on the $nth floors",
+                methodFor("aMethodWithListOfLongs"), someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        candidateStep.createFrom("When windows on the 1L,2L,3L floors").perform();
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList(1L, 2L, 3L).toString()));
+
+        candidateStep = new CandidateStep("windows on the $nth floors", methodFor("aMethodWithListOfIntegers"),
+                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()));
+
+        candidateStep = new CandidateStep("windows on the $nth floors", methodFor("aMethodWithListOfDoubles"),
+                someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        candidateStep.createFrom("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 CandidateStep("windows on the $nth floors", methodFor("aMethodWithListOfFloats"),
+                someSteps, PATTERN_BUILDER, MONITOR, "Given", "When", "Then");
+        candidateStep.createFrom("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
     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()));
+        ensureThat(((List<?>) someSteps.args).toString(), equalTo(asList("1", "2", "3").toString()));
     }
 
     public static Method methodFor(String methodName) throws IntrospectionException {
@@ -157,5 +182,22 @@
         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;
+        }
+
     }
 }

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

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateStep.java	2008-08-24 16:41:41 UTC (rev 892)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/CandidateStep.java	2008-08-25 17:34:58 UTC (rev 893)
@@ -6,6 +6,9 @@
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.text.NumberFormat;
+import java.text.ParseException;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -13,7 +16,6 @@
 import org.jbehave.scenario.errors.PendingError;
 import org.jbehave.scenario.parser.StepPatternBuilder;
 
-
 public class CandidateStep {
 
     private static final String NL = System.getProperty("line.separator");
@@ -21,20 +23,25 @@
     private final Method method;
     private final Steps steps;
     private final StepMonitor monitor;
-    private Pattern pattern;
-    private String[] startingWords;
+    private final String[] startingWords;
+    private final Pattern pattern;
+    private final List<? extends ArgumentConverter> converters;
 
-    public CandidateStep(String matchThis, Method method, Steps steps, StepPatternBuilder patterBuilder, 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 = patterBuilder.buildPattern(matchThis);
+        this.pattern = patterBuilder.buildPattern(matchThis);
+        this.converters = asList(new NumberConverter(), new NumberListConverter(), new StringListConverter());
     }
 
     public boolean matches(String step) {
         String word = findStartingWord(step);
-        if (word == null) { return false; }
+        if (word == null) {
+            return false;
+        }
         String trimmed = trimStartingWord(word, step);
         Matcher matcher = pattern.matcher(trimmed);
         boolean matches = matcher.matches();
@@ -50,10 +57,11 @@
         String startingWord = findStartingWord(stepAsString);
         Matcher matcher = pattern.matcher(trimStartingWord(startingWord, stepAsString));
         matcher.find();
+        Type[] types = method.getGenericParameterTypes();
         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.getGenericParameterTypes()[group]);
+            Object converted = convert(arg, types[group]);
             args[group] = converted;
         }
         return createStep(stepAsString, args);
@@ -74,8 +82,7 @@
                 try {
                     method.invoke(steps, args);
                     return StepResult.success(stepAsString);
-                }
-                catch (Throwable t) {
+                } catch (Throwable t) {
                     return failureWithOriginalException(stepAsString, t);
                 }
             }
@@ -99,31 +106,109 @@
     }
 
     private Object convert(String value, Type type) {
-        monitor.convertingValueOfType(value, type);
-        if (type == Integer.class || type == int.class) {
-            return Integer.valueOf(value);
-        } else if (type == Long.class || type == long.class) {
-            return Long.valueOf(value);
-        } else if (type == Double.class || type == double.class) {
-            return Double.valueOf(value);
-        } else if (type == Float.class || type == float.class) {
-            return Float.valueOf(value);
-        } else if (type instanceof ParameterizedType ){
-            return listFor(value, (ParameterizedType)type);
-        } else if (type == String.class) {
-            return replaceNewlinesWithSystemNewlines(value);
+        // check if any converters accepts type
+        for (ArgumentConverter converter : converters) {
+            if (converter.accept(type)) {
+                monitor.convertingValueOfType(value, type, converter.getClass());
+                return converter.convertValue(value, type);
+            }
         }
-        return value;
+        // default to String
+        return replaceNewlinesWithSystemNewlines(value);
     }
 
-    private Object listFor(String value, ParameterizedType type) {
-        if ( List.class.isAssignableFrom((Class<?>)type.getRawType()) ){
+    private Object replaceNewlinesWithSystemNewlines(String value) {
+        return value.replaceAll("(\n)|(\r\n)", NL);
+    }
+
+    private static interface ArgumentConverter {
+
+        boolean accept(Type type);
+
+        Object convertValue(String value, Type type);
+
+    }
+
+    @SuppressWarnings("serial")
+    private static class InvalidArgumentException extends RuntimeException {
+
+        public InvalidArgumentException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+    }
+
+    private static class NumberConverter implements ArgumentConverter {
+
+        public boolean accept(Type type) {
+            if (type instanceof Class) {
+                return (type == Integer.class || type == int.class || type == Long.class || type == long.class
+                        || type == Double.class || type == double.class || type == Float.class || type == float.class);
+            }
+            return false;
+        }
+
+        public Object convertValue(String value, Type type) {
+            if (type == Integer.class || type == int.class) {
+                return Integer.valueOf(value);
+            } else if (type == Long.class || type == long.class) {
+                return Long.valueOf(value);
+            } else if (type == Double.class || type == double.class) {
+                return Double.valueOf(value);
+            } else if (type == Float.class || type == float.class) {
+                return Float.valueOf(value);
+            }
+            return value;
+        }
+
+    }
+
+    private static class NumberListConverter implements ArgumentConverter {
+
+        public boolean accept(Type type) {
+            if (type instanceof ParameterizedType) {
+                ParameterizedType parameterizedType = (ParameterizedType) type;
+                Type rawType = parameterizedType.getRawType();
+                Type argumentType = parameterizedType.getActualTypeArguments()[0];
+                return List.class.isAssignableFrom((Class<?>) rawType)
+                        && Number.class.isAssignableFrom((Class<?>) argumentType);
+            }
+            return false;
+        }
+
+        public Object convertValue(String value, Type type) {
+            List<String> values = asList(value.split(COMMA));
+            NumberFormat numberFormat = NumberFormat.getInstance();
+            List<Number> numbers = new ArrayList<Number>();
+            for (String numberValue : values) {
+                try {
+                    numbers.add(numberFormat.parse(numberValue));
+                } catch (ParseException e) {
+                    throw new InvalidArgumentException(numberValue, e);
+                }
+            }
+            return numbers;
+        }
+
+    }
+
+    private static class StringListConverter implements ArgumentConverter {
+
+        public boolean accept(Type type) {
+            if (type instanceof ParameterizedType) {
+                ParameterizedType parameterizedType = (ParameterizedType) type;
+                Type rawType = parameterizedType.getRawType();
+                Type argumentType = parameterizedType.getActualTypeArguments()[0];
+                return List.class.isAssignableFrom((Class<?>) rawType)
+                        && String.class.isAssignableFrom((Class<?>) argumentType);
+            }
+            return false;
+        }
+
+        public Object convertValue(String value, Type type) {
             return asList(value.split(COMMA));
         }
-        return replaceNewlinesWithSystemNewlines(value);
+
     }
 
-    private Object replaceNewlinesWithSystemNewlines(String value) {
-        return value.replaceAll("(\n)|(\r\n)", NL);
-    }
 }

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

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java	2008-08-24 16:41:41 UTC (rev 892)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrintStreamStepMonitor.java	2008-08-25 17:34:58 UTC (rev 893)
@@ -18,15 +18,15 @@
 
     public void stepMatchesPattern(String step, boolean matches, String pattern) {
         String message = format("Step ''{0}'' {1} pattern ''{2}''", step, (matches ? "matches" : "does not match"),
-                pattern);        
+                pattern);
         print(output, message);
     }
 
-    public void convertingValueOfType(String value, Type type) {
-        String message = format("Converting value ''{0}'' of type ''{1}''", value, type);
-        print(output,message);
+    public void convertingValueOfType(String value, Type type, Class<?> converterClass) {
+        String message = format("Converting value ''{0}'' of type ''{1}'' with converter ''{2}''", value, type, converterClass);
+        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 (892 => 893)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepMonitor.java	2008-08-24 16:41:41 UTC (rev 892)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepMonitor.java	2008-08-25 17:34:58 UTC (rev 893)
@@ -11,6 +11,6 @@
 
     void stepMatchesPattern(String string, boolean matches, String pattern);
 
-    void convertingValueOfType(String value, Type type);
+    void convertingValueOfType(String value, Type type, Class<?> converterClass);
 
 }


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to