Skip to content

Commit 81f2c98

Browse files
author
Tim te Beek
committed
Introduce ScenarioScoped interface to allow for world reference disposal
1 parent 8acd75e commit 81f2c98

File tree

6 files changed

+37
-4
lines changed

6 files changed

+37
-4
lines changed

core/src/main/java/cucumber/runner/Glue.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import cucumber.runtime.DuplicateStepDefinitionException;
44
import cucumber.runtime.HookDefinition;
5+
import cucumber.runtime.ScenarioScoped;
56
import cucumber.runtime.StepDefinition;
67
import io.cucumber.stepexpression.Argument;
78
import cucumber.api.StepDefinitionReporter;
@@ -138,6 +139,10 @@ private void removeScenarioScopedHooks(List<HookDefinition> beforeHooks) {
138139
Iterator<HookDefinition> hookIterator = beforeHooks.iterator();
139140
while (hookIterator.hasNext()) {
140141
HookDefinition hook = hookIterator.next();
142+
if (hook instanceof ScenarioScoped) {
143+
ScenarioScoped scenarioScopedHookDefinition = (ScenarioScoped) hook;
144+
scenarioScopedHookDefinition.disposeScenarioScope();
145+
}
141146
if (hook.isScenarioScoped()) {
142147
hookIterator.remove();
143148
}
@@ -148,6 +153,10 @@ private void removeScenariosScopedStepDefinitions(Map<String, StepDefinition> st
148153
Iterator<Map.Entry<String, StepDefinition>> stepDefinitionIterator = stepDefinitions.entrySet().iterator();
149154
while(stepDefinitionIterator.hasNext()){
150155
StepDefinition stepDefinition = stepDefinitionIterator.next().getValue();
156+
if (stepDefinition instanceof ScenarioScoped) {
157+
ScenarioScoped scenarioScopedStepDefinition = (ScenarioScoped) stepDefinition;
158+
scenarioScopedStepDefinition.disposeScenarioScope();
159+
}
151160
if(stepDefinition.isScenarioScoped()){
152161
stepDefinitionIterator.remove();
153162
}

core/src/main/java/cucumber/runtime/HookDefinition.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ public interface HookDefinition {
2121
int getOrder();
2222

2323
/**
24+
* @deprecated replaced with {@link ScenarioScoped}
2425
* @return true if this instance is scoped to a single scenario, or false if it can be reused across scenarios.
2526
*/
27+
@Deprecated
2628
boolean isScenarioScoped();
2729
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package cucumber.runtime;
2+
3+
public interface ScenarioScoped {
4+
/**
5+
* Dispose references to Runtime world to allow garbage collection to run.
6+
*/
7+
void disposeScenarioScope();
8+
}

core/src/main/java/cucumber/runtime/StepDefinition.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,9 @@ public interface StepDefinition {
4444
String getPattern();
4545

4646
/**
47+
* @deprecated replaced with {@link ScenarioScoped}
4748
* @return true if this instance is scoped to a single scenario, or false if it can be reused across scenarios.
4849
*/
50+
@Deprecated
4951
boolean isScenarioScoped();
5052
}

java8/src/main/java/cucumber/runtime/java8/Java8HookDefinition.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,19 @@
66
import cucumber.api.java8.HookBody;
77
import cucumber.api.java8.HookNoArgsBody;
88
import cucumber.runtime.HookDefinition;
9+
import cucumber.runtime.ScenarioScoped;
910
import cucumber.runtime.filter.TagPredicate;
1011
import cucumber.runtime.Timeout;
1112
import gherkin.pickles.PickleTag;
1213

1314
import java.util.Collection;
1415

15-
public class Java8HookDefinition implements HookDefinition {
16+
public class Java8HookDefinition implements HookDefinition, ScenarioScoped {
1617
private final TagPredicate tagPredicate;
1718
private final int order;
1819
private final long timeoutMillis;
1920
private final HookNoArgsBody hookNoArgsBody;
20-
private final HookBody hookBody;
21+
private HookBody hookBody;
2122
private final StackTraceElement location;
2223

2324
private Java8HookDefinition(String[] tagExpressions, int order, long timeoutMillis, HookBody hookBody, HookNoArgsBody hookNoArgsBody) {
@@ -69,4 +70,9 @@ public int getOrder() {
6970
public boolean isScenarioScoped() {
7071
return true;
7172
}
73+
74+
@Override
75+
public void disposeScenarioScope() {
76+
this.hookBody = null;
77+
}
7278
}

java8/src/main/java/cucumber/runtime/java8/Java8StepDefinition.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import cucumber.api.java8.StepdefBody;
1010
import io.cucumber.stepexpression.ArgumentMatcher;
1111
import cucumber.runtime.CucumberException;
12+
import cucumber.runtime.ScenarioScoped;
1213
import io.cucumber.stepexpression.ExpressionArgumentMatcher;
1314
import cucumber.runtime.StepDefinition;
1415
import io.cucumber.stepexpression.StepExpression;
@@ -24,7 +25,7 @@
2425
import java.util.List;
2526
import java.util.Map;
2627

27-
public class Java8StepDefinition implements StepDefinition {
28+
public class Java8StepDefinition implements StepDefinition, ScenarioScoped {
2829

2930
public static <T extends StepdefBody> Java8StepDefinition create(
3031
String expression, Class<T> bodyClass, T body, TypeRegistry typeRegistry) {
@@ -37,7 +38,7 @@ public static <T extends StepdefBody> StepDefinition create(
3738
}
3839

3940
private final long timeoutMillis;
40-
private final StepdefBody body;
41+
private StepdefBody body;
4142

4243
private final StepExpression expression;
4344
private final StackTraceElement location;
@@ -161,4 +162,9 @@ private Type requireNonMapOrListType(Type argumentType) {
161162
return argumentType;
162163
}
163164
}
165+
166+
@Override
167+
public void disposeScenarioScope() {
168+
this.body = null;
169+
}
164170
}

0 commit comments

Comments
 (0)