Skip to content

Commit

Permalink
add missing async, not implemented exceptions and test coverage
Browse files Browse the repository at this point in the history
Signed-off-by: leohoare <leo@insight.co>
  • Loading branch information
leohoare committed Nov 13, 2024
1 parent 4af03eb commit 657ef96
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 8 deletions.
12 changes: 6 additions & 6 deletions openfeature/provider/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ async def resolve_boolean_details(
default_value: bool,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[bool]:
pass
raise NotImplementedError("Method not implemented")

@abstractmethod
async def resolve_string_details(
Expand All @@ -183,7 +183,7 @@ async def resolve_string_details(
default_value: str,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[str]:
pass
raise NotImplementedError("Method not implemented")

@abstractmethod
async def resolve_integer_details(
Expand All @@ -192,7 +192,7 @@ async def resolve_integer_details(
default_value: int,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[int]:
pass
raise NotImplementedError("Method not implemented")

@abstractmethod
async def resolve_float_details(
Expand All @@ -201,13 +201,13 @@ async def resolve_float_details(
default_value: float,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[float]:
pass
raise NotImplementedError("Method not implemented")

@abstractmethod
def resolve_object_details(
async def resolve_object_details(
self,
flag_key: str,
default_value: typing.Union[dict, list],
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[typing.Union[dict, list]]:
pass
raise NotImplementedError("Method not implemented")
7 changes: 5 additions & 2 deletions openfeature/provider/no_op_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from openfeature.evaluation_context import EvaluationContext
from openfeature.flag_evaluation import FlagResolutionDetails, Reason
from openfeature.hook import Hook
from openfeature.provider import AbstractProvider, Metadata
from openfeature.provider import AbstractProvider, AsyncAbstractProvider, Metadata
from openfeature.provider.no_op_metadata import NoOpMetadata

PASSED_IN_DEFAULT = "Passed in default"
Expand Down Expand Up @@ -77,7 +77,10 @@ def resolve_object_details(
)


class AsyncNoOpProvider(NoOpProvider):
class AsyncNoOpProvider(AsyncAbstractProvider):
def get_metadata(self) -> Metadata:
return NoOpMetadata()

async def resolve_boolean_details(
self,
flag_key: str,
Expand Down
69 changes: 69 additions & 0 deletions tests/provider/test_no_op_provider.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import typing
from numbers import Number

import pytest

from openfeature.evaluation_context import EvaluationContext
from openfeature.flag_evaluation import FlagResolutionDetails
from openfeature.provider import AsyncAbstractProvider
from openfeature.provider.no_op_provider import NoOpProvider


Expand Down Expand Up @@ -80,3 +86,66 @@ def test_should_resolve_object_flag_from_no_op():
assert flag is not None
assert flag.value == return_value
assert isinstance(flag.value, dict)


class ConcreteAsyncProvider(AsyncAbstractProvider):
def get_metadata(self):
return super().get_metadata()

Check warning on line 93 in tests/provider/test_no_op_provider.py

View check run for this annotation

Codecov / codecov/patch

tests/provider/test_no_op_provider.py#L93

Added line #L93 was not covered by tests

async def resolve_boolean_details(
self,
flag_key: str,
default_value: bool,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[bool]:
return await super().resolve_boolean_details(flag_key, default_value)

async def resolve_string_details(
self,
flag_key: str,
default_value: str,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[str]:
return await super().resolve_string_details(flag_key, default_value)

async def resolve_integer_details(
self,
flag_key: str,
default_value: int,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[int]:
return await super().resolve_integer_details(flag_key, default_value)

async def resolve_float_details(
self,
flag_key: str,
default_value: float,
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[float]:
return await super().resolve_float_details(flag_key, default_value)

async def resolve_object_details(
self,
flag_key: str,
default_value: typing.Union[dict, list],
evaluation_context: typing.Optional[EvaluationContext] = None,
) -> FlagResolutionDetails[typing.Union[dict, list]]:
return await super().resolve_object_details(flag_key, default_value)


@pytest.mark.parametrize(
"get_method, default",
(
("resolve_boolean_details", True),
("resolve_string_details", "default"),
("resolve_integer_details", 42),
("resolve_float_details", 3.14),
("resolve_object_details", {"key": "value"}),
),
)
@pytest.mark.asyncio
async def test_abstract_provider_throws_not_implemented(get_method, default):
with pytest.raises(NotImplementedError) as exception:
provider = ConcreteAsyncProvider()
await getattr(provider, get_method)("test_flag", default)
assert str(exception.value) == "Method not implemented"

0 comments on commit 657ef96

Please sign in to comment.