Пример #1
0
            self.one = one

    class Container(Injector):
        class SubContainer(Injector):
            foo = Foo
            one = 1

        foo = this.SubContainer.foo.one

    assert Container.foo == 1


# Item access.


item_access = CodeCollector()


@item_access.parametrize
def test_item_getter(code):
    """We can describe item access in the `Injector` in the declarative
    manner."""

    result = code()
    assert result == 1


@item_access
def ce642f492941():
    """Get item with string key."""
Пример #2
0
"""Tests related to Injector classes written inside other Injector classes."""
from dependencies import Injector
from dependencies import Package
from dependencies import this
from helpers import CodeCollector

parent_attr = CodeCollector()
subcontainer = CodeCollector("sub")


@parent_attr.parametrize
@subcontainer.parametrize
def test_attribute_getter_parent_access(code, sub):
    """We can access attribute of outer container."""
    Container = code(sub())
    assert Container.SubContainer.bar == 1


@parent_attr
def _ac7814095628(sub):
    class Container(Injector):
        foo = 1
        SubContainer = sub

    return Container


@parent_attr
def _f607abc82079(sub):
    return Injector(foo=1, SubContainer=sub)
# -*- coding: utf-8 -*-
"""Tests related to the circle detection in the injector definitions."""
import pytest

from dependencies import Injector
from dependencies import operation
from dependencies import Package
from dependencies import value
from dependencies.exceptions import DependencyError
from helpers import CodeCollector

# Simple circle.

circle_deps = CodeCollector()
circle_defs = CodeCollector("foo")


@circle_deps.parametrize
@circle_defs.parametrize
def test_circle_dependencies(code, foo):
    """Throw `DependencyError` if class needs a dependency named same as class.

    `Summator.foo` will fail with maximum recursion depth.

    So we need to raise exception before this attribute access.

    """
    with pytest.raises(DependencyError) as exc_info:
        code(foo())

    message = str(exc_info.value)
Пример #4
0
"""Tests related to descriptor objects."""
import pytest

from dependencies import Injector
from dependencies import Package
from dependencies.exceptions import DependencyError
from helpers import CodeCollector

deny_descriptors = CodeCollector()
define_descriptors = CodeCollector("foo")


@deny_descriptors.parametrize
@define_descriptors.parametrize
def test_deny_descriptors(code, foo):
    """Descriptors passed to the injector have confusing expectations.

    If users pass method descriptor to the injector, they probably expect access to the
    Injector itself.

    """
    with pytest.raises(DependencyError) as exc_info:
        code(foo())

    expected = """
Attribute 'foo' contains descriptor.

Descriptors usage will be confusing inside Injector subclasses.

Use @value decorator instead, if you really need inject descriptor instance somewhere.
""".strip()
Пример #5
0
from dependencies.exceptions import DependencyError
from helpers import CodeCollector


def test_protect_against_classes():
    """Deny to decorate classes with @value proxy."""
    with pytest.raises(DependencyError) as exc_info:

        @value
        class Foo:
            pass  # pragma: no cover

    assert str(exc_info.value) == "'value' decorator can not be used on classes"


deny_method = CodeCollector()


@deny_method.parametrize
def test_protect_against_self(code):
    """Deny to define a value with argument called `self`."""

    @value
    def method(self, foo, bar):
        pass  # pragma: no cover

    with pytest.raises(DependencyError) as exc_info:
        code(method)

    assert str(exc_info.value) == "'value' decorator can not be used on methods"
Пример #6
0

def test_keyword_arguments():
    class Container(Injector):

        foo = 1
        bar = 2

        @value
        def result(foo, bar, baz=3):
            return foo + bar + baz

    assert Container.result == 6


deny_method = CodeCollector()


@deny_method.parametrize
def test_protect_against_self(code):
    """Deny to define a value with argument called `self`."""

    @value
    def method(self, foo, bar):
        pass  # pragma: no cover

    with pytest.raises(DependencyError) as exc_info:
        code(method)

    assert str(exc_info.value) == "'value' decorator can not be used on methods"
# -*- coding: utf-8 -*-
"""Tests related to the loops detection in the injector definition."""
import pytest

from dependencies import Injector
from dependencies import Package
from dependencies import this
from dependencies.exceptions import DependencyError
from helpers import CodeCollector

# Flat injector.

flat_injector = CodeCollector()


@flat_injector.parametrize
def test_circle_links(code):
    """We can detect link loops in the same container without hierarchy."""
    with pytest.raises(DependencyError) as exc_info:
        code()

    assert str(exc_info.value) in {
        "'foo' is a circle link in the 'Container' injector",
        "'foo' is a circle link in the 'Injector' injector",
        "'bar' is a circle link in the 'Container' injector",
        "'bar' is a circle link in the 'Injector' injector",
        "'baz' is a circle link in the 'Container' injector",
        "'baz' is a circle link in the 'Injector' injector",
    }

Пример #8
0
"""Tests related to the Package object."""
import inspect

import pytest

from dependencies import Injector
from dependencies import Package
from helpers import CodeCollector

package_definitions = CodeCollector()


@package_definitions.parametrize
def test_provide_module(code):
    """Package instance itself should refer to the module."""
    Container = code()

    assert inspect.ismodule(Container.itself)
    assert inspect.ismodule(Container.submodule)


