예제 #1
0
def test_repr_str(container: DependencyContainer):
    container.register_provider(DummyProvider({'name': 'Antidote'}))
    container.update_singletons({'test': 1})

    assert 'test' in repr(container)
    assert repr(container.providers[DummyProvider]) in repr(container)
    assert str(container.providers[DummyProvider]) in str(container)
예제 #2
0
def test_implements(container: DependencyContainer):
    @implements(IService, container=container)
    @register(container=container)
    class Service(IService):
        pass

    assert container.get(IService) is container.get(Service)
예제 #3
0
def test_undefined_context(container: DependencyContainer,
                           interface_provider: IndirectProvider,
                           factory_provider: FactoryProvider):
    factory_provider.register_class(ServiceA)
    factory_provider.register_class(ServiceB)
    interface_provider.register(IService, ServiceA, Profile.A)
    container.update_singletons({Profile: Profile.B})

    with pytest.raises(UndefinedContextError):
        interface_provider.provide(IService)
예제 #4
0
def test_ignored_type_hints(type_hint):
    container = DependencyContainer()
    container.update_singletons({type_hint: object()})

    @inject(container=container)
    def f(x: type_hint):
        pass

    with pytest.raises(TypeError):
        f()
예제 #5
0
def test_multi_wire(container: DependencyContainer):
    xx = container.get('x')
    yy = container.get('y')

    @wire(methods=['f', 'g'], dependencies=('x', 'y'), container=container)
    class Dummy:
        def f(self, x):
            return x

        def g(self, x, y):
            return x, y

    d1 = Dummy()
    assert xx == d1.f()
    assert (xx, yy) == d1.g()

    @wire(methods=['f', 'g'],
          dependencies=dict(x='x', y='y'),
          container=container)
    class Dummy:
        def f(self, x):
            return x

        def g(self, x, y):
            return x, y

    d1 = Dummy()
    assert xx == d1.f()
    assert (xx, yy) == d1.g()

    @wire(methods=['f', 'g'], use_names=['x', 'y'], container=container)
    class Dummy2:
        def f(self, x):
            return x

        def g(self, x, y):
            return x, y

    d2 = Dummy2()
    assert xx == d2.f()
    assert (xx, yy) == d2.g()

    container.update_singletons({Dummy: d1, Dummy2: d2})

    @wire(methods=['f', 'g'], use_type_hints=['x', 'y'], container=container)
    class Dummy3:
        def f(self, x: Dummy):
            return x

        def g(self, x: Dummy, y: Dummy2):
            return x, y

    assert d1 == Dummy3().f()
    assert (d1, d2) == Dummy3().g()
예제 #6
0
def test_invalid_arguments():
    with pytest.raises(ValueError):
        ProxyContainer(DependencyContainer(), include=object())

    with pytest.raises(ValueError):
        ProxyContainer(DependencyContainer(), exclude=object())

    with pytest.raises(ValueError):
        ProxyContainer(DependencyContainer(), missing=object())

    with pytest.raises(ValueError):
        ProxyContainer(DependencyContainer(), dependencies=object())
예제 #7
0
def test_implements_profile(container: DependencyContainer):
    @implements(IService, state=Profile.A, container=container)
    @register(container=container)
    class ServiceA(IService):
        pass

    @implements(IService, state=Profile.B, container=container)
    @register(container=container)
    class ServiceB(IService):
        pass

    container.update_singletons({Profile: Profile.A})
    assert container.get(IService) is container.get(ServiceA)
예제 #8
0
def test_singleton_profile_instance(container: DependencyContainer,
                                    interface_provider: IndirectProvider,
                                    factory_provider: FactoryProvider):
    factory_provider.register_class(ServiceA)
    factory_provider.register_class(ServiceB, singleton=False)
    interface_provider.register(IService, ServiceA, Profile.A)
    interface_provider.register(IService, ServiceB, Profile.B)

    service_a = container.get(ServiceA)

    container.update_singletons({Profile: Profile.A})
    assert service_a is interface_provider.provide(IService).instance
    assert interface_provider.provide(IService).singleton is True
예제 #9
0
def test_context_include():
    container = DependencyContainer()
    container.update_singletons({'test': 1})
    container.update_singletons({'name': 'Antidote'})
    s = Service()
    container.update_singletons({Service: s})

    proxy_container = ProxyContainer(container, include=[Service])

    assert s is proxy_container.get(Service)

    with pytest.raises(DependencyNotFoundError):
        proxy_container.get('name')

    with pytest.raises(DependencyNotFoundError):
        proxy_container.get('test')

    proxy_container = ProxyContainer(container, include=[])

    with pytest.raises(DependencyNotFoundError):
        proxy_container.get(Service)

    with pytest.raises(DependencyNotFoundError):
        proxy_container.get('name')

    with pytest.raises(DependencyNotFoundError):
        proxy_container.get('test')
예제 #10
0
def test_arguments():
    container = DependencyContainer()
    container.update_singletons(dict(a=12, b=24))

    def f(a, b):
        pass

    arguments = Arguments.from_callable(f)

    @inject(arguments=arguments, use_names=True, container=container)
    def g(**kwargs):
        return kwargs

    assert dict(a=12, b=24) == g()
