diff --git a/java-lambda/README.md b/java-lambda/README.md new file mode 100644 index 0000000000..8b3159ddcd --- /dev/null +++ b/java-lambda/README.md @@ -0,0 +1,35 @@ +Cucumber Java8 +============== + +Provides lambda based step definitions. To use add the `cucumber-java-lambda` dependency to your pom.xml: + +```xml + + [...] + + io.cucumber + cucumber-java-lambda + ${cucumber.version} + test + + [...] + +``` + +## Step Definitions + +## Hooks + +## Transformers + +### Parameter Type + +### Data Table Type + +#### Default Transformers + +#### Empty Cells + +#### Transposing Tables + +### DocString type diff --git a/java-lambda/pom.xml b/java-lambda/pom.xml new file mode 100644 index 0000000000..dca27604d6 --- /dev/null +++ b/java-lambda/pom.xml @@ -0,0 +1,80 @@ + + 4.0.0 + + + io.cucumber + cucumber-jvm + 7.3.3-SNAPSHOT + + + cucumber-java-lambda + jar + Cucumber-JVM: Java Lambda + + + io.cucumber.lambda + 1.1.2 + 5.8.2 + 0.6.3 + 3.22.0 + + + + + + io.cucumber + cucumber-bom + ${project.version} + pom + import + + + org.junit + junit-bom + ${junit-jupiter.version} + pom + import + + + + + + + io.cucumber + cucumber-core + + + org.apiguardian + apiguardian-api + ${apiguardian-api.version} + + + net.jodah + typetools + ${typetools.version} + + + + io.cucumber + cucumber-junit-platform-engine + test + + + org.junit.platform + junit-platform-suite + test + + + org.junit.jupiter + junit-jupiter + test + + + + org.assertj + assertj-core + ${assertj.version} + + + + diff --git a/java-lambda/src/main/java/io/cucumber/lambda/Invoker.java b/java-lambda/src/main/java/io/cucumber/lambda/Invoker.java new file mode 100644 index 0000000000..f7da075e98 --- /dev/null +++ b/java-lambda/src/main/java/io/cucumber/lambda/Invoker.java @@ -0,0 +1,30 @@ +package io.cucumber.lambda; + +import io.cucumber.core.backend.CucumberBackendException; +import io.cucumber.core.backend.CucumberInvocationTargetException; +import io.cucumber.core.backend.Located; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +final class Invoker { + + private Invoker() { + + } + + static Object invoke(Located located, Object target, Method method, Object... args) { + boolean accessible = method.canAccess(target); + try { + method.setAccessible(true); + return method.invoke(target, args); + } catch (IllegalArgumentException | IllegalAccessException e) { + throw new CucumberBackendException("Failed to invoke " + located.getLocation(), e); + } catch (InvocationTargetException e) { + throw new CucumberInvocationTargetException(located, e); + } finally { + method.setAccessible(accessible); + } + } + +} diff --git a/java-lambda/src/main/java/io/cucumber/lambda/StepDeclaration.java b/java-lambda/src/main/java/io/cucumber/lambda/StepDeclaration.java new file mode 100644 index 0000000000..8baeb54096 --- /dev/null +++ b/java-lambda/src/main/java/io/cucumber/lambda/StepDeclaration.java @@ -0,0 +1,77 @@ +package io.cucumber.lambda; + +import io.cucumber.core.backend.Located; +import io.cucumber.core.backend.SourceReference; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +import static io.cucumber.core.backend.SourceReference.fromStackTraceElement; +import static java.lang.String.format; +import static java.util.Objects.requireNonNull; + +class StepDeclaration implements Located { + private final String expression; + private final Class context; + private final StepDefinitionFunction function; + private final StackTraceElement location; + private SourceReference sourceReference; + + StepDeclaration(String expression, Class context, StepDefinitionFunction function, StackTraceElement location) { + this.expression = requireNonNull(expression, "expression should not be null"); + this.context = requireNonNull(context, "context should not be null"); + this.function = requireNonNull(function, "function should not be null"); + this.location = requireNonNull(location, "location should not be null"); + + } + + String getExpression() { + return expression; + } + + Class getContext() { + return context; + } + + @Override + public final boolean isDefinedAt(StackTraceElement stackTraceElement) { + return location.getFileName() != null && location.getFileName().equals(stackTraceElement.getFileName()); + } + + @Override + public Optional getSourceReference() { + if (sourceReference == null) { + sourceReference = fromStackTraceElement(location); + } + return Optional.of(sourceReference); + } + + @Override + public final String getLocation() { + return location.toString(); + } + + void invoke(Object contextInstance, Object[] arguments) { + Method acceptMethod = getAcceptMethod(function.getClass()); + Object body = Invoker.invoke(this, function, acceptMethod, contextInstance); + Method bodyAcceptMethod = getAcceptMethod(body.getClass()); + Invoker.invoke(this, body, bodyAcceptMethod, arguments); + } + + private Method getAcceptMethod(Class bodyClass) { + List acceptMethods = new ArrayList<>(); + for (Method method : bodyClass.getDeclaredMethods()) { + if (!method.isBridge() && !method.isSynthetic() && "accept".equals(method.getName())) { + acceptMethods.add(method); + } + } + if (acceptMethods.size() != 1) { + throw new IllegalStateException(format( + "Expected single 'accept' method on body class, found '%s'", acceptMethods)); + } + return acceptMethods.get(0); + } + +} diff --git a/java-lambda/src/main/java/io/cucumber/lambda/StepDefinitionFunction.java b/java-lambda/src/main/java/io/cucumber/lambda/StepDefinitionFunction.java new file mode 100644 index 0000000000..dcc1e44250 --- /dev/null +++ b/java-lambda/src/main/java/io/cucumber/lambda/StepDefinitionFunction.java @@ -0,0 +1,140 @@ +package io.cucumber.lambda; + +import org.apiguardian.api.API; + +import static org.apiguardian.api.API.Status.EXPERIMENTAL; + +@API(status = EXPERIMENTAL, since = "7.4.0") +public interface StepDefinitionFunction { + + @FunctionalInterface + interface C0A0 extends StepDefinitionFunction { + StepDefinitionBody.A0 accept(); + + } + + @FunctionalInterface + interface C1A0 extends StepDefinitionFunction { + StepDefinitionBody.A0 accept(Context context); + + } + + @FunctionalInterface + interface C1A1 extends StepDefinitionFunction { + StepDefinitionBody.A1 accept(Context context); + + } + + @FunctionalInterface + interface C1A2 extends StepDefinitionFunction { + StepDefinitionBody.A2 accept(Context context); + + } + + @FunctionalInterface + interface C1A3 extends StepDefinitionFunction { + StepDefinitionBody.A3 accept(Context context); + + } + + @FunctionalInterface + interface C1A4 extends StepDefinitionFunction { + StepDefinitionBody.A4 accept(Context context); + + } + + @FunctionalInterface + interface C1A5 extends StepDefinitionFunction { + StepDefinitionBody.A5 accept(Context context); + + } + + @FunctionalInterface + interface C1A6 extends StepDefinitionFunction { + StepDefinitionBody.A6 accept(Context context); + + } + + @FunctionalInterface + interface C1A7 extends StepDefinitionFunction { + StepDefinitionBody.A7 accept(Context context); + + } + + @FunctionalInterface + interface C1A8 extends StepDefinitionFunction { + StepDefinitionBody.A8 accept(Context context); + + } + + @FunctionalInterface + interface C1A9 extends StepDefinitionFunction { + StepDefinitionBody.A9 accept(Context context); + + } + + interface StepDefinitionBody { + + @FunctionalInterface + interface A0 extends StepDefinitionBody { + void accept() throws Throwable; + + } + + @FunctionalInterface + interface A1 extends StepDefinitionBody { + void accept(T1 t1) throws Throwable; + + } + + @FunctionalInterface + interface A2 extends StepDefinitionBody { + void accept(T1 t1, T2 t2) throws Throwable; + + } + + @FunctionalInterface + interface A3 extends StepDefinitionBody { + void accept(T1 t1, T2 t2, T3 t3) throws Throwable; + + } + + @FunctionalInterface + interface A4 extends StepDefinitionBody { + void accept(T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable; + + } + + @FunctionalInterface + interface A5 extends StepDefinitionBody { + void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) throws Throwable; + + } + + @FunctionalInterface + interface A6 extends StepDefinitionBody { + void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) throws Throwable; + + } + + @FunctionalInterface + interface A7 extends StepDefinitionBody { + void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) throws Throwable; + + } + + @FunctionalInterface + interface A8 extends StepDefinitionBody { + void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) throws Throwable; + + } + + @FunctionalInterface + interface A9 extends StepDefinitionBody { + void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) throws Throwable; + + } + + } + +} diff --git a/java-lambda/src/main/java/io/cucumber/lambda/StepDefinitions.java b/java-lambda/src/main/java/io/cucumber/lambda/StepDefinitions.java new file mode 100644 index 0000000000..550240c00a --- /dev/null +++ b/java-lambda/src/main/java/io/cucumber/lambda/StepDefinitions.java @@ -0,0 +1,132 @@ +package io.cucumber.lambda; + +import io.cucumber.lambda.StepDefinitionFunction.C1A0; +import io.cucumber.lambda.StepDefinitionFunction.C1A1; +import io.cucumber.lambda.StepDefinitionFunction.C1A2; +import io.cucumber.lambda.StepDefinitionFunction.C1A3; +import io.cucumber.lambda.StepDefinitionFunction.C1A4; +import io.cucumber.lambda.StepDefinitionFunction.C1A5; +import io.cucumber.lambda.StepDefinitionFunction.C1A6; +import io.cucumber.lambda.StepDefinitionFunction.C1A7; +import io.cucumber.lambda.StepDefinitionFunction.C1A8; +import io.cucumber.lambda.StepDefinitionFunction.C1A9; +import org.apiguardian.api.API; + +import java.util.ArrayList; +import java.util.List; + +import static org.apiguardian.api.API.Status.EXPERIMENTAL; + +@API(status = EXPERIMENTAL, since = "7.4.0") +public final class StepDefinitions { + + private final List stepDeclarations; + StepDefinitions(List stepDefinitions) { + this.stepDeclarations = stepDefinitions; + } + + List getStepDeclarations() { + return stepDeclarations; + } + + public static Builder using(Class context) { + return new Builder<>(context); + } + + public static final class Builder { + + private final List stepDefinitions = new ArrayList<>(); + private final Class context; + + Builder(Class context) { + this.context = context; + } + + public StepDefinitions build() { + return new StepDefinitions(stepDefinitions); + } + + public Builder step(String expression, C1A0 stepDefinitionFunction) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step(String expression, C1A1 stepDefinitionFunction) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step(String expression, C1A2 stepDefinitionFunction) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step( + String expression, + C1A3 stepDefinitionFunction + ) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step( + String expression, + C1A4 stepDefinitionFunction + ) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step( + String expression, + C1A5 stepDefinitionFunction + ) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step( + String expression, + C1A6 stepDefinitionFunction + ) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step( + String expression, + C1A7 stepDefinitionFunction + ) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step( + String expression, + C1A8 stepDefinitionFunction + ) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + public Builder step( + String expression, + C1A9 stepDefinitionFunction + ) { + StackTraceElement location = new Exception().getStackTrace()[1]; + stepDefinitions.add(new StepDeclaration(expression, context, stepDefinitionFunction, location)); + return this; + } + + } + +} diff --git a/java-lambda/src/test/java/io/cucumber/lambda/InvokerTest.java b/java-lambda/src/test/java/io/cucumber/lambda/InvokerTest.java new file mode 100644 index 0000000000..4c5b519766 --- /dev/null +++ b/java-lambda/src/test/java/io/cucumber/lambda/InvokerTest.java @@ -0,0 +1,65 @@ +package io.cucumber.lambda; + +import io.cucumber.core.backend.CucumberBackendException; +import io.cucumber.core.backend.CucumberInvocationTargetException; +import io.cucumber.core.backend.Located; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; + +import java.lang.reflect.Method; +import java.util.function.Function; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; + +class InvokerTest { + + final Located located = new Located() { + @Override + public boolean isDefinedAt(StackTraceElement stackTraceElement) { + return false; + } + + @Override + public String getLocation() { + return "io.cucumber.lambda.InvokerTest.example(InvokerTest.java:1)"; + } + }; + + final Function function = o -> o; + + final Method functionApply = getApplyMethod(function); + + @Test + void invokes() { + Object result = assertDoesNotThrow(() -> Invoker.invoke(located, function, functionApply, "Hello")); + assertThat(result).isEqualTo("Hello"); + } + + @Test + void complainsAboutArguments() { + Executable executable = () -> Invoker.invoke(located, function, functionApply); + CucumberBackendException exception = assertThrows(CucumberBackendException.class, executable); + assertThat(exception).hasMessage("Failed to invoke io.cucumber.lambda.InvokerTest.example(InvokerTest.java:1)"); + } + + @Test + void complainsAboutFailureInMethod() { + RuntimeException runtimeException = new RuntimeException("Oops"); + Function failingFunction = (Object ignored) -> { + throw runtimeException; + }; + Executable executable = () -> Invoker.invoke(located, failingFunction, getApplyMethod(failingFunction), "Hello"); + CucumberInvocationTargetException exception = assertThrows(CucumberInvocationTargetException.class, executable); + assertThat(exception.getInvocationTargetExceptionCause()).isSameAs(runtimeException); + } + + private static Method getApplyMethod(Function function) { + try { + return function.getClass().getMethod("apply", Object.class); + } catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + +} diff --git a/java-lambda/src/test/java/io/cucumber/lambda/StepDeclarationTest.java b/java-lambda/src/test/java/io/cucumber/lambda/StepDeclarationTest.java new file mode 100644 index 0000000000..5e8f4322ae --- /dev/null +++ b/java-lambda/src/test/java/io/cucumber/lambda/StepDeclarationTest.java @@ -0,0 +1,203 @@ +package io.cucumber.lambda; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static io.cucumber.lambda.StepDefinitions.using; +import static java.util.Objects.requireNonNull; +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; + +public class StepDeclarationTest { + + // @formatter:off + final StepDefinitions allStepDefinitions = using(World.class) + .step("0 arguments", + (World world) + -> () + -> world.zero()) + .step("1 arguments {int}", + (World world) -> (Integer one) + -> world.one(one)) + .step("2 arguments {int}, {int}", + (World world) + -> (Integer one, Integer two) + -> world.two(one, two)) + .step("3 arguments {int}, {int}, {int}", + (World world) + -> (Integer one, Integer two, Integer three) + -> world.three(one, two, three)) + .step("4 arguments {int}, {int}, {int}, {int}", + (World world) + -> (Integer one, Integer two, Integer three, Integer four) + -> world.four(one, two, three, four)) + .step("5 arguments {int}, {int}, {int}, {int}, {int}", + (World world) + -> (Integer one, Integer two, Integer three, Integer four, Integer five) + -> world.five(one, two, three, four, five)) + .step("6 arguments {int}, {int}, {int}, {int}, {int}, {int}", + (World world) + -> (Integer one, Integer two, Integer three, Integer four, Integer five, Integer six) + -> world.six(one, two, three, four, five, six)) + .step("7 arguments {int}, {int}, {int}, {int}, {int}, {int}, {int}", + (World world) + -> (Integer one, Integer two, Integer three, Integer four, Integer five, Integer six, Integer seven) + -> world.seven(one, two, three, four, five, six, seven)) + .step("8 arguments {int}, {int}, {int}, {int}, {int}, {int}, {int}, {int}", + (World world) + -> (Integer one, Integer two, Integer three, Integer four, Integer five, Integer six, Integer seven, Integer eight) + -> world.eight(one, two, three, four, five, six, seven, eight)) + .step("9 arguments {int}, {int}, {int}, {int}, {int}, {int}, {int}, {int}, {int}", + (World world) + -> (Integer one, Integer two, Integer three, Integer four, Integer five, Integer six, Integer seven, Integer eight, Integer nine) + -> world.nine(one, two, three, four, five, six, seven, eight, nine)) + .build(); + // @formatter:on + + @Test + void knowsItsLocationInAFile() { + assertThat(allStepDefinitions.getStepDeclarations()) + .extracting(StepDeclaration::getLocation) + .containsExactly( + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:17)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:21)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:24)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:28)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:32)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:36)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:40)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:44)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:48)", + "io.cucumber.lambda.StepDeclarationTest.(StepDeclarationTest.java:52)" + ); + } + + + @Test + void hasAContextClass() { + assertThat(allStepDefinitions.getStepDeclarations()) + .extracting(StepDeclaration::getContext) + .map(Class.class::cast) + .containsOnly(World.class); + } + + @Test + void hasAnExpression() { + List declarations = allStepDefinitions.getStepDeclarations(); + assertThat(declarations) + .extracting(StepDeclaration::getExpression) + .containsExactly( + "0 arguments", + "1 arguments {int}", + "2 arguments {int}, {int}", + "3 arguments {int}, {int}, {int}", + "4 arguments {int}, {int}, {int}, {int}", + "5 arguments {int}, {int}, {int}, {int}, {int}", + "6 arguments {int}, {int}, {int}, {int}, {int}, {int}", + "7 arguments {int}, {int}, {int}, {int}, {int}, {int}, {int}", + "8 arguments {int}, {int}, {int}, {int}, {int}, {int}, {int}, {int}", + "9 arguments {int}, {int}, {int}, {int}, {int}, {int}, {int}, {int}, {int}"); + } + @Test + void supportsUpToNineArguments() { + List declarations = allStepDefinitions.getStepDeclarations(); + World world = new World(); + assertAll( + // @formatter:off + () -> assertDoesNotThrow(() -> declarations.get(0).invoke(world, new Integer[] { })), + () -> assertDoesNotThrow(() -> declarations.get(1).invoke(world, new Integer[] { 1 })), + () -> assertDoesNotThrow(() -> declarations.get(2).invoke(world, new Integer[] { 1, 2 })), + () -> assertDoesNotThrow(() -> declarations.get(3).invoke(world, new Integer[] { 1, 2, 3 })), + () -> assertDoesNotThrow(() -> declarations.get(4).invoke(world, new Integer[] { 1, 2, 3, 4 })), + () -> assertDoesNotThrow(() -> declarations.get(5).invoke(world, new Integer[] { 1, 2, 3, 4, 5 })), + () -> assertDoesNotThrow(() -> declarations.get(6).invoke(world, new Integer[] { 1, 2, 3, 4, 5, 5 })), + () -> assertDoesNotThrow(() -> declarations.get(7).invoke(world, new Integer[] { 1, 2, 3, 4, 5, 5, 7 })), + () -> assertDoesNotThrow(() -> declarations.get(8).invoke(world, new Integer[] { 1, 2, 3, 4, 5, 5, 7, 8 })), + () -> assertDoesNotThrow(() -> declarations.get(9).invoke(world, new Integer[] { 1, 2, 3, 4, 5, 5, 7, 8, 9 })) + // @formatter:on + ); + } + + public static class World { + // @formatter:off + public void zero() { + + } + + public void one(Integer one) { + requireNonNull(one); + } + + public void two(Integer one, Integer two) { + requireNonNull(one); + requireNonNull(two); + } + + public void three(Integer one, Integer two, Integer three) { + requireNonNull(one); + requireNonNull(two); + requireNonNull(three); + } + + public void four(Integer one, Integer two, Integer three, Integer four) { + requireNonNull(one); + requireNonNull(two); + requireNonNull(three); + requireNonNull(four); + } + + public void five(Integer one, Integer two, Integer three, Integer four, Integer five) { + requireNonNull(one); + requireNonNull(two); + requireNonNull(three); + requireNonNull(four); + requireNonNull(five); + } + + public void six(Integer one, Integer two, Integer three, Integer four, Integer five, Integer six) { + requireNonNull(one); + requireNonNull(two); + requireNonNull(three); + requireNonNull(four); + requireNonNull(five); + requireNonNull(six); + } + + public void seven(Integer one, Integer two, Integer three, Integer four, Integer five, Integer six, Integer seven) { + requireNonNull(one); + requireNonNull(two); + requireNonNull(three); + requireNonNull(four); + requireNonNull(five); + requireNonNull(six); + requireNonNull(seven); + } + + public void eight(Integer one, Integer two, Integer three, Integer four, Integer five, Integer six, Integer seven, Integer eight) { + requireNonNull(one); + requireNonNull(two); + requireNonNull(three); + requireNonNull(four); + requireNonNull(five); + requireNonNull(six); + requireNonNull(seven); + requireNonNull(eight); + } + + public void nine(Integer one, Integer two, Integer three, Integer four, Integer five, Integer six, Integer seven, Integer eight, Integer nine) { + requireNonNull(one); + requireNonNull(two); + requireNonNull(three); + requireNonNull(four); + requireNonNull(five); + requireNonNull(six); + requireNonNull(seven); + requireNonNull(eight); + requireNonNull(nine); + } + // @formatter:on + } + +} diff --git a/java-lambda/src/test/resources/junit-platform.properties b/java-lambda/src/test/resources/junit-platform.properties new file mode 100644 index 0000000000..b48dd63bf1 --- /dev/null +++ b/java-lambda/src/test/resources/junit-platform.properties @@ -0,0 +1 @@ +cucumber.publish.quiet=true diff --git a/pom.xml b/pom.xml index ad696019ce..a735a40971 100644 --- a/pom.xml +++ b/pom.xml @@ -50,6 +50,7 @@ jakarta-openejb java8 java + java-lambda junit junit-platform-engine kotlin-java8 @@ -355,7 +356,7 @@ API Packages - cucumber.api.*:io.cucumber.core.api:io.cucumber.core.api.*:io.cucumber.junit:io.cucumber.junit.platform.engine:io.cucumber.testng:io.cucumber.java:io.cucumber.java8:io.cucumber.docstring:io.cucumber.plugin:io.cucumber.plugin.event + cucumber.api.*:io.cucumber.core.api:io.cucumber.core.api.*:io.cucumber.junit:io.cucumber.junit.platform.engine:io.cucumber.testng:io.cucumber.java:io.cucumber.lambda:io.cucumber.java8:io.cucumber.docstring:io.cucumber.plugin:io.cucumber.plugin.event