Title: [877] trunk/jbehave-core/src/java/org/jbehave/scenario/steps: [Liz]: DollarStepPatternBuilder -> PrefixCapturingPatternBuilder, can configure with a prefix; also escapes all regexp characters

Diff

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

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/CandidateStepBehaviour.java	2008-07-22 17:11:43 UTC (rev 876)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/CandidateStepBehaviour.java	2008-07-24 12:53:56 UTC (rev 877)
@@ -11,7 +11,7 @@
 
 public class CandidateStepBehaviour {
 
-    private static final StepPatternBuilder PATTERN_BUILDER = new DollarStepPatternBuilder();
+    private static final StepPatternBuilder PATTERN_BUILDER = new PrefixCapturingPatternBuilder();
     private static final StepMonitor MONITOR = new SilentStepMonitor();
     private static final String NL = System.getProperty("line.separator");
 

Deleted: trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/DollarStepPatternBuilderBehaviour.java (876 => 877)

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/DollarStepPatternBuilderBehaviour.java	2008-07-22 17:11:43 UTC (rev 876)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/DollarStepPatternBuilderBehaviour.java	2008-07-24 12:53:56 UTC (rev 877)
@@ -1,67 +0,0 @@
-package org.jbehave.scenario.steps;
-
-import static org.hamcrest.CoreMatchers.equalTo;
-import static org.jbehave.Ensure.ensureThat;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import org.junit.Test;
-
-
-public class DollarStepPatternBuilderBehaviour {
-
-	private static final String NL = System.getProperty("line.separator");
-
-	@Test
-	public void shouldReplaceAllDollarArgumentsWithCaptures() {
-		StepPatternBuilder builder = new DollarStepPatternBuilder();
-		ensureThat(builder.buildPattern("a house with $numberOfDoors doors and $some windows").matcher("a house with 3 doors and 4 windows").matches());
-		ensureThat(builder.buildPattern("the house on $street").matcher("the house on Easy Street").matches());
-		ensureThat(builder.buildPattern("$number houses").matcher("5 houses").matches());
-		ensureThat(builder.buildPattern("my house").matcher("my house").matches());
-	}
-	
-	@Test
-	public void shouldEscapeExistingBrackets() {
-		StepPatternBuilder matcher = new DollarStepPatternBuilder();
-		ensureThat(matcher.buildPattern("I toggle the cell at ($column, $row)").matcher("I toggle the cell at (3, 4)").matches());
-	}
-	
-	@Test
-	public void shouldNotCareSoMuchAboutWhitespace() {
-		StepPatternBuilder matcher = new DollarStepPatternBuilder();
-		Pattern pattern = matcher.buildPattern("The grid looks like $grid");
-		
-		// Given an argument on a new line
-		Matcher matched = pattern.matcher(
-				"The grid looks like" + NL +
-				".." + NL +
-				".." + NL
-				);
-		ensureThat(matched.matches());
-		ensureThat(matched.group(1), equalTo(
-				".." + NL +
-				".." + NL));
-		
-		// Given an argument on a new line with extra spaces
-		matched = pattern.matcher(
-				"The grid looks like " + NL +
-				".." + NL +
-				".." + NL
-				);
-		ensureThat(matched.matches());
-		ensureThat(matched.group(1), equalTo(
-				".." + NL +
-				".." + NL));
-		
-		// Given an argument with extra spaces
-		matched = pattern.matcher(
-				"The grid looks like  .");
-		ensureThat(matched.matches());
-		ensureThat(matched.group(1), equalTo(
-				"."));
-		
-	}
-
-}

Added: trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/PrefixCapturingPatternBuilderBehaviour.java (0 => 877)

--- trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/PrefixCapturingPatternBuilderBehaviour.java	                        (rev 0)
+++ trunk/jbehave-core/src/behaviour/org/jbehave/scenario/steps/PrefixCapturingPatternBuilderBehaviour.java	2008-07-24 12:53:56 UTC (rev 877)
@@ -0,0 +1,75 @@
+package org.jbehave.scenario.steps;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.jbehave.Ensure.ensureThat;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.junit.Test;
+
+
+public class PrefixCapturingPatternBuilderBehaviour {
+
+	private static final String NL = System.getProperty("line.separator");
+
+	@Test
+	public void shouldReplaceAllDollarArgumentsWithCaptures() {
+		StepPatternBuilder builder = new PrefixCapturingPatternBuilder();
+		ensureThat(builder.buildPattern("a house with $numberOfDoors doors and $some windows").matcher("a house with 3 doors and 4 windows").matches());
+		ensureThat(builder.buildPattern("the house on $street").matcher("the house on Easy Street").matches());
+		ensureThat(builder.buildPattern("$number houses").matcher("5 houses").matches());
+		ensureThat(builder.buildPattern("my house").matcher("my house").matches());
+	}
+	
+	@Test
+	public void shouldEscapeExistingPunctuationUsedInRegexps() {
+		StepPatternBuilder builder = new PrefixCapturingPatternBuilder();
+		ensureThat(builder.buildPattern("I toggle the cell at ($column, $row)").matcher("I toggle the cell at (3, 4)").matches());
+		ensureThat(builder.buildPattern("$name should ask, \"Why?\"").matcher("Fred should ask, \"Why?\"").matches());
+		ensureThat(builder.buildPattern("$thousands x 10^3").matcher("2 x 10^3").matches());
+		
+		Matcher aMatcherWithAllTheRegexpPunctuation = builder
+			.buildPattern("$regexp should not be confused by []{}?^.*()+\\")
+			.matcher("[]{}?^.*()+\\ should not be confused by []{}?^.*()+\\");
+		ensureThat(aMatcherWithAllTheRegexpPunctuation.matches());
+		ensureThat(aMatcherWithAllTheRegexpPunctuation.group(1), equalTo("[]{}?^.*()+\\"));
+	}
+	
+	@Test
+	public void shouldNotCareSoMuchAboutWhitespace() {
+		StepPatternBuilder matcher = new PrefixCapturingPatternBuilder();
+		Pattern pattern = matcher.buildPattern("The grid looks like $grid");
+		
+		// Given an argument on a new line
+		Matcher matched = pattern.matcher(
+				"The grid looks like" + NL +
+				".." + NL +
+				".." + NL
+				);
+		ensureThat(matched.matches());
+		ensureThat(matched.group(1), equalTo(
+				".." + NL +
+				".." + NL));
+		
+		// Given an argument on a new line with extra spaces
+		matched = pattern.matcher(
+				"The grid looks like " + NL +
+				".." + NL +
+				".." + NL
+				);
+		ensureThat(matched.matches());
+		ensureThat(matched.group(1), equalTo(
+				".." + NL +
+				".." + NL));
+		
+		// Given an argument with extra spaces
+		matched = pattern.matcher(
+				"The grid looks like  .");
+		ensureThat(matched.matches());
+		ensureThat(matched.group(1), equalTo(
+				"."));
+		
+	}
+
+}

Deleted: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/DollarStepPatternBuilder.java (876 => 877)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/DollarStepPatternBuilder.java	2008-07-22 17:11:43 UTC (rev 876)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/DollarStepPatternBuilder.java	2008-07-24 12:53:56 UTC (rev 877)
@@ -1,64 +0,0 @@
-package org.jbehave.scenario.steps;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class DollarStepPatternBuilder implements StepPatternBuilder {
-
-	private static final String ANY_WORD_BEGINNING_WITH_DOLLAR = "(\\$\\w*)(\\W|\\Z)";
-
-	public Pattern buildPattern(String matchThis) {
-		String matchThisButLeaveBrackets = escapeBrackets(matchThis);
-		List<Replacement> replacements = findArgumentsToReplace(matchThisButLeaveBrackets);
-		String patternToMatchAgainst = replaceIdentifiedArgsWithCapture(matchThisButLeaveBrackets, replacements);
-		String matchThisButIgnoreWhitespace = anyWhitespaceWillDo(patternToMatchAgainst);
-		return Pattern.compile(matchThisButIgnoreWhitespace, Pattern.DOTALL);
-	}
-
-	private String anyWhitespaceWillDo(String matchThis) {
-		return matchThis.replaceAll("\\s+", "\\\\s+");
-	}
-
-	private List<Replacement> findArgumentsToReplace(
-			String matchThisButLeaveBrackets) {
-		Matcher findingAllTheDollarWords = Pattern.compile(ANY_WORD_BEGINNING_WITH_DOLLAR, Pattern.DOTALL).matcher(matchThisButLeaveBrackets);
-		List<Replacement> replacements = new ArrayList<Replacement>();
-		while(findingAllTheDollarWords.find()) {
-			replacements.add(new Replacement(findingAllTheDollarWords.start(), findingAllTheDollarWords.end(), findingAllTheDollarWords.group(2)));
-		}
-		return replacements;
-	}
-
-	private String replaceIdentifiedArgsWithCapture(String escapedMatch,
-			List<Replacement> replacements) {
-		String matchTemp = escapedMatch;
-		for (int i = replacements.size(); i > 0; i--) {
-			String start = matchTemp.substring(0, replacements.get(i - 1).start);
-			String end = matchTemp.substring(replacements.get(i - 1).end);
-			String whitespaceIfAny = replacements.get(i - 1).whitespaceIfAny;
-			matchTemp = start + "(.*)" + whitespaceIfAny + end;
-		}
-		return matchTemp;
-	}
-	
-	private String escapeBrackets(String matchThis) {
-		String escapedMatch = matchThis.replace("(", "\\(");
-		escapedMatch = escapedMatch.replace(")", "\\)");
-		return escapedMatch;
-	}
-
-	private static class Replacement {
-		private final int start;
-		private final int end;
-		private final String whitespaceIfAny;
-
-		public Replacement(int start, int end, String whitespaceIfAny) {
-			this.start = start;
-			this.end = end;
-			this.whitespaceIfAny = whitespaceIfAny;
-		}
-	}
-
-}

Added: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrefixCapturingPatternBuilder.java (0 => 877)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrefixCapturingPatternBuilder.java	                        (rev 0)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/PrefixCapturingPatternBuilder.java	2008-07-24 12:53:56 UTC (rev 877)
@@ -0,0 +1,85 @@
+package org.jbehave.scenario.steps;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Provides a pattern which will capture arguments starting with the given
+ * prefix in any matching step. Default prefix is $.
+ * 
+ * @author Elizabeth Keogh
+ */
+public class PrefixCapturingPatternBuilder implements StepPatternBuilder {
+
+	private String anyWordBeginningWithThePrefix = "(\\$\\w*)(\\W|\\Z)";
+
+	/**
+	 * Creates a pattern which captures arguments starting with $ in
+	 * a matching step.
+	 */
+	public PrefixCapturingPatternBuilder() {
+		this("$");
+	}
+
+	/**
+	 * Creates a pattern which captures arguments starting with a given
+	 * prefix in a matching step.
+	 */
+	public PrefixCapturingPatternBuilder(String prefix) {
+		anyWordBeginningWithThePrefix = "(\\" + prefix + "\\w*)(\\W|\\Z)";
+	}
+
+	public Pattern buildPattern(String matchThis) {
+		String matchThisButLeaveBrackets = escapeRegexpPunctuation(matchThis);
+		List<Replacement> replacements = findArgumentsToReplace(matchThisButLeaveBrackets);
+		String patternToMatchAgainst = replaceIdentifiedArgsWithCapture(matchThisButLeaveBrackets, replacements);
+		String matchThisButIgnoreWhitespace = anyWhitespaceWillDo(patternToMatchAgainst);
+		return Pattern.compile(matchThisButIgnoreWhitespace, Pattern.DOTALL);
+	}
+
+	private String anyWhitespaceWillDo(String matchThis) {
+		return matchThis.replaceAll("\\s+", "\\\\s+");
+	}
+
+	private List<Replacement> findArgumentsToReplace(
+			String matchThisButLeaveBrackets) {
+		Matcher findingAllTheDollarWords = Pattern.compile(anyWordBeginningWithThePrefix, Pattern.DOTALL).matcher(matchThisButLeaveBrackets);
+		List<Replacement> replacements = new ArrayList<Replacement>();
+		while(findingAllTheDollarWords.find()) {
+			replacements.add(new Replacement(findingAllTheDollarWords.start(), findingAllTheDollarWords.end(), findingAllTheDollarWords.group(2)));
+		}
+		return replacements;
+	}
+
+	private String replaceIdentifiedArgsWithCapture(String escapedMatch,
+			List<Replacement> replacements) {
+		String matchTemp = escapedMatch;
+		for (int i = replacements.size(); i > 0; i--) {
+			String start = matchTemp.substring(0, replacements.get(i - 1).start);
+			String end = matchTemp.substring(replacements.get(i - 1).end);
+			String whitespaceIfAny = replacements.get(i - 1).whitespaceIfAny;
+			matchTemp = start + "(.*)" + whitespaceIfAny + end;
+		}
+		return matchTemp;
+	}
+	
+	private String escapeRegexpPunctuation(String matchThis) {
+		String escapedMatch = matchThis.replaceAll("([\\[\\]\\{\\}\\?\\^\\.\\*\\(\\)\\+\\\\])", "\\\\$1");
+		return escapedMatch;
+	}
+
+	private static class Replacement {
+		private final int start;
+		private final int end;
+		private final String whitespaceIfAny;
+
+		public Replacement(int start, int end, String whitespaceIfAny) {
+			this.start = start;
+			this.end = end;
+			this.whitespaceIfAny = whitespaceIfAny;
+		}
+	}
+
+}

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepPatternBuilder.java (876 => 877)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepPatternBuilder.java	2008-07-22 17:11:43 UTC (rev 876)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/StepPatternBuilder.java	2008-07-24 12:53:56 UTC (rev 877)
@@ -4,11 +4,23 @@
 
 /**
  * Builds a regex pattern from a template step, as provided in the annotations,
- * which will in turn match real steps conforming to the template. Eg: "When I
- * give $money to $name" becomes "When I give (.*) to (.*)"
+ * which will in turn match real steps conforming to the template. Eg: &quot;I
+ * give $money to $name&quot; becomes &quot;I give (.*) to (.*)&quot;, which matches
+ * &quot;I give £10 to Fred&quot;. The captured arguments will be &quot;£10&quot; 
+ * and &quot;Fred&quot;.</p>
+ * 
+ * <p>To create your own pattern builder, the text in the annotation should
+ * be converted to a pattern that matches a real step in the scenario with
+ * any precursor words removed. The arguments in the real step should
+ * be the only captured groups.</p>
  */
 public interface StepPatternBuilder {
 
+	/**
+	 * Builds a regexp pattern from a template step.
+	 * @param matchThis the template step
+	 * @return a regexp pattern which will capture the arguments associated with a matching real step
+	 */
     Pattern buildPattern(String matchThis);
 
 }

Modified: trunk/jbehave-core/src/java/org/jbehave/scenario/steps/Steps.java (876 => 877)

--- trunk/jbehave-core/src/java/org/jbehave/scenario/steps/Steps.java	2008-07-22 17:11:43 UTC (rev 876)
+++ trunk/jbehave-core/src/java/org/jbehave/scenario/steps/Steps.java	2008-07-24 12:53:56 UTC (rev 877)
@@ -14,7 +14,7 @@
     private final String[] startingWords;
 
     public Steps() {
-        this(new DollarStepPatternBuilder(), new SilentStepMonitor(), "Given", "When", "Then", "And");
+        this(new PrefixCapturingPatternBuilder(), new SilentStepMonitor(), "Given", "When", "Then", "And");
     }
 
     public Steps(StepPatternBuilder patternBuilder, StepMonitor monitor, String... startingWords) {


To unsubscribe from this list please visit:

http://xircles.codehaus.org/manage_email

Reply via email to