예제 #11
0
def test_invalid_type_hint():
    @inject(container=DependencyContainer())
    def f(x: Service):
        return x

    with pytest.raises(DependencyNotFoundError):
        f()
예제 #12
0
def test_profile_instance(container: DependencyContainer,
                          interface_provider: IndirectProvider,
                          factory_provider: FactoryProvider):
    factory_provider.register_class(ServiceA)
    factory_provider.register_class(ServiceB, singleton=False)
    interface_provider.register(IService, ServiceA, Profile.A)
    interface_provider.register(IService, ServiceB, Profile.B)
    current_profile = Profile.A

    def get_profile():
        return current_profile

    factory_provider.register_factory(Profile,
                                      singleton=False,
                                      factory=get_profile)

    service_a = container.get(ServiceA)
    service_b = container.get(ServiceB)

    assert service_a is interface_provider.provide(IService).instance
    assert interface_provider.provide(IService).singleton is False

    current_profile = Profile.B
    assert service_b is not interface_provider.provide(IService).instance
    assert isinstance(interface_provider.provide(IService).instance, ServiceB)
    assert interface_provider.provide(IService).singleton is False
예제 #13
0
def test_repr(provider: TagProvider):
    provider = TagProvider(DependencyContainer())

    x = object()
    provider.register(x, [Tag(name='tag')])

    assert str(x) in repr(provider)
예제 #14
0
def test_invalid(error, kwargs):
    container = DependencyContainer()

    with pytest.raises(error):
        @inject(container=container, **kwargs)
        def f(x):
            return x

        f()

    with pytest.raises(error):
        class A:
            @inject(container=container, **kwargs)
            def method(self, x):
                return x

        A().method()

    with pytest.raises(error):
        class A:
            @inject(container=container, **kwargs)
            @classmethod
            def classmethod(cls, x):
                return x

        A.classmethod()

    with pytest.raises(error):
        class A:
            @inject(container=container, **kwargs)
            @staticmethod
            def staticmethod(x):
                return x

        A.staticmethod()
예제 #15
0
def test_invalid(error, kwargs):
    container = DependencyContainer()

    def f(x):
        return x

    with pytest.raises(error):
        inject(f, container=container, **kwargs)()
예제 #16
0
def test_tagged_dependencies_invalid_dependency():
    tag = Tag('tag1')
    c = DependencyContainer()

    t = TaggedDependencies(container=c, dependencies=['d'], tags=[tag])
    assert ['d'] == list(t.dependencies())
    assert [tag] == list(t.tags())
    with pytest.raises(DependencyNotFoundError):
        list(t.instances())
예제 #17
0
def test_interface(container: DependencyContainer,
                   interface_provider: IndirectProvider,
                   factory_provider: FactoryProvider):
    factory_provider.register_class(Service)
    interface_provider.register(IService, Service)

    expected = container.get(Service)
    assert interface_provider.provide(IService).instance is expected
    assert interface_provider.provide(IService).singleton is True
예제 #18
0
def test_cannot_inject_self(error, kwargs):
    container = DependencyContainer()
    container.update_singletons(dict(x=object(), y=object()))

    with pytest.raises(error):
        class A:
            @inject(container=container, **kwargs)
            def method(self, x=None):
                return x
        A()

    with pytest.raises(error):
        class A:
            @inject(container=container, **kwargs)
            @classmethod
            def classmethod(self, x=None):
                return x
        A()
예제 #19
0
def test_no_injections():
    container = DependencyContainer()

    def f(x):
        return x

    injected_f = inject(f, container=container)

    # When nothing can be injected, the same function should be returned
    assert injected_f is f
예제 #20
0
def test_not_singleton_interface(container: DependencyContainer,
                                 interface_provider: IndirectProvider,
                                 factory_provider: FactoryProvider):
    factory_provider.register_class(Service, singleton=False)
    interface_provider.register(IService, Service)

    service = container.get(Service)
    assert interface_provider.provide(IService).instance is not service
    assert isinstance(interface_provider.provide(IService).instance, Service)
    assert interface_provider.provide(IService).singleton is False
예제 #21
0
def test_with_type_hints(expected, kwargs):
    container = DependencyContainer()
    container.update_singletons({Service: Service(),
                                 AnotherService: AnotherService(),
                                 'first': object(),
                                 'second': object(),
                                 'prefix:first': object(),
                                 'prefix:second': object()})
    default = object()

    @inject(container=container, **kwargs)
    def f(first: Service = default, second: str = default):
        return first, second

    class A:
        @inject(container=container, **kwargs)
        def method(self, first: Service = default, second: str = default):
            return first, second

        @inject(container=container, **kwargs)
        @classmethod
        def class_method(cls, first: Service = default, second: str = default):
            return first, second

        @inject(container=container, **kwargs)
        @staticmethod
        def static_method(first: Service = default, second: str = default):
            return first, second

    expected = tuple((
        container.get(d) if d is not None else default
        for d in expected
    ))
    assert expected == f()
    assert expected == A().method()
    assert expected == A.class_method()
    assert expected == A.static_method()

    a, b = object(), object()
    assert (a, b) == f(a, b)
    assert (a, b) == A().method(a, b)
    assert (a, b) == A.class_method(a, b)
    assert (a, b) == A.static_method(a, b)
