Skip to content

Commit 3cef4b6

Browse files
committed
Setup step delcarations for cucumber-java-lambda
1 parent cbddfd0 commit 3cef4b6

File tree

10 files changed

+765
-1
lines changed

10 files changed

+765
-1
lines changed

java-lambda/README.md

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
Cucumber Java8
2+
==============
3+
4+
Provides lambda based step definitions. To use add the `cucumber-java-lambda` dependency to your pom.xml:
5+
6+
```xml
7+
<dependencies>
8+
[...]
9+
<dependency>
10+
<groupId>io.cucumber</groupId>
11+
<artifactId>cucumber-java-lambda</artifactId>
12+
<version>${cucumber.version}</version>
13+
<scope>test</scope>
14+
</dependency>
15+
[...]
16+
</dependencies>
17+
```
18+
19+
## Step Definitions
20+
21+
## Hooks
22+
23+
## Transformers
24+
25+
### Parameter Type
26+
27+
### Data Table Type
28+
29+
#### Default Transformers
30+
31+
#### Empty Cells
32+
33+
#### Transposing Tables
34+
35+
### DocString type

java-lambda/pom.xml

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
4+
<parent>
5+
<groupId>io.cucumber</groupId>
6+
<artifactId>cucumber-jvm</artifactId>
7+
<version>7.3.3-SNAPSHOT</version>
8+
</parent>
9+
10+
<artifactId>cucumber-java-lambda</artifactId>
11+
<packaging>jar</packaging>
12+
<name>Cucumber-JVM: Java Lambda</name>
13+
14+
<properties>
15+
<project.Automatic-Module-Name>io.cucumber.lambda</project.Automatic-Module-Name>
16+
<apiguardian-api.version>1.1.2</apiguardian-api.version>
17+
<junit-jupiter.version>5.8.2</junit-jupiter.version>
18+
<typetools.version>0.6.3</typetools.version>
19+
<assertj.version>3.22.0</assertj.version>
20+
</properties>
21+
22+
<dependencyManagement>
23+
<dependencies>
24+
<dependency>
25+
<groupId>io.cucumber</groupId>
26+
<artifactId>cucumber-bom</artifactId>
27+
<version>${project.version}</version>
28+
<type>pom</type>
29+
<scope>import</scope>
30+
</dependency>
31+
<dependency>
32+
<groupId>org.junit</groupId>
33+
<artifactId>junit-bom</artifactId>
34+
<version>${junit-jupiter.version}</version>
35+
<type>pom</type>
36+
<scope>import</scope>
37+
</dependency>
38+
</dependencies>
39+
</dependencyManagement>
40+
41+
<dependencies>
42+
<dependency>
43+
<groupId>io.cucumber</groupId>
44+
<artifactId>cucumber-core</artifactId>
45+
</dependency>
46+
<dependency>
47+
<groupId>org.apiguardian</groupId>
48+
<artifactId>apiguardian-api</artifactId>
49+
<version>${apiguardian-api.version}</version>
50+
</dependency>
51+
<dependency>
52+
<groupId>net.jodah</groupId>
53+
<artifactId>typetools</artifactId>
54+
<version>${typetools.version}</version>
55+
</dependency>
56+
57+
<dependency>
58+
<groupId>io.cucumber</groupId>
59+
<artifactId>cucumber-junit-platform-engine</artifactId>
60+
<scope>test</scope>
61+
</dependency>
62+
<dependency>
63+
<groupId>org.junit.platform</groupId>
64+
<artifactId>junit-platform-suite</artifactId>
65+
<scope>test</scope>
66+
</dependency>
67+
<dependency>
68+
<groupId>org.junit.jupiter</groupId>
69+
<artifactId>junit-jupiter</artifactId>
70+
<scope>test</scope>
71+
</dependency>
72+
73+
<dependency>
74+
<groupId>org.assertj</groupId>
75+
<artifactId>assertj-core</artifactId>
76+
<version>${assertj.version}</version>
77+
</dependency>
78+
</dependencies>
79+
80+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package io.cucumber.lambda;
2+
3+
import io.cucumber.core.backend.CucumberBackendException;
4+
import io.cucumber.core.backend.CucumberInvocationTargetException;
5+
import io.cucumber.core.backend.Located;
6+
7+
import java.lang.reflect.InvocationTargetException;
8+
import java.lang.reflect.Method;
9+
10+
final class Invoker {
11+
12+
private Invoker() {
13+
14+
}
15+
16+
static Object invoke(Located located, Object target, Method method, Object... args) {
17+
boolean accessible = method.canAccess(target);
18+
try {
19+
method.setAccessible(true);
20+
return method.invoke(target, args);
21+
} catch (IllegalArgumentException | IllegalAccessException e) {
22+
throw new CucumberBackendException("Failed to invoke " + located.getLocation(), e);
23+
} catch (InvocationTargetException e) {
24+
throw new CucumberInvocationTargetException(located, e);
25+
} finally {
26+
method.setAccessible(accessible);
27+
}
28+
}
29+
30+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package io.cucumber.lambda;
2+
3+
import io.cucumber.core.backend.Located;
4+
import io.cucumber.core.backend.SourceReference;
5+
6+
import java.lang.reflect.Method;
7+
import java.util.ArrayList;
8+
import java.util.List;
9+
import java.util.Optional;
10+
11+
import static io.cucumber.core.backend.SourceReference.fromStackTraceElement;
12+
import static java.lang.String.format;
13+
import static java.util.Objects.requireNonNull;
14+
15+
class StepDeclaration implements Located {
16+
private final String expression;
17+
private final Class<?> context;
18+
private final StepDefinitionFunction function;
19+
private final StackTraceElement location;
20+
private SourceReference sourceReference;
21+
22+
StepDeclaration(String expression, Class<?> context, StepDefinitionFunction function, StackTraceElement location) {
23+
this.expression = requireNonNull(expression, "expression should not be null");
24+
this.context = requireNonNull(context, "context should not be null");
25+
this.function = requireNonNull(function, "function should not be null");
26+
this.location = requireNonNull(location, "location should not be null");
27+
28+
}
29+
30+
String getExpression() {
31+
return expression;
32+
}
33+
34+
Class<?> getContext() {
35+
return context;
36+
}
37+
38+
@Override
39+
public final boolean isDefinedAt(StackTraceElement stackTraceElement) {
40+
return location.getFileName() != null && location.getFileName().equals(stackTraceElement.getFileName());
41+
}
42+
43+
@Override
44+
public Optional<SourceReference> getSourceReference() {
45+
if (sourceReference == null) {
46+
sourceReference = fromStackTraceElement(location);
47+
}
48+
return Optional.of(sourceReference);
49+
}
50+
51+
@Override
52+
public final String getLocation() {
53+
return location.toString();
54+
}
55+
56+
void invoke(Object contextInstance, Object[] arguments) {
57+
Method acceptMethod = getAcceptMethod(function.getClass());
58+
Object body = Invoker.invoke(this, function, acceptMethod, contextInstance);
59+
Method bodyAcceptMethod = getAcceptMethod(body.getClass());
60+
Invoker.invoke(this, body, bodyAcceptMethod, arguments);
61+
}
62+
63+
private Method getAcceptMethod(Class<?> bodyClass) {
64+
List<Method> acceptMethods = new ArrayList<>();
65+
for (Method method : bodyClass.getDeclaredMethods()) {
66+
if (!method.isBridge() && !method.isSynthetic() && "accept".equals(method.getName())) {
67+
acceptMethods.add(method);
68+
}
69+
}
70+
if (acceptMethods.size() != 1) {
71+
throw new IllegalStateException(format(
72+
"Expected single 'accept' method on body class, found '%s'", acceptMethods));
73+
}
74+
return acceptMethods.get(0);
75+
}
76+
77+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
package io.cucumber.lambda;
2+
3+
import org.apiguardian.api.API;
4+
5+
import static org.apiguardian.api.API.Status.EXPERIMENTAL;
6+
7+
@API(status = EXPERIMENTAL, since = "7.4.0")
8+
public interface StepDefinitionFunction {
9+
10+
@FunctionalInterface
11+
interface C0A0 extends StepDefinitionFunction {
12+
StepDefinitionBody.A0 accept();
13+
14+
}
15+
16+
@FunctionalInterface
17+
interface C1A0<Context> extends StepDefinitionFunction {
18+
StepDefinitionBody.A0 accept(Context context);
19+
20+
}
21+
22+
@FunctionalInterface
23+
interface C1A1<Context, T1> extends StepDefinitionFunction {
24+
StepDefinitionBody.A1<T1> accept(Context context);
25+
26+
}
27+
28+
@FunctionalInterface
29+
interface C1A2<Context, T1, T2> extends StepDefinitionFunction {
30+
StepDefinitionBody.A2<T1, T2> accept(Context context);
31+
32+
}
33+
34+
@FunctionalInterface
35+
interface C1A3<Context, T1, T2, A3> extends StepDefinitionFunction {
36+
StepDefinitionBody.A3<T1, T2, A3> accept(Context context);
37+
38+
}
39+
40+
@FunctionalInterface
41+
interface C1A4<Context, T1, T2, T3, T4> extends StepDefinitionFunction {
42+
StepDefinitionBody.A4<T1, T2, T3, T4> accept(Context context);
43+
44+
}
45+
46+
@FunctionalInterface
47+
interface C1A5<Context, T1, T2, T3, T4, T5> extends StepDefinitionFunction {
48+
StepDefinitionBody.A5<T1, T2, T3, T4, T5> accept(Context context);
49+
50+
}
51+
52+
@FunctionalInterface
53+
interface C1A6<Context, T1, T2, T3, T4, T5, T6> extends StepDefinitionFunction {
54+
StepDefinitionBody.A6<T1, T2, T3, T4, T5, T6> accept(Context context);
55+
56+
}
57+
58+
@FunctionalInterface
59+
interface C1A7<Context, T1, T2, T3, T4, T5, T6, T7> extends StepDefinitionFunction {
60+
StepDefinitionBody.A7<T1, T2, T3, T4, T5, T6, T7> accept(Context context);
61+
62+
}
63+
64+
@FunctionalInterface
65+
interface C1A8<Context, T1, T2, T3, T4, T5, T6, T7, T8> extends StepDefinitionFunction {
66+
StepDefinitionBody.A8<T1, T2, T3, T4, T5, T6, T7, T8> accept(Context context);
67+
68+
}
69+
70+
@FunctionalInterface
71+
interface C1A9<Context, T1, T2, T3, T4, T5, T6, T7, T8, T9> extends StepDefinitionFunction {
72+
StepDefinitionBody.A9<T1, T2, T3, T4, T5, T6, T7, T8, T9> accept(Context context);
73+
74+
}
75+
76+
interface StepDefinitionBody {
77+
78+
@FunctionalInterface
79+
interface A0 extends StepDefinitionBody {
80+
void accept() throws Throwable;
81+
82+
}
83+
84+
@FunctionalInterface
85+
interface A1<T1> extends StepDefinitionBody {
86+
void accept(T1 t1) throws Throwable;
87+
88+
}
89+
90+
@FunctionalInterface
91+
interface A2<T1, T2> extends StepDefinitionBody {
92+
void accept(T1 t1, T2 t2) throws Throwable;
93+
94+
}
95+
96+
@FunctionalInterface
97+
interface A3<T1, T2, T3> extends StepDefinitionBody {
98+
void accept(T1 t1, T2 t2, T3 t3) throws Throwable;
99+
100+
}
101+
102+
@FunctionalInterface
103+
interface A4<T1, T2, T3, T4> extends StepDefinitionBody {
104+
void accept(T1 t1, T2 t2, T3 t3, T4 t4) throws Throwable;
105+
106+
}
107+
108+
@FunctionalInterface
109+
interface A5<T1, T2, T3, T4, T5> extends StepDefinitionBody {
110+
void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) throws Throwable;
111+
112+
}
113+
114+
@FunctionalInterface
115+
interface A6<T1, T2, T3, T4, T5, T6> extends StepDefinitionBody {
116+
void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) throws Throwable;
117+
118+
}
119+
120+
@FunctionalInterface
121+
interface A7<T1, T2, T3, T4, T5, T6, T7> extends StepDefinitionBody {
122+
void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) throws Throwable;
123+
124+
}
125+
126+
@FunctionalInterface
127+
interface A8<T1, T2, T3, T4, T5, T6, T7, T8> extends StepDefinitionBody {
128+
void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) throws Throwable;
129+
130+
}
131+
132+
@FunctionalInterface
133+
interface A9<T1, T2, T3, T4, T5, T6, T7, T8, T9> extends StepDefinitionBody {
134+
void accept(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) throws Throwable;
135+
136+
}
137+
138+
}
139+
140+
}

0 commit comments

Comments
 (0)