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_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_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_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_singleton(container: DependencyContainer): container.register_provider(DummyFactoryProvider({ Service: lambda: Service(), AnotherService: lambda: AnotherService(), })) service = container.get(Service) assert service is container.get(Service) container.providers[DummyFactoryProvider].singleton = False another_service = container.get(AnotherService) assert another_service is not container.get(AnotherService) singletons = {k: v.instance for k, v in container.singletons.items()} assert {Service: service, DependencyContainer: container} == singletons
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_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_dependency_cycle_error(container: DependencyContainer): container.register_provider(DummyFactoryProvider({ Service: lambda: Service(container.get(AnotherService)), AnotherService: lambda: AnotherService(container.get(YetAnotherService)), YetAnotherService: lambda: YetAnotherService(container.get(Service)), })) with pytest.raises(DependencyCycleError): container.get(Service) with pytest.raises(DependencyCycleError): container.get(AnotherService) with pytest.raises(DependencyCycleError): container.get(YetAnotherService)
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_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_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_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_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_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_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_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_wire_super(container: DependencyContainer): xx = container.get('x') sentinel = object() class Dummy: def method(self, x): return self, x @wire(wire_super=True, methods=['method'], use_names=True, container=container) class SubDummy(Dummy): pass sub_dummy = SubDummy() assert (sub_dummy, xx) == sub_dummy.method() assert (sub_dummy, sentinel) == sub_dummy.method(sentinel) with pytest.raises(TypeError): # did not affect base class Dummy().method()
def test_tagged_dependencies_instantiation_safety( container: DependencyContainer): n_dependencies = 40 for i in range(n_dependencies): factory(make_delayed_factory( type('Service{}'.format(i), (object, ), {})), singleton=False, tags=['test'], container=container) tagged = container.get(Tagged('test')) # type: TaggedDependencies dependencies = [] def worker(): for i, dep in enumerate(tagged.instances()): dependencies.append((i, dep)) multi_thread_do(worker) assert n_dependencies == len(set(dependencies)) assert set(dependencies) == set(enumerate(tagged.instances()))
def test_getitem(container: DependencyContainer): container.register_provider(DummyFactoryProvider({ Service: lambda: Service(), ServiceWithNonMetDependency: lambda: ServiceWithNonMetDependency(), })) container.register_provider(DummyProvider({'name': 'Antidote'})) with pytest.raises(DependencyNotFoundError): container.get(object) with pytest.raises(DependencyInstantiationError): container.get(ServiceWithNonMetDependency) assert isinstance(container.get(Service), Service) assert isinstance(container.provide(Service), DependencyInstance) assert 'Antidote' == container.get('name') assert 'Antidote' == container.provide('name').instance
def test_setitem(container: DependencyContainer): s = object() container.update_singletons({'service': s}) assert s is container.get('service') assert repr(s) in repr(container)