Beispiel #1
0
def test_register_with_instance():
    instance = object()

    with pytest.raises(ValueError) as exception:
        Component.register(instance)

    assert str(exception.value) == f'Need class. Got: {instance}'
    assert exception.value.args == (f'Need class. Got: {instance}', )
Beispiel #2
0
def validate_missing_raises_annotations():
    from winter.web.exceptions.problem_annotation import ProblemAnnotation
    from winter.web.exceptions.raises import ExceptionAnnotation
    from winter.core import Component

    all_problem_exception: Set[Type[Exception]] = set()
    global_exceptions: Set[Type[Exception]] = set()
    declared_raises_exceptions: Set[Type[Exception]] = set()
    for cls, component in Component.get_all().items():
        if component.annotations.get_one_or_none(ProblemAnnotation):
            all_problem_exception.add(cls)
        if component.annotations.get_one_or_none(GlobalExceptionAnnotation):
            global_exceptions.add(cls)
        for method_component in component.methods:
            exception_annotations: Iterable[
                ExceptionAnnotation] = method_component.annotations.get(
                    ExceptionAnnotation)
            for exception_annotation in exception_annotations:
                declared_raises_exceptions.add(
                    exception_annotation.exception_cls)

    not_global_exceptions = all_problem_exception - global_exceptions
    missing_exceptions = not_global_exceptions - declared_raises_exceptions
    if missing_exceptions:
        message = ', '.join(
            exc.__name__
            for exc in sorted(missing_exceptions, key=lambda ex: ex.__name__))
        raise AssertionError(
            'You are missing declaration for next exceptions: ' + message)
Beispiel #3
0
def test_global_exception_decorator_declarative_way():
    @global_exception
    class GlobalException(Exception):
        pass

    component = Component.get_by_cls(GlobalException)
    assert component is not None
    assert component.annotations.get(GlobalExceptionAnnotation) == [GlobalExceptionAnnotation(GlobalException)]
Beispiel #4
0
def test_global_exception_decorator_imperative_way():
    class GlobalException(Exception):
        pass

    register_global_exception(GlobalException)

    component = Component.get_by_cls(GlobalException)
    assert component is not None
    assert component.annotations.get(GlobalExceptionAnnotation) == [GlobalExceptionAnnotation(GlobalException)]
Beispiel #5
0
def test_on_class_by_decorator(decorator):
    @decorator('test')
    class SimpleComponent:
        pass

    assert is_component(SimpleComponent)
    component = Component.get_by_cls(SimpleComponent)
    assert component.annotations.get(SimpleAnnotation) == [
        SimpleAnnotation('test')
    ]
Beispiel #6
0
def test_resolve_path_parameter(path, arg_name, expected_value):
    component = Component.get_by_cls(ControllerWithPathParameters)
    argument = component.get_method('test').get_argument(arg_name)
    resolver = PathParametersArgumentResolver()
    request = Mock(spec=Request)
    request.path_info = path

    # Act
    result = resolver.resolve_argument(argument, request, {})

    # Assert
    assert result == expected_value
Beispiel #7
0
def autodiscover_problem_annotations(handler_generator: ProblemExceptionHandlerGenerator):
    handled_problems: Dict[Type[Exception], ProblemAnnotation] = {
        cls: component.annotations.get_one(ProblemAnnotation)
        for cls, component in Component.get_all().items()
        if component.annotations.get_one_or_none(ProblemAnnotation)
    }
    for exception_class, problem_annotation in handled_problems.items():
        handler_class = handler_generator.generate(exception_class, problem_annotation.handling_info)
        exception_handlers_registry.add_handler(
            exception_class,
            handler_class,
            auto_handle=True,
        )
Beispiel #8
0
def test_methods():
    class SimpleComponent:
        @winter.core.component_method
        def simple_method(self):
            return self

    component = Component.get_by_cls(SimpleComponent)

    assert len(component.methods) == 1, SimpleComponent.simple_method
    method = component.get_method('simple_method')

    assert method is SimpleComponent.simple_method
    component = SimpleComponent()
    assert SimpleComponent.simple_method(component) is component
Beispiel #9
0
def generate_problem_handlers():
    mapper = ProblemExceptionMapper()
    handler_generator = ProblemExceptionHandlerGenerator()
    handled_problems: Dict[Type[Exception], ProblemAnnotation] = {
        cls: component.annotations.get_one(ProblemAnnotation)
        for cls, component in Component.get_all().items()
        if component.annotations.get_one_or_none(ProblemAnnotation)
    }
    for exception_class, problem_annotation in handled_problems.items():
        handler_class = handler_generator.generate(exception_class, mapper)
        exception_handlers_registry.add_handler(
            exception_class,
            handler_class,
            auto_handle=problem_annotation.auto_handle,
        )
Beispiel #10
0
def test_empty_annotation():
    @annotate(None)
    class Controller:
        @annotate(None)
        def simple_method(self):  # pragma: no cover
            pass

    component = Component.get_by_cls(Controller)

    # Assert
    assert Controller.simple_method.annotations.get_one_or_none(None) is None
    assert Controller.simple_method.annotations.get_one_or_none(
        type(None)) is None
    assert component.annotations.get_one_or_none(None) is None
    assert component.annotations.get_one_or_none(type(None)) is None
Beispiel #11
0
    def to_response_body(self, request: Request, exception: Exception) -> Dict:
        exception_class = exception.__class__
        component = Component.get_by_cls(exception_class)
        annotation = component.annotations.get_one(ProblemAnnotation)
        assert isinstance(annotation, ProblemAnnotation)

        problem_dict = dict(
            status=annotation.status,
            title=annotation.title
            or self._generate_default_title_value(exception_class),
            detail=annotation.detail or str(exception),
            type=annotation.type or self._generate_type_value(exception_class),
        )
        if dataclasses.is_dataclass(exception.__class__):
            problem_dict.update(dataclasses.asdict(exception))

        return problem_dict
Beispiel #12
0
    def generate(self, exception_class: Type[Exception],
                 exception_mapper: ExceptionMapper) -> Type[ExceptionHandler]:
        from winter import response_status

        component = Component.get_by_cls(exception_class)
        annotation = component.annotations.get_one(ProblemAnnotation)
        assert isinstance(annotation, ProblemAnnotation)

        return_type_class = self._build_exception_dataclass(exception_class)

        @response_status(annotation.status)
        def handle_method(self, request: Request, exception: exception_class,
                          **kwargs) -> return_type_class:
            return exception_mapper.to_response_body(request, exception)

        handler_class_name = exception_class.__name__ + 'Handler'
        handler_class = type(handler_class_name, (ExceptionHandler, ),
                             {'handle': handle_method})
        return handler_class
Beispiel #13
0
def controller(controller_class: Type) -> Type:
    Component.register(controller_class)
    return controller_class
Beispiel #14
0
def get_component(class_: Type) -> Component:
    return Component.get_by_cls(class_)
Beispiel #15
0
def get_component(controller_class: _ControllerType) -> Component:
    return Component.get_by_cls(controller_class)