diff --git a/CHANGELOG.md b/CHANGELOG.md index 7636a6aae9..ebdc7f6571 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,13 +11,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/). * [Core] Warn when glue path is passed as file scheme instead of classpath ([#2547](https://github.com/cucumber/cucumber-jvm/pull/2547) M.P. Korstanje) ### Changed +* [Core] Flush pretty output manually ([#2573](https://github.com/cucumber/cucumber-jvm/pull/2573) M.P. Korstanje) ### Deprecated ### Removed ### Fixed -* [Spring] Cleanly stop after failure to start application context +* [Spring] Cleanly stop after failure to start application context ([#2570](https://github.com/cucumber/cucumber-jvm/pull/2570) M.P. Korstanje) +* [JUnit] Scenario logging does not show up in step notifications ([#2563](https://github.com/cucumber/cucumber-jvm/pull/2545) M.P. Korstanje) ## [7.3.4] (2022-05-02) diff --git a/core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java b/core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java index 3871d25b7f..61ef287bb3 100644 --- a/core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java +++ b/core/src/main/java/io/cucumber/core/plugin/AnsiEscapes.java @@ -30,10 +30,6 @@ static AnsiEscapes up(int count) { return new AnsiEscapes(count + "A"); } - void appendTo(NiceAppendable a) { - a.append(ESC).append(BRACKET).append(value); - } - @Override public String toString() { StringBuilder sb = new StringBuilder(); diff --git a/core/src/main/java/io/cucumber/core/plugin/MessageFormatter.java b/core/src/main/java/io/cucumber/core/plugin/MessageFormatter.java index 865add861e..5fbc096590 100644 --- a/core/src/main/java/io/cucumber/core/plugin/MessageFormatter.java +++ b/core/src/main/java/io/cucumber/core/plugin/MessageFormatter.java @@ -25,7 +25,6 @@ private void writeMessage(Envelope envelope) { try { Jackson.OBJECT_MAPPER.writeValue(writer, envelope); writer.write("\n"); - writer.flush(); if (envelope.getTestRunFinished().isPresent()) { writer.close(); } diff --git a/core/src/main/java/io/cucumber/core/plugin/NiceAppendable.java b/core/src/main/java/io/cucumber/core/plugin/NiceAppendable.java deleted file mode 100644 index 0dded5f9c5..0000000000 --- a/core/src/main/java/io/cucumber/core/plugin/NiceAppendable.java +++ /dev/null @@ -1,96 +0,0 @@ -package io.cucumber.core.plugin; - -import java.io.Closeable; -import java.io.Flushable; -import java.io.IOException; - -/** - * A nice appendable that doesn't throw checked exceptions - */ -final class NiceAppendable implements Appendable { - - private static final CharSequence NL = "\n"; - private final Appendable out; - private final boolean flushEveryWrite; - - public NiceAppendable(Appendable out) { - this(out, false); - } - - public NiceAppendable(Appendable out, boolean flushEveryWrite) { - this.out = out; - this.flushEveryWrite = flushEveryWrite; - } - - public NiceAppendable println() { - return append(NL); - } - - public NiceAppendable append(CharSequence csq) { - try { - out.append(csq); - tryFlush(); - return this; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public NiceAppendable append(CharSequence csq, int start, int end) { - try { - out.append(csq, start, end); - tryFlush(); - return this; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public NiceAppendable append(char c) { - try { - out.append(c); - tryFlush(); - return this; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - private void tryFlush() { - if (!(out instanceof Flushable)) { - return; - } - - if (!flushEveryWrite) { - return; - } - - try { - ((Flushable) out).flush(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public NiceAppendable println(CharSequence csq) { - try { - out.append(csq).append(NL); - tryFlush(); - return this; - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - public void close() { - try { - tryFlush(); - if (out instanceof Closeable) { - ((Closeable) out).close(); - } - } catch (IOException e) { - throw new RuntimeException(e); - } - } - -} diff --git a/core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java b/core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java index ad64d8132d..7c65a33e63 100644 --- a/core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java +++ b/core/src/main/java/io/cucumber/core/plugin/PrettyFormatter.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.IOException; import java.io.OutputStream; +import java.io.PrintWriter; import java.io.StringReader; import java.net.URI; import java.net.URISyntaxException; @@ -37,6 +38,12 @@ import static java.lang.Math.max; import static java.util.Locale.ROOT; +/** + * Prints a pretty report of the scenario execution as it happens. + *

+ * When scenarios are executed concurrently the output will interleave. This is + * to be expected. + */ public final class PrettyFormatter implements ConcurrentEventListener, ColorAware { private static final String SCENARIO_INDENT = ""; @@ -45,11 +52,11 @@ public final class PrettyFormatter implements ConcurrentEventListener, ColorAwar private final Map commentStartIndex = new HashMap<>(); - private final NiceAppendable out; + private final PrintWriter out; private Formats formats = ansi(); public PrettyFormatter(OutputStream out) { - this.out = new NiceAppendable(new UTF8OutputStreamWriter(out)); + this.out = new UTF8PrintWriter(out); } @Override @@ -66,25 +73,27 @@ private void handleTestCaseStarted(TestCaseStarted event) { preCalculateLocationIndent(event); printTags(event); printScenarioDefinition(event); + out.flush(); } private void handleTestStepFinished(TestStepFinished event) { printStep(event); printError(event); + out.flush(); } private void handleWrite(WriteEvent event) { out.println(); printText(event); out.println(); - + out.flush(); } private void handleEmbed(EmbedEvent event) { out.println(); printEmbedding(event); out.println(); - + out.flush(); } private void handleTestRunFinished(TestRunFinished event) { @@ -188,9 +197,8 @@ private void printText(WriteEvent event) { while ((line = lines.readLine()) != null) { builder.append(STEP_SCENARIO_INDENT) .append(line) - .append(System.lineSeparator()); // Add system line - // separator - \n won't - // do it! + // Add system line separator - \n won't do it! + .append(System.lineSeparator()); } } catch (IOException e) { throw new CucumberException(e); diff --git a/core/src/main/java/io/cucumber/core/plugin/ProgressFormatter.java b/core/src/main/java/io/cucumber/core/plugin/ProgressFormatter.java index 3843393c1c..6ba1c2986e 100644 --- a/core/src/main/java/io/cucumber/core/plugin/ProgressFormatter.java +++ b/core/src/main/java/io/cucumber/core/plugin/ProgressFormatter.java @@ -9,6 +9,7 @@ import io.cucumber.plugin.event.TestStepFinished; import java.io.OutputStream; +import java.io.PrintWriter; import java.util.HashMap; import java.util.Map; @@ -35,13 +36,11 @@ public final class ProgressFormatter implements ConcurrentEventListener, ColorAw } }; - private final NiceAppendable out; + private final PrintWriter out; private boolean monochrome = false; public ProgressFormatter(OutputStream out) { - // Configure the NiceAppendable to flush on every append, since the - // point of this formatter is to display a progress bar. - this.out = new NiceAppendable(new UTF8OutputStreamWriter(out), true); + this.out = new UTF8PrintWriter(out); } @Override @@ -71,6 +70,7 @@ private void handleTestStepFinished(TestStepFinished event) { AnsiEscapes.RESET.appendTo(buffer); } out.append(buffer); + out.flush(); } private void handleTestRunFinished(TestRunFinished testRunFinished) { diff --git a/core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java b/core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java index b487fa76e2..522ec827a6 100644 --- a/core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java +++ b/core/src/main/java/io/cucumber/core/plugin/RerunFormatter.java @@ -8,6 +8,7 @@ import io.cucumber.plugin.event.TestRunFinished; import java.io.OutputStream; +import java.io.PrintWriter; import java.net.URI; import java.util.ArrayList; import java.util.Collection; @@ -16,6 +17,7 @@ import static io.cucumber.core.feature.FeatureWithLines.create; import static io.cucumber.core.plugin.PrettyFormatter.relativize; +import static java.nio.charset.StandardCharsets.UTF_8; /** * Formatter for reporting all failed test cases and print their locations @@ -23,11 +25,11 @@ */ public final class RerunFormatter implements ConcurrentEventListener { - private final NiceAppendable out; + private final PrintWriter out; private final Map> featureAndFailedLinesMapping = new HashMap<>(); public RerunFormatter(OutputStream out) { - this.out = new NiceAppendable(new UTF8OutputStreamWriter(out)); + this.out = new PrintWriter(out, false, UTF_8); } @Override diff --git a/core/src/main/java/io/cucumber/core/plugin/UTF8PrintWriter.java b/core/src/main/java/io/cucumber/core/plugin/UTF8PrintWriter.java new file mode 100644 index 0000000000..e71bbf268a --- /dev/null +++ b/core/src/main/java/io/cucumber/core/plugin/UTF8PrintWriter.java @@ -0,0 +1,13 @@ +package io.cucumber.core.plugin; + +import java.io.OutputStream; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; + +final class UTF8PrintWriter extends PrintWriter { + + UTF8PrintWriter(OutputStream out) { + super(out, false, StandardCharsets.UTF_8); + } + +} diff --git a/core/src/main/java/io/cucumber/core/plugin/UnusedStepsSummaryPrinter.java b/core/src/main/java/io/cucumber/core/plugin/UnusedStepsSummaryPrinter.java index 637ae52654..3130a6f322 100644 --- a/core/src/main/java/io/cucumber/core/plugin/UnusedStepsSummaryPrinter.java +++ b/core/src/main/java/io/cucumber/core/plugin/UnusedStepsSummaryPrinter.java @@ -9,6 +9,7 @@ import io.cucumber.plugin.event.TestStepFinished; import java.io.OutputStream; +import java.io.PrintWriter; import java.util.Map; import java.util.Map.Entry; import java.util.Set; @@ -23,11 +24,11 @@ public final class UnusedStepsSummaryPrinter implements ColorAware, ConcurrentEv private final Map registeredSteps = new TreeMap<>(); private final Set usedSteps = new TreeSet<>(); - private final NiceAppendable out; + private final PrintWriter out; private Formats formats = ansi(); public UnusedStepsSummaryPrinter(OutputStream out) { - this.out = new NiceAppendable(new UTF8OutputStreamWriter(out)); + this.out = new UTF8PrintWriter(out); } @Override diff --git a/core/src/test/java/io/cucumber/core/plugin/NiceAppendableTest.java b/core/src/test/java/io/cucumber/core/plugin/NiceAppendableTest.java deleted file mode 100644 index 0269503189..0000000000 --- a/core/src/test/java/io/cucumber/core/plugin/NiceAppendableTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package io.cucumber.core.plugin; - -import org.junit.jupiter.api.Test; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStreamWriter; - -import static io.cucumber.core.plugin.BytesEqualTo.isBytesEqualTo; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -class NiceAppendableTest { - - @Test - public void should_flush_every_call_if_configured() throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutputStreamWriter writer = spy(new OutputStreamWriter(out)); - NiceAppendable appendable = new NiceAppendable(writer, true); - - appendable - .append("First String,") - .append("__Second String__", 2, 15) - .append("\n") - .println("Second line") - .println() - .close(); - - assertThat(out, isBytesEqualTo("First String,Second String\nSecond line\n\n")); - verify(writer, times(6)).flush(); // Each method call flushes - } - - @Test - public void should_not_flush_unless_configured() throws IOException { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - OutputStreamWriter writer = spy(new OutputStreamWriter(out)); - NiceAppendable appendable = new NiceAppendable(writer); - - appendable - .append("First String,") - .append("__Second String__", 2, 15) - .append("\n") - .println("Second line") - .println() - .close(); - - assertThat(out, isBytesEqualTo("First String,Second String\nSecond line\n\n")); - verify(writer, times(0)).flush(); - } - -} diff --git a/core/src/test/java/io/cucumber/core/plugin/PluginFactoryTest.java b/core/src/test/java/io/cucumber/core/plugin/PluginFactoryTest.java index 82c6e40395..21f8a24435 100644 --- a/core/src/test/java/io/cucumber/core/plugin/PluginFactoryTest.java +++ b/core/src/test/java/io/cucumber/core/plugin/PluginFactoryTest.java @@ -17,12 +17,12 @@ import io.cucumber.plugin.event.TestRunStarted; import io.cucumber.plugin.event.TestStepFinished; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.function.Executable; import org.junit.jupiter.api.io.TempDir; import java.io.ByteArrayOutputStream; +import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.OutputStream; @@ -208,7 +208,7 @@ void plugin_does_not_buffer_its_output() { void instantiates_single_custom_appendable_plugin_with_stdout() { PluginOption option = parse(WantsOutputStream.class.getName()); WantsOutputStream plugin = (WantsOutputStream) fc.create(option); - assertThat(plugin.printStream, is(not(nullValue()))); + assertThat(plugin.out, is(not(nullValue()))); CucumberException exception = assertThrows(CucumberException.class, () -> fc.create(option)); assertThat(exception.getMessage(), is(equalTo( @@ -298,10 +298,10 @@ void fails_to_instantiate_plugin_that_declares_two_single_arg_constructors_when_ public static class WantsOutputStream extends StubFormatter { - public OutputStream printStream; + public OutputStream out; - public WantsOutputStream(OutputStream outputStream) { - this.printStream = Objects.requireNonNull(outputStream); + public WantsOutputStream(OutputStream out) { + this.out = Objects.requireNonNull(out); } } @@ -353,15 +353,18 @@ public WantsString(String arg) { public static class WantsAppendable extends StubFormatter { - public final NiceAppendable arg; + public final Appendable out; - public WantsAppendable(Appendable arg) { - this.arg = new NiceAppendable(Objects.requireNonNull(arg)); + public WantsAppendable(Appendable out) { + this.out = Objects.requireNonNull(out); } - public void writeAndClose(String s) { - this.arg.println(s); - this.arg.close(); + public void writeAndClose(String s) throws IOException { + out.append(s); + if (out instanceof Closeable) { + Closeable closeable = (Closeable) out; + closeable.close(); + } } } diff --git a/core/src/test/java/io/cucumber/core/plugin/ProgressFormatterTest.java b/core/src/test/java/io/cucumber/core/plugin/ProgressFormatterTest.java index 2aa184ea19..fbe1dfda23 100644 --- a/core/src/test/java/io/cucumber/core/plugin/ProgressFormatterTest.java +++ b/core/src/test/java/io/cucumber/core/plugin/ProgressFormatterTest.java @@ -37,49 +37,51 @@ void setup() { @Test void prints_empty_line_for_empty_test_run() { - Result runResult = new Result(PASSED, Duration.ZERO, null); - bus.send(new TestRunFinished(Instant.now(), runResult)); + Result result = new Result(PASSED, Duration.ZERO, null); + bus.send(new TestRunFinished(Instant.now(), result)); assertThat(out, isBytesEqualTo("\n")); } @Test - void print_green_dot_for_passing_step() { + void prints_empty_line_and_green_dot_for_passing_test_run() { Result result = new Result(PASSED, Duration.ZERO, null); bus.send(new TestStepFinished(Instant.now(), mock(TestCase.class), mock(PickleStepTestStep.class), result)); bus.send(new TestRunFinished(Instant.now(), result)); assertThat(out, isBytesEqualTo(AnsiEscapes.GREEN + "." + AnsiEscapes.RESET + "\n")); } + @Test + void print_green_dot_for_passing_step() { + Result result = new Result(PASSED, Duration.ZERO, null); + bus.send(new TestStepFinished(Instant.now(), mock(TestCase.class), mock(PickleStepTestStep.class), result)); + assertThat(out, isBytesEqualTo(AnsiEscapes.GREEN + "." + AnsiEscapes.RESET)); + } + @Test void print_yellow_U_for_undefined_step() { Result result = new Result(UNDEFINED, Duration.ZERO, null); bus.send(new TestStepFinished(Instant.now(), mock(TestCase.class), mock(PickleStepTestStep.class), result)); - bus.send(new TestRunFinished(Instant.now(), result)); - assertThat(out, isBytesEqualTo(AnsiEscapes.YELLOW + "U" + AnsiEscapes.RESET + "\n")); + assertThat(out, isBytesEqualTo(AnsiEscapes.YELLOW + "U" + AnsiEscapes.RESET)); } @Test void print_nothing_for_passed_hook() { Result result = new Result(PASSED, Duration.ZERO, null); bus.send(new TestStepFinished(Instant.now(), mock(TestCase.class), mock(HookTestStep.class), result)); - bus.send(new TestRunFinished(Instant.now(), result)); - assertThat(out, isBytesEqualTo("\n")); } @Test void print_red_F_for_failed_step() { Result result = new Result(FAILED, Duration.ZERO, null); bus.send(new TestStepFinished(Instant.now(), mock(TestCase.class), mock(PickleStepTestStep.class), result)); - bus.send(new TestRunFinished(Instant.now(), result)); - assertThat(out, isBytesEqualTo(AnsiEscapes.RED + "F" + AnsiEscapes.RESET + "\n")); + assertThat(out, isBytesEqualTo(AnsiEscapes.RED + "F" + AnsiEscapes.RESET)); } @Test void print_red_F_for_failed_hook() { Result result = new Result(FAILED, Duration.ZERO, null); bus.send(new TestStepFinished(Instant.now(), mock(TestCase.class), mock(HookTestStep.class), result)); - bus.send(new TestRunFinished(Instant.now(), result)); - assertThat(out, isBytesEqualTo(AnsiEscapes.RED + "F" + AnsiEscapes.RESET + "\n")); + assertThat(out, isBytesEqualTo(AnsiEscapes.RED + "F" + AnsiEscapes.RESET)); } } diff --git a/spring/src/test/java/io/cucumber/spring/SpringFactoryTest.java b/spring/src/test/java/io/cucumber/spring/SpringFactoryTest.java index 81e0f1c8db..34c4727922 100644 --- a/spring/src/test/java/io/cucumber/spring/SpringFactoryTest.java +++ b/spring/src/test/java/io/cucumber/spring/SpringFactoryTest.java @@ -61,10 +61,10 @@ void shouldGiveUsNewStepInstancesForEachScenario() { factory.stop(); assertAll( - () -> assertThat(o1, is(notNullValue())), - () -> assertThat(o2, is(notNullValue())), - () -> assertThat(o1, is(not(equalTo(o2)))), - () -> assertThat(o2, is(not(equalTo(o1))))); + () -> assertThat(o1, is(notNullValue())), + () -> assertThat(o2, is(notNullValue())), + () -> assertThat(o1, is(not(equalTo(o2)))), + () -> assertThat(o2, is(not(equalTo(o1))))); } @Test @@ -105,10 +105,10 @@ void shouldNeverCreateNewApplicationBeanInstances() { factory2.stop(); assertAll( - () -> assertThat(o1, is(notNullValue())), - () -> assertThat(o2, is(notNullValue())), - () -> assertThat(o1, is(equalTo(o1))), - () -> assertThat(o2, is(equalTo(o2)))); + () -> assertThat(o1, is(notNullValue())), + () -> assertThat(o2, is(notNullValue())), + () -> assertThat(o1, is(equalTo(o1))), + () -> assertThat(o2, is(equalTo(o2)))); } @Test @@ -128,10 +128,10 @@ void shouldNeverCreateNewApplicationBeanInstancesUsingMetaConfiguration() { factory2.stop(); assertAll( - () -> assertThat(o1, is(notNullValue())), - () -> assertThat(o2, is(notNullValue())), - () -> assertThat(o1, is(equalTo(o1))), - () -> assertThat(o2, is(equalTo(o2)))); + () -> assertThat(o1, is(notNullValue())), + () -> assertThat(o2, is(notNullValue())), + () -> assertThat(o1, is(equalTo(o1))), + () -> assertThat(o2, is(equalTo(o2)))); } @Test @@ -147,10 +147,10 @@ void shouldFindStepDefsCreatedImplicitlyForAutowiring() { factory1.stop(); assertAll( - () -> assertThat(o1.getThirdStepDef(), is(notNullValue())), - () -> assertThat(o2, is(notNullValue())), - () -> assertThat(o1.getThirdStepDef(), is(equalTo(o2))), - () -> assertThat(o2, is(equalTo(o1.getThirdStepDef())))); + () -> assertThat(o1.getThirdStepDef(), is(notNullValue())), + () -> assertThat(o2, is(notNullValue())), + () -> assertThat(o1.getThirdStepDef(), is(equalTo(o2))), + () -> assertThat(o2, is(equalTo(o1.getThirdStepDef())))); } @Test @@ -166,10 +166,10 @@ void shouldReuseStepDefsCreatedImplicitlyForAutowiring() { factory1.stop(); assertAll( - () -> assertThat(o1.getThirdStepDef(), is(notNullValue())), - () -> assertThat(o3.getThirdStepDef(), is(notNullValue())), - () -> assertThat(o1.getThirdStepDef(), is(equalTo(o3.getThirdStepDef()))), - () -> assertThat(o3.getThirdStepDef(), is(equalTo(o1.getThirdStepDef())))); + () -> assertThat(o1.getThirdStepDef(), is(notNullValue())), + () -> assertThat(o3.getThirdStepDef(), is(notNullValue())), + () -> assertThat(o1.getThirdStepDef(), is(equalTo(o3.getThirdStepDef()))), + () -> assertThat(o3.getThirdStepDef(), is(equalTo(o1.getThirdStepDef())))); } @Test @@ -213,10 +213,10 @@ void shouldRespectDirtiesContextAnnotationsInStepDefs() { factory.stop(); assertAll( - () -> assertThat(o1, is(notNullValue())), - () -> assertThat(o2, is(notNullValue())), - () -> assertThat(o1, is(not(equalTo(o2)))), - () -> assertThat(o2, is(not(equalTo(o1))))); + () -> assertThat(o1, is(notNullValue())), + () -> assertThat(o2, is(notNullValue())), + () -> assertThat(o1, is(not(equalTo(o2)))), + () -> assertThat(o2, is(not(equalTo(o1))))); } @Test @@ -236,10 +236,10 @@ void shouldRespectDirtiesContextAnnotationsInStepDefsUsingMetaConfiguration() { factory.stop(); assertAll( - () -> assertThat(o1, is(notNullValue())), - () -> assertThat(o2, is(notNullValue())), - () -> assertThat(o1, is(not(equalTo(o2)))), - () -> assertThat(o2, is(not(equalTo(o1))))); + () -> assertThat(o1, is(notNullValue())), + () -> assertThat(o2, is(notNullValue())), + () -> assertThat(o1, is(not(equalTo(o2)))), + () -> assertThat(o2, is(not(equalTo(o1))))); } @Test @@ -261,9 +261,9 @@ void shouldFailIfMultipleClassesWithSpringAnnotationsAreFound() { Executable testMethod = () -> factory.addClass(BellyStepDefinitions.class); CucumberBackendException actualThrown = assertThrows(CucumberBackendException.class, testMethod); assertThat(actualThrown.getMessage(), startsWith( - "Glue class class io.cucumber.spring.contextconfig.BellyStepDefinitions and class io.cucumber.spring.SpringFactoryTest$WithSpringAnnotations are both annotated with @CucumberContextConfiguration.\n" - + - "Please ensure only one class configures the spring context")); + "Glue class class io.cucumber.spring.contextconfig.BellyStepDefinitions and class io.cucumber.spring.SpringFactoryTest$WithSpringAnnotations are both annotated with @CucumberContextConfiguration.\n" + + + "Please ensure only one class configures the spring context")); } @Test @@ -273,7 +273,7 @@ void shouldFailIfClassWithSpringComponentAnnotationsIsFound() { Executable testMethod = () -> factory.addClass(WithComponentAnnotation.class); CucumberBackendException actualThrown = assertThrows(CucumberBackendException.class, testMethod); assertThat(actualThrown.getMessage(), is(equalTo( - "Glue class io.cucumber.spring.componentannotation.WithComponentAnnotation was annotated with @Component; marking it as a candidate for auto-detection by Spring. Glue classes are detected and registered by Cucumber. Auto-detection of glue classes by spring may lead to duplicate bean definitions. Please remove the @Component annotation"))); + "Glue class io.cucumber.spring.componentannotation.WithComponentAnnotation was annotated with @Component; marking it as a candidate for auto-detection by Spring. Glue classes are detected and registered by Cucumber. Auto-detection of glue classes by spring may lead to duplicate bean definitions. Please remove the @Component annotation"))); } @Test @@ -283,7 +283,7 @@ void shouldFailIfClassWithAnnotationAnnotatedWithSpringComponentAnnotationsIsFou Executable testMethod = () -> factory.addClass(WithControllerAnnotation.class); CucumberBackendException actualThrown = assertThrows(CucumberBackendException.class, testMethod); assertThat(actualThrown.getMessage(), is(equalTo( - "Glue class io.cucumber.spring.componentannotation.WithControllerAnnotation was annotated with @Controller; marking it as a candidate for auto-detection by Spring. Glue classes are detected and registered by Cucumber. Auto-detection of glue classes by spring may lead to duplicate bean definitions. Please remove the @Controller annotation"))); + "Glue class io.cucumber.spring.componentannotation.WithControllerAnnotation was annotated with @Controller; marking it as a candidate for auto-detection by Spring. Glue classes are detected and registered by Cucumber. Auto-detection of glue classes by spring may lead to duplicate bean definitions. Please remove the @Controller annotation"))); } @Test @@ -304,10 +304,10 @@ void shouldGlueScopedSpringBeanBehaveLikeGlueLifecycle() { factory.stop(); assertAll( - () -> assertThat(glueInstance1, is(not(glueInstance2))), - () -> assertThat(glueInstance2, is(not(glueInstance1))), - () -> assertThat(bellyInstance1, is(bellyInstance2)), - () -> assertThat(bellyInstance2, is(bellyInstance1))); + () -> assertThat(glueInstance1, is(not(glueInstance2))), + () -> assertThat(glueInstance2, is(not(glueInstance1))), + () -> assertThat(bellyInstance1, is(bellyInstance2)), + () -> assertThat(bellyInstance2, is(bellyInstance1))); } @Test @@ -331,7 +331,7 @@ void shouldBeStoppableWhenFacedWithInvalidConfiguration() { IllegalStateException exception = assertThrows(IllegalStateException.class, factory::start); assertThat(exception.getMessage(), - containsString("DelegatingSmartContextLoader was unable to detect defaults")); + containsString("DelegatingSmartContextLoader was unable to detect defaults")); assertDoesNotThrow(factory::stop); }