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())
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()
def test_invalid_type_hint(): @inject(container=DependencyContainer()) def f(x: Service): return x with pytest.raises(DependencyNotFoundError): f()
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')
def test_context_isolation(): container = DependencyContainer() container.update_singletons({'test': 1}) container.update_singletons({'name': 'Antidote'}) s = Service() container.update_singletons({Service: s}) proxy_container = ProxyContainer(container) assert s is proxy_container.get(Service) assert 1 == proxy_container.get('test') assert 'Antidote' == proxy_container.get('name') proxy_container.update_singletons({'another_service': AnotherService()}) assert isinstance(proxy_container.get('another_service'), AnotherService) s2 = Service() proxy_container.update_singletons({Service: s2}) assert s2 is proxy_container.get(Service) with pytest.raises(DependencyNotFoundError): container.get('another_service') assert s is container.get(Service) assert 1 == container.get('test') assert 'Antidote' == container.get('name')
def test_repr(provider: TagProvider): provider = TagProvider(DependencyContainer()) x = object() provider.register(x, [Tag(name='tag')]) assert str(x) in repr(provider)
def test_invalid(error, kwargs): container = DependencyContainer() def f(x): return x with pytest.raises(error): inject(f, container=container, **kwargs)()
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())
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()
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
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
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')
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()
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)
def test_tagged_dependencies(): tag1 = Tag('tag1') tag2 = Tag('tag2', dummy=True) c = DependencyContainer() t = TaggedDependencies(container=c, dependencies=['d', 'd2'], tags=[tag1, tag2]) assert {tag1, tag2} == set(t.tags()) assert {'d', 'd2'} == set(t.dependencies()) assert 2 == len(t) # instantiation from container c.update_singletons({'d': 'test', 'd2': 'test2'}) assert {'test', 'test2'} == set(t.instances()) # from cache c.update_singletons({'d': 'different', 'd2': 'different2'}) assert {'test', 'test2'} == set(t.instances())
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()
def test_without_type_hints(expected, kwargs): container = DependencyContainer() container.update_singletons({Service: Service()}) container.update_singletons({AnotherService: AnotherService()}) container.update_singletons({'first': object()}) container.update_singletons({'second': object()}) container.update_singletons({'prefix:first': object()}) container.update_singletons({'prefix:second': object()}) default = object() @inject(container=container, **kwargs) def f(first=default, second=default): return first, second class A: @inject(container=container, **kwargs) def method(self, first=default, second=default): return first, second @inject(container=container, **kwargs) @classmethod def class_method(cls, first=default, second=default): return first, second @inject(container=container, **kwargs) @staticmethod def static_method(first=default, second=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)
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()
def test_without_type_hints(expected, kwargs): container = DependencyContainer() container.update_singletons({Service: Service()}) container.update_singletons({AnotherService: AnotherService()}) container.update_singletons({'first': object()}) container.update_singletons({'second': object()}) container.update_singletons({'prefix:first': object()}) container.update_singletons({'prefix:second': object()}) default = object() @inject(container=container, **kwargs) def f(first=default, second=default): return first, second expected = tuple( (container.get(d) if d is not None else default for d in expected)) assert expected == f() a, b = object(), object() assert (a, b) == f(a, b)
def test_bound_dependency_types_conflict(): class CustomDependency: pass class DummyProvider1(DependencyProvider): bound_dependency_types = (CustomDependency,) def provide(self, dependency: Any) -> DependencyInstance: return DependencyInstance(self) class DummyProvider2(DependencyProvider): bound_dependency_types = (CustomDependency,) def provide(self, dependency: Any) -> DependencyInstance: return DependencyInstance(self) container = DependencyContainer() container.register_provider(DummyProvider1(container)) with pytest.raises(RuntimeError): container.register_provider(DummyProvider2(container))
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')
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)
def test_class_inject(): container = DependencyContainer() with pytest.raises(TypeError): @inject(container=container) class Dummy: pass
""" Test only that the wrapper behaves nicely in all cases. Injection itself is tested through inject. """ from typing import Any, List, Tuple import pytest from antidote._internal.wrapper import InjectedWrapper, Injection, InjectionBlueprint from antidote.core import DependencyContainer from antidote.exceptions import DependencyNotFoundError default_container = DependencyContainer() sentinel = object() sentinel_2 = object() sentinel_3 = object() default_container.update_singletons(dict(x=sentinel)) inject_self_x = [('self', True, None), ('x', True, 'x')] inject_cls_x = [('cls', True, None), ('x', True, 'x')] inject_x = [('x', True, 'x')] def easy_wrap(func=None, arg_dependency: List[Tuple[str, bool, Any]] = tuple(), container: DependencyContainer = None): def wrapper(func): return InjectedWrapper( container=container or default_container, blueprint=InjectionBlueprint(tuple([ Injection(arg_name, required, dependency)
def container(): c = DependencyContainer() c.register_provider(LazyCallProvider(container=c)) c.register_provider(FactoryProvider(container=c)) return c
def container(): container = DependencyContainer() container.update_singletons(dict(x=object(), y=object())) return container
def container(): c = DependencyContainer() c.register_provider(FactoryProvider(container=c)) c.register_provider(IndirectProvider(container=c)) return c
def provider(): container = DependencyContainer() provider = FactoryProvider(container=container) container.register_provider(provider) return provider
def container(): return DependencyContainer()