Skip to content

Commit d69cf5d

Browse files
fix: consistent method chainability (#913)
* mutablecontext settargetkey now return(s) this method chainable Signed-off-by: DBlanchard88 <[email protected]> * addHooks & setEvaluationContext are now chainable Signed-off-by: DBlanchard88 <[email protected]> * OpenFeatureAPI setEvaluationContext new chainable Signed-off-by: DBlanchard88 <[email protected]> * Update src/test/java/dev/openfeature/sdk/MutableContextTest.java Signed-off-by: Todd Baert <[email protected]> --------- Signed-off-by: DBlanchard88 <[email protected]> Signed-off-by: Todd Baert <[email protected]> Co-authored-by: Todd Baert <[email protected]>
1 parent f364ca5 commit d69cf5d

File tree

7 files changed

+64
-6
lines changed

7 files changed

+64
-6
lines changed

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,15 @@ public interface Client extends Features, EventBus<Client> {
1818
* Set the client-level evaluation context.
1919
* @param ctx Client level context.
2020
*/
21-
void setEvaluationContext(EvaluationContext ctx);
21+
Client setEvaluationContext(EvaluationContext ctx);
2222

2323
/**
2424
* Adds hooks for evaluation.
2525
* Hooks are run in the order they're added in the before stage. They are run in reverse order for all other stages.
2626
*
2727
* @param hooks The hook to add.
2828
*/
29-
void addHooks(Hook... hooks);
29+
Client addHooks(Hook... hooks);
3030

3131
/**
3232
* Fetch the hooks associated to this client.

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,11 @@ public MutableContext add(String key, List<Value> value) {
8787
/**
8888
* Override or set targeting key for this mutable context. Value should be non-null and non-empty to be accepted.
8989
*/
90-
public void setTargetingKey(String targetingKey) {
90+
public MutableContext setTargetingKey(String targetingKey) {
9191
if (targetingKey != null && !targetingKey.trim().isEmpty()) {
9292
this.add(TARGETING_KEY, targetingKey);
9393
}
94+
return this;
9495
}
9596

9697

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,11 @@ public Client getClient(@Nullable String name, @Nullable String version) {
8383
/**
8484
* {@inheritDoc}
8585
*/
86-
public void setEvaluationContext(EvaluationContext evaluationContext) {
86+
public OpenFeatureAPI setEvaluationContext(EvaluationContext evaluationContext) {
8787
try (AutoCloseableLock __ = lock.writeLockAutoCloseable()) {
8888
this.evaluationContext = evaluationContext;
8989
}
90+
return this;
9091
}
9192

9293
/**

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

+4-2
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,11 @@ public OpenFeatureClient(OpenFeatureAPI openFeatureAPI, String name, String vers
5656
* {@inheritDoc}
5757
*/
5858
@Override
59-
public void addHooks(Hook... hooks) {
59+
public OpenFeatureClient addHooks(Hook... hooks) {
6060
try (AutoCloseableLock __ = this.hooksLock.writeLockAutoCloseable()) {
6161
this.clientHooks.addAll(Arrays.asList(hooks));
6262
}
63+
return this;
6364
}
6465

6566
/**
@@ -76,10 +77,11 @@ public List<Hook> getHooks() {
7677
* {@inheritDoc}
7778
*/
7879
@Override
79-
public void setEvaluationContext(EvaluationContext evaluationContext) {
80+
public OpenFeatureClient setEvaluationContext(EvaluationContext evaluationContext) {
8081
try (AutoCloseableLock __ = contextLock.writeLockAutoCloseable()) {
8182
this.evaluationContext = evaluationContext;
8283
}
84+
return this;
8385
}
8486

8587
/**

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

+15
Original file line numberDiff line numberDiff line change
@@ -116,4 +116,19 @@ void mergeShouldRetainItsSubkeysWhenOverridingContextHasNoTargetingKey() {
116116
Structure value = key1.asStructure();
117117
assertArrayEquals(new Object[]{"key1_1"}, value.keySet().toArray());
118118
}
119+
120+
@DisplayName("Ensure mutations are chainable")
121+
@Test
122+
void shouldAllowChainingOfMutations() {
123+
MutableContext context = new MutableContext();
124+
context.add("key1", "val1")
125+
.add("key2", 2)
126+
.setTargetingKey("TARGETING_KEY")
127+
.add("key3", 3.0);
128+
129+
assertEquals("TARGETING_KEY", context.getTargetingKey());
130+
assertEquals("val1", context.getValue("key1").asString());
131+
assertEquals(2, context.getValue("key2").asInteger());
132+
assertEquals(3.0, context.getValue("key3").asDouble());
133+
}
119134
}

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

+9
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import static org.junit.jupiter.api.Assertions.assertEquals;
66

77
import java.util.Collections;
8+
import java.util.HashMap;
89

910
import org.junit.jupiter.api.BeforeEach;
1011
import org.junit.jupiter.api.Test;
@@ -78,4 +79,12 @@ void settingNamedClientProviderToNullErrors() {
7879
void settingTransactionalContextPropagatorToNullErrors() {
7980
assertThatCode(() -> api.setTransactionContextPropagator(null)).isInstanceOf(IllegalArgumentException.class);
8081
}
82+
83+
@Test
84+
void setEvaluationContextShouldAllowChaining() {
85+
OpenFeatureClient client = new OpenFeatureClient(api, "name", "version");
86+
EvaluationContext ctx = new ImmutableContext("targeting key", new HashMap<>());
87+
OpenFeatureClient result = client.setEvaluationContext(ctx);
88+
assertEquals(client, result);
89+
}
8190
}

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

+30
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,18 @@
33
import java.util.*;
44

55
import dev.openfeature.sdk.fixtures.HookFixtures;
6+
67
import org.junit.jupiter.api.*;
78
import org.mockito.Mockito;
89
import org.simplify4u.slf4jmock.LoggerMock;
910
import org.slf4j.Logger;
1011

1112
import static org.assertj.core.api.Assertions.assertThat;
13+
import static org.junit.jupiter.api.Assertions.assertEquals;
14+
import static org.mockito.ArgumentMatchers.any;
15+
import static org.mockito.ArgumentMatchers.anyString;
16+
import static org.mockito.ArgumentMatchers.argThat;
17+
import static org.mockito.ArgumentMatchers.eq;
1218
import static org.mockito.Mockito.*;
1319

1420
class OpenFeatureClientTest implements HookFixtures {
@@ -67,4 +73,28 @@ void mergeContextTest() {
6773

6874
assertThat(result.getValue()).isTrue();
6975
}
76+
77+
@Test
78+
@DisplayName("addHooks should allow chaining by returning the same client instance")
79+
void addHooksShouldAllowChaining() {
80+
OpenFeatureAPI api = mock(OpenFeatureAPI.class);
81+
OpenFeatureClient client = new OpenFeatureClient(api, "name", "version");
82+
Hook<?> hook1 = Mockito.mock(Hook.class);
83+
Hook<?> hook2 = Mockito.mock(Hook.class);
84+
85+
OpenFeatureClient result = client.addHooks(hook1, hook2);
86+
assertEquals(client, result);
87+
}
88+
89+
@Test
90+
@DisplayName("setEvaluationContext should allow chaining by returning the same client instance")
91+
void setEvaluationContextShouldAllowChaining() {
92+
OpenFeatureAPI api = mock(OpenFeatureAPI.class);
93+
OpenFeatureClient client = new OpenFeatureClient(api, "name", "version");
94+
EvaluationContext ctx = new ImmutableContext("targeting key", new HashMap<>());
95+
96+
OpenFeatureClient result = client.setEvaluationContext(ctx);
97+
assertEquals(client, result);
98+
}
99+
70100
}

0 commit comments

Comments
 (0)