def test_big_dependency_tree():
    metrics = MagicMock()
    container = Container()
    container.set_metrics(metrics)
    container.register(Settings, value=object())
    container.register(OneCustomType, value=OneCustomType(object))
    container.register(TwoCustomType, value=TwoCustomType(object))
    container.register(ThreeCustomType, value=ThreeCustomType(object))
    container.register(FourCustomType, value=FourCustomType(object))
    container.register(FiveCustomType, value=FiveCustomType(object))
    container.register(AbstractService, factory=ImplementationService)

    @container.inject
    def set_values(
        param1: int,
        d1: ServiceOne = Depends(ServiceOne),
        d2: MyMainClass = Depends(MyMainClass),
        d3: AnotherMainClass = Depends(AnotherMainClass),
    ) -> None:
        ...

    for _ in range(10):
        set_values(1)

    calls = metrics.save_metric.mock_calls
    assert calls
示例#2
0
def test_sub_container():
    class Dependency(Protocol):
        x: int

    class Dependency1:
        x = 1

    class Dependency2:
        x = 2

    class Client:
        def __init__(self, dependency: Dependency) -> None:
            self.x = dependency.x

    container = Container()

    sub_container = container.sub_container()
    sub_container.register(Dependency, value=Dependency1())

    with pytest.raises(ResolverError) as e:
        container.resolve(Client)

    client1 = sub_container.resolve(Client)

    assert client1.x == 1

    container.register(Dependency, value=Dependency2())
    client2 = container.resolve(Client)

    assert client2.x == 2
示例#3
0
def test_container_clear() -> None:
    test_callable = MagicMock()

    class Dependency:
        def __init__(self):
            test_callable()

    class Client:
        def __init__(self, dep: Dependency):
            ...

    container = Container()

    container.resolve(Dependency)
    test_callable.assert_called_once()

    container.resolve(Dependency)
    test_callable.assert_called_once()

    container.clear()
    container.resolve(Dependency)
    test_callable.assert_has_calls([call(), call()])

    container.resolve(Dependency)
    test_callable.assert_has_calls([call(), call()])
示例#4
0
def test_preload():
    container = Container()
    m1, m2, m3 = MagicMock(), MagicMock(), MagicMock()

    class B:
        def __init__(self) -> None:
            m1()

    class C:
        def __init__(self) -> None:
            m2()

    class A:
        def __init__(self, b: B, c: C) -> None:
            m3()

    @container.inject
    def my_function(dependency=Depends(A)) -> None:
        ...

    @container.inject
    def another_function(dependency=Depends(B)) -> None:
        ...

    @container.inject
    def and_another_function(dependency=Depends(C)) -> None:
        ...

    container.preload_injected()

    m1.assert_has_calls([call(), call()])
    m2.assert_has_calls([call(), call()])
    m3.assert_has_calls([call()])
示例#5
0
def test_cache_thread_safety():
    test_fn = MagicMock()

    class Dependency:
        def __init__(self):
            sleep(0.1)
            test_fn()

    container = Container()

    @container.inject
    def function(d: Dependency = Depends(Dependency)):
        ...

    threads = []

    for _ in range(10):
        thread = Thread(target=function)
        threads.append(thread)
        thread.start()

    for thread in threads:
        thread.join()

    test_fn.assert_called_once()
示例#6
0
def test_basic_register_resolve():
    class TestDependency:
        def __init__(self):
            self.x = 1

    container = Container()
    container.register(TestDependency)

    assert container.resolve(TestDependency).x == 1
示例#7
0
def test_resolving_with_wrong_parameters():
    class Dependency:
        x = 1

    class Client:
        def __init__(self, dependency: Dependency) -> None:
            self._dependency = dependency

    container = Container()

    with pytest.raises(ResolverError):
        client = container.resolve(Client, non_existing_parameter=Dependency())
示例#8
0
def test_resolve_with_default_values_override_with_parameters():
    class Dependency:
        def __init__(self, x: int = 1):
            self.x = x

    class Service:
        def __init__(self, dependency: Dependency, value: int = 1):
            self.x = dependency.x + value

    container = Container()
    service = container.resolve(Service, value=2)

    assert service.x == 3
