package org.jbehave.core.parsers;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import org.jbehave.core.steps.StepType;
import org.junit.Test;
public class RegexPrefixCapturingPatternParserBehaviour {
private StepPatternParser parser = new RegexPrefixCapturingPatternParser();
@Test
public void shouldMatchStepWithPatterns() {
assertThatPatternMatchesStep(parser, "a house with $numberOfDoors doors and $some windows",
"a house with 3 doors and 4 windows", true, "numberOfDoors", "some");
assertThatPatternMatchesStep(parser, "the house on $street", "the house on Easy Street", true, "street");
assertThatPatternMatchesStep(parser, "$number houses", "5 houses", true, "number");
assertThatPatternMatchesStep(parser, "my house", "my house", true);
assertThatPatternMatchesStep(parser, "I toggle the cell at ( $column , $row )",
"I toggle the cell at ( 3 , 4 )", true, "column", "row");
assertThatPatternMatchesStep(parser, "$name should ask, \"Why?\"", "Fred should ask, \"Why?\"", true, "name");
assertThatPatternMatchesStep(parser, "$thousands x 10^3", "2 x 10^3", true, "thousands");
}
@Test
public void shouldMatchStepWithPatternsUsingUnderscoresInParameterNames() {
assertThatPatternMatchesStep(parser, "a house with $number_of_1st_floor_doors doors and $facing_to windows",
"a house with 3 doors and 4 windows", true, "number_of_1st_floor_doors", "facing_to");
}
@Test
public void shouldMatchStepWithPatternsUsingNumbersInParameterNames() {
assertThatPatternMatchesStep(parser, "a house with $numberOf1stFloorDoors doors and $facing2 windows",
"a house with 3 doors and 4 windows", true, "numberOf1stFloorDoors", "facing2");
}
@Test
public void shouldMatchStepWithPatternsUsingAccentsInParameterNames() {
assertThatPatternMatchesStep(parser, "une maison avec $numérosDesPortes portes et $quelques fenêtres",
"une maison avec 3 portes et 4 fenêtres", true, "numérosDesPortes", "quelques");
assertThatPatternMatchesStep(parser, "ein Haus mit $anzahlDerTüren Türen und $einige Fenster",
"ein Haus mit 3 Türen und 4 Fenster", true, "anzahlDerTüren", "einige");
}
@Test
public void shouldMatchStepWithPatternsUsingCustomPrefix() {
RegexPrefixCapturingPatternParser parser = new RegexPrefixCapturingPatternParser("%");
assertThat(parser.getPrefix(), equalTo("%"));
assertThat(parser.toString(), containsString("prefix=%"));
assertThatPatternMatchesStep(parser, "a house with %numberOfDoors doors and %some windows",
"a house with 3 doors and 4 windows", true, "numberOfDoors", "some");
assertThatPatternMatchesStep(parser, "the house on %street", "the house on Easy Street", true, "street");
assertThatPatternMatchesStep(parser, "%number houses", "5 houses", true, "number");
assertThatPatternMatchesStep(parser, "my house", "my house", true);
assertThatPatternMatchesStep(parser, "I toggle the cell at ( %column , %row )",
"I toggle the cell at ( 3 , 4 )", true, "column", "row");
assertThatPatternMatchesStep(parser, "%name should ask, \"Why?\"", "Fred should ask, \"Why?\"", true, "name");
assertThatPatternMatchesStep(parser, "%thousands x 10^3", "2 x 10^3", true, "thousands");
}
@Test
public void shouldMatchStepWithPatternsUsingCustomCharacterClass() {
RegexPrefixCapturingPatternParser parserAllowingOnlyLettersInParameterNames = new RegexPrefixCapturingPatternParser("$", "[\\p{L}]");
assertThatPatternMatchesStep(parserAllowingOnlyLettersInParameterNames, "a house with $numberOfFirstFloorDoors doors and $facing windows",
"a house with 3 doors and 4 windows", true, "numberOfFirstFloorDoors", "facing");
assertThatPatternMatchesStep(parserAllowingOnlyLettersInParameterNames, "a house with $numberOf1stFloorDoors doors and $facing2 windows",
"a house with 3 doors and 4 windows", false);
}
@Test
public void shouldEscapeRegexPunctuationUsedInPatterns() {
StepMatcher matcherWithAllTheRegexPunctuation = parser
.parseStep(StepType.GIVEN, "$regexp should not be confused by []{}?^.*()+\\");
assertThat(matcherWithAllTheRegexPunctuation.matches("[]{}?^.*()+\\ should not be confused by []{}?^.*()+\\"),
is(true));
assertThat(matcherWithAllTheRegexPunctuation.parameter(1), equalTo("[]{}?^.*()+\\"));
}
@Test
public void shouldMatchStepWithPatternContainingRegexPunctuation() {
assertThatPatternMatchesStep(parser, "a house with no. $number",
"a house with no. 3", true, "number");
assertThatPatternMatchesStep(parser, "a hotel with $number *",
"a hotel with 3 *", true, "number");
}
private void assertThatPatternMatchesStep(StepPatternParser parser, String pattern, String step,
boolean matching, String... parameterNames) {
StepMatcher stepMatcher = parser.parseStep(StepType.GIVEN, pattern);
assertThat(stepMatcher.matches(step), is(matching));
assertThat(stepMatcher.parameterNames(), equalTo(parameterNames));
}
@Test
public void shouldNotCareSoMuchAboutWhitespace() {
StepMatcher stepMatcher = parser.parseStep(StepType.GIVEN, "The grid looks like $grid");
// Given an argument on a new line
assertThat(stepMatcher.matches("The grid looks like\n" + "..\n" + "..\n"), is(true));
assertThat(stepMatcher.parameter(1), equalTo("..\n" + "..\n"));
// Given an argument on a new line with extra spaces
assertThat(stepMatcher.matches("The grid looks like \n" + "..\n" + "..\n"), is(true));
assertThat(stepMatcher.parameter(1), equalTo("..\n" + "..\n"));
// Given an argument with extra spaces
assertThat(stepMatcher.matches("The grid looks like ."), is(true));
assertThat(stepMatcher.parameter(1), equalTo("."));
}
@Test
public void shouldExtractParameterNamesFromStepPattern() {
String[] names = parser.parseStep(StepType.GIVEN, "The grid $name looks like $grid").parameterNames();
assertThat(names.length, equalTo(2));
assertThat(names[0], equalTo("name"));
assertThat(names[1], equalTo("grid"));
}
@Test
public void shouldExtractParameterNamesWithoutQuotes() {
String[] names = parser.parseStep(StepType.GIVEN, "The grid \"$name\" looks like \"$grid\"").parameterNames();
assertThat(names.length, equalTo(2));
assertThat(names[0], equalTo("name"));
assertThat(names[1], equalTo("grid"));
}
}