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)
def test_implements(container: DependencyContainer): @implements(IService, container=container) @register(container=container) class Service(IService): pass assert container.get(IService) is container.get(Service)
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)
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_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()
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_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)
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
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_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_invalid_type_hint(): @inject(container=DependencyContainer()) def f(x: Service): return x with pytest.raises(DependencyNotFoundError): f()
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
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() 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(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_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
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_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_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
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)
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_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_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_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_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_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
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()
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')
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')