def collector_with_handlers(handler_as_function): collector = Collector() for index in range(1, 31): body = "/{0}".format("a" * index) collector.add_handler(handler=handler_as_function, body=body, name=str(index)) return collector
class FSM: def __init__(self, states: Type[Enum]) -> None: self.transitions: Dict[Enum, Transition] = {} self.collector = Collector() self.states = states def handler( self, on_state: Enum, next_state: Optional[Union[Enum, object]] = _default_transition, on_failure: Optional[Union[Enum, object]] = _default_transition, ) -> Callable: def decorator(handler: Callable) -> Callable: self.collector.add_handler( handler, body=on_state.name, name=on_state.name, include_in_status=False, ) self.transitions[on_state] = Transition( on_success=next_state, on_failure=on_failure, ) return handler return decorator
def test_defining_handler_in_collector_as_decorator( handler_as_function, extract_collector, collector_cls, ): collector = Collector() collector.handler()(handler_as_function) handlers = [collector.handler_for("handler_function")] assert handlers
async def test_execution_when_full_match(message, build_handler): event = threading.Event() message.command.body = "/command" collector = Collector() collector.add_handler(build_handler(event), body=message.command.body) await collector.handle_message(message) assert event.is_set()
async def test_executing_handler_when_partial_match(message, build_handler): event = threading.Event() message.command.body = "/command with arguments" collector = Collector() collector.add_handler(build_handler(event), body=message.command.command) await collector.handle_message(message) assert event.is_set()
def test_default_handler_after_including_into_another_collector( default_handler, handler_as_function, ): collector1 = Collector() collector2 = Collector(default=default_handler) collector1.include_collector(collector2) assert collector1.default_message_handler == collector2.default_message_handler
def test_preserve_length_sort_when_merging_collectors( collector_with_handlers, handler_as_function, ): collector = Collector() collector.add_handler(handler=handler_as_function, body="/{0}".format("a" * 1000)) collector_with_handlers.include_collector(collector) added_handlers = collector_with_handlers.sorted_handlers assert added_handlers[0] == collector.handlers[0]
def __init__( # noqa: WPS211 self, executor: Executor, bot: Bot, functions: Union[Dict[str, Callable], Sequence[Callable]], break_handler: Optional[Union[Handler, str, Callable]] = None, dependencies: Optional[Sequence[Depends]] = None, dependency_overrides_provider: Any = None, ) -> None: """Init middleware with required query_params. Arguments: executor: next callable that should be executed. bot: bot that will store ns state. functions: dict of functions and their names that will be used as next step handlers or set of sequence of functions that will be registered by their names. break_handler: handler instance or name of handler that will break next step handlers chain. dependencies: background dependencies that should be applied to handlers. dependency_overrides_provider: object that will override dependencies for this handler. """ super().__init__(executor) dependencies = converters.optional_sequence_to_list( bot.collector.dependencies, ) + converters.optional_sequence_to_list(dependencies, ) # noqa: W503 dep_override = (dependency_overrides_provider or bot.collector.dependency_overrides_provider) bot.state.ns_collector = Collector( dependencies=dependencies, dependency_overrides_provider=dep_override, ) bot.state.ns_store = {} bot.state.ns_break_handler = None if break_handler: if isinstance(break_handler, Handler): bot.state.ns_collector.handlers.append(break_handler) bot.state.ns_break_handler = break_handler.name elif callable(break_handler): register_function_as_ns_handler(bot, break_handler) bot.state.ns_break_handler = get_name_from_callable( break_handler) else: bot.state.ns_collector.handlers.append( bot.collector.handler_for(break_handler), ) bot.state.ns_break_handler = break_handler if isinstance(functions, dict): functions_dict = functions else: functions_dict = { get_name_from_callable(func): func for func in functions } for name, function in functions_dict.items(): register_function_as_ns_handler(bot, function, name)
def test_error_when_merging_handlers_with_equal_bodies(build_handler): collector1 = Collector() collector1.add_handler( handler=build_handler("handler1"), body="/body", name="handler1", ) collector2 = Collector() collector2.add_handler( handler=build_handler("handler2"), body="/body", name="handler2", ) with pytest.raises(AssertionError): collector1.include_collector(collector2)
async def test_dependency_saved_after_include_collector( bot, incoming_message, client, build_handler, ): event1 = threading.Event() event2 = threading.Event() collector = Collector() collector.default(build_handler(event1)) bot.collector = bot.exception_middleware.executor = Collector( dependencies=[Depends(build_handler(event2))], ) bot.include_collector(collector) await client.send_command(incoming_message) assert event1.is_set() assert event2.is_set()
def test_generating_body_from_snake_case(handler_as_normal_method): collector = Collector() collector.add_handler(handler=handler_as_normal_method) handler = collector.handler_for("handler_method_snake_case") assert handler.body == "/handler-method-snake-case"
def test_only_single_default_handler_can_defined_in_collector(default_handler): collector1 = Collector(default=default_handler) collector2 = Collector(default=default_handler) with pytest.raises(AssertionError): collector1.include_collector(collector2)
def test_collector_default_handler_generating(default_handler): collector = Collector(default=default_handler) assert collector.default_message_handler == default_handler
import asyncio from dataclasses import dataclass from uuid import UUID from botx import Bot, Collector, DependencyFailure, Depends, Message @dataclass class User: user_huid: UUID username: str is_authenticated: bool collector = Collector() def get_user_huid_from_message(message: Message) -> UUID: return message.user_huid async def fetch_user_by_huid( user_huid: UUID = Depends(get_user_huid_from_message), ) -> User: # some operations with db for example await asyncio.sleep(0.5) return User(user_huid=user_huid, username="******", is_authenticated=False) async def authenticate_user( bot: Bot, message: Message, user: User = Depends(fetch_user_by_huid)
def test_generating_body_from_pascal_case(handler_as_pascal_case_method): collector = Collector() collector.add_handler(handler=handler_as_pascal_case_method) handler = collector.handler_for("HandlerMethodPascalCase") assert handler.body == "/handler-method-pascal-case"
def test_generating_body_from_camel_case(handler_as_camel_case_method): collector = Collector() collector.add_handler(handler=handler_as_camel_case_method) handler = collector.handler_for("handlerMethodCamelCase") assert handler.body == "/handler-method-camel-case"
def test_handler_can_not_consist_from_slashes_only(handler_as_function): collector = Collector() with pytest.raises(ValidationError): collector.add_handler(handler_as_function, body="////")
def __init__(self, states: Type[Enum]) -> None: self.transitions: Dict[Enum, Transition] = {} self.collector = Collector() self.states = states