Skip to content

Commit b10acc7

Browse files
committed
feat: remove use of evaluation context in no_op
Signed-off-by: YUE Daian <[email protected]>
1 parent ad3e29d commit b10acc7

File tree

3 files changed

+127
-120
lines changed

3 files changed

+127
-120
lines changed

README.md

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,23 +97,20 @@ async fn example() {
9797
.unwrap_or(false);
9898

9999
// Let's get evaluation details.
100-
// Note that we will inject `300` as the int value via evaluation context.
101-
// It is not a feature mentioned in the standard but rather implemented for the
102-
// convenience.
103100
let result = client
104101
.get_int_details(
105102
"key",
106-
Some(&EvaluationContext::default().with_custom_field("Value", 300)),
103+
Some(&EvaluationContext::default().with_custom_field("some_key", "some_value")),
107104
None,
108105
)
109106
.await;
110107

111108
match result {
112109
Ok(details) => {
113-
assert_eq!(details.value, 300);
110+
assert_eq!(details.value, 100);
114111
assert_eq!(details.reason, Some(EvaluationReason::Static));
115112
assert_eq!(details.variant, Some("Static".to_string()));
116-
assert_eq!(details.flag_metadata.values.iter().count(), 1);
113+
assert_eq!(details.flag_metadata.values.iter().count(), 2);
117114
}
118115
Err(error) => {
119116
println!(

src/api/api.rs

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ mod tests {
102102
use std::sync::Arc;
103103

104104
use super::*;
105-
use crate::{provider::NoOpProvider, EvaluationContextFieldValue, EvaluationReason};
105+
use crate::{
106+
provider::NoOpProvider, EvaluationContextFieldValue, EvaluationReason, FlagMetadataValue,
107+
};
106108
use spec::spec;
107109

108110
#[spec(
@@ -295,48 +297,69 @@ mod tests {
295297
)]
296298
#[tokio::test]
297299
async fn evaluation_context() {
298-
// Ensure the value set into provider is picked up.
300+
// Set global client context and ensure its values are picked up.
301+
let evaluation_context = EvaluationContext::builder()
302+
.targeting_key("global_targeting_key")
303+
.build()
304+
.with_custom_field("key", "global_value");
305+
299306
let mut api = OpenFeature::default();
300-
api.set_provider(NoOpProvider::builder().int_value(100).build())
301-
.await;
307+
api.set_evaluation_context(evaluation_context).await;
302308

303309
let mut client = api.create_client();
304310

305-
assert_eq!(client.get_int_value("", None, None).await.unwrap(), 100);
311+
let result = client.get_int_details("", None, None).await.unwrap();
306312

307-
// Ensure the value set into global context is picked up.
308-
api.set_evaluation_context(
309-
EvaluationContext::default()
310-
.with_custom_field("Value", EvaluationContextFieldValue::Int(200)),
311-
)
312-
.await;
313+
assert_eq!(
314+
*result.flag_metadata.values.get("TargetingKey").unwrap(),
315+
FlagMetadataValue::String("global_targeting_key".to_string())
316+
);
317+
318+
assert_eq!(
319+
*result.flag_metadata.values.get("key").unwrap(),
320+
FlagMetadataValue::String("global_value".to_string())
321+
);
313322

314-
assert_eq!(client.get_int_value("", None, None).await.unwrap(), 200);
323+
// Set client evaluation context and ensure its values overwrite the global ones.
324+
let evaluation_context = EvaluationContext::builder()
325+
.targeting_key("client_targeting_key")
326+
.build()
327+
.with_custom_field("key", "client_value");
315328

316-
// Set another provider to the API and ensure its value is picked up.
317-
api.set_evaluation_context(
318-
EvaluationContext::default()
319-
.with_custom_field("Value", EvaluationContextFieldValue::Int(150)),
320-
)
321-
.await;
329+
client.set_evaluation_context(evaluation_context);
330+
331+
let result = client.get_bool_details("", None, None).await.unwrap();
322332

323-
assert_eq!(client.get_int_value("", None, None).await.unwrap(), 150);
333+
assert_eq!(
334+
*result.flag_metadata.values.get("TargetingKey").unwrap(),
335+
FlagMetadataValue::String("client_targeting_key".to_string())
336+
);
324337

325-
// Ensure the value set into client context is picked up.
326-
client.set_evaluation_context(
327-
EvaluationContext::default()
328-
.with_custom_field("Value", EvaluationContextFieldValue::Int(300)),
338+
assert_eq!(
339+
*result.flag_metadata.values.get("key").unwrap(),
340+
FlagMetadataValue::String("client_value".to_string())
329341
);
330342

331-
assert_eq!(client.get_int_value("", None, None).await.unwrap(), 300);
343+
// Use invocation level evaluation context and ensure its values are used.
344+
let evaluation_context = EvaluationContext::builder()
345+
.targeting_key("invocation_targeting_key")
346+
.build()
347+
.with_custom_field("key", "invocation_value");
348+
349+
let result = client
350+
.get_string_details("", Some(&evaluation_context), None)
351+
.await
352+
.unwrap();
332353

333-
// Ensure the value set into invocation evaluation context is picked up.
334-
client.set_evaluation_context(
335-
EvaluationContext::default()
336-
.with_custom_field("Value", EvaluationContextFieldValue::Int(400)),
354+
assert_eq!(
355+
*result.flag_metadata.values.get("TargetingKey").unwrap(),
356+
FlagMetadataValue::String("invocation_targeting_key".to_string())
337357
);
338358

339-
assert_eq!(client.get_int_value("", None, None).await.unwrap(), 400);
359+
assert_eq!(
360+
*result.flag_metadata.values.get("key").unwrap(),
361+
FlagMetadataValue::String("invocation_value".to_string())
362+
);
340363
}
341364

342365
#[spec(
@@ -363,26 +386,13 @@ mod tests {
363386
// Note the `await` call here because asynchronous lock is used to guarantee thread safety.
364387
let mut api = OpenFeature::singleton_mut().await;
365388

366-
// Createa a global evaluation context and set it into the API.
367-
// Note that this is optional. By default it uses an empty one.
368-
let global_evaluation_context = EvaluationContext::default();
369-
api.set_evaluation_context(global_evaluation_context).await;
370-
371-
// Set the default feature provider.
372-
// If you do not do that, [`NoOpProvider`] will be used by default.
373-
//
374-
// By default, [`NoOpProvider`] will simply return the default value of each type.
375-
// You can inject value you want via its builder or evaluation context. See its document
376-
// for more details.
377-
//
378-
// If you set a new provider after creating some clients, the existing clients will pick up
379-
// the new provider you just set.
380-
api.set_provider(NoOpProvider::default()).await;
389+
api.set_provider(NoOpProvider::builder().int_value(100).build())
390+
.await;
381391

382392
// Create an unnamed client.
383393
let client = api.create_client();
384394

385-
// Createa an evaluation context.
395+
// Create an evaluation context.
386396
// It supports types mentioned in the specification.
387397
//
388398
// You have multiple ways to add a custom field.
@@ -404,41 +414,31 @@ mod tests {
404414
EvaluationContextFieldValue::new_struct(MyStruct::default()),
405415
);
406416

407-
assert_eq!(
408-
client
409-
.get_bool_value("key", Some(&evaluation_context), None)
410-
.await
411-
.unwrap(),
412-
bool::default()
413-
);
414-
415-
// Create a named provider and bind it.
416-
api.set_named_provider("named", NoOpProvider::builder().int_value(42).build())
417-
.await;
418-
419-
// This named client will use the feature provider bound to this name.
420-
let client = api.create_named_client("named");
417+
// This function returns a `Result`. You can process it with functions provided by std.
418+
let is_feature_enabled = client
419+
.get_bool_value("SomeFlagEnabled", Some(&evaluation_context), None)
420+
.await
421+
.unwrap_or(false);
421422

422-
assert_eq!(42, client.get_int_value("key", None, None).await.unwrap());
423+
if is_feature_enabled {
424+
// Do something.
425+
}
423426

424427
// Let's get evaluation details.
425-
// Note that we will inject `300` as the int value via evaluation context.
426-
// It is not a feature mentioned in the standard but rather implemented for the
427-
// convenience.
428428
let result = client
429429
.get_int_details(
430430
"key",
431-
Some(&EvaluationContext::default().with_custom_field("Value", 300)),
431+
Some(&EvaluationContext::default().with_custom_field("some_key", "some_value")),
432432
None,
433433
)
434434
.await;
435435

436436
match result {
437437
Ok(details) => {
438-
assert_eq!(details.value, 300);
438+
assert_eq!(details.value, 100);
439439
assert_eq!(details.reason, Some(EvaluationReason::Static));
440440
assert_eq!(details.variant, Some("Static".to_string()));
441-
assert_eq!(details.flag_metadata.values.iter().count(), 1);
441+
assert_eq!(details.flag_metadata.values.iter().count(), 2);
442442
}
443443
Err(error) => {
444444
println!(

0 commit comments

Comments
 (0)