Ejemplo n.º 1
0
 def __init__(
         self,
         policies: Optional[Sequence[PolicyType]] = None,
         cascade: Optional[HandlerFactoryCascade] = None,
         modifiers: Sequence[ModifierFactory] = (),
 ):
     """
     Initializes event handler registry.
     :param policies:
     (optional) sequence of policies to be used as recipe
     to convert raw objects into handlers;
     if not provided default CallableHandlerPolicy is used;
     overwritten when cascade is provided
     :param cascade:
     (optional/advanced) custom handler factory cascade to customize
     policy into handler factory mapping
     :param modifiers: sequence of modifiers to be applied on new handler entries
     """
     HandlerRegistry.__init__(
         self,
         store=CollectionHandlerStore(),
         policies=policies or [CallableHandlerPolicy()],
         cascade=cascade,
         modifiers=modifiers,
     )
Ejemplo n.º 2
0
 def __init__(
         self,
         policies: Optional[Sequence[PolicyType]] = None,
         cascade: Optional[HandlerFactoryCascade] = None,
         modifiers: Sequence[ModifierFactory] = (),
         sync_mode: bool = False,
 ):
     """
     Initializes local event bus with given specification.
     :param policies:
     (optional) sequence of policies to be used as recipe
     to convert raw objects into handlers;
     if not provided default `CallableHandlerPolicy` will be used;
     overwritten when cascade is provided
     :param cascade:
     (optional) custom handler factory cascade to customize
     policy into handler factory mapping
     :param modifiers: sequence of modifiers to be applied on new handler entries
     """
     scheduler_store = _EventSchedulerHandlerStore(sync_mode=sync_mode)
     HandlerRegistry.__init__(
         self,
         store=scheduler_store,
         policies=policies or [CallableHandlerPolicy()],
         cascade=cascade,
         modifiers=modifiers,
     )
     self._scheduler = scheduler_store
def _registry_cascade_factory():
    return HandlerRegistry(
        store=CollectionHandlerStore(),
        cascade=HandlerFactoryCascade(
            policies=[CallableHandlerPolicy()],
            mapper=DefaultHandlerFactoryMapper(),
        ),
    )
Ejemplo n.º 4
0
async def test_handler_factory_cascade_replace():
    cascade = HandlerFactoryCascade(policies=[CallableHandlerPolicy()])
    obj = _A()

    with pytest.raises(IncompatibleHandlerFactoryCascadeError):
        cascade(obj)

    cascade = cascade.replace(policies=[MethodHandlerPolicy(name="method")])
    handler = cascade(obj)
    await _check_handler_works(handler)
Ejemplo n.º 5
0
def test_callable_handler_policy():
    policy = CallableHandlerPolicy()
    assert not policy.subject_as_keyword

    policy = CallableHandlerPolicy(subject_arg="test")
    assert policy.subject_as_keyword

    second_policy = CallableHandlerPolicy()
    assert policy.replace_map(second_policy) is second_policy
    assert policy.replace_map(None) is policy
Ejemplo n.º 6
0
async def test_local_event_bus_sync():
    cnt = {"test": 0}

    async def _handler(event: str):
        await asyncio.sleep(0.0)
        cnt[event] += 1

    policies = [CallableHandlerPolicy()]
    bus = LocalEventBus(policies=policies, sync_mode=True)
    bus.register(_handler, policies=policies)
    bus.register(_handler, policies=policies)
    await bus.publish("test")
    assert cnt["test"] == 2
async def test_handler_modifiers(
    global_modifiers: Sequence[ModifierFactory],
    local_modifiers: Sequence[ModifierFactory],
    seq: Sequence[str],
    mockup_action_factory: Callable[[], ActionSubject],
):
    registry = HandlerRegistry(
        store=CollectionHandlerStore(),
        policies=[CallableHandlerPolicy()],
        modifiers=global_modifiers,
    )
    registry.register(_return_seq, modifiers=local_modifiers)
    registry.register(modifiers=local_modifiers)(_return_seq)
    for entry in registry:
        call = entry.handler_pipeline()
        result = await call(mockup_action_factory())
        assert result.result == seq
Ejemplo n.º 8
0
def test_method_handler_policy():
    policy = MethodHandlerPolicy(name="test", subtype_of=[str])
    assert policy.precises_type

    policy = MethodHandlerPolicy(name="test")
    assert not policy.precises_type

    callable_policy = CallableHandlerPolicy()
    new_policy = policy.replace_map(callable_policy)
    assert isinstance(new_policy, MethodHandlerPolicy)
    assert new_policy.policy is callable_policy
    assert new_policy.name == policy.name
    assert list(new_policy.subtype_of) == list(policy.subtype_of)

    second_policy = MethodHandlerPolicy(name="other")
    assert policy.replace_map(second_policy) is second_policy

    assert policy.replace_map(None) is policy
