Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Core] Fix PrettyFormatter exception on nested arguments #1200

Merged
merged 3 commits into from
Aug 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java
Original file line number Diff line number Diff line change
Expand Up @@ -208,22 +208,28 @@ private void printStep(TestStep testStep, Result result) {
}

String formatStepText(String keyword, String stepText, Format textFormat, Format argFormat, List<Argument> arguments) {
int textStart = 0;
int beginIndex = 0;
StringBuilder result = new StringBuilder(textFormat.text(keyword));
for (Argument argument : arguments) {
// can be null if the argument is missing.
if (argument.getOffset() != null) {
String text = stepText.substring(textStart, argument.getOffset());
int argumentOffset = argument.getOffset();
// a nested argument starts before the enclosing argument ends; ignore it when formatting
if (argumentOffset < beginIndex ) {
continue;
}
String text = stepText.substring(beginIndex, argumentOffset);
result.append(textFormat.text(text));
}
// val can be null if the argument isn't there, for example @And("(it )?has something")
if (argument.getVal() != null) {
result.append(argFormat.text(argument.getVal()));
textStart = argument.getOffset() + argument.getVal().length();
// set beginIndex to end of argument
beginIndex = argument.getOffset() + argument.getVal().length();
}
}
if (textStart != stepText.length()) {
String text = stepText.substring(textStart, stepText.length());
if (beginIndex != stepText.length()) {
String text = stepText.substring(beginIndex, stepText.length());
result.append(textFormat.text(text));
}
return result.toString();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ public void canHandleVariableNumberOfArguments() {
assertNull(matcher.argumentsFrom("I wait for some time").get(0).getVal());
}

@Test
public void canHandleNestedCaptureGroups() throws UnsupportedEncodingException {
assertVariables("the order is placed( and( not yet)? confirmed)?", "the order is placed and not yet confirmed",
" and not yet confirmed", 19,
" not yet", 23);
}

private void assertVariables(String regex, String string, String v1, Integer pos1, String v2, Integer pos2) throws UnsupportedEncodingException {
List<Argument> args = new JdkPatternArgumentMatcher(Pattern.compile(regex)).argumentsFrom(string);
assertEquals(2, args.size());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class PrettyFormatterTest {
Expand Down Expand Up @@ -50,7 +51,7 @@ public void should_align_the_indentation_of_location_strings() throws Throwable
}

@Test
public void should_handle_backgound() throws Throwable {
public void should_handle_background() throws Throwable {
CucumberFeature feature = feature("path/test.feature", "" +
"Feature: feature name\n" +
" Background: background name\n" +
Expand Down Expand Up @@ -366,7 +367,7 @@ public void should_color_code_error_message_according_to_the_result() throws Thr
}

@Test
public void should_mark_arguments_in_steps() throws Throwable {
public void should_mark_subsequent_arguments_in_steps() throws Throwable {
Formats formats = new AnsiFormats();
Argument arg1 = new Argument(5, "arg1");
Argument arg2 = new Argument(15, "arg2");
Expand All @@ -381,6 +382,35 @@ public void should_mark_arguments_in_steps() throws Throwable {
AnsiEscapes.GREEN + AnsiEscapes.INTENSITY_BOLD + "arg2" + AnsiEscapes.RESET));
}

@Test
public void should_mark_nested_argument_as_part_of_full_argument(){
Formats formats = new AnsiFormats();
Argument enclosingArg = new Argument(19, " and not yet confirmed");
Argument nestedArg = new Argument(23, " not yet ");
PrettyFormatter prettyFormatter = new PrettyFormatter(null);

String formattedText = prettyFormatter.formatStepText("Given ", "the order is placed and not yet confirmed", formats.get("passed"), formats.get("passed_arg"), asList(enclosingArg, nestedArg));

assertThat(formattedText, equalTo(AnsiEscapes.GREEN + "Given " + AnsiEscapes.RESET +
AnsiEscapes.GREEN + "the order is placed" + AnsiEscapes.RESET +
AnsiEscapes.GREEN + AnsiEscapes.INTENSITY_BOLD + " and not yet confirmed" + AnsiEscapes.RESET));
}

@Test
public void should_mark_nested_arguments_as_part_of_enclosing_argument(){
Formats formats = new AnsiFormats();
Argument enclosingArg = new Argument(19, " and not yet confirmed");
Argument nestedArg = new Argument(23, " not yet ");
Argument nestedNestedArg = new Argument(27, "yet ");
PrettyFormatter prettyFormatter = new PrettyFormatter(null);

String formattedText = prettyFormatter.formatStepText("Given ", "the order is placed and not yet confirmed", formats.get("passed"), formats.get("passed_arg"), asList(enclosingArg, nestedArg, nestedNestedArg));

assertThat(formattedText, equalTo(AnsiEscapes.GREEN + "Given " + AnsiEscapes.RESET +
AnsiEscapes.GREEN + "the order is placed" + AnsiEscapes.RESET +
AnsiEscapes.GREEN + AnsiEscapes.INTENSITY_BOLD + " and not yet confirmed" + AnsiEscapes.RESET));
}

private String runFeatureWithPrettyFormatter(final CucumberFeature feature, final Map<String, String> stepsToLocation) throws Throwable {
return runFeatureWithPrettyFormatter(feature, stepsToLocation, Collections.<String, Result>emptyMap());
}
Expand Down