Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions medyator/medyator.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# medyator.py
from abc import ABC
from typing import Callable, Dict, Type, TypeVar, Union, cast, overload

Expand Down Expand Up @@ -36,12 +37,14 @@ def __init__(self, service_provider: ServiceProvider) -> None:
self.__handlers = HandlerContainer()

@overload
def send(self, request: Command) -> None: ...
async def send(self, request: Command) -> None: ...

@overload
def send(self, request: Query[TResponse]) -> TResponse: ...
async def send(self, request: Query[TResponse]) -> TResponse: ...

def send(self, request: Union[Command, Query[TResponse]]) -> Union[None, TResponse]:
async def send(
self, request: Union[Command, Query[TResponse]]
) -> Union[None, TResponse]:
try:
if isinstance(request, Command):
handler = cast(
Expand All @@ -51,7 +54,7 @@ def send(self, request: Union[Command, Query[TResponse]]) -> Union[None, TRespon
lambda: CommandHandlerWrapperImpl[type(request)](),
),
)
handler(request, self.__service_provider)
await handler(request, self.__service_provider)
return None
elif isinstance(request, Query):
handler = cast(
Expand All @@ -61,7 +64,7 @@ def send(self, request: Union[Command, Query[TResponse]]) -> Union[None, TRespon
lambda: QueryHandlerWrapperImpl[type(request), TResponse](),
),
)
return handler(request, self.__service_provider)
return await handler(request, self.__service_provider)
else:
raise TypeError("Unsupported request type")
except KeyError:
Expand Down
9 changes: 6 additions & 3 deletions medyator/sender.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
class Sender(ABC):
@overload
@abstractmethod
def send(self, request: Command) -> None: ...
async def send(self, request: Command) -> None: ...

@overload
@abstractmethod
def send(self, request: Query[TResponse]) -> TResponse: ...
async def send(self, request: Query[TResponse]) -> TResponse: ...

@abstractmethod
def send(self, request: Union[Command, Query[TResponse]]) -> Union[None, TResponse]:
async def send(
self, request: Union[Command, Query[TResponse]]
) -> Union[None, TResponse]:
raise NotImplementedError

30 changes: 19 additions & 11 deletions tests/test_medyator.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def __init__(self, value: int) -> None:
self.value = value

class TestQueryHandler(QueryHandler[TestQuery, int]):
def __call__(self, request: TestQuery) -> int:
async def __call__(self, request: TestQuery) -> int:
return request.value + 9000

return TestQuery, TestQueryHandler()
Expand All @@ -35,40 +35,48 @@ class TestCommandHandler(CommandHandler[TestCommand]):
def __init__(self) -> None:
self.value = None

def __call__(self, request: TestCommand) -> None:
async def __call__(self, request: TestCommand) -> None:
self.value = request.value

return TestCommand, TestCommandHandler()


def test_query_should_execute_query_handler_twice_and_return_same_value(test_query):
@pytest.mark.asyncio
async def test_query_should_execute_query_handler_twice_and_return_same_value(
test_query,
):
di.add_medyator()
query, query_handler = test_query
di[query] = query_handler
medyator = di[Medyator]

# should get handler from serviceprovider (di container)
result = medyator.send(query(1))
# Should get handler from service provider (di container)
result = await medyator.send(query(1))
assert result == 9001

# should get handler from medyator container
result = medyator.send(query(1))
# Should get handler from medyator container
result = await medyator.send(query(1))
assert result == 9001


def test_should_execute_command_handler_and_set_the_value(test_command):
@pytest.mark.asyncio
async def test_should_execute_command_handler_and_set_the_value(test_command):
di.add_medyator()
command, _ = test_command
medyator = di[Medyator]

medyator.send(command("Hello, World!"))
await medyator.send(command("Hello, World!"))
handler = di[command]
assert handler.value == "Hello, World!"


def test_should_raise_HandlerNotFound_error_when_query_handler_is_not_found(test_query):
@pytest.mark.asyncio
async def test_should_raise_HandlerNotFound_error_when_query_handler_is_not_found(
test_query,
):
di.add_medyator()
medyator = di[Medyator]
query, _ = test_query
with pytest.raises(HandlerNotFound):
medyator.send(query(1))
await medyator.send(query(1))