Ejemplo n.º 9
0
async def test_local_request_executor():
    policies = [CallableHandlerPolicy()]
    executor = LocalRequestBus(
        policies=policies, modifiers=MockupModifierFactory.modifiers("abc"))
    executor.register(_handle_a)

    registry = RequestHandlerRegistry(
        policies=policies, modifiers=MockupModifierFactory.modifiers("xyz"))
    registry.register(_handle_b)
    executor.include(registry)

    for rq, expected_seq in [
        (_RequestA(), list("abc")),
        (_RequestB(), list("abcxyz")),
    ]:
        result_seq = await executor.execute(rq, seq=[])
        assert result_seq == expected_seq

    with pytest.raises(LookupHandlerStoreError):
        await executor.execute(object())
Ejemplo n.º 10
0
async def test_local_event_bus():
    policies = [CallableHandlerPolicy()]
    bus = LocalEventBus(policies=policies)
    registry = EventHandlerRegistry(policies=policies)

    events = {i: asyncio.Event() for i in [0, 1, 100, 200]}

    bus.register(_create_event_handler(events, 0, _MockupEvent1))
    bus.register(_create_event_handler(events, 1, _MockupEvent1))
    registry.register(_create_event_handler(events, 100, _MockupEvent2))
    registry.register(_create_event_handler(events, 200, _MockupEvent2))
    bus.include(registry)

    for to_check, event_type in [
        ([0, 1], _MockupEvent1),
        ([100, 200], _MockupEvent2),
    ]:
        await bus.publish(event_type())
        for index in to_check:
            event = events[index]
            await asyncio.wait_for(event.wait(), timeout=0.5)
Ejemplo n.º 11
0
async def test_handler_factory_cascade_success(obj):
    cascade = HandlerFactoryCascade(
        policies=[CallableHandlerPolicy(),
                  MethodHandlerPolicy(name="method")])
    handler = cascade(obj)
    await _check_handler_works(handler)
Ejemplo n.º 12
0
            factory_errors, [MethodHandlerFactory, CallableHandlerFactory]):
        assert isinstance(factory, factory_type)
        assert isinstance(factory_error, IncompatibleHandlerFactoryError)


@pytest.mark.parametrize(
    "obj, policies, error_check",
    [
        (None, [], _check_config_error),
        (_A(), [MethodHandlerPolicy(name="method_no_type")
                ], _check_inspect_error),
        (
            _A(),
            [
                MethodHandlerPolicy(name="non_existing"),
                CallableHandlerPolicy()
            ],
            _check_incompatible_error,
        ),
    ],
)
def test_handler_factory_cascade_error(
    obj,
    policies: Sequence[PolicyType],
    error_check: Callable[[HandlerFactoryCascadeError], Any],
):
    with pytest.raises(HandlerFactoryCascadeError) as e:
        cascade = HandlerFactoryCascade(policies=policies)
        cascade(obj)
    error_check(e.value)
Ejemplo n.º 13
0
from dataclasses import dataclass

import pytest

from mediator.common.factory import CallableHandlerPolicy, MethodHandlerPolicy
from mediator.request import LocalRequestBus, RequestHandlerRegistry

# Create local request registry with given policies.
# Single policy tells the handler inspector where to find callable
# which handles particular action.
# - add policy that suggest to get object attribute named "execute"
#   and try to analyze as request handler
# - add policy that suggest given object is request handler callable
registry = RequestHandlerRegistry(
    policies=[MethodHandlerPolicy(name="execute"), CallableHandlerPolicy()],
)


@dataclass
class PrintCommand:
    message: str


class PrintCommandHandler:
    # noinspection PyMethodMayBeStatic
    async def execute(self, command: PrintCommand):
        print(f"print: {command.message}")
        return command.message


# ... MethodHandlerPolicy(...) gives ability to inspect handler object
Ejemplo n.º 14
0
def _registry_policies_factory():
    return HandlerRegistry(
        store=CollectionHandlerStore(),
        policies=[CallableHandlerPolicy()],
    )
Ejemplo n.º 15
0
        return arg, a, b

    async def c(self, arg: str, a: int):
        return arg, a, a + 1


async def _check_handler(handler: Handler):
    action = ActionSubject(subject="test", inject={"x": 1, "y": 2})
    result: ActionResult = await handler(action)
    assert result.result == ("test", 1, 2)


@pytest.mark.parametrize(
    "obj, policy",
    [
        (_A().a, CallableHandlerPolicy(arg_strict=True)),
        (_A().b,
         CallableHandlerPolicy(arg_map={
             "x": "a",
             "y": "b"
         }, arg_strict=True)),
        (_A().c, CallableHandlerPolicy(arg_map={"x": "a"})),
    ],
)
@pytest.mark.asyncio
async def test_callable_handler_factory(obj, policy: CallableHandlerPolicy):
    factory = CallableHandlerFactory(policy)
    handler = factory.create(obj)
    await _check_handler(handler)