Skip to content

Commit dd9227a

Browse files
chrfwowaepfli
andauthored
feat: update test harness with metadata assertions open-feature#1467 (open-feature#1319)
* feat: implement gherkin tests Signed-off-by: christian.lutnik <[email protected]> * fixup! feat: implement gherkin tests Signed-off-by: christian.lutnik <[email protected]> * fixup! feat: implement gherkin tests Signed-off-by: christian.lutnik <[email protected]> * fixup! feat: implement gherkin tests Signed-off-by: christian.lutnik <[email protected]> * fixup: add version for dependency Signed-off-by: Simon Schrottner <[email protected]> --------- Signed-off-by: christian.lutnik <[email protected]> Signed-off-by: Simon Schrottner <[email protected]> Co-authored-by: Simon Schrottner <[email protected]>
1 parent cdcdc14 commit dd9227a

File tree

16 files changed

+381
-23
lines changed

16 files changed

+381
-23
lines changed

pom.xml

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@
143143
<scope>test</scope>
144144
</dependency>
145145

146+
<dependency>
147+
<groupId>io.cucumber</groupId>
148+
<artifactId>cucumber-picocontainer</artifactId>
149+
<version>${io.cucumber.version}</version>
150+
<scope>test</scope>
151+
</dependency>
152+
146153
<dependency>
147154
<groupId>org.simplify4u</groupId>
148155
<artifactId>slf4j2-mock</artifactId>
@@ -681,21 +688,6 @@
681688
</arguments>
682689
</configuration>
683690
</execution>
684-
<execution>
685-
<id>copy-evaluation-gherkin-tests</id>
686-
<phase>validate</phase>
687-
<goals>
688-
<goal>exec</goal>
689-
</goals>
690-
<configuration>
691-
<!-- copy the feature spec we want to test into resources so them can be easily loaded -->
692-
<executable>cp</executable>
693-
<arguments>
694-
<argument>spec/specification/assets/gherkin/evaluation.feature</argument>
695-
<argument>src/test/resources/features/</argument>
696-
</arguments>
697-
</configuration>
698-
</execution>
699691
</executions>
700692
</plugin>
701693
</plugins>

src/main/java/dev/openfeature/sdk/ImmutableMetadata.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ public <T> T getValue(final String key, final Class<T> type) {
9797
}
9898
}
9999

100+
public boolean isEmpty() {
101+
return metadata.isEmpty();
102+
}
103+
100104
/**
101105
* Obtain a builder for {@link ImmutableMetadata}.
102106
*/