예제 #22
0
def test_context_override():
    container = DependencyContainer()
    container.update_singletons({'test': 1})
    container.update_singletons({'name': 'Antidote'})
    s = Service()
    container.update_singletons({Service: s})

    proxy_container = ProxyContainer(container,
                                     dependencies=dict(test=2, name='testing'))

    assert s is proxy_container.get(Service)
    assert 2 == proxy_container.get('test')
    assert 'testing' == proxy_container.get('name')
예제 #23
0
def test_class_static_method():
    container = DependencyContainer()
    sentinel = object()
    container.update_singletons(dict(x=sentinel))

    class Dummy:
        @inject(container=container, use_names=True)
        @staticmethod
        def static_method(x):
            return x

        @inject(container=container, use_names=True)
        @classmethod
        def class_method(cls, x):
            return x

    assert sentinel == Dummy.static_method()
    assert sentinel == Dummy.class_method()
    assert sentinel == Dummy().static_method()
    assert sentinel == Dummy().class_method()
예제 #24
0
def test_already_injected():
    container = DependencyContainer()

    @inject(container=container, use_names=True)
    def f(x):
        return x

    injected_f = inject(f, container=container)

    # When the function has already its arguments injected, the same function should
    # be returned
    assert injected_f is f
예제 #25
0
def test_multiple_injections():
    container = DependencyContainer()
    xx = object()
    yy = object()
    zz = object()
    container.update_singletons(dict(xx=xx, yy=yy))

    @easy_wrap(arg_dependency=[('x', True, 'xx'),
                               ('y', True, 'yy'),
                               ('z', False, 'zz')],
               container=container)
    def f(x, y, z=zz):
        return x, y, z

    assert (xx, yy, zz) == f()
    assert (xx, sentinel, zz) == f(y=sentinel)
    assert (xx, yy, sentinel) == f(z=sentinel)
    assert (sentinel, yy, zz) == f(x=sentinel)
    assert (sentinel, yy, sentinel_2) == f(sentinel, z=sentinel_2)

    with pytest.raises(TypeError):
        f(sentinel, x=sentinel)
예제 #26
0
def test_bound_dependency_types():
    class CustomDependency:
        pass

    class DummyProvider1(DependencyProvider):
        bound_dependency_types = (CustomDependency,)

        def provide(self, dependency: Any) -> DependencyInstance:
            return DependencyInstance(self)

    class DummyProvider2(DependencyProvider):
        def provide(self, dependency: Any) -> DependencyInstance:
            raise Exception()

    container = DependencyContainer()
    container.register_provider(DummyProvider2(container))
    container.register_provider(DummyProvider1(container))
    assert isinstance(container.get(CustomDependency()), DummyProvider1)

    container = DependencyContainer()
    container.register_provider(DummyProvider1(container))
    container.register_provider(DummyProvider2(container))
    assert isinstance(container.get(CustomDependency()), DummyProvider1)
예제 #27
0
def test_resource_meta(container: DependencyContainer):
    class Conf(metaclass=LazyConstantsMeta, container=container):
        A = 'a'
        B = 'b'

        def get(self, key):
            return key * 2

    assert 'aa' == container.get(Conf.A)
    assert 'bb' == container.get(Conf.B)

    conf = Conf()

    assert 'aa' == conf.A
    assert 'bb' == conf.B
예제 #28
0
def test_subclass_classmethod(container: DependencyContainer):
    xx = container.get('x')

    @wire(methods=['cls_method'], use_names=True, container=container)
    class Dummy:
        @classmethod
        def cls_method(cls, x):
            return cls, x

    assert (Dummy, xx) == Dummy.cls_method()

    class SubDummy(Dummy):
        pass

    assert (SubDummy, xx) == SubDummy.cls_method()
예제 #29
0
def test_update(container: DependencyContainer):
    container.update_singletons({Service: Service()})

    another_service = AnotherService()
    x = object()

    container.update_singletons({
        Service: another_service,
        'x': x
    })

    assert another_service is container.get(Service)
    assert x is container.get('x')
예제 #30
0
def test_context_missing():
    container = DependencyContainer()
    container.update_singletons({'test': 1})
    container.register_provider(DummyProvider({'name': 'Antidote'}))
    s = Service()
    container.update_singletons({Service: s})

    proxy_container = ProxyContainer(container, missing=['name'])

    assert s is proxy_container.get(Service)
    assert 1 == proxy_container.get('test')

    with pytest.raises(DependencyNotFoundError):
        proxy_container.get('name')

    proxy_container = ProxyContainer(container, missing=['test'], include=[Service])

    assert s is proxy_container.get(Service)
    assert 'Antidote' == proxy_container.get('name')

    with pytest.raises(DependencyNotFoundError):
        proxy_container.get('test')