From 5b653173f99085196843f48bdf40d64ccb42113a Mon Sep 17 00:00:00 2001 From: maritvandijk Date: Sat, 12 Aug 2017 04:20:20 +0200 Subject: [PATCH 1/3] Fix PrettyFormatter exception on nested arguments --- .../runtime/formatter/PrettyFormatter.java | 16 ++++++--- .../JdkPatternArgumentMatcherTest.java | 7 ++++ .../formatter/PrettyFormatterTest.java | 34 +++++++++++++++++-- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java b/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java index 504b81dbb5..c6a8a0056b 100644 --- a/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java +++ b/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java @@ -208,22 +208,28 @@ private void printStep(TestStep testStep, Result result) { } String formatStepText(String keyword, String stepText, Format textFormat, Format argFormat, List 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 argumentgit + 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(); diff --git a/core/src/test/java/cucumber/runtime/JdkPatternArgumentMatcherTest.java b/core/src/test/java/cucumber/runtime/JdkPatternArgumentMatcherTest.java index a8654ecdbe..b67905fa76 100644 --- a/core/src/test/java/cucumber/runtime/JdkPatternArgumentMatcherTest.java +++ b/core/src/test/java/cucumber/runtime/JdkPatternArgumentMatcherTest.java @@ -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 args = new JdkPatternArgumentMatcher(Pattern.compile(regex)).argumentsFrom(string); assertEquals(2, args.size()); diff --git a/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java b/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java index 7512fd049b..0ef709d9c3 100755 --- a/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java @@ -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 { @@ -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" + @@ -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"); @@ -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(20, "and not yet confirmed"); + Argument nestedArg = new Argument(-17, "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(20, "and not yet confirmed"); + Argument nestedArg = new Argument(-17, "not yet "); + Argument nestedNestedArg = new Argument(-5, "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 stepsToLocation) throws Throwable { return runFeatureWithPrettyFormatter(feature, stepsToLocation, Collections.emptyMap()); } From 70c6c370ec00d350aa1612bc5151a58c1b0074d5 Mon Sep 17 00:00:00 2001 From: maritvandijk Date: Sun, 20 Aug 2017 21:41:46 +0200 Subject: [PATCH 2/3] Fix PrettyFormatter nested arguments --- .../runtime/formatter/PrettyFormatterTest.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java b/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java index 0ef709d9c3..b2e4a85442 100755 --- a/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java +++ b/core/src/test/java/cucumber/runtime/formatter/PrettyFormatterTest.java @@ -385,30 +385,30 @@ public void should_mark_subsequent_arguments_in_steps() throws Throwable { @Test public void should_mark_nested_argument_as_part_of_full_argument(){ Formats formats = new AnsiFormats(); - Argument enclosingArg = new Argument(20, "and not yet confirmed"); - Argument nestedArg = new Argument(-17, "not yet "); + 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)); + 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(20, "and not yet confirmed"); - Argument nestedArg = new Argument(-17, "not yet "); - Argument nestedNestedArg = new Argument(-5, "yet "); + 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)); + 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 stepsToLocation) throws Throwable { From d1e6c231650e72a42cd2e13e891a1de0155a783a Mon Sep 17 00:00:00 2001 From: maritvandijk Date: Sun, 20 Aug 2017 21:44:56 +0200 Subject: [PATCH 3/3] Fix PrettyFormatter nested arguments --- .../main/java/cucumber/runtime/formatter/PrettyFormatter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java b/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java index c6a8a0056b..33d6ed196d 100644 --- a/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java +++ b/core/src/main/java/cucumber/runtime/formatter/PrettyFormatter.java @@ -224,7 +224,7 @@ String formatStepText(String keyword, String stepText, Format textFormat, Format // 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())); - // set beginIndex to end of argumentgit + // set beginIndex to end of argument beginIndex = argument.getOffset() + argument.getVal().length(); } }