src/main/java/dev/openfeature/sdk/OpenFeatureClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ private <T> FlagEvaluationDetails<T> evaluateFlag(
217217
}
218218
} catch (Exception e) {
219219
if (details == null) {
220-
details = FlagEvaluationDetails.<T>builder().build();
220+
details = FlagEvaluationDetails.<T>builder().flagKey(key).build();
221221
}
222222
if (e instanceof OpenFeatureError) {
223223
details.setErrorCode(((OpenFeatureError) e).getErrorCode());

src/main/java/dev/openfeature/sdk/providers/memory/Flag.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package dev.openfeature.sdk.providers.memory;
22

3+
import dev.openfeature.sdk.ImmutableMetadata;
34
import java.util.Map;
45
import lombok.Builder;
56
import lombok.Getter;
@@ -18,4 +19,5 @@ public class Flag<T> {
1819

1920
private String defaultVariant;
2021
private ContextEvaluator<T> contextEvaluator;
22+
private ImmutableMetadata flagMetadata;
2123
}

src/main/java/dev/openfeature/sdk/providers/memory/InMemoryProvider.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ private <T> ProviderEvaluation<T> getEvaluation(
152152
.value(value)
153153
.variant(flag.getDefaultVariant())
154154
.reason(Reason.STATIC.toString())
155+
.flagMetadata(flag.getFlagMetadata())
155156
.build();
156157
}
157158
}

src/test/java/dev/openfeature/sdk/FlagMetadataTest.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package dev.openfeature.sdk;
22

33
import static org.assertj.core.api.Assertions.assertThat;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
5+
import static org.junit.jupiter.api.Assertions.assertTrue;
46

57
import org.junit.jupiter.api.DisplayName;
68
import org.junit.jupiter.api.Test;
@@ -9,7 +11,7 @@ class FlagMetadataTest {
911

1012
@Test
1113
@DisplayName("Test metadata payload construction and retrieval")
12-
public void builder_validation() {
14+
void builder_validation() {
1315
// given
1416
ImmutableMetadata flagMetadata = ImmutableMetadata.builder()
1517
.addString("string", "string")
@@ -42,7 +44,7 @@ public void builder_validation() {
4244

4345
@Test
4446
@DisplayName("Value type mismatch returns a null")
45-
public void value_type_validation() {
47+
void value_type_validation() {
4648
// given
4749
ImmutableMetadata flagMetadata =
4850
ImmutableMetadata.builder().addString("string", "string").build();
@@ -53,11 +55,32 @@ public void value_type_validation() {
5355

5456
@Test
5557
@DisplayName("A null is returned if key does not exist")
56-
public void notfound_error_validation() {
58+
void notfound_error_validation() {
5759
// given
5860
ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build();
5961

6062
// then
6163
assertThat(flagMetadata.getBoolean("string")).isNull();
6264
}
65+
66+
@Test
67+
@DisplayName("isEmpty returns true iff the metadata is empty")
68+
void isEmpty_returns_true_if_metadata_is_empty() {
69+
// given
70+
ImmutableMetadata flagMetadata = ImmutableMetadata.builder().build();
71+
72+
// then
73+
assertTrue(flagMetadata.isEmpty());
74+
}
75+
76+
@Test
77+
@DisplayName("isEmpty returns false iff the metadata is not empty")
78+
void isEmpty_returns_false_if_metadata_is_not_empty() {
79+
// given
80+
ImmutableMetadata flagMetadata =
81+
ImmutableMetadata.builder().addString("a", "b").build();
82+
83+
// then
84+
assertFalse(flagMetadata.isEmpty());
85+
}
6386
}
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package dev.openfeature.sdk.e2e;
22

33
import static io.cucumber.junit.platform.engine.Constants.GLUE_PROPERTY_NAME;
4+
import static io.cucumber.junit.platform.engine.Constants.OBJECT_FACTORY_PROPERTY_NAME;
45
import static io.cucumber.junit.platform.engine.Constants.PLUGIN_PROPERTY_NAME;
56

67
import org.junit.platform.suite.api.ConfigurationParameter;
78
import org.junit.platform.suite.api.IncludeEngines;
8-
import org.junit.platform.suite.api.SelectClasspathResource;
9+
import org.junit.platform.suite.api.SelectDirectories;
910
import org.junit.platform.suite.api.Suite;
1011

1112
@Suite
1213
@IncludeEngines("cucumber")
13-
@SelectClasspathResource("features/evaluation.feature")
14+
@SelectDirectories("spec/specification/assets/gherkin")
1415
@ConfigurationParameter(key = PLUGIN_PROPERTY_NAME, value = "pretty")
15-
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.sdk.e2e.evaluation")
16+
@ConfigurationParameter(key = GLUE_PROPERTY_NAME, value = "dev.openfeature.sdk.e2e.steps")
17+
@ConfigurationParameter(key = OBJECT_FACTORY_PROPERTY_NAME, value = "io.cucumber.picocontainer.PicoFactory")
1618
public class EvaluationTest {}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dev.openfeature.sdk.e2e;
2+
3+
public class Flag {
4+
public String name;
5+
public Object defaultValue;
6+
public String type;
7+
8+
public Flag(String type, String name, Object defaultValue) {
9+
this.name = name;
10+
this.defaultValue = defaultValue;
11+
this.type = type;
12+
}
13+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package dev.openfeature.sdk.e2e;
2+
3+
import dev.openfeature.sdk.EvaluationContext;
4+
import dev.openfeature.sdk.FlagEvaluationDetails;
5+
import dev.openfeature.sdk.Hook;
6+
import dev.openfeature.sdk.HookContext;
7+
import java.util.HashMap;
8+
import java.util.Map;
9+
import java.util.Optional;
10+
import lombok.Getter;
11+
12+
public class MockHook implements Hook {
13+
@Getter
14+
private boolean beforeCalled;
15+
16+
@Getter
17+
private boolean afterCalled;
18+
19+
@Getter
20+
private boolean errorCalled;
21+
22+
@Getter
23+
private boolean finallyAfterCalled;
24+
25+
@Getter
26+
private final Map<String, FlagEvaluationDetails> evaluationDetails = new HashMap<>();
27+
28+
@Override
29+
public Optional<EvaluationContext> before(HookContext ctx, Map hints) {
30+
beforeCalled = true;
31+
return Optional.of(ctx.getCtx());
32+
}
33+
34+
@Override
35+
public void after(HookContext ctx, FlagEvaluationDetails details, Map hints) {
36+
afterCalled = true;
37+
evaluationDetails.put("after", details);
38+
}
39+
40+
@Override
41+
public void error(HookContext ctx, Exception error, Map hints) {
42+
errorCalled = true;
43+
}
44+
45+
@Override
46+
public void finallyAfter(HookContext ctx, FlagEvaluationDetails details, Map hints) {
47+
finallyAfterCalled = true;
48+
evaluationDetails.put("finally", details);
49+
}
50+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dev.openfeature.sdk.e2e;
2+
3+
import dev.openfeature.sdk.Client;
4+
import dev.openfeature.sdk.FlagEvaluationDetails;
5+
import dev.openfeature.sdk.MutableContext;
6+
7+
public class State {
8+
public Client client;
9+
public Flag flag;
10+
public MutableContext context = new MutableContext();
11+
public FlagEvaluationDetails evaluation;
12+
public MockHook hook;
13+
}

0 commit comments

Comments
 (0)