@@ -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