示例#9
0
def test_new_type_properly_set() -> None:
    container = Container()
    MyType = NewType("MyType", int)
    my_type_value = MyType(1)

    container.register(MyType, value=my_type_value)

    class MyService:
        def __init__(self, my_type: MyType) -> None:
            self.my_type = my_type

    instance = container.resolve(MyService)
    assert instance.my_type == my_type_value
示例#10
0
def test_decorator_dependency():
    class Dependency:
        def __init__(self):
            self.x = 1

    container = Container()

    @container.inject
    def my_function(
        value: int, dependency: Dependency = Depends(Dependency)) -> int:
        return value + dependency.x

    assert my_function(value=1) == 2
示例#11
0
def test_simple_hierarchy_depedency():
    class TestDependency:
        def __init__(self):
            self.x = 1

    class AnotherTestDependency:
        def __init__(self, dependency: TestDependency):
            self.x = dependency.x + 1

    container = Container()
    container.register(AnotherTestDependency)

    assert container.resolve(AnotherTestDependency).x == 2
示例#12
0
def test_dependency_without_registered_dependencies():
    class TestDependency:
        def __init__(self):
            self.x = 1

    container = Container()

    dependency_1 = container.resolve(TestDependency)
    dependency_2 = container.resolve(TestDependency)

    assert dependency_1.x == 1
    assert dependency_2.x == 1
    assert dependency_1 is dependency_2
示例#13
0
def test_register_dependency_with_default_value():
    class TestDependency:
        def __init__(self, x):
            self.x = x

    class AnotherTestDependency:
        def __init__(self, dependency: TestDependency):
            self.x = dependency.x + 1

    container = Container()
    container.register(TestDependency, value=TestDependency(x=2))

    assert container.resolve(AnotherTestDependency).x == 3
示例#14
0
def test_sub_container():
    os.environ["test"] = "test"

    class MySettings(BaseSettings):
        test: str

    class Client:
        def __init__(self, settings: MySettings) -> None:
            self.settings_test = settings.test

    container = Container()
    client = container.resolve(Client)

    assert client.settings_test == "test"
示例#15
0
def test_multiple_basic_register_resolve():
    class TestDependency:
        def __init__(self):
            self.x = 1

    class AnotherTestDependency:
        def __init__(self):
            self.x = 2

    container = Container()
    container.register(TestDependency)
    container.register(AnotherTestDependency)

    assert container.resolve(TestDependency).x == 1
    assert container.resolve(AnotherTestDependency).x == 2
示例#16
0
def test_register_dependency_by_factory():
    class Dependency:
        def __init__(self, x):
            self.x = x

    def dependency_factory() -> Dependency:
        return Dependency(1)

    class AnotherDependency:
        def __init__(self, dependency: Dependency):
            self.x = dependency.x

    container = Container()
    container.register(Dependency, factory=dependency_factory)

    assert container.resolve(AnotherDependency).x == 1
示例#17
0
def test_simple_hierarchy_depedency_without_registerd_dependency():
    class TestDependency:
        def __init__(self):
            self.x = 1

    class AnotherTestDependency:
        def __init__(self, dependency: TestDependency):
            self.x = dependency.x + 1

    container = Container()

    dependency_1 = container.resolve(AnotherTestDependency)
    dependency_2 = container.resolve(AnotherTestDependency)

    assert dependency_1 is dependency_2
    assert dependency_1.x == 2
示例#18
0
def test_decorator_dependency_with_mixed_arguments():
    class Dependency:
        def __init__(self):
            self.x = 1

    container = Container()

    @container.inject
    def my_function(p1: int,
                    p2: int,
                    p3: int,
                    p4: int,
                    dep: Dependency = Depends(Dependency)) -> int:
        return p1 + p2 + dep.x + p3 + p4

    assert my_function(1, 2, 3, p4=4) == 11
    assert my_function(1, p3=2, p2=3, p4=4) == 11
