22import typing
33
44import pytest
5+ from asserts import assert_equal
56from pytest_bdd import given , parsers , then , when
67from tests .e2e .parsers import to_bool
78
89from openfeature import api
910from openfeature .client import OpenFeatureClient
1011from openfeature .evaluation_context import EvaluationContext
1112from openfeature .event import EventDetails , ProviderEvent
13+ from openfeature .flag_evaluation import ErrorCode , FlagEvaluationDetails , Reason
14+ from openfeature .provider import ProviderStatus
1215
1316JsonPrimitive = typing .Union [str , bool , float , int ]
1417
@@ -19,44 +22,44 @@ def evaluation_context() -> EvaluationContext:
1922
2023
2124@given ("a flagd provider is set" , target_fixture = "client" )
25+ @given ("a provider is registered" , target_fixture = "client" )
2226def setup_provider () -> OpenFeatureClient :
23- return api .get_client ()
27+ client = api .get_client ()
28+ wait_for (lambda : client .get_provider_status () == ProviderStatus .READY )
29+ return client
2430
2531
2632@when (
2733 parsers .cfparse (
28- 'a zero-value boolean flag with key "{key}" is evaluated with default value "{default:bool}"' ,
29- extra_types = {"bool" : to_bool },
34+ 'a {ignored:s?} boolean flag with key "{key}" is evaluated with {details:s?} default value "{default:bool}"' ,
35+ extra_types = {"bool" : to_bool , "s" : str },
3036 ),
3137 target_fixture = "key_and_default" ,
3238)
3339@when (
3440 parsers .cfparse (
35- 'a zero-value string flag with key "{key}" is evaluated with default value "{default}"' ,
41+ 'a {ignored:s?}string flag with key "{key}" is evaluated with {details:s?}default value "{default}"' ,
42+ extra_types = {"s" : str },
3643 ),
3744 target_fixture = "key_and_default" ,
3845)
3946@when (
4047 parsers .cfparse (
41- 'a string flag with key "{key}" is evaluated with default value "{default}"'
48+ 'a{ignored:s?} integer flag with key "{key}" is evaluated with {details:s?}default value {default:d}' ,
49+ extra_types = {"s" : str },
4250 ),
4351 target_fixture = "key_and_default" ,
4452)
4553@when (
4654 parsers .cfparse (
47- 'a zero-value integer flag with key "{key}" is evaluated with default value {default:d}' ,
55+ 'a {ignored:s?}float flag with key "{key}" is evaluated with {details:s?}default value {default:f}' ,
56+ extra_types = {"s" : str },
4857 ),
4958 target_fixture = "key_and_default" ,
5059)
5160@when (
5261 parsers .cfparse (
53- 'an integer flag with key "{key}" is evaluated with default value {default:d}' ,
54- ),
55- target_fixture = "key_and_default" ,
56- )
57- @when (
58- parsers .cfparse (
59- 'a zero-value float flag with key "{key}" is evaluated with default value {default:f}' ,
62+ 'a string flag with key "{key}" is evaluated as an integer, with details and a default value {default:d}' ,
6063 ),
6164 target_fixture = "key_and_default" ,
6265)
@@ -111,6 +114,12 @@ def update_context_nested(
111114 evaluation_context .attributes [outer ][inner ] = value
112115
113116
117+ @then (
118+ parsers .cfparse (
119+ 'the resolved boolean value should be "{expected_value:bool}"' ,
120+ extra_types = {"bool" : to_bool },
121+ )
122+ )
114123@then (
115124 parsers .cfparse (
116125 'the resolved boolean zero-value should be "{expected_value:bool}"' ,
@@ -125,12 +134,34 @@ def assert_boolean_value(
125134):
126135 key , default = key_and_default
127136 evaluation_result = client .get_boolean_value (key , default , evaluation_context )
128- assert evaluation_result == expected_value
137+ assert_equal ( evaluation_result , expected_value )
129138
130139
131140@then (
132141 parsers .cfparse (
133- "the resolved integer zero-value should be {expected_value:d}" ,
142+ 'the resolved boolean details value should be "{expected_value:bool}", the variant should be "{variant}", and the reason should be "{reason}"' ,
143+ extra_types = {"bool" : to_bool },
144+ )
145+ )
146+ def assert_boolean_value_with_details (
147+ client : OpenFeatureClient ,
148+ key_and_default : tuple ,
149+ expected_value : bool ,
150+ variant : str ,
151+ reason : str ,
152+ evaluation_context : EvaluationContext ,
153+ ):
154+ key , default = key_and_default
155+ evaluation_result = client .get_boolean_details (key , default , evaluation_context )
156+ assert_equal (evaluation_result .value , expected_value )
157+ assert_equal (evaluation_result .reason , reason )
158+ assert_equal (evaluation_result .variant , variant )
159+
160+
161+ @then (
162+ parsers .cfparse (
163+ "the resolved integer {ignored:s?}value should be {expected_value:d}" ,
164+ extra_types = {"s" : str },
134165 )
135166)
136167@then (parsers .cfparse ("the returned value should be {expected_value:d}" ))
@@ -139,15 +170,36 @@ def assert_integer_value(
139170 key_and_default : tuple ,
140171 expected_value : bool ,
141172 evaluation_context : EvaluationContext ,
173+ ):
174+ key , default = key_and_default
175+ evaluation_result = client .get_integer_value (key , default , evaluation_context )
176+ assert_equal (evaluation_result , expected_value )
177+
178+
179+ @then (
180+ parsers .cfparse (
181+ 'the resolved integer details value should be {expected_value:d}, the variant should be "{variant}", and the reason should be "{reason}"' ,
182+ )
183+ )
184+ def assert_integer_value_with_details (
185+ client : OpenFeatureClient ,
186+ key_and_default : tuple ,
187+ expected_value : int ,
188+ variant : str ,
189+ reason : str ,
190+ evaluation_context : EvaluationContext ,
142191):
143192 key , default = key_and_default
144193 evaluation_result = client .get_integer_details (key , default , evaluation_context )
145- assert evaluation_result == expected_value
194+ assert_equal (evaluation_result .value , expected_value )
195+ assert_equal (evaluation_result .reason , reason )
196+ assert_equal (evaluation_result .variant , variant )
146197
147198
148199@then (
149200 parsers .cfparse (
150- "the resolved float zero-value should be {expected_value:f}" ,
201+ "the resolved float {ignored:s?}value should be {expected_value:f}" ,
202+ extra_types = {"s" : str },
151203 )
152204)
153205def assert_float_value (
@@ -158,7 +210,27 @@ def assert_float_value(
158210):
159211 key , default = key_and_default
160212 evaluation_result = client .get_float_value (key , default , evaluation_context )
161- assert evaluation_result == expected_value
213+ assert_equal (evaluation_result , expected_value )
214+
215+
216+ @then (
217+ parsers .cfparse (
218+ 'the resolved float details value should be {expected_value:f}, the variant should be "{variant}", and the reason should be "{reason}"' ,
219+ )
220+ )
221+ def assert_float_value_with_details (
222+ client : OpenFeatureClient ,
223+ key_and_default : tuple ,
224+ expected_value : float ,
225+ variant : str ,
226+ reason : str ,
227+ evaluation_context : EvaluationContext ,
228+ ):
229+ key , default = key_and_default
230+ evaluation_result = client .get_float_details (key , default , evaluation_context )
231+ assert_equal (evaluation_result .value , expected_value )
232+ assert_equal (evaluation_result .reason , reason )
233+ assert_equal (evaluation_result .variant , variant )
162234
163235
164236@then (parsers .cfparse ('the returned value should be "{expected_value}"' ))
@@ -169,8 +241,8 @@ def assert_string_value(
169241 evaluation_context : EvaluationContext ,
170242):
171243 key , default = key_and_default
172- evaluation_result = client .get_string_value (key , default , evaluation_context )
173- assert evaluation_result == expected_value
244+ evaluation_details = client .get_string_details (key , default , evaluation_context )
245+ assert_equal ( evaluation_details . value , expected_value )
174246
175247
176248@then (
@@ -182,10 +254,98 @@ def assert_empty_string(
182254 client : OpenFeatureClient ,
183255 key_and_default : tuple ,
184256 evaluation_context : EvaluationContext ,
257+ ):
258+ assert_string (client , key_and_default , evaluation_context , "" )
259+
260+
261+ @then (
262+ parsers .cfparse (
263+ 'the resolved string value should be "{expected_value}"' ,
264+ )
265+ )
266+ def assert_string (
267+ client : OpenFeatureClient ,
268+ key_and_default : tuple ,
269+ evaluation_context : EvaluationContext ,
270+ expected_value : str ,
185271):
186272 key , default = key_and_default
187273 evaluation_result = client .get_string_value (key , default , evaluation_context )
188- assert evaluation_result == ""
274+ assert_equal (evaluation_result , expected_value )
275+
276+
277+ @then (
278+ parsers .cfparse (
279+ "the default string value should be returned" ,
280+ ),
281+ target_fixture = "evaluation_details" ,
282+ )
283+ def assert_default_string (
284+ client : OpenFeatureClient ,
285+ key_and_default : tuple ,
286+ evaluation_context : EvaluationContext ,
287+ ) -> FlagEvaluationDetails [str ]:
288+ key , default = key_and_default
289+ evaluation_result = client .get_string_details (key , default , evaluation_context )
290+ assert_equal (evaluation_result .value , default )
291+ return evaluation_result
292+
293+
294+ @then (
295+ parsers .cfparse (
296+ "the default integer value should be returned" ,
297+ ),
298+ target_fixture = "evaluation_details" ,
299+ )
300+ def assert_default_integer (
301+ client : OpenFeatureClient ,
302+ key_and_default : tuple ,
303+ evaluation_context : EvaluationContext ,
304+ ) -> FlagEvaluationDetails [int ]:
305+ key , default = key_and_default
306+ evaluation_result = client .get_integer_details (key , default , evaluation_context )
307+ assert_equal (evaluation_result .value , default )
308+ return evaluation_result
309+
310+
311+ @then (
312+ parsers .cfparse (
313+ 'the reason should indicate an error and the error code should indicate a missing flag with "{error}"' ,
314+ )
315+ )
316+ @then (
317+ parsers .cfparse (
318+ 'the reason should indicate an error and the error code should indicate a type mismatch with "{error}"' ,
319+ )
320+ )
321+ def assert_for_error (
322+ client : OpenFeatureClient ,
323+ evaluation_details : FlagEvaluationDetails ,
324+ error : str ,
325+ ):
326+ assert_equal (evaluation_details .error_code , ErrorCode [error ])
327+ assert_equal (evaluation_details .reason , Reason .ERROR )
328+
329+
330+ @then (
331+ parsers .cfparse (
332+ 'the resolved string details value should be "{expected_value}", the variant should be "{variant}", and the reason should be "{reason}"' ,
333+ extra_types = {"bool" : to_bool },
334+ )
335+ )
336+ def assert_string_value_with_details (
337+ client : OpenFeatureClient ,
338+ key_and_default : tuple ,
339+ expected_value : str ,
340+ variant : str ,
341+ reason : str ,
342+ evaluation_context : EvaluationContext ,
343+ ):
344+ key , default = key_and_default
345+ evaluation_result = client .get_string_details (key , default , evaluation_context )
346+ assert_equal (evaluation_result .value , expected_value )
347+ assert_equal (evaluation_result .reason , reason )
348+ assert_equal (evaluation_result .variant , variant )
189349
190350
191351@then (parsers .cfparse ('the returned reason should be "{reason}"' ))
@@ -198,7 +358,7 @@ def assert_reason(
198358 """the returned reason should be <reason>."""
199359 key , default = key_and_default
200360 evaluation_result = client .get_string_details (key , default , evaluation_context )
201- assert evaluation_result .reason . value == reason
361+ assert_equal ( evaluation_result .reason , reason )
202362
203363
204364provider_ready_ran = False
0 commit comments