mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-04-14 22:24:25 +03:00
Migrate async tests
This commit is contained in:
parent
6015afa76b
commit
11721b0d5a
45
tests/unit/providers/async/common.py
Normal file
45
tests/unit/providers/async/common.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
"""Common test artifacts."""
|
||||
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
from dependency_injector import containers, providers
|
||||
|
||||
|
||||
RESOURCE1 = object()
|
||||
RESOURCE2 = object()
|
||||
|
||||
|
||||
async def init_resource(resource):
|
||||
await asyncio.sleep(random.randint(1, 10) / 1000)
|
||||
yield resource
|
||||
await asyncio.sleep(random.randint(1, 10) / 1000)
|
||||
|
||||
|
||||
class Client:
|
||||
def __init__(self, resource1: object, resource2: object) -> None:
|
||||
self.resource1 = resource1
|
||||
self.resource2 = resource2
|
||||
|
||||
|
||||
class Service:
|
||||
def __init__(self, client: Client) -> None:
|
||||
self.client = client
|
||||
|
||||
|
||||
class BaseContainer(containers.DeclarativeContainer):
|
||||
resource1 = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
resource2 = providers.Resource(init_resource, providers.Object(RESOURCE2))
|
||||
|
||||
|
||||
class Container(BaseContainer):
|
||||
client = providers.Factory(
|
||||
Client,
|
||||
resource1=BaseContainer.resource1,
|
||||
resource2=BaseContainer.resource2,
|
||||
)
|
||||
|
||||
service = providers.Factory(
|
||||
Service,
|
||||
client=client,
|
||||
)
|
45
tests/unit/providers/async/test_async_mode_api_py36.py
Normal file
45
tests/unit/providers/async/test_async_mode_api_py36.py
Normal file
|
@ -0,0 +1,45 @@
|
|||
"""Tests for provider async mode API."""
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import fixture
|
||||
|
||||
|
||||
@fixture
|
||||
def provider():
|
||||
return providers.Provider()
|
||||
|
||||
|
||||
def test_default_mode(provider: providers.Provider):
|
||||
assert provider.is_async_mode_enabled() is False
|
||||
assert provider.is_async_mode_disabled() is False
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
|
||||
def test_enable(provider: providers.Provider):
|
||||
provider.enable_async_mode()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
assert provider.is_async_mode_disabled() is False
|
||||
assert provider.is_async_mode_undefined() is False
|
||||
|
||||
|
||||
def test_disable(provider: providers.Provider):
|
||||
provider.disable_async_mode()
|
||||
|
||||
assert provider.is_async_mode_enabled() is False
|
||||
assert provider.is_async_mode_disabled() is True
|
||||
assert provider.is_async_mode_undefined() is False
|
||||
|
||||
|
||||
def test_reset(provider: providers.Provider):
|
||||
provider.enable_async_mode()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
assert provider.is_async_mode_disabled() is False
|
||||
assert provider.is_async_mode_undefined() is False
|
||||
|
||||
provider.reset_async_mode()
|
||||
|
||||
assert provider.is_async_mode_enabled() is False
|
||||
assert provider.is_async_mode_disabled() is False
|
||||
assert provider.is_async_mode_undefined() is True
|
38
tests/unit/providers/async/test_delegated_singleton_py36.py
Normal file
38
tests/unit/providers/async/test_delegated_singleton_py36.py
Normal file
|
@ -0,0 +1,38 @@
|
|||
"""DelegatedSingleton provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.DelegatedSingleton(create_instance)
|
||||
|
||||
instance1 = await provider()
|
||||
instance2 = await provider()
|
||||
|
||||
assert instance1 is instance2
|
||||
assert instance1 is instance
|
||||
assert instance2 is instance
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_concurrent_init():
|
||||
async def create_instance():
|
||||
return object()
|
||||
|
||||
provider = providers.DelegatedSingleton(create_instance)
|
||||
|
||||
future_instance1 = provider()
|
||||
future_instance2 = provider()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(future_instance1, future_instance2)
|
||||
|
||||
assert instance1 is instance2
|
|
@ -0,0 +1,38 @@
|
|||
"""DelegatedThreadLocalSingleton provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.DelegatedThreadLocalSingleton(create_instance)
|
||||
|
||||
instance1 = await provider()
|
||||
instance2 = await provider()
|
||||
|
||||
assert instance1 is instance2
|
||||
assert instance1 is instance
|
||||
assert instance2 is instance
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_concurrent_init():
|
||||
async def create_instance():
|
||||
return object()
|
||||
|
||||
provider = providers.DelegatedThreadLocalSingleton(create_instance)
|
||||
|
||||
future_instance1 = provider()
|
||||
future_instance2 = provider()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(future_instance1, future_instance2)
|
||||
|
||||
assert instance1 is instance2
|
|
@ -0,0 +1,38 @@
|
|||
"""DelegatedThreadSafeSingleton provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.DelegatedThreadSafeSingleton(create_instance)
|
||||
|
||||
instance1 = await provider()
|
||||
instance2 = await provider()
|
||||
|
||||
assert instance1 is instance2
|
||||
assert instance1 is instance
|
||||
assert instance2 is instance
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_concurrent_init():
|
||||
async def create_instance():
|
||||
return object()
|
||||
|
||||
provider = providers.DelegatedThreadSafeSingleton(create_instance)
|
||||
|
||||
future_instance1 = provider()
|
||||
future_instance2 = provider()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(future_instance1, future_instance2)
|
||||
|
||||
assert instance1 is instance2
|
88
tests/unit/providers/async/test_dependency_py36.py
Normal file
88
tests/unit/providers/async/test_dependency_py36.py
Normal file
|
@ -0,0 +1,88 @@
|
|||
"""Dependency provider async mode tests."""
|
||||
|
||||
from dependency_injector import providers, errors
|
||||
from pytest import mark, raises
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provide_error():
|
||||
async def get_async():
|
||||
raise Exception
|
||||
|
||||
provider = providers.Dependency()
|
||||
provider.override(providers.Callable(get_async))
|
||||
|
||||
with raises(Exception):
|
||||
await provider()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_isinstance():
|
||||
dependency = 1.0
|
||||
|
||||
async def get_async():
|
||||
return dependency
|
||||
|
||||
provider = providers.Dependency(instance_of=float)
|
||||
provider.override(providers.Callable(get_async))
|
||||
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
dependency1 = await provider()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
dependency2 = await provider()
|
||||
|
||||
assert dependency1 == dependency
|
||||
assert dependency2 == dependency
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_isinstance_invalid():
|
||||
async def get_async():
|
||||
return {}
|
||||
|
||||
provider = providers.Dependency(instance_of=float)
|
||||
provider.override(providers.Callable(get_async))
|
||||
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
with raises(errors.Error):
|
||||
await provider()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
dependency = 123
|
||||
|
||||
async def get_async():
|
||||
return dependency
|
||||
|
||||
def get_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Dependency(instance_of=int)
|
||||
provider.override(providers.Factory(get_async))
|
||||
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
dependency1 = await provider()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
dependency2 = await provider()
|
||||
assert dependency1 == dependency
|
||||
assert dependency2 == dependency
|
||||
|
||||
provider.override(providers.Factory(get_sync))
|
||||
|
||||
dependency3 = await provider()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
dependency4 = await provider()
|
||||
assert dependency3 == dependency
|
||||
assert dependency4 == dependency
|
23
tests/unit/providers/async/test_dict_py36.py
Normal file
23
tests/unit/providers/async/test_dict_py36.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
"""Dict provider async mode tests."""
|
||||
|
||||
from dependency_injector import containers, providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provide():
|
||||
async def create_resource(param: str):
|
||||
return param
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
||||
resources = providers.Dict(
|
||||
foo=providers.Resource(create_resource, "foo"),
|
||||
bar=providers.Resource(create_resource, "bar")
|
||||
)
|
||||
|
||||
container = Container()
|
||||
resources = await container.resources()
|
||||
|
||||
assert resources["foo"] == "foo"
|
||||
assert resources["bar"] == "bar"
|
30
tests/unit/providers/async/test_factory_aggregate_py36.py
Normal file
30
tests/unit/providers/async/test_factory_aggregate_py36.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
"""FactoryAggregate provider async mode tests."""
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
object1 = object()
|
||||
object2 = object()
|
||||
|
||||
async def _get_object1():
|
||||
return object1
|
||||
|
||||
def _get_object2():
|
||||
return object2
|
||||
|
||||
provider = providers.FactoryAggregate(
|
||||
object1=providers.Factory(_get_object1),
|
||||
object2=providers.Factory(_get_object2),
|
||||
)
|
||||
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
created_object1 = await provider("object1")
|
||||
assert created_object1 is object1
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
created_object2 = await provider("object2")
|
||||
assert created_object2 is object2
|
|
@ -1,49 +1,11 @@
|
|||
"""Factory async mode tests."""
|
||||
"""Factory provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
from dependency_injector import containers, providers
|
||||
from pytest import mark, raises
|
||||
|
||||
|
||||
RESOURCE1 = object()
|
||||
RESOURCE2 = object()
|
||||
|
||||
|
||||
async def init_resource(resource):
|
||||
await asyncio.sleep(random.randint(1, 10) / 1000)
|
||||
yield resource
|
||||
await asyncio.sleep(random.randint(1, 10) / 1000)
|
||||
|
||||
|
||||
class Client:
|
||||
def __init__(self, resource1: object, resource2: object) -> None:
|
||||
self.resource1 = resource1
|
||||
self.resource2 = resource2
|
||||
|
||||
|
||||
class Service:
|
||||
def __init__(self, client: Client) -> None:
|
||||
self.client = client
|
||||
|
||||
|
||||
class BaseContainer(containers.DeclarativeContainer):
|
||||
resource1 = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
resource2 = providers.Resource(init_resource, providers.Object(RESOURCE2))
|
||||
|
||||
|
||||
class Container(BaseContainer):
|
||||
client = providers.Factory(
|
||||
Client,
|
||||
resource1=BaseContainer.resource1,
|
||||
resource2=BaseContainer.resource2,
|
||||
)
|
||||
|
||||
service = providers.Factory(
|
||||
Service,
|
||||
client=client,
|
||||
)
|
||||
from .common import RESOURCE1, RESOURCE2, Client, Service, BaseContainer, Container, init_resource
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
|
@ -184,6 +146,86 @@ async def test_args_kwargs_injection():
|
|||
assert service1.client is not service2.client
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_provider_with_async_injections():
|
||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/368
|
||||
async def async_client_provider():
|
||||
return {"client": "OK"}
|
||||
|
||||
async def async_service(client):
|
||||
return {"service": "OK", "client": client}
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
client = providers.Factory(async_client_provider)
|
||||
service = providers.Factory(async_service, client=client)
|
||||
|
||||
container = Container()
|
||||
service = await container.service()
|
||||
|
||||
assert service == {"service": "OK", "client": {"client": "OK"}}
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_with_awaitable_injection():
|
||||
class SomeResource:
|
||||
def __await__(self):
|
||||
raise RuntimeError("Should never happen")
|
||||
|
||||
async def init_resource():
|
||||
yield SomeResource()
|
||||
|
||||
class Service:
|
||||
def __init__(self, resource) -> None:
|
||||
self.resource = resource
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource)
|
||||
service = providers.Factory(Service, resource=resource)
|
||||
|
||||
container = Container()
|
||||
|
||||
assert isinstance(container.service(), asyncio.Future)
|
||||
assert isinstance(container.resource(), asyncio.Future)
|
||||
|
||||
resource = await container.resource()
|
||||
service = await container.service()
|
||||
|
||||
assert isinstance(resource, SomeResource)
|
||||
assert isinstance(service.resource, SomeResource)
|
||||
assert service.resource is resource
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_with_awaitable_injection_and_with_init_resources_call():
|
||||
class SomeResource:
|
||||
def __await__(self):
|
||||
raise RuntimeError("Should never happen")
|
||||
|
||||
async def init_resource():
|
||||
yield SomeResource()
|
||||
|
||||
class Service:
|
||||
def __init__(self, resource) -> None:
|
||||
self.resource = resource
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource)
|
||||
service = providers.Factory(Service, resource=resource)
|
||||
|
||||
container = Container()
|
||||
|
||||
await container.init_resources()
|
||||
assert isinstance(container.service(), asyncio.Future)
|
||||
assert isinstance(container.resource(), asyncio.Future)
|
||||
|
||||
resource = await container.resource()
|
||||
service = await container.service()
|
||||
|
||||
assert isinstance(resource, SomeResource)
|
||||
assert isinstance(service.resource, SomeResource)
|
||||
assert service.resource is resource
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_injection_error():
|
||||
async def init_resource():
|
||||
|
|
24
tests/unit/providers/async/test_list_py36.py
Normal file
24
tests/unit/providers/async/test_list_py36.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
"""List provider async mode tests."""
|
||||
|
||||
from dependency_injector import containers, providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provide():
|
||||
# See issue: https://github.com/ets-labs/python-dependency-injector/issues/450
|
||||
async def create_resource(param: str):
|
||||
return param
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
||||
resources = providers.List(
|
||||
providers.Resource(create_resource, "foo"),
|
||||
providers.Resource(create_resource, "bar")
|
||||
)
|
||||
|
||||
container = Container()
|
||||
resources = await container.resources()
|
||||
|
||||
assert resources[0] == "foo"
|
||||
assert resources[1] == "bar"
|
127
tests/unit/providers/async/test_override_py36.py
Normal file
127
tests/unit/providers/async/test_override_py36.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
"""Tests for provider overriding in async mode."""
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provider():
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
def _get_dependency_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Provider()
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_async))
|
||||
dependency1 = await provider()
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_sync))
|
||||
dependency2 = await provider()
|
||||
|
||||
assert dependency1 is dependency
|
||||
assert dependency2 is dependency
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_callable():
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
def _get_dependency_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Callable(_get_dependency_async)
|
||||
dependency1 = await provider()
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_sync))
|
||||
dependency2 = await provider()
|
||||
|
||||
assert dependency1 is dependency
|
||||
assert dependency2 is dependency
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_factory():
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
def _get_dependency_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Factory(_get_dependency_async)
|
||||
dependency1 = await provider()
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_sync))
|
||||
dependency2 = await provider()
|
||||
|
||||
assert dependency1 is dependency
|
||||
assert dependency2 is dependency
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode_enabling():
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
provider = providers.Callable(_get_dependency_async)
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
await provider()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode_disabling():
|
||||
dependency = object()
|
||||
|
||||
def _get_dependency():
|
||||
return dependency
|
||||
|
||||
provider = providers.Callable(_get_dependency)
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
provider()
|
||||
|
||||
assert provider.is_async_mode_disabled() is True
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode_enabling_on_overriding():
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
provider = providers.Provider()
|
||||
provider.override(providers.Callable(_get_dependency_async))
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
await provider()
|
||||
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
|
||||
def test_async_mode_disabling_on_overriding():
|
||||
dependency = object()
|
||||
|
||||
def _get_dependency():
|
||||
return dependency
|
||||
|
||||
provider = providers.Provider()
|
||||
provider.override(providers.Callable(_get_dependency))
|
||||
assert provider.is_async_mode_undefined() is True
|
||||
|
||||
provider()
|
||||
|
||||
assert provider.is_async_mode_disabled() is True
|
180
tests/unit/providers/async/test_provided_instance_py36.py
Normal file
180
tests/unit/providers/async/test_provided_instance_py36.py
Normal file
|
@ -0,0 +1,180 @@
|
|||
"""ProvidedInstance provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
|
||||
from dependency_injector import containers, providers
|
||||
from pytest import mark, raises
|
||||
|
||||
from .common import RESOURCE1, init_resource
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_attribute():
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestService:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
service = providers.Factory(TestService, resource=client.provided.resource)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(
|
||||
container.service(),
|
||||
container.service(),
|
||||
)
|
||||
|
||||
assert instance1.resource is RESOURCE1
|
||||
assert instance2.resource is RESOURCE1
|
||||
assert instance1.resource is instance2.resource
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_attribute_error():
|
||||
async def raise_exception():
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(raise_exception)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with raises(RuntimeError):
|
||||
await container.client.provided.attr()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_attribute_undefined_attribute():
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with raises(AttributeError):
|
||||
await container.client.provided.attr()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_item():
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
|
||||
class TestService:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
service = providers.Factory(TestService, resource=client.provided["resource"])
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(
|
||||
container.service(),
|
||||
container.service(),
|
||||
)
|
||||
|
||||
assert instance1.resource is RESOURCE1
|
||||
assert instance2.resource is RESOURCE1
|
||||
assert instance1.resource is instance2.resource
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_item_error():
|
||||
async def raise_exception():
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(raise_exception)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with raises(RuntimeError):
|
||||
await container.client.provided["item"]()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_item_undefined_item():
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(dict, resource=resource)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with raises(KeyError):
|
||||
await container.client.provided["item"]()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_method_call():
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
def get_resource(self):
|
||||
return self.resource
|
||||
|
||||
class TestService:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
service = providers.Factory(TestService, resource=client.provided.get_resource.call())
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(
|
||||
container.service(),
|
||||
container.service(),
|
||||
)
|
||||
|
||||
assert instance1.resource is RESOURCE1
|
||||
assert instance2.resource is RESOURCE1
|
||||
assert instance1.resource is instance2.resource
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_method_call_parent_error():
|
||||
async def raise_exception():
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(raise_exception)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with raises(RuntimeError):
|
||||
await container.client.provided.method.call()()
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_provided_method_call_error():
|
||||
class TestClient:
|
||||
def method(self):
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(TestClient)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with raises(RuntimeError):
|
||||
await container.client.provided.method.call()()
|
117
tests/unit/providers/async/test_singleton_py36.py
Normal file
117
tests/unit/providers/async/test_singleton_py36.py
Normal file
|
@ -0,0 +1,117 @@
|
|||
"""Singleton provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark, raises
|
||||
|
||||
from .common import RESOURCE1, RESOURCE2, BaseContainer, Client, Service
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_injections():
|
||||
class ContainerWithSingletons(BaseContainer):
|
||||
client = providers.Singleton(
|
||||
Client,
|
||||
resource1=BaseContainer.resource1,
|
||||
resource2=BaseContainer.resource2,
|
||||
)
|
||||
|
||||
service = providers.Singleton(
|
||||
Service,
|
||||
client=client,
|
||||
)
|
||||
|
||||
container = ContainerWithSingletons()
|
||||
|
||||
client1 = await container.client()
|
||||
client2 = await container.client()
|
||||
|
||||
assert isinstance(client1, Client)
|
||||
assert client1.resource1 is RESOURCE1
|
||||
assert client1.resource2 is RESOURCE2
|
||||
|
||||
assert isinstance(client2, Client)
|
||||
assert client2.resource1 is RESOURCE1
|
||||
assert client2.resource2 is RESOURCE2
|
||||
|
||||
service1 = await container.service()
|
||||
service2 = await container.service()
|
||||
|
||||
assert isinstance(service1, Service)
|
||||
assert isinstance(service1.client, Client)
|
||||
assert service1.client.resource1 is RESOURCE1
|
||||
assert service1.client.resource2 is RESOURCE2
|
||||
|
||||
assert isinstance(service2, Service)
|
||||
assert isinstance(service2.client, Client)
|
||||
assert service2.client.resource1 is RESOURCE1
|
||||
assert service2.client.resource2 is RESOURCE2
|
||||
|
||||
assert service1 is service2
|
||||
assert service1.client is service2.client
|
||||
assert service1.client is client1
|
||||
|
||||
assert service2.client is client2
|
||||
assert client1 is client2
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.Singleton(create_instance)
|
||||
|
||||
instance1 = await provider()
|
||||
instance2 = await provider()
|
||||
|
||||
assert instance1 is instance2
|
||||
assert instance1 is instance
|
||||
assert instance2 is instance
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_concurrent_init():
|
||||
async def create_instance():
|
||||
await asyncio.sleep(random.randint(1, 10) / 1000)
|
||||
return object()
|
||||
|
||||
provider = providers.Singleton(create_instance)
|
||||
|
||||
future_instance1 = provider()
|
||||
future_instance2 = provider()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(future_instance1, future_instance2)
|
||||
instance3 = await provider()
|
||||
|
||||
assert instance1 is instance2 is instance3
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_init_with_error():
|
||||
async def create_instance():
|
||||
create_instance.counter += 1
|
||||
raise RuntimeError()
|
||||
|
||||
create_instance.counter = 0
|
||||
|
||||
provider = providers.Singleton(create_instance)
|
||||
|
||||
future = provider()
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
with raises(RuntimeError):
|
||||
await future
|
||||
|
||||
assert create_instance.counter == 1
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
with raises(RuntimeError):
|
||||
await provider()
|
||||
|
||||
assert create_instance.counter == 2
|
||||
assert provider.is_async_mode_enabled() is True
|
|
@ -0,0 +1,63 @@
|
|||
"""ThreadLocalSingleton provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark, raises
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.ThreadLocalSingleton(create_instance)
|
||||
|
||||
instance1 = await provider()
|
||||
instance2 = await provider()
|
||||
|
||||
assert instance1 is instance2
|
||||
assert instance1 is instance
|
||||
assert instance2 is instance
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_concurrent_init():
|
||||
async def create_instance():
|
||||
return object()
|
||||
|
||||
provider = providers.ThreadLocalSingleton(create_instance)
|
||||
|
||||
future_instance1 = provider()
|
||||
future_instance2 = provider()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(future_instance1, future_instance2)
|
||||
|
||||
assert instance1 is instance2
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_init_with_error():
|
||||
async def create_instance():
|
||||
create_instance.counter += 1
|
||||
raise RuntimeError()
|
||||
create_instance.counter = 0
|
||||
|
||||
provider = providers.ThreadLocalSingleton(create_instance)
|
||||
|
||||
future = provider()
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
with raises(RuntimeError):
|
||||
await future
|
||||
|
||||
assert create_instance.counter == 1
|
||||
assert provider.is_async_mode_enabled() is True
|
||||
|
||||
with raises(RuntimeError):
|
||||
await provider()
|
||||
|
||||
assert create_instance.counter == 2
|
||||
assert provider.is_async_mode_enabled() is True
|
|
@ -0,0 +1,38 @@
|
|||
"""ThreadSafeSingleton provider async mode tests."""
|
||||
|
||||
import asyncio
|
||||
|
||||
from dependency_injector import providers
|
||||
from pytest import mark
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_mode():
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.ThreadSafeSingleton(create_instance)
|
||||
|
||||
instance1 = await provider()
|
||||
instance2 = await provider()
|
||||
|
||||
assert instance1 is instance2
|
||||
assert instance1 is instance
|
||||
assert instance2 is instance
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_concurrent_init():
|
||||
async def create_instance():
|
||||
return object()
|
||||
|
||||
provider = providers.ThreadSafeSingleton(create_instance)
|
||||
|
||||
future_instance1 = provider()
|
||||
future_instance2 = provider()
|
||||
|
||||
instance1, instance2 = await asyncio.gather(future_instance1, future_instance2)
|
||||
|
||||
assert instance1 is instance2
|
36
tests/unit/providers/async/test_typing_stubs_py36.py
Normal file
36
tests/unit/providers/async/test_typing_stubs_py36.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
"""Tests for provide async mode typing stubs."""
|
||||
|
||||
from pytest import mark
|
||||
|
||||
from .common import Container, Client, Service, RESOURCE1, RESOURCE2
|
||||
|
||||
|
||||
@mark.asyncio
|
||||
async def test_async_():
|
||||
container = Container()
|
||||
|
||||
client1 = await container.client.async_()
|
||||
client2 = await container.client.async_()
|
||||
|
||||
assert isinstance(client1, Client)
|
||||
assert client1.resource1 is RESOURCE1
|
||||
assert client1.resource2 is RESOURCE2
|
||||
|
||||
assert isinstance(client2, Client)
|
||||
assert client2.resource1 is RESOURCE1
|
||||
assert client2.resource2 is RESOURCE2
|
||||
|
||||
service1 = await container.service.async_()
|
||||
service2 = await container.service.async_()
|
||||
|
||||
assert isinstance(service1, Service)
|
||||
assert isinstance(service1.client, Client)
|
||||
assert service1.client.resource1 is RESOURCE1
|
||||
assert service1.client.resource2 is RESOURCE2
|
||||
|
||||
assert isinstance(service2, Service)
|
||||
assert isinstance(service2.client, Client)
|
||||
assert service2.client.resource1 is RESOURCE1
|
||||
assert service2.client.resource2 is RESOURCE2
|
||||
|
||||
assert service1.client is not service2.client
|
|
@ -1,843 +0,0 @@
|
|||
import asyncio
|
||||
import random
|
||||
import unittest
|
||||
|
||||
from dependency_injector import containers, providers, errors
|
||||
|
||||
# Runtime import to get asyncutils module
|
||||
import os
|
||||
_TOP_DIR = os.path.abspath(
|
||||
os.path.sep.join((
|
||||
os.path.dirname(__file__),
|
||||
"../",
|
||||
)),
|
||||
)
|
||||
import sys
|
||||
sys.path.append(_TOP_DIR)
|
||||
|
||||
from asyncutils import AsyncTestCase
|
||||
|
||||
|
||||
RESOURCE1 = object()
|
||||
RESOURCE2 = object()
|
||||
|
||||
|
||||
async def init_resource(resource):
|
||||
await asyncio.sleep(random.randint(1, 10) / 1000)
|
||||
yield resource
|
||||
await asyncio.sleep(random.randint(1, 10) / 1000)
|
||||
|
||||
|
||||
class Client:
|
||||
def __init__(self, resource1: object, resource2: object) -> None:
|
||||
self.resource1 = resource1
|
||||
self.resource2 = resource2
|
||||
|
||||
|
||||
class Service:
|
||||
def __init__(self, client: Client) -> None:
|
||||
self.client = client
|
||||
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
resource1 = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
resource2 = providers.Resource(init_resource, providers.Object(RESOURCE2))
|
||||
|
||||
client = providers.Factory(
|
||||
Client,
|
||||
resource1=resource1,
|
||||
resource2=resource2,
|
||||
)
|
||||
|
||||
service = providers.Factory(
|
||||
Service,
|
||||
client=client,
|
||||
)
|
||||
|
||||
|
||||
class FactoryAggregateTests(AsyncTestCase):
|
||||
|
||||
def test_async_mode(self):
|
||||
object1 = object()
|
||||
object2 = object()
|
||||
|
||||
async def _get_object1():
|
||||
return object1
|
||||
|
||||
def _get_object2():
|
||||
return object2
|
||||
|
||||
provider = providers.FactoryAggregate(
|
||||
object1=providers.Factory(_get_object1),
|
||||
object2=providers.Factory(_get_object2),
|
||||
)
|
||||
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
created_object1 = self._run(provider("object1"))
|
||||
self.assertIs(created_object1, object1)
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
created_object2 = self._run(provider("object2"))
|
||||
self.assertIs(created_object2, object2)
|
||||
|
||||
|
||||
class SingletonTests(AsyncTestCase):
|
||||
|
||||
def test_injections(self):
|
||||
class ContainerWithSingletons(containers.DeclarativeContainer):
|
||||
resource1 = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
resource2 = providers.Resource(init_resource, providers.Object(RESOURCE2))
|
||||
|
||||
client = providers.Singleton(
|
||||
Client,
|
||||
resource1=resource1,
|
||||
resource2=resource2,
|
||||
)
|
||||
|
||||
service = providers.Singleton(
|
||||
Service,
|
||||
client=client,
|
||||
)
|
||||
|
||||
container = ContainerWithSingletons()
|
||||
|
||||
client1 = self._run(container.client())
|
||||
client2 = self._run(container.client())
|
||||
|
||||
self.assertIsInstance(client1, Client)
|
||||
self.assertIs(client1.resource1, RESOURCE1)
|
||||
self.assertIs(client1.resource2, RESOURCE2)
|
||||
|
||||
self.assertIsInstance(client2, Client)
|
||||
self.assertIs(client2.resource1, RESOURCE1)
|
||||
self.assertIs(client2.resource2, RESOURCE2)
|
||||
|
||||
service1 = self._run(container.service())
|
||||
service2 = self._run(container.service())
|
||||
|
||||
self.assertIsInstance(service1, Service)
|
||||
self.assertIsInstance(service1.client, Client)
|
||||
self.assertIs(service1.client.resource1, RESOURCE1)
|
||||
self.assertIs(service1.client.resource2, RESOURCE2)
|
||||
|
||||
self.assertIsInstance(service2, Service)
|
||||
self.assertIsInstance(service2.client, Client)
|
||||
self.assertIs(service2.client.resource1, RESOURCE1)
|
||||
self.assertIs(service2.client.resource2, RESOURCE2)
|
||||
|
||||
self.assertIs(service1, service2)
|
||||
self.assertIs(service1.client, service2.client)
|
||||
self.assertIs(service1.client, client1)
|
||||
|
||||
self.assertIs(service2.client, client2)
|
||||
self.assertIs(client1, client2)
|
||||
|
||||
def test_async_mode(self):
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.Singleton(create_instance)
|
||||
|
||||
instance1 = self._run(provider())
|
||||
instance2 = self._run(provider())
|
||||
|
||||
self.assertIs(instance1, instance2)
|
||||
self.assertIs(instance, instance)
|
||||
|
||||
def test_async_init_with_error(self):
|
||||
# Disable default exception handling to prevent output
|
||||
asyncio.get_event_loop().set_exception_handler(lambda loop, context: ...)
|
||||
|
||||
async def create_instance():
|
||||
create_instance.counter += 1
|
||||
raise RuntimeError()
|
||||
|
||||
create_instance.counter = 0
|
||||
|
||||
provider = providers.Singleton(create_instance)
|
||||
|
||||
|
||||
future = provider()
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(future)
|
||||
|
||||
self.assertEqual(create_instance.counter, 1)
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(provider())
|
||||
|
||||
self.assertEqual(create_instance.counter, 2)
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
# Restore default exception handling
|
||||
asyncio.get_event_loop().set_exception_handler(None)
|
||||
|
||||
|
||||
class DelegatedSingletonTests(AsyncTestCase):
|
||||
|
||||
def test_async_mode(self):
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.DelegatedSingleton(create_instance)
|
||||
|
||||
instance1 = self._run(provider())
|
||||
instance2 = self._run(provider())
|
||||
|
||||
self.assertIs(instance1, instance2)
|
||||
self.assertIs(instance, instance)
|
||||
|
||||
|
||||
class ThreadSafeSingletonTests(AsyncTestCase):
|
||||
|
||||
def test_async_mode(self):
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.ThreadSafeSingleton(create_instance)
|
||||
|
||||
instance1 = self._run(provider())
|
||||
instance2 = self._run(provider())
|
||||
|
||||
self.assertIs(instance1, instance2)
|
||||
self.assertIs(instance, instance)
|
||||
|
||||
|
||||
class DelegatedThreadSafeSingletonTests(AsyncTestCase):
|
||||
|
||||
def test_async_mode(self):
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.DelegatedThreadSafeSingleton(create_instance)
|
||||
|
||||
instance1 = self._run(provider())
|
||||
instance2 = self._run(provider())
|
||||
|
||||
self.assertIs(instance1, instance2)
|
||||
self.assertIs(instance, instance)
|
||||
|
||||
|
||||
class ThreadLocalSingletonTests(AsyncTestCase):
|
||||
|
||||
def test_async_mode(self):
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.ThreadLocalSingleton(create_instance)
|
||||
|
||||
instance1 = self._run(provider())
|
||||
instance2 = self._run(provider())
|
||||
|
||||
self.assertIs(instance1, instance2)
|
||||
self.assertIs(instance, instance)
|
||||
|
||||
|
||||
def test_async_init_with_error(self):
|
||||
# Disable default exception handling to prevent output
|
||||
asyncio.get_event_loop().set_exception_handler(lambda loop, context: ...)
|
||||
|
||||
async def create_instance():
|
||||
create_instance.counter += 1
|
||||
raise RuntimeError()
|
||||
create_instance.counter = 0
|
||||
|
||||
provider = providers.ThreadLocalSingleton(create_instance)
|
||||
|
||||
future = provider()
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(future)
|
||||
|
||||
self.assertEqual(create_instance.counter, 1)
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(provider())
|
||||
|
||||
self.assertEqual(create_instance.counter, 2)
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
# Restore default exception handling
|
||||
asyncio.get_event_loop().set_exception_handler(None)
|
||||
|
||||
|
||||
class DelegatedThreadLocalSingletonTests(AsyncTestCase):
|
||||
|
||||
def test_async_mode(self):
|
||||
instance = object()
|
||||
|
||||
async def create_instance():
|
||||
return instance
|
||||
|
||||
provider = providers.DelegatedThreadLocalSingleton(create_instance)
|
||||
|
||||
instance1 = self._run(provider())
|
||||
instance2 = self._run(provider())
|
||||
|
||||
self.assertIs(instance1, instance2)
|
||||
self.assertIs(instance, instance)
|
||||
|
||||
|
||||
class ProvidedInstanceTests(AsyncTestCase):
|
||||
|
||||
def test_provided_attribute(self):
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestService:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
service = providers.Factory(TestService, resource=client.provided.resource)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
instance1, instance2 = self._run(
|
||||
asyncio.gather(
|
||||
container.service(),
|
||||
container.service(),
|
||||
),
|
||||
)
|
||||
|
||||
self.assertIs(instance1.resource, RESOURCE1)
|
||||
self.assertIs(instance2.resource, RESOURCE1)
|
||||
self.assertIs(instance1.resource, instance2.resource)
|
||||
|
||||
def test_provided_attribute_error(self):
|
||||
async def raise_exception():
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(raise_exception)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(container.client.provided.attr())
|
||||
|
||||
def test_provided_attribute_undefined_attribute(self):
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with self.assertRaises(AttributeError):
|
||||
self._run(container.client.provided.attr())
|
||||
|
||||
def test_provided_item(self):
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
def __getitem__(self, item):
|
||||
return getattr(self, item)
|
||||
|
||||
class TestService:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
service = providers.Factory(TestService, resource=client.provided["resource"])
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
instance1, instance2 = self._run(
|
||||
asyncio.gather(
|
||||
container.service(),
|
||||
container.service(),
|
||||
),
|
||||
)
|
||||
|
||||
self.assertIs(instance1.resource, RESOURCE1)
|
||||
self.assertIs(instance2.resource, RESOURCE1)
|
||||
self.assertIs(instance1.resource, instance2.resource)
|
||||
|
||||
def test_provided_item_error(self):
|
||||
async def raise_exception():
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(raise_exception)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(container.client.provided["item"]())
|
||||
|
||||
def test_provided_item_undefined_item(self):
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(dict, resource=resource)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with self.assertRaises(KeyError):
|
||||
self._run(container.client.provided["item"]())
|
||||
|
||||
def test_provided_method_call(self):
|
||||
class TestClient:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
def get_resource(self):
|
||||
return self.resource
|
||||
|
||||
class TestService:
|
||||
def __init__(self, resource):
|
||||
self.resource = resource
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||
client = providers.Factory(TestClient, resource=resource)
|
||||
service = providers.Factory(TestService, resource=client.provided.get_resource.call())
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
instance1, instance2 = self._run(
|
||||
asyncio.gather(
|
||||
container.service(),
|
||||
container.service(),
|
||||
),
|
||||
)
|
||||
|
||||
self.assertIs(instance1.resource, RESOURCE1)
|
||||
self.assertIs(instance2.resource, RESOURCE1)
|
||||
self.assertIs(instance1.resource, instance2.resource)
|
||||
|
||||
def test_provided_method_call_parent_error(self):
|
||||
async def raise_exception():
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(raise_exception)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(container.client.provided.method.call()())
|
||||
|
||||
def test_provided_method_call_error(self):
|
||||
class TestClient:
|
||||
def method(self):
|
||||
raise RuntimeError()
|
||||
|
||||
class TestContainer(containers.DeclarativeContainer):
|
||||
client = providers.Factory(TestClient)
|
||||
|
||||
container = TestContainer()
|
||||
|
||||
with self.assertRaises(RuntimeError):
|
||||
self._run(container.client.provided.method.call()())
|
||||
|
||||
|
||||
class DependencyTests(AsyncTestCase):
|
||||
|
||||
def test_provide_error(self):
|
||||
async def get_async():
|
||||
raise Exception
|
||||
|
||||
provider = providers.Dependency()
|
||||
provider.override(providers.Callable(get_async))
|
||||
|
||||
with self.assertRaises(Exception):
|
||||
self._run(provider())
|
||||
|
||||
def test_isinstance(self):
|
||||
dependency = 1.0
|
||||
|
||||
async def get_async():
|
||||
return dependency
|
||||
|
||||
provider = providers.Dependency(instance_of=float)
|
||||
provider.override(providers.Callable(get_async))
|
||||
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
dependency1 = self._run(provider())
|
||||
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
dependency2 = self._run(provider())
|
||||
|
||||
self.assertEqual(dependency1, dependency)
|
||||
self.assertEqual(dependency2, dependency)
|
||||
|
||||
def test_isinstance_invalid(self):
|
||||
async def get_async():
|
||||
return {}
|
||||
|
||||
provider = providers.Dependency(instance_of=float)
|
||||
provider.override(providers.Callable(get_async))
|
||||
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
with self.assertRaises(errors.Error):
|
||||
self._run(provider())
|
||||
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
def test_async_mode(self):
|
||||
dependency = 123
|
||||
|
||||
async def get_async():
|
||||
return dependency
|
||||
|
||||
def get_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Dependency(instance_of=int)
|
||||
provider.override(providers.Factory(get_async))
|
||||
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
dependency1 = self._run(provider())
|
||||
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
dependency2 = self._run(provider())
|
||||
self.assertEqual(dependency1, dependency)
|
||||
self.assertEqual(dependency2, dependency)
|
||||
|
||||
provider.override(providers.Factory(get_sync))
|
||||
|
||||
dependency3 = self._run(provider())
|
||||
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
dependency4 = self._run(provider())
|
||||
self.assertEqual(dependency3, dependency)
|
||||
self.assertEqual(dependency4, dependency)
|
||||
|
||||
|
||||
class ListTests(AsyncTestCase):
|
||||
|
||||
def test_provide(self):
|
||||
# See issue: https://github.com/ets-labs/python-dependency-injector/issues/450
|
||||
async def create_resource(param: str):
|
||||
return param
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
||||
resources = providers.List(
|
||||
providers.Resource(create_resource, "foo"),
|
||||
providers.Resource(create_resource, "bar")
|
||||
)
|
||||
|
||||
container = Container()
|
||||
resources = self._run(container.resources())
|
||||
|
||||
self.assertEqual(resources[0], "foo")
|
||||
self.assertEqual(resources[1], "bar")
|
||||
|
||||
|
||||
class DictTests(AsyncTestCase):
|
||||
|
||||
def test_provide(self):
|
||||
async def create_resource(param: str):
|
||||
return param
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
||||
resources = providers.Dict(
|
||||
foo=providers.Resource(create_resource, "foo"),
|
||||
bar=providers.Resource(create_resource, "bar")
|
||||
)
|
||||
|
||||
container = Container()
|
||||
resources = self._run(container.resources())
|
||||
|
||||
self.assertEqual(resources["foo"], "foo")
|
||||
self.assertEqual(resources["bar"], "bar")
|
||||
|
||||
|
||||
class OverrideTests(AsyncTestCase):
|
||||
|
||||
def test_provider(self):
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
def _get_dependency_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Provider()
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_async))
|
||||
dependency1 = self._run(provider())
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_sync))
|
||||
dependency2 = self._run(provider())
|
||||
|
||||
self.assertIs(dependency1, dependency)
|
||||
self.assertIs(dependency2, dependency)
|
||||
|
||||
def test_callable(self):
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
def _get_dependency_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Callable(_get_dependency_async)
|
||||
dependency1 = self._run(provider())
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_sync))
|
||||
dependency2 = self._run(provider())
|
||||
|
||||
self.assertIs(dependency1, dependency)
|
||||
self.assertIs(dependency2, dependency)
|
||||
|
||||
def test_factory(self):
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
def _get_dependency_sync():
|
||||
return dependency
|
||||
|
||||
provider = providers.Factory(_get_dependency_async)
|
||||
dependency1 = self._run(provider())
|
||||
|
||||
provider.override(providers.Callable(_get_dependency_sync))
|
||||
dependency2 = self._run(provider())
|
||||
|
||||
self.assertIs(dependency1, dependency)
|
||||
self.assertIs(dependency2, dependency)
|
||||
|
||||
def test_async_mode_enabling(self):
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
provider = providers.Callable(_get_dependency_async)
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
self._run(provider())
|
||||
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
def test_async_mode_disabling(self):
|
||||
dependency = object()
|
||||
|
||||
def _get_dependency():
|
||||
return dependency
|
||||
|
||||
provider = providers.Callable(_get_dependency)
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
provider()
|
||||
|
||||
self.assertTrue(provider.is_async_mode_disabled())
|
||||
|
||||
def test_async_mode_enabling_on_overriding(self):
|
||||
dependency = object()
|
||||
|
||||
async def _get_dependency_async():
|
||||
return dependency
|
||||
|
||||
provider = providers.Provider()
|
||||
provider.override(providers.Callable(_get_dependency_async))
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
self._run(provider())
|
||||
|
||||
self.assertTrue(provider.is_async_mode_enabled())
|
||||
|
||||
def test_async_mode_disabling_on_overriding(self):
|
||||
dependency = object()
|
||||
|
||||
def _get_dependency():
|
||||
return dependency
|
||||
|
||||
provider = providers.Provider()
|
||||
provider.override(providers.Callable(_get_dependency))
|
||||
self.assertTrue(provider.is_async_mode_undefined())
|
||||
|
||||
provider()
|
||||
|
||||
self.assertTrue(provider.is_async_mode_disabled())
|
||||
|
||||
|
||||
class TestAsyncModeApi(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.provider = providers.Provider()
|
||||
|
||||
def test_default_mode(self):
|
||||
self.assertFalse(self.provider.is_async_mode_enabled())
|
||||
self.assertFalse(self.provider.is_async_mode_disabled())
|
||||
self.assertTrue(self.provider.is_async_mode_undefined())
|
||||
|
||||
def test_enable(self):
|
||||
self.provider.enable_async_mode()
|
||||
|
||||
self.assertTrue(self.provider.is_async_mode_enabled())
|
||||
self.assertFalse(self.provider.is_async_mode_disabled())
|
||||
self.assertFalse(self.provider.is_async_mode_undefined())
|
||||
|
||||
def test_disable(self):
|
||||
self.provider.disable_async_mode()
|
||||
|
||||
self.assertFalse(self.provider.is_async_mode_enabled())
|
||||
self.assertTrue(self.provider.is_async_mode_disabled())
|
||||
self.assertFalse(self.provider.is_async_mode_undefined())
|
||||
|
||||
def test_reset(self):
|
||||
self.provider.enable_async_mode()
|
||||
|
||||
self.assertTrue(self.provider.is_async_mode_enabled())
|
||||
self.assertFalse(self.provider.is_async_mode_disabled())
|
||||
self.assertFalse(self.provider.is_async_mode_undefined())
|
||||
|
||||
self.provider.reset_async_mode()
|
||||
|
||||
self.assertFalse(self.provider.is_async_mode_enabled())
|
||||
self.assertFalse(self.provider.is_async_mode_disabled())
|
||||
self.assertTrue(self.provider.is_async_mode_undefined())
|
||||
|
||||
|
||||
class AsyncTypingStubTests(AsyncTestCase):
|
||||
|
||||
def test_async_(self):
|
||||
container = Container()
|
||||
|
||||
client1 = self._run(container.client.async_())
|
||||
client2 = self._run(container.client.async_())
|
||||
|
||||
self.assertIsInstance(client1, Client)
|
||||
self.assertIs(client1.resource1, RESOURCE1)
|
||||
self.assertIs(client1.resource2, RESOURCE2)
|
||||
|
||||
self.assertIsInstance(client2, Client)
|
||||
self.assertIs(client2.resource1, RESOURCE1)
|
||||
self.assertIs(client2.resource2, RESOURCE2)
|
||||
|
||||
service1 = self._run(container.service.async_())
|
||||
service2 = self._run(container.service.async_())
|
||||
|
||||
self.assertIsInstance(service1, Service)
|
||||
self.assertIsInstance(service1.client, Client)
|
||||
self.assertIs(service1.client.resource1, RESOURCE1)
|
||||
self.assertIs(service1.client.resource2, RESOURCE2)
|
||||
|
||||
self.assertIsInstance(service2, Service)
|
||||
self.assertIsInstance(service2.client, Client)
|
||||
self.assertIs(service2.client.resource1, RESOURCE1)
|
||||
self.assertIs(service2.client.resource2, RESOURCE2)
|
||||
|
||||
self.assertIsNot(service1.client, service2.client)
|
||||
|
||||
|
||||
class AsyncProvidersWithAsyncDependenciesTests(AsyncTestCase):
|
||||
|
||||
def test_injections(self):
|
||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/368
|
||||
async def async_db_provider():
|
||||
return {"db": "ok"}
|
||||
|
||||
async def async_service(db=None):
|
||||
return {"service": "ok", "db": db}
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
|
||||
db = providers.Factory(async_db_provider)
|
||||
service = providers.Singleton(async_service, db=db)
|
||||
|
||||
container = Container()
|
||||
service = self._run(container.service())
|
||||
|
||||
self.assertEqual(service, {"service": "ok", "db": {"db": "ok"}})
|
||||
|
||||
|
||||
class AsyncProviderWithAwaitableObjectTests(AsyncTestCase):
|
||||
|
||||
def test(self):
|
||||
class SomeResource:
|
||||
def __await__(self):
|
||||
raise RuntimeError("Should never happen")
|
||||
|
||||
async def init_resource():
|
||||
pool = SomeResource()
|
||||
yield pool
|
||||
|
||||
class Service:
|
||||
def __init__(self, resource) -> None:
|
||||
self.resource = resource
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource)
|
||||
service = providers.Singleton(Service, resource=resource)
|
||||
|
||||
container = Container()
|
||||
|
||||
self._run(container.init_resources())
|
||||
self.assertIsInstance(container.service(), asyncio.Future)
|
||||
self.assertIsInstance(container.resource(), asyncio.Future)
|
||||
|
||||
resource = self._run(container.resource())
|
||||
service = self._run(container.service())
|
||||
|
||||
self.assertIsInstance(resource, SomeResource)
|
||||
self.assertIsInstance(service.resource, SomeResource)
|
||||
self.assertIs(service.resource, resource)
|
||||
|
||||
def test_without_init_resources(self):
|
||||
class SomeResource:
|
||||
def __await__(self):
|
||||
raise RuntimeError("Should never happen")
|
||||
|
||||
async def init_resource():
|
||||
pool = SomeResource()
|
||||
yield pool
|
||||
|
||||
class Service:
|
||||
def __init__(self, resource) -> None:
|
||||
self.resource = resource
|
||||
|
||||
class Container(containers.DeclarativeContainer):
|
||||
resource = providers.Resource(init_resource)
|
||||
service = providers.Singleton(Service, resource=resource)
|
||||
|
||||
container = Container()
|
||||
|
||||
self.assertIsInstance(container.service(), asyncio.Future)
|
||||
self.assertIsInstance(container.resource(), asyncio.Future)
|
||||
|
||||
resource = self._run(container.resource())
|
||||
service = self._run(container.service())
|
||||
|
||||
self.assertIsInstance(resource, SomeResource)
|
||||
self.assertIsInstance(service.resource, SomeResource)
|
||||
self.assertIs(service.resource, resource)
|
Loading…
Reference in New Issue
Block a user