示例#19
0
def test_sub_container_2():
    class Dependency(Protocol):
        x: int

    class Dependency1:
        x = 1

    class Client:
        def __init__(self, dependency: Dependency) -> None:
            self.x = dependency.x

    container = Container()
    container.register(Dependency, value=Dependency1())

    sub_container = container.sub_container()
    client = sub_container.resolve(Client)

    assert client.x == 1
示例#20
0
def test_value_and_factory_register_exception():
    class Dependency:
        def __init__(self, x):
            self.x = x

    def dependency_factory() -> Dependency:
        return Dependency(1)

    class AnotherDependency:
        def __init__(self, dependency: Dependency):
            self.x = dependency.x

    container = Container()

    with pytest.raises(ContainerRegisterError):
        container.register(Dependency,
                           factory=dependency_factory,
                           value=Dependency(2))
示例#21
0
def test_missing_dependencies() -> None:
    class Dependency:
        ...

    class Client:
        def __init__(self, dep: Dependency, unknown_dep):
            ...

    def function(dep: Client, unknown_param):
        ...

    container = Container()

    with pytest.raises(ResolverError, match="Can resolve dependencies for"):
        container.resolve(Client)

    with pytest.raises(ResolverError, match="Can resolve dependencies for"):
        container.resolve(function)
示例#22
0
def test_inject_scoped():
    test_fn = MagicMock()

    class Dependency:
        def __init__(self):
            test_fn()

    container = Container()

    @container.inject_scoped
    def function(d: Dependency = Depends(Dependency)):
        ...

    test_fn.assert_not_called()
    function()
    test_fn.assert_called_once()
    function()
    test_fn.assert_has_calls([call(), call()])
def test_dummy_celery_injector():
    container = Container()

    class Dependency:
        def __init__(self):
            self.x = 1

    class Celery:
        def task(self, fn):
            return fn

    celery = Celery()

    @celery_task(celery, container)
    def my_function(dependency: Dependency = Depends(Dependency)):
        return dependency.x

    assert my_function() == 1
示例#24
0
def test_multiple_dependencies():
    class Dependency1:
        def __init__(self):
            self.x = 1

    class Dependency2:
        def __init__(self):
            self.x = 2

    class Dependency3:
        def __init__(self, dependency: Dependency1):
            self.x = dependency.x + 1

    class Dependency4:
        def __init__(self, dependency_3: Dependency3,
                     dependency_2: Dependency2):
            self.x = dependency_3.x + dependency_2.x

    container = Container()

    assert container.resolve(Dependency4).x == 4
示例#25
0
def test_metrics():
    metrics = MagicMock()
    container = Container(metrics=metrics)

    class B:
        ...

    class C:
        ...

    class A:
        def __init__(self, b: B, c: C) -> None:
            ...

    @container.inject
    def my_function(dependency=Depends(A)) -> None:
        ...

    for _ in range(100):
        my_function()

    assert metrics.save_metric.mock_calls
示例#26
0
def test_more_complex_example():
    class Dependency:
        x = 1

    def factory():
        return 1

    Dep = NewType("Dep", int)

    class Client:
        def __init__(self, dep1: Dependency, dep2: Dep) -> None:
            self.dep1 = dep1
            self.dep2 = dep2

    container = Container()
    container.register(Dep, factory=factory)
    container.register(Dependency, value=Dependency())

    client = container.resolve(Client)

    assert client.dep1.x == 1
    assert client.dep2 == 1
示例#27
0
def test_resolving_with_parameters():
    class FirstDependency:
        x = 1

    class Dependency(Protocol):
        y: int

    class ConcreteDependency:
        y = 2

    class Client:
        def __init__(self, first_dependency: FirstDependency,
                     second_dependency: Dependency) -> None:
            self.x = first_dependency.x
            self.y = second_dependency.y

        def add(self) -> int:
            return self.x + self.y

    container = Container()
    client = container.resolve(Client, second_dependency=ConcreteDependency)

    assert client.add() == 3