@package_definitions.parametrize
def test_provide_an_instance(code):
    """Package attribute access should provide an instance when refer to a class."""
    Container = code()

    from examples.submodule import Foo, Bar

    assert isinstance(Container.instance, Foo) or isinstance(
        Container.instance, Bar)
    assert hasattr(Container.instance, "do")
Пример #9
0
    assert "x" in dir(Foo.let(x=1))


def test_omit_parent_link_in_dir_listing():
    """
    Don't show `__parent__` link in the `dir` output.  It is an
    implementation detail.
    """
    class Foo(Injector):
        class Bar(Injector):
            pass

    assert "__parent__" not in dir(Foo.Bar)


attribute_assignment = CodeCollector()


@attribute_assignment.parametrize
def test_deny_injector_changes(code):
    """Explicitly deny change of any kind on `Injector` and its subclasses."""

    with pytest.raises(DependencyError) as exc_info:
        code()

    assert str(exc_info.value) == "'Injector' modification is not allowed"


@attribute_assignment
def mvT9oyJdXhzh():
    """Attribute assignment."""
Пример #10
0
from dependencies import Injector
from dependencies.exceptions import DependencyError
from helpers import CodeCollector


@unique
class Choices(Enum):
    """Enumeration class."""

    one = auto()
    two = auto()
    three = auto()


deny_enums = CodeCollector()


@deny_enums.parametrize
def test_deny_enums(code):
    """Deny inject enum classes.

    We should suggest to inject a specific enum member instead.

    """
    with pytest.raises(DependencyError) as exc_info:
        code()

    expected = """
Attribute 'foo' contains Enum.
Пример #11
0
"""Tests related to injectable objects."""
import pytest

from dependencies import Injector
from dependencies import value
from dependencies.exceptions import DependencyError
from helpers import CodeCollector

deny_varargs = CodeCollector()
varargs_defs = CodeCollector("foo")


@deny_varargs.parametrize
@varargs_defs.parametrize
def test_deny_arbitrary_argument_list(code, foo):
    """Raise `DependencyError` if constructor have *args argument."""
    with pytest.raises(DependencyError) as exc_info:
        code(foo())

    message = str(exc_info.value)
    assert message in {
        "'Foo.__init__' have variable-length positional arguments",
        "'func' have variable-length positional arguments",
    }


@deny_varargs
def _dfe1c22c641e(Foo):
    class Container(Injector):
        foo = Foo
        args = (1, 2, 3)
    app.tasks.clear()
    return app


class Run(object):
    def __init__(self, args, kwargs):
        self.args = args
        self.kwargs = kwargs

    def __call__(self):
        assert self.args == ("foo",)
        assert self.kwargs == {"bar": "baz"}
        return 1


containers = CodeCollector()


@containers
def bAMWkT3WSTN1(_app):
    """Task decorator."""

    @contrib.task
    class Container(Injector):

        app = _app
        name = "foo.bar.baz"
        run = Run

    return Container
Пример #13
0
        def __init__(self, one):
            self.one = one

    class Container(Injector):

        class SubContainer(Injector):
            foo = Foo
            one = 1

        foo = this.SubContainer.foo.one

    assert Container.foo == 1


parent_attr = CodeCollector()


@parent_attr.parametrize
def test_attribute_getter_parent_access(code):
    """We can access attribute of outer container."""

    Container = code()
    assert Container.SubContainer.bar == 1


@parent_attr
def ac7814095628():
    """Declarative injector."""

    class Container(Injector):
Пример #14
0

def test_omit_parent_link_in_dir_listing():
    """Don't show `__parent__` link in the `dir` output.

    It is an implementation detail.

    """
    class Foo(Injector):
        class Bar(Injector):
            x = 1

    assert "__parent__" not in dir(Foo.Bar)


attribute_assignment = CodeCollector()


@attribute_assignment.parametrize
def test_deny_injector_changes(code):
    """Explicitly deny change of any kind on `Injector` and its subclasses."""
    with pytest.raises(DependencyError) as exc_info:
        code()

    assert str(exc_info.value) == "'Injector' modification is not allowed"


@attribute_assignment
def _mvT9oyJdXhzh():
    class Container(Injector):
        x = 1
Пример #15
0
"""Tests related to the Injector subclasses checks."""
import pytest

from dependencies import Injector
from dependencies.exceptions import DependencyError
from helpers import CodeCollector

subclasses_only = CodeCollector()


@subclasses_only.parametrize
def test_multiple_inheritance_deny_regular_classes(code):
    """Only `Injector` subclasses are allowed to be used in the inheritance."""
    class Foo:
        pass

    with pytest.raises(DependencyError) as exc_info:
        code(Foo)

    message = str(exc_info.value)
    assert message == "Multiple inheritance is allowed for Injector subclasses only"


@subclasses_only
def _f1583394f1a6(Foo):
    class Bar(Injector, Foo):
        pass


@subclasses_only
def _b51814725d07(Foo):
Пример #16
0
import inspect

import pytest
from dependencies import Injector, Package
from helpers import CodeCollector

package_definitions = CodeCollector()


@package_definitions.parametrize
def test_provide_module(code):
    """Package instance itself should refer to the module."""

    Container = code()

    assert inspect.ismodule(Container.itself)
    assert inspect.ismodule(Container.submodule)


@package_definitions.parametrize
def test_provide_an_instance(code):
    """
    Package instance attribute access should provide injectable spec
    when refer to a class.
    """

    Container = code()

    from pkg.submodule import Foo, Bar

    assert isinstance(Container.instance, Foo) or isinstance(Container.instance, Bar)