def test_argument_ioc_at_scoped(): root_provider = ServiceProvider() with root_provider.scope() as scoped_provider: def singleton_func(ioc): # when you register in scoped_provider, # value should singleton base on scoped_provider. assert ioc is scoped_provider return 'singleton' def scoped_func(ioc): assert ioc is scoped_provider return 'scoped' def transient_func(ioc): assert ioc is scoped_provider return 'transient' scoped_provider.register_singleton(1, singleton_func) scoped_provider.register_scoped(2, scoped_func) scoped_provider.register_transient(3, transient_func) assert scoped_provider[1] == 'singleton' assert scoped_provider[2] == 'scoped' assert scoped_provider[3] == 'transient'
def test_symbol_caller_frame_from_deep(): provider = ServiceProvider() def get_name(ioc): fr = ioc[Symbols.caller_frame] mo = inspect.getmodule(fr.frame) return mo.__name__ provider.register_transient('name', get_name) assert provider['name'] == 'test_symbols'
def test_builder_register_inject_by_can_be_str_name(): provider = ServiceProvider() provider.register_value('f1', 1) provider.register_value('f2', 2) @provider.builder.transient('wtf', inject_by='name') def func(f1, f2): return f1 + f2 assert 3 == provider['wtf']
def test_resolve_group(): provider = ServiceProvider() provider.register_transient('str', lambda: 'name') provider.register_transient('int', lambda: 1) provider.register_value('float', 1.1) group_keys = ['str', 'int'] provider.register_group('any', group_keys) assert provider['any'] == ('name', 1) # always transient: assert provider['any'] is not provider['any'] # allow to add later group_keys.append('float') assert provider['any'] == ('name', 1, 1.1)
def test_symbols_values_ref(): from anyioc.symbols import Symbols provider = ServiceProvider() assert provider[Symbols.provider] is provider assert provider[Symbols.provider_root] is provider assert provider[Symbols.cache] is provider[Symbols.cache] with provider.scope() as scoped_provider: assert scoped_provider[Symbols.provider] is scoped_provider assert scoped_provider[Symbols.provider_root] is provider assert scoped_provider[Symbols.cache] is scoped_provider[Symbols.cache] assert scoped_provider[Symbols.cache] is not provider[Symbols.cache]
def test_type_resolver_with_cache(): class CLASS: def __init__(self, name): self.name = name provider = ServiceProvider() provider.register_value('name', 'some-name') with raises(ServiceNotFoundError): _ = provider[CLASS] tsir = TypesServiceInfoResolver() tsir.inject_by = inject_by_name provider[Symbols.missing_resolver].append(tsir) assert provider[CLASS].name == 'some-name' assert provider[CLASS] is not provider[CLASS]
def test_chain_resolver(): class CLASS: def __init__(self, name): self.name = name provider = ServiceProvider() provider.register_value('name', 'some-name') tsir = TypesServiceInfoResolver() tsir.inject_by = inject_by_name provider[Symbols.missing_resolver].append(ImportServiceInfoResolver() + tsir) import sys assert provider['sys'] is sys assert provider[CLASS].name == 'some-name' with raises(ServiceNotFoundError): _ = provider['unknown-some-wtf-module']
def test_builder_group_with_no_keys(): provider = ServiceProvider() group = provider.builder.group() group.value(object())(2) group.value(object())(4) group.value(object())(6) assert provider[group] == (2, 4, 6)
def assert_value_transient(provider: ServiceProvider, key): scoped_1 = provider.scope() scoped_2 = provider.scope() scoped_1_1 = scoped_1.scope() for l, r in itertools.combinations_with_replacement( [provider, scoped_1, scoped_2, scoped_1_1], 2): assert l.get(key) is not r.get(key)
def test_builder_register_key_canbe_none(): provider = ServiceProvider() @provider.builder.singleton(None) def func(): return 1 assert provider[func] == 1
def test_builder_register_as_decorator_return_factory(): provider = ServiceProvider() @provider.builder.singleton(1) def func(): pass assert func is not None and func.__name__ == 'func'
def test_builder_singleton_as_decorator(): provider = ServiceProvider() @provider.builder.singleton(1) def func(): return ServiceProvider() assert_value_singleton(provider, 1)
def test_builder_scoped_as_decorator(): provider = ServiceProvider() @provider.builder.scoped(1) def func(): return ServiceProvider() assert_value_scoped(provider, 1)
def test_builder_transient_as_decorator(): provider = ServiceProvider() @provider.builder.transient(1) def func(): return ServiceProvider() assert_value_transient(provider, 1)
def test_get_many(): provider = ServiceProvider() provider.register_transient('a', lambda ioc: 1) provider.register_transient('a', lambda ioc: 2) provider.register_transient('a', lambda ioc: 3) assert [3, 2, 1] == provider.get_many('a')
def test_builder_register_key_canbe_a_list(): provider = ServiceProvider() @provider.builder.singleton([1, 2]) def func(): return 3 assert provider[1] == 3 assert provider[2] == 3
def test_builder_value(): provider = ServiceProvider() @provider.builder.value('type:A') class A: pass assert provider['type:A'] == A assert isinstance(A, type)
def test_get_many_from_multilevel(): provider = ServiceProvider() provider.register_transient('a', lambda ioc: 10) provider.register_transient('a', lambda ioc: 11) provider2 = provider.scope() provider2.register_transient('a', lambda ioc: 20) provider2.register_transient('a', lambda ioc: 21) provider3 = provider2.scope() provider3.register_transient('a', lambda ioc: 30) provider3.register_transient('a', lambda ioc: 31) provider4 = provider3.scope() provider4.register_transient('a', lambda ioc: 40) provider4.register_transient('a', lambda ioc: 41) assert [31, 30, 21, 20, 11, 10] == provider3.get_many('a')
def test_options_auto_enter(): provider = ServiceProvider(auto_enter=True) class ContextManager: value = 0 def __enter__(self): self.value = 1 return self def __exit__(self, exc_type, exc_val, exc_tb): self.value = 2 provider.register_scoped('mgr', ContextManager) with provider.scope() as scoped_provider: mgr = scoped_provider['mgr'] assert mgr.value == 1 assert mgr.value == 2
def test_builder_group_as_decorator(): provider = ServiceProvider() group = provider.builder.group() @group.singleton() class A: pass instance, = provider[group] assert isinstance(instance, A)
def test_parameters_count(): provider = ServiceProvider() # 0 args provider.register_singleton(1, lambda: 101) # 1 args provider.register_singleton(2, lambda x: 102) # 2 args with raises(TypeError): provider.register_singleton(3, lambda x, y: 103) assert provider[1] == 101 assert provider[2] == 102
def test_symbols_types(): from anyioc.symbols import Symbols from anyioc.ioc import IServiceProvider from anyioc.ioc_resolver import IServiceInfoResolver provider = ServiceProvider() assert isinstance(provider[Symbols.provider], IServiceProvider) assert isinstance(provider[Symbols.provider_root], IServiceProvider) assert isinstance(provider[Symbols.cache], dict) assert isinstance(provider[Symbols.missing_resolver], IServiceInfoResolver) with provider.scope() as scoped_provider: assert isinstance(scoped_provider[Symbols.provider], IServiceProvider) assert isinstance(scoped_provider[Symbols.provider_root], IServiceProvider) assert isinstance(scoped_provider[Symbols.cache], dict) assert isinstance(scoped_provider[Symbols.missing_resolver], IServiceInfoResolver)
def test_import_resolver(): provider = ServiceProvider() with raises(ServiceNotFoundError): _ = provider['anyioc'] provider[Symbols.missing_resolver].append(ImportServiceInfoResolver()) import anyioc assert provider['anyioc'] is anyioc import sys assert provider['sys'] is sys with raises(ServiceNotFoundError): _ = provider['unknown-some-wtf-module']
def test_predefined_keys(): map_to_self_keys = ( # str 'ioc', 'provider', 'service_provider', # type ServiceProvider, IServiceProvider, # symbol Symbols.provider ) provider = ServiceProvider() for k in map_to_self_keys: assert provider is provider[k] with provider.scope() as scoped: for k in map_to_self_keys: assert scoped is scoped[k] with scoped.scope() as deep_scoped: for k in map_to_self_keys: assert deep_scoped is deep_scoped[k]
def test_builder_register_inject_by_can_be_str_anno(): provider = ServiceProvider() provider.register_value(int, 10) provider.register_value(str, '2') @provider.builder.transient('wtf', inject_by='anno') def func(f1: int, f2: str): return f'{f1}{f2}' assert '102' == provider['wtf']
def test_error_message(): provider = ServiceProvider() provider.register_transient('a', lambda ioc: ioc['b']) provider.register_transient('b', lambda ioc: ioc['c']) provider.register_transient('c', lambda ioc: ioc['d']) with raises( ServiceNotFoundError, match="unknown service: 'd'; resolve chain: 'a'->'b'->'c'->'d'"): provider['a']
def test_argument_ioc_at_root(): root_provider = ServiceProvider() with root_provider.scope() as scoped_provider: def singleton_func(ioc): assert ioc is root_provider return 'singleton' def scoped_func(ioc): assert ioc is scoped_provider return 'scoped' def transient_func(ioc): assert ioc is scoped_provider return 'transient' root_provider.register_singleton(1, singleton_func) root_provider.register_scoped(2, scoped_func) root_provider.register_transient(3, transient_func) assert scoped_provider[1] == 'singleton' assert scoped_provider[2] == 'scoped' assert scoped_provider[3] == 'transient'
def test_service_info(): other_kwargs = { 'service_provider': ServiceProvider(), 'key': 'test-key', 'lifetime': LifeTime.transient, } # without parameters si = ServiceInfo(factory=lambda: 15, **other_kwargs) assert si.get(other_kwargs['service_provider']) == 15 # with one parameter si = ServiceInfo(factory=lambda _: 15, **other_kwargs) assert si.get(other_kwargs['service_provider']) == 15 # with one keyword parameter si = ServiceInfo(factory=lambda *, sr2fe: 15, **other_kwargs) assert si.get(other_kwargs['service_provider']) == 15
def test_(): from anyioc.ioc_resolver import TypingServiceInfoResolver from typing import Tuple, List class TestClass: pass provider = ServiceProvider() provider.register_transient(TestClass, TestClass) provider.register_value(int, 15) provider[Symbols.missing_resolver].append(TypingServiceInfoResolver()) ret = provider[Tuple[TestClass, int]] assert isinstance(ret, tuple) assert isinstance(ret[0], TestClass) assert ret[1] == 15
def func(): return ServiceProvider()