Skip to content

Commit 8b77e7e

Browse files
Memoize configuration parameters that are costly to create
1 parent 48ddfce commit 8b77e7e

2 files changed

Lines changed: 41 additions & 15 deletions

File tree

cucumber-junit-platform-engine/src/main/java/io/cucumber/junit/platform/engine/CucumberConfiguration.java

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import java.util.Locale;
3030
import java.util.Optional;
3131
import java.util.Set;
32+
import java.util.concurrent.ConcurrentHashMap;
33+
import java.util.function.Function;
3234
import java.util.regex.Pattern;
3335
import java.util.stream.Collectors;
3436

@@ -62,6 +64,7 @@ class CucumberConfiguration implements
6264

6365
private final ConfigurationParameters configurationParameters;
6466
private final DiscoveryIssueReporter issueReporter;
67+
private final ConcurrentHashMap<String, Optional<?>> memoizing = new ConcurrentHashMap<>();
6568

6669
CucumberConfiguration(ConfigurationParameters configurationParameters, DiscoveryIssueReporter issueReporter) {
6770
this.configurationParameters = requireNonNull(configurationParameters);
@@ -70,7 +73,7 @@ class CucumberConfiguration implements
7073

7174
@Override
7275
public List<Plugin> plugins() {
73-
List<Plugin> plugins = configurationParameters.get(PLUGIN_PROPERTY_NAME, s -> Arrays.stream(s.split(","))
76+
List<Plugin> plugins = memoize(PLUGIN_PROPERTY_NAME, s -> Arrays.stream(s.split(","))
7477
.map(String::trim)
7578
.map(PluginOption::parse)
7679
.map(pluginOption -> (Plugin) pluginOption)
@@ -131,18 +134,22 @@ public boolean isWip() {
131134
return false;
132135
}
133136

137+
@SuppressWarnings("unchecked")
138+
private <T> Optional<T> memoize(String key, Function<? super String, ? extends @Nullable T> transformer) {
139+
return (Optional<T>) memoizing.computeIfAbsent(key, k -> configurationParameters.get(k, transformer));
140+
}
141+
134142
Optional<Expression> tagFilter() {
135-
return configurationParameters.get(FILTER_TAGS_PROPERTY_NAME, TagExpressionParser::parse);
143+
return memoize(FILTER_TAGS_PROPERTY_NAME, TagExpressionParser::parse);
136144
}
137145

138146
Optional<Pattern> nameFilter() {
139-
return configurationParameters.get(FILTER_NAME_PROPERTY_NAME, Pattern::compile);
147+
return memoize(FILTER_NAME_PROPERTY_NAME, Pattern::compile);
140148
}
141149

142150
@Override
143151
public List<URI> getGlue() {
144-
return configurationParameters
145-
.get(GLUE_PROPERTY_NAME, s -> Arrays.asList(s.split(",")))
152+
return memoize(GLUE_PROPERTY_NAME, s -> Arrays.asList(s.split(",")))
146153
.orElse(Collections.singletonList(CLASSPATH_SCHEME_PREFIX))
147154
.stream()
148155
.map(String::trim)
@@ -159,22 +166,19 @@ public boolean isDryRun() {
159166

160167
@Override
161168
public SnippetType getSnippetType() {
162-
return configurationParameters
163-
.get(SNIPPET_TYPE_PROPERTY_NAME, SnippetTypeParser::parseSnippetType)
169+
return memoize(SNIPPET_TYPE_PROPERTY_NAME, SnippetTypeParser::parseSnippetType)
164170
.orElse(SnippetType.UNDERSCORE);
165171
}
166172

167173
@Override
168174
public @Nullable Class<? extends ObjectFactory> getObjectFactoryClass() {
169-
return configurationParameters
170-
.get(OBJECT_FACTORY_PROPERTY_NAME, ObjectFactoryParser::parseObjectFactory)
175+
return memoize(OBJECT_FACTORY_PROPERTY_NAME, ObjectFactoryParser::parseObjectFactory)
171176
.orElse(null);
172177
}
173178

174179
@Override
175180
public @Nullable Class<? extends UuidGenerator> getUuidGeneratorClass() {
176-
return configurationParameters
177-
.get(UUID_GENERATOR_PROPERTY_NAME, UuidGeneratorParser::parseUuidGenerator)
181+
return memoize(UUID_GENERATOR_PROPERTY_NAME, UuidGeneratorParser::parseUuidGenerator)
178182
.orElse(null);
179183
}
180184

@@ -185,8 +189,7 @@ boolean isParallelExecutionEnabled() {
185189
}
186190

187191
NamingStrategy namingStrategy() {
188-
return configurationParameters
189-
.get(JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, DefaultNamingStrategyProvider::getStrategyProvider)
192+
return memoize(JUNIT_PLATFORM_NAMING_STRATEGY_PROPERTY_NAME, DefaultNamingStrategyProvider::getStrategyProvider)
190193
.map(this::reportIssueIfSurefireStrategyIsUsed)
191194
.orElse(DefaultNamingStrategyProvider.SHORT)
192195
.create(configurationParameters);
@@ -203,7 +206,7 @@ private DefaultNamingStrategyProvider reportIssueIfSurefireStrategyIsUsed(Defaul
203206
}
204207

205208
Set<FeatureWithLinesSelector> featuresWithLines() {
206-
return configurationParameters.get(FEATURES_PROPERTY_NAME,
209+
return memoize(FEATURES_PROPERTY_NAME,
207210
s -> Arrays.stream(s.split(","))
208211
.map(String::trim)
209212
.map(FeatureWithLines::parse)
@@ -213,7 +216,7 @@ Set<FeatureWithLinesSelector> featuresWithLines() {
213216
}
214217

215218
ExecutionMode getExecutionModeFeature() {
216-
return configurationParameters.get(EXECUTION_MODE_FEATURE_PROPERTY_NAME,
219+
return memoize(EXECUTION_MODE_FEATURE_PROPERTY_NAME,
217220
value -> ExecutionMode.valueOf(value.toUpperCase(Locale.ROOT)))
218221
.orElse(ExecutionMode.CONCURRENT);
219222
}

cucumber-junit-platform-engine/src/test/java/io/cucumber/junit/platform/engine/CucumberConfigurationTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import io.cucumber.core.eventbus.IncrementingUuidGenerator;
55
import io.cucumber.core.plugin.Options;
66
import io.cucumber.core.snippets.SnippetType;
7+
import io.cucumber.tagexpressions.Expression;
78
import org.junit.jupiter.api.Test;
89
import org.junit.platform.engine.ConfigurationParameters;
910
import org.junit.platform.engine.DiscoveryIssue;
@@ -13,10 +14,13 @@
1314
import java.util.ArrayList;
1415
import java.util.List;
1516
import java.util.Map;
17+
import java.util.Optional;
18+
import java.util.regex.Pattern;
1619

1720
import static java.util.stream.Collectors.toList;
1821
import static org.hamcrest.CoreMatchers.is;
1922
import static org.hamcrest.MatcherAssert.assertThat;
23+
import static org.hamcrest.Matchers.sameInstance;
2024
import static org.hamcrest.collection.IsEmptyCollection.empty;
2125
import static org.hamcrest.collection.IsIterableContainingInOrder.contains;
2226
import static org.hamcrest.core.IsIterableContaining.hasItem;
@@ -193,4 +197,23 @@ void uuidGenerator() {
193197
assertThat(new CucumberConfiguration(configurationParameters, issueReporter).getUuidGeneratorClass(),
194198
is(IncrementingUuidGenerator.class));
195199
}
200+
201+
@Test
202+
void tagFilter() {
203+
ConfigurationParameters tags = new MapConfigurationParameters(Constants.FILTER_TAGS_PROPERTY_NAME, "@foo");
204+
CucumberConfiguration cucumberConfiguration = new CucumberConfiguration(tags, issueReporter);
205+
Optional<Expression> expression = cucumberConfiguration.tagFilter();
206+
assertTrue(expression.orElseThrow().evaluate(List.of("@foo")));
207+
assertThat(expression, sameInstance(cucumberConfiguration.tagFilter()));
208+
}
209+
210+
@Test
211+
void nameFilter() {
212+
ConfigurationParameters nameFilter = new MapConfigurationParameters(Constants.FILTER_NAME_PROPERTY_NAME,
213+
".*foo.*");
214+
CucumberConfiguration cucumberConfiguration = new CucumberConfiguration(nameFilter, issueReporter);
215+
Optional<Pattern> pattern = cucumberConfiguration.nameFilter();
216+
assertTrue(pattern.orElseThrow().matcher("aaa foo zzz").matches());
217+
assertThat(pattern, sameInstance(cucumberConfiguration.nameFilter()));
218+
}
196219
}

0 commit comments

Comments
 (0)