mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2024-11-25 11:04:01 +03:00
Pytest migration (#519)
* Add pytest and pytest-asyncio to the requirements * Update aiohttp ext test * Update setup.cfg * Update tox.ini * Add pytest to the tox requirements * Update tox.ini * Move configuration to tox.ini * Add pytest configs * Rename pytest-py34-py35.ini -> pytest-py35.ini * Update config file paths * Update makefile * Migrate common tests to pytest * Migrate FastAPI and Flask wiring tests * Rename flask and fastapi wiring test files * Move wiring autoloader tests * Add pytest-asyncio to the tox.ini * Migrate wiring async injection tests * Migrate main wiring tests * Migrate wiring string module and package names tests * Migrate wiring config tests * Migrate misc wiring tests * Update tests structure * Migrate misc wiring tests * Refactor container.from_schema() API tests * Migrate container.from_schema() integration tests * Rename schema samples * Update sample imports * Migrate container tests * Refactor container tests * Migrate container self tests * Migrate container instance tests * Migrate container custom string attribute name tests * Migrate container async resource tests * Fix py2 container tests * Migrate container cls tests * Migrate container class custom string cls as atrribute name tests * Migrate ext.aiohttp tests * Migrate ext.flasks tests * Update ext package tests doc block * Migrate provider utils tests * Migrate Factory async mode tests * Migrate async tests * Rename common test module * Refactor asserts in provider tests * Migrate factory tests * Migrate selector provider tests * Migrate object provider tests * Migrate self provider tests * Migrate delegate provider tests * Migrate provider tests * Migrate dependency provider tests * Migrate dependencies container provider tests * Fix warnings * Migrate list provider tests * Migrate dict provider tests * Migrate callable tests * Migrate injection tests * Migrate container provider tests * Migrate coroutine providers * Migrate traversal tests * Migrate resource tests * Migrate configuration tests * Migrate provided instance provider tests * Update doc blocks and imports * Migrate singleton tests * Update changelog and cosmetic fixes
This commit is contained in:
parent
4cc4ca9188
commit
94aca21fb8
11
Makefile
11
Makefile
|
@ -45,17 +45,10 @@ install: uninstall clean cythonize
|
||||||
uninstall:
|
uninstall:
|
||||||
- pip uninstall -y -q dependency-injector 2> /dev/null
|
- pip uninstall -y -q dependency-injector 2> /dev/null
|
||||||
|
|
||||||
test-py2: build
|
test:
|
||||||
# Unit tests with coverage report
|
# Unit tests with coverage report
|
||||||
coverage erase
|
coverage erase
|
||||||
coverage run --rcfile=./.coveragerc -m unittest discover -s tests/unit/ -p test_*_py2_py3.py
|
coverage run --rcfile=./.coveragerc -m pytest -c tests/.configs/pytest.ini
|
||||||
coverage report --rcfile=./.coveragerc
|
|
||||||
coverage html --rcfile=./.coveragerc
|
|
||||||
|
|
||||||
test: build
|
|
||||||
# Unit tests with coverage report
|
|
||||||
coverage erase
|
|
||||||
coverage run --rcfile=./.coveragerc -m unittest discover -s tests/unit/ -p test_*py3*.py
|
|
||||||
coverage report --rcfile=./.coveragerc
|
coverage report --rcfile=./.coveragerc
|
||||||
coverage html --rcfile=./.coveragerc
|
coverage html --rcfile=./.coveragerc
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,9 @@ Develop
|
||||||
- Add support of ``with`` statement for ``container.override_providers()`` method.
|
- Add support of ``with`` statement for ``container.override_providers()`` method.
|
||||||
- Drop support of Python 3.4. There are no immediate breaking changes, but Dependency Injector
|
- Drop support of Python 3.4. There are no immediate breaking changes, but Dependency Injector
|
||||||
will no longer be tested on Python 3.4 and any bugs will not be fixed.
|
will no longer be tested on Python 3.4 and any bugs will not be fixed.
|
||||||
|
- Fix ``Dependency.is_defined`` attribute to always return boolean value.
|
||||||
- Update documentation and fix typos.
|
- Update documentation and fix typos.
|
||||||
|
- Migrate tests to ``pytest``.
|
||||||
|
|
||||||
4.36.2
|
4.36.2
|
||||||
------
|
------
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
cython==0.29.22
|
cython==0.29.22
|
||||||
|
pytest
|
||||||
|
pytest-asyncio
|
||||||
tox
|
tox
|
||||||
coverage
|
coverage
|
||||||
flake8
|
flake8
|
||||||
|
|
|
@ -49,7 +49,7 @@ class Container:
|
||||||
def __delattr__(self, name: str) -> None: ...
|
def __delattr__(self, name: str) -> None: ...
|
||||||
def set_providers(self, **providers: Provider): ...
|
def set_providers(self, **providers: Provider): ...
|
||||||
def set_provider(self, name: str, provider: Provider) -> None: ...
|
def set_provider(self, name: str, provider: Provider) -> None: ...
|
||||||
def override(self, overriding: C_Base) -> None: ...
|
def override(self, overriding: Union[Container, Type[Container]]) -> None: ...
|
||||||
def override_providers(self, **overriding_providers: Union[Provider, Any]) -> ProvidersOverridingContext[C_Base]: ...
|
def override_providers(self, **overriding_providers: Union[Provider, Any]) -> ProvidersOverridingContext[C_Base]: ...
|
||||||
def reset_last_overriding(self) -> None: ...
|
def reset_last_overriding(self) -> None: ...
|
||||||
def reset_override(self) -> None: ...
|
def reset_override(self) -> None: ...
|
||||||
|
@ -88,6 +88,14 @@ class DeclarativeContainer(Container):
|
||||||
cls_providers: ClassVar[Dict[str, Provider]]
|
cls_providers: ClassVar[Dict[str, Provider]]
|
||||||
inherited_providers: ClassVar[Dict[str, Provider]]
|
inherited_providers: ClassVar[Dict[str, Provider]]
|
||||||
def __init__(self, **overriding_providers: Union[Provider, Any]) -> None: ...
|
def __init__(self, **overriding_providers: Union[Provider, Any]) -> None: ...
|
||||||
|
@classmethod
|
||||||
|
def override(cls, overriding: Union[Container, Type[Container]]) -> None: ...
|
||||||
|
@classmethod
|
||||||
|
def override_providers(cls, **overriding_providers: Union[Provider, Any]) -> ProvidersOverridingContext[C_Base]: ...
|
||||||
|
@classmethod
|
||||||
|
def reset_last_overriding(cls) -> None: ...
|
||||||
|
@classmethod
|
||||||
|
def reset_override(cls) -> None: ...
|
||||||
|
|
||||||
|
|
||||||
class ProvidersOverridingContext(Generic[T]):
|
class ProvidersOverridingContext(Generic[T]):
|
||||||
|
|
|
@ -17675,7 +17675,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_14set_de
|
||||||
* @property
|
* @property
|
||||||
* def is_defined(self): # <<<<<<<<<<<<<<
|
* def is_defined(self): # <<<<<<<<<<<<<<
|
||||||
* """Return True if dependency is defined."""
|
* """Return True if dependency is defined."""
|
||||||
* return self.__last_overriding or self.__default
|
* return self.__last_overriding is not None or self.__default is not None
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Python wrapper */
|
/* Python wrapper */
|
||||||
|
@ -17696,6 +17696,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
|
||||||
__Pyx_RefNannyDeclarations
|
__Pyx_RefNannyDeclarations
|
||||||
PyObject *__pyx_t_1 = NULL;
|
PyObject *__pyx_t_1 = NULL;
|
||||||
int __pyx_t_2;
|
int __pyx_t_2;
|
||||||
|
PyObject *__pyx_t_3 = NULL;
|
||||||
int __pyx_lineno = 0;
|
int __pyx_lineno = 0;
|
||||||
const char *__pyx_filename = NULL;
|
const char *__pyx_filename = NULL;
|
||||||
int __pyx_clineno = 0;
|
int __pyx_clineno = 0;
|
||||||
|
@ -17704,20 +17705,25 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
|
||||||
/* "dependency_injector/providers.pyx":774
|
/* "dependency_injector/providers.pyx":774
|
||||||
* def is_defined(self):
|
* def is_defined(self):
|
||||||
* """Return True if dependency is defined."""
|
* """Return True if dependency is defined."""
|
||||||
* return self.__last_overriding or self.__default # <<<<<<<<<<<<<<
|
* return self.__last_overriding is not None or self.__default is not None # <<<<<<<<<<<<<<
|
||||||
*
|
*
|
||||||
* def provided_by(self, provider):
|
* def provided_by(self, provider):
|
||||||
*/
|
*/
|
||||||
__Pyx_XDECREF(__pyx_r);
|
__Pyx_XDECREF(__pyx_r);
|
||||||
__pyx_t_2 = __Pyx_PyObject_IsTrue(((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding)); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(1, 774, __pyx_L1_error)
|
__pyx_t_2 = (((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding) != Py_None);
|
||||||
if (!__pyx_t_2) {
|
if (!__pyx_t_2) {
|
||||||
} else {
|
} else {
|
||||||
__Pyx_INCREF(((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding));
|
__pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 774, __pyx_L1_error)
|
||||||
__pyx_t_1 = ((PyObject *)__pyx_v_self->__pyx_base.__pyx___last_overriding);
|
__Pyx_GOTREF(__pyx_t_3);
|
||||||
|
__pyx_t_1 = __pyx_t_3;
|
||||||
|
__pyx_t_3 = 0;
|
||||||
goto __pyx_L3_bool_binop_done;
|
goto __pyx_L3_bool_binop_done;
|
||||||
}
|
}
|
||||||
__Pyx_INCREF(__pyx_v_self->__pyx___default);
|
__pyx_t_2 = (__pyx_v_self->__pyx___default != Py_None);
|
||||||
__pyx_t_1 = __pyx_v_self->__pyx___default;
|
__pyx_t_3 = __Pyx_PyBool_FromLong(__pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(1, 774, __pyx_L1_error)
|
||||||
|
__Pyx_GOTREF(__pyx_t_3);
|
||||||
|
__pyx_t_1 = __pyx_t_3;
|
||||||
|
__pyx_t_3 = 0;
|
||||||
__pyx_L3_bool_binop_done:;
|
__pyx_L3_bool_binop_done:;
|
||||||
__pyx_r = __pyx_t_1;
|
__pyx_r = __pyx_t_1;
|
||||||
__pyx_t_1 = 0;
|
__pyx_t_1 = 0;
|
||||||
|
@ -17728,12 +17734,13 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
|
||||||
* @property
|
* @property
|
||||||
* def is_defined(self): # <<<<<<<<<<<<<<
|
* def is_defined(self): # <<<<<<<<<<<<<<
|
||||||
* """Return True if dependency is defined."""
|
* """Return True if dependency is defined."""
|
||||||
* return self.__last_overriding or self.__default
|
* return self.__last_overriding is not None or self.__default is not None
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* function exit code */
|
/* function exit code */
|
||||||
__pyx_L1_error:;
|
__pyx_L1_error:;
|
||||||
__Pyx_XDECREF(__pyx_t_1);
|
__Pyx_XDECREF(__pyx_t_1);
|
||||||
|
__Pyx_XDECREF(__pyx_t_3);
|
||||||
__Pyx_AddTraceback("dependency_injector.providers.Dependency.is_defined.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
|
__Pyx_AddTraceback("dependency_injector.providers.Dependency.is_defined.__get__", __pyx_clineno, __pyx_lineno, __pyx_filename);
|
||||||
__pyx_r = NULL;
|
__pyx_r = NULL;
|
||||||
__pyx_L0:;
|
__pyx_L0:;
|
||||||
|
@ -17743,7 +17750,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_10is_def
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "dependency_injector/providers.pyx":776
|
/* "dependency_injector/providers.pyx":776
|
||||||
* return self.__last_overriding or self.__default
|
* return self.__last_overriding is not None or self.__default is not None
|
||||||
*
|
*
|
||||||
* def provided_by(self, provider): # <<<<<<<<<<<<<<
|
* def provided_by(self, provider): # <<<<<<<<<<<<<<
|
||||||
* """Set external dependency provider.
|
* """Set external dependency provider.
|
||||||
|
@ -17805,7 +17812,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_16provid
|
||||||
goto __pyx_L0;
|
goto __pyx_L0;
|
||||||
|
|
||||||
/* "dependency_injector/providers.pyx":776
|
/* "dependency_injector/providers.pyx":776
|
||||||
* return self.__last_overriding or self.__default
|
* return self.__last_overriding is not None or self.__default is not None
|
||||||
*
|
*
|
||||||
* def provided_by(self, provider): # <<<<<<<<<<<<<<
|
* def provided_by(self, provider): # <<<<<<<<<<<<<<
|
||||||
* """Set external dependency provider.
|
* """Set external dependency provider.
|
||||||
|
|
|
@ -771,7 +771,7 @@ cdef class Dependency(Provider):
|
||||||
@property
|
@property
|
||||||
def is_defined(self):
|
def is_defined(self):
|
||||||
"""Return True if dependency is defined."""
|
"""Return True if dependency is defined."""
|
||||||
return self.__last_overriding or self.__default
|
return self.__last_overriding is not None or self.__default is not None
|
||||||
|
|
||||||
def provided_by(self, provider):
|
def provided_by(self, provider):
|
||||||
"""Set external dependency provider.
|
"""Set external dependency provider.
|
||||||
|
|
6
tests/.configs/pytest-py27.ini
Normal file
6
tests/.configs/pytest-py27.ini
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[pytest]
|
||||||
|
testpaths = tests/unit
|
||||||
|
python_files = test_*_py2_py3.py
|
||||||
|
filterwarnings =
|
||||||
|
ignore:Module \"dependency_injector.ext.aiohttp\" is deprecated since version 4\.0\.0:DeprecationWarning
|
||||||
|
ignore:Module \"dependency_injector.ext.flask\" is deprecated since version 4\.0\.0:DeprecationWarning
|
6
tests/.configs/pytest-py35.ini
Normal file
6
tests/.configs/pytest-py35.ini
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[pytest]
|
||||||
|
testpaths = tests/unit
|
||||||
|
python_files = test_*_py3.py
|
||||||
|
filterwarnings =
|
||||||
|
ignore:Module \"dependency_injector.ext.aiohttp\" is deprecated since version 4\.0\.0:DeprecationWarning
|
||||||
|
ignore:Module \"dependency_injector.ext.flask\" is deprecated since version 4\.0\.0:DeprecationWarning
|
6
tests/.configs/pytest.ini
Normal file
6
tests/.configs/pytest.ini
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[pytest]
|
||||||
|
testpaths = tests/unit/
|
||||||
|
python_files = test_*_py3*.py
|
||||||
|
filterwarnings =
|
||||||
|
ignore:Module \"dependency_injector.ext.aiohttp\" is deprecated since version 4\.0\.0:DeprecationWarning
|
||||||
|
ignore:Module \"dependency_injector.ext.flask\" is deprecated since version 4\.0\.0:DeprecationWarning
|
|
@ -1 +1 @@
|
||||||
"""Dependency injector unit tests."""
|
"""Tests package."""
|
||||||
|
|
|
@ -1,57 +0,0 @@
|
||||||
"""Test utils."""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import contextlib
|
|
||||||
import sys
|
|
||||||
import gc
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
|
|
||||||
def run(main):
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
return loop.run_until_complete(main)
|
|
||||||
|
|
||||||
|
|
||||||
def setup_test_loop(
|
|
||||||
loop_factory=asyncio.new_event_loop
|
|
||||||
) -> asyncio.AbstractEventLoop:
|
|
||||||
loop = loop_factory()
|
|
||||||
try:
|
|
||||||
module = loop.__class__.__module__
|
|
||||||
skip_watcher = "uvloop" in module
|
|
||||||
except AttributeError: # pragma: no cover
|
|
||||||
# Just in case
|
|
||||||
skip_watcher = True
|
|
||||||
asyncio.set_event_loop(loop)
|
|
||||||
if sys.platform != "win32" and not skip_watcher:
|
|
||||||
policy = asyncio.get_event_loop_policy()
|
|
||||||
watcher = asyncio.SafeChildWatcher() # type: ignore
|
|
||||||
watcher.attach_loop(loop)
|
|
||||||
with contextlib.suppress(NotImplementedError):
|
|
||||||
policy.set_child_watcher(watcher)
|
|
||||||
return loop
|
|
||||||
|
|
||||||
|
|
||||||
def teardown_test_loop(loop: asyncio.AbstractEventLoop, fast: bool = False) -> None:
|
|
||||||
closed = loop.is_closed()
|
|
||||||
if not closed:
|
|
||||||
loop.call_soon(loop.stop)
|
|
||||||
loop.run_forever()
|
|
||||||
loop.close()
|
|
||||||
|
|
||||||
if not fast:
|
|
||||||
gc.collect()
|
|
||||||
|
|
||||||
asyncio.set_event_loop(None)
|
|
||||||
|
|
||||||
|
|
||||||
class AsyncTestCase(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.loop = setup_test_loop()
|
|
||||||
|
|
||||||
def tearDown(self):
|
|
||||||
teardown_test_loop(self.loop)
|
|
||||||
|
|
||||||
def _run(self, f):
|
|
||||||
return self.loop.run_until_complete(f)
|
|
8
tests/unit/conftest.py
Normal file
8
tests/unit/conftest.py
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
"""Fixtures module."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os.path
|
||||||
|
|
||||||
|
|
||||||
|
# Add current package to import samples/ dir
|
||||||
|
sys.path.append(os.path.dirname(__file__))
|
|
@ -1 +1 @@
|
||||||
"""Dependency injector container unit tests."""
|
"""Container tests."""
|
||||||
|
|
1
tests/unit/containers/cls/__init__.py
Normal file
1
tests/unit/containers/cls/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Container class tests."""
|
36
tests/unit/containers/cls/test_custom_strings_py2_py3.py
Normal file
36
tests/unit/containers/cls/test_custom_strings_py2_py3.py
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
"""Tests for container cls with custom string classes as attribute names.
|
||||||
|
|
||||||
|
See: https://github.com/ets-labs/python-dependency-injector/issues/479
|
||||||
|
"""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
|
||||||
|
class CustomString(str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CustomClass:
|
||||||
|
thing = None
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider():
|
||||||
|
return providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_setattr(provider):
|
||||||
|
setattr(Container, CustomString("test_attr"), provider)
|
||||||
|
assert Container.test_attr is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_delattr():
|
||||||
|
setattr(Container, CustomString("test_attr"), provider)
|
||||||
|
delattr(Container, CustomString("test_attr"))
|
||||||
|
with raises(AttributeError):
|
||||||
|
Container.test_attr
|
498
tests/unit/containers/cls/test_main_py2_py3.py
Normal file
498
tests/unit/containers/cls/test_main_py2_py3.py
Normal file
|
@ -0,0 +1,498 @@
|
||||||
|
"""Main container class tests."""
|
||||||
|
|
||||||
|
import collections
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerA(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerB(ContainerA):
|
||||||
|
p21 = providers.Provider()
|
||||||
|
p22 = providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
class ContainerC(ContainerB):
|
||||||
|
p31 = providers.Provider()
|
||||||
|
p32 = providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_attribute():
|
||||||
|
assert ContainerA.providers == dict(p11=ContainerA.p11, p12=ContainerA.p12)
|
||||||
|
assert ContainerB.providers == dict(
|
||||||
|
p11=ContainerA.p11,
|
||||||
|
p12=ContainerA.p12,
|
||||||
|
p21=ContainerB.p21,
|
||||||
|
p22=ContainerB.p22,
|
||||||
|
)
|
||||||
|
assert ContainerC.providers == dict(
|
||||||
|
p11=ContainerA.p11,
|
||||||
|
p12=ContainerA.p12,
|
||||||
|
p21=ContainerB.p21,
|
||||||
|
p22=ContainerB.p22,
|
||||||
|
p31=ContainerC.p31,
|
||||||
|
p32=ContainerC.p32,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_attribute_with_redefinition():
|
||||||
|
p1 = providers.Provider()
|
||||||
|
p2 = providers.Provider()
|
||||||
|
|
||||||
|
class ContainerA2(ContainerA):
|
||||||
|
p11 = p1
|
||||||
|
p12 = p2
|
||||||
|
|
||||||
|
assert ContainerA.providers == {
|
||||||
|
"p11": ContainerA.p11,
|
||||||
|
"p12": ContainerA.p12,
|
||||||
|
}
|
||||||
|
assert ContainerA2.providers == {
|
||||||
|
"p11": p1,
|
||||||
|
"p12": p2,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_cls_providers_attribute():
|
||||||
|
assert ContainerA.cls_providers == dict(p11=ContainerA.p11, p12=ContainerA.p12)
|
||||||
|
assert ContainerB.cls_providers == dict(p21=ContainerB.p21, p22=ContainerB.p22)
|
||||||
|
assert ContainerC.cls_providers == dict(p31=ContainerC.p31, p32=ContainerC.p32)
|
||||||
|
|
||||||
|
|
||||||
|
def test_inherited_providers_attribute():
|
||||||
|
assert ContainerA.inherited_providers == dict()
|
||||||
|
assert ContainerB.inherited_providers == dict(p11=ContainerA.p11, p12=ContainerA.p12)
|
||||||
|
assert ContainerC.inherited_providers == dict(
|
||||||
|
p11=ContainerA.p11,
|
||||||
|
p12=ContainerA.p12,
|
||||||
|
p21=ContainerB.p21,
|
||||||
|
p22=ContainerB.p22,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_dependencies_attribute():
|
||||||
|
class ContainerD(ContainerC):
|
||||||
|
p41 = providers.Dependency()
|
||||||
|
p42 = providers.DependenciesContainer()
|
||||||
|
|
||||||
|
class ContainerE(ContainerD):
|
||||||
|
p51 = providers.Dependency()
|
||||||
|
p52 = providers.DependenciesContainer()
|
||||||
|
|
||||||
|
assert ContainerD.dependencies == {
|
||||||
|
"p41": ContainerD.p41,
|
||||||
|
"p42": ContainerD.p42,
|
||||||
|
}
|
||||||
|
assert ContainerE.dependencies == {
|
||||||
|
"p41": ContainerD.p41,
|
||||||
|
"p42": ContainerD.p42,
|
||||||
|
"p51": ContainerE.p51,
|
||||||
|
"p52": ContainerE.p52,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_get_del_providers():
|
||||||
|
a_p13 = providers.Provider()
|
||||||
|
b_p23 = providers.Provider()
|
||||||
|
|
||||||
|
ContainerA.p13 = a_p13
|
||||||
|
ContainerB.p23 = b_p23
|
||||||
|
|
||||||
|
assert ContainerA.providers == dict(
|
||||||
|
p11=ContainerA.p11,
|
||||||
|
p12=ContainerA.p12,
|
||||||
|
p13=a_p13,
|
||||||
|
)
|
||||||
|
assert ContainerB.providers == dict(
|
||||||
|
p11=ContainerA.p11,
|
||||||
|
p12=ContainerA.p12,
|
||||||
|
p21=ContainerB.p21,
|
||||||
|
p22=ContainerB.p22,
|
||||||
|
p23=b_p23,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert ContainerA.cls_providers == dict(
|
||||||
|
p11=ContainerA.p11,
|
||||||
|
p12=ContainerA.p12,
|
||||||
|
p13=a_p13,
|
||||||
|
)
|
||||||
|
assert ContainerB.cls_providers == dict(
|
||||||
|
p21=ContainerB.p21,
|
||||||
|
p22=ContainerB.p22,
|
||||||
|
p23=b_p23,
|
||||||
|
)
|
||||||
|
|
||||||
|
del ContainerA.p13
|
||||||
|
del ContainerB.p23
|
||||||
|
|
||||||
|
assert ContainerA.providers == dict(p11=ContainerA.p11, p12=ContainerA.p12)
|
||||||
|
assert ContainerB.providers == dict(
|
||||||
|
p11=ContainerA.p11,
|
||||||
|
p12=ContainerA.p12,
|
||||||
|
p21=ContainerB.p21,
|
||||||
|
p22=ContainerB.p22,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert ContainerA.cls_providers == dict(p11=ContainerA.p11, p12=ContainerA.p12)
|
||||||
|
assert ContainerB.cls_providers == dict(p21=ContainerB.p21, p22=ContainerB.p22)
|
||||||
|
|
||||||
|
|
||||||
|
def test_declare_with_valid_provider_type():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
provider_type = providers.Object
|
||||||
|
px = providers.Object(object())
|
||||||
|
|
||||||
|
assert isinstance(_Container.px, providers.Object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_declare_with_invalid_provider_type():
|
||||||
|
with raises(errors.Error):
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
provider_type = providers.Object
|
||||||
|
px = providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_seth_valid_provider_type():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
provider_type = providers.Object
|
||||||
|
|
||||||
|
_Container.px = providers.Object(object())
|
||||||
|
|
||||||
|
assert isinstance(_Container.px, providers.Object)
|
||||||
|
|
||||||
|
def test_set_invalid_provider_type():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
provider_type = providers.Object
|
||||||
|
|
||||||
|
with raises(errors.Error):
|
||||||
|
_Container.px = providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_override():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer1(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer2(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
_Container.override(_OverridingContainer1)
|
||||||
|
_Container.override(_OverridingContainer2)
|
||||||
|
|
||||||
|
assert _Container.overridden == (_OverridingContainer1, _OverridingContainer2)
|
||||||
|
assert _Container.p11.overridden == (_OverridingContainer1.p11, _OverridingContainer2.p11)
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_with_it():
|
||||||
|
with raises(errors.Error):
|
||||||
|
ContainerA.override(ContainerA)
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_with_parent():
|
||||||
|
with raises(errors.Error):
|
||||||
|
ContainerB.override(ContainerA)
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_decorator():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
@containers.override(_Container)
|
||||||
|
class _OverridingContainer1(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
@containers.override(_Container)
|
||||||
|
class _OverridingContainer2(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
assert _Container.overridden == (_OverridingContainer1, _OverridingContainer2)
|
||||||
|
assert _Container.p11.overridden == (_OverridingContainer1.p11, _OverridingContainer2.p11)
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_last_overriding():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer1(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer2(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
_Container.override(_OverridingContainer1)
|
||||||
|
_Container.override(_OverridingContainer2)
|
||||||
|
_Container.reset_last_overriding()
|
||||||
|
|
||||||
|
assert _Container.overridden == (_OverridingContainer1,)
|
||||||
|
assert _Container.p11.overridden == (_OverridingContainer1.p11,)
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_last_overriding_when_not_overridden():
|
||||||
|
with raises(errors.Error):
|
||||||
|
ContainerA.reset_last_overriding()
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_override():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer1(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer2(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
_Container.override(_OverridingContainer1)
|
||||||
|
_Container.override(_OverridingContainer2)
|
||||||
|
_Container.reset_override()
|
||||||
|
|
||||||
|
assert _Container.overridden == tuple()
|
||||||
|
assert _Container.p11.overridden == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy():
|
||||||
|
@containers.copy(ContainerA)
|
||||||
|
class _Container1(ContainerA):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@containers.copy(ContainerA)
|
||||||
|
class _Container2(ContainerA):
|
||||||
|
pass
|
||||||
|
|
||||||
|
assert ContainerA.p11 is not _Container1.p11
|
||||||
|
assert ContainerA.p12 is not _Container1.p12
|
||||||
|
|
||||||
|
assert ContainerA.p11 is not _Container2.p11
|
||||||
|
assert ContainerA.p12 is not _Container2.p12
|
||||||
|
|
||||||
|
assert _Container1.p11 is not _Container2.p11
|
||||||
|
assert _Container1.p12 is not _Container2.p12
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy_with_replacing():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Object(0)
|
||||||
|
p12 = providers.Factory(dict, p11=p11)
|
||||||
|
|
||||||
|
@containers.copy(_Container)
|
||||||
|
class _Container1(_Container):
|
||||||
|
p11 = providers.Object(1)
|
||||||
|
p13 = providers.Object(11)
|
||||||
|
|
||||||
|
@containers.copy(_Container)
|
||||||
|
class _Container2(_Container):
|
||||||
|
p11 = providers.Object(2)
|
||||||
|
p13 = providers.Object(22)
|
||||||
|
|
||||||
|
assert _Container.p11 is not _Container1.p11
|
||||||
|
assert _Container.p12 is not _Container1.p12
|
||||||
|
|
||||||
|
assert _Container.p11 is not _Container2.p11
|
||||||
|
assert _Container.p12 is not _Container2.p12
|
||||||
|
|
||||||
|
assert _Container1.p11 is not _Container2.p11
|
||||||
|
assert _Container1.p12 is not _Container2.p12
|
||||||
|
|
||||||
|
assert _Container.p12() == {"p11": 0}
|
||||||
|
assert _Container1.p12() == {"p11": 1}
|
||||||
|
assert _Container2.p12() == {"p11": 2}
|
||||||
|
|
||||||
|
assert _Container1.p13() == 11
|
||||||
|
assert _Container2.p13() == 22
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy_with_parent_dependency():
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/477
|
||||||
|
class Base(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Object(0)
|
||||||
|
p12 = providers.Factory(dict, p11=p11)
|
||||||
|
|
||||||
|
@containers.copy(Base)
|
||||||
|
class New(Base):
|
||||||
|
p13 = providers.Factory(dict, p12=Base.p12)
|
||||||
|
|
||||||
|
new1 = New()
|
||||||
|
new2 = New(p11=1)
|
||||||
|
new3 = New(p11=2)
|
||||||
|
|
||||||
|
assert new1.p13() == {"p12": {"p11": 0}}
|
||||||
|
assert new2.p13() == {"p12": {"p11": 1}}
|
||||||
|
assert new3.p13() == {"p12": {"p11": 2}}
|
||||||
|
|
||||||
|
|
||||||
|
def test_copy_with_replacing_subcontainer_providers():
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/374
|
||||||
|
class X(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Dependency(instance_of=str)
|
||||||
|
|
||||||
|
def build_x():
|
||||||
|
return X(foo="1")
|
||||||
|
|
||||||
|
class A(containers.DeclarativeContainer):
|
||||||
|
x = providers.DependenciesContainer(**X.providers)
|
||||||
|
y = x.foo
|
||||||
|
|
||||||
|
@containers.copy(A)
|
||||||
|
class B1(A):
|
||||||
|
x = providers.Container(build_x)
|
||||||
|
|
||||||
|
b1 = B1()
|
||||||
|
|
||||||
|
assert b1.y() == "1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_containers_attribute():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
class Container1(containers.DeclarativeContainer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class Container2(containers.DeclarativeContainer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
Container3 = containers.DynamicContainer()
|
||||||
|
|
||||||
|
assert Container.containers == dict(
|
||||||
|
Container1=Container.Container1,
|
||||||
|
Container2=Container.Container2,
|
||||||
|
Container3=Container.Container3,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_overriding_providers():
|
||||||
|
p1 = providers.Provider()
|
||||||
|
p2 = providers.Provider()
|
||||||
|
|
||||||
|
container = ContainerA(p11=p1, p12=p2)
|
||||||
|
|
||||||
|
assert container.p11.last_overriding is p1
|
||||||
|
assert container.p12.last_overriding is p2
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_overridden_dependency():
|
||||||
|
# Bug: https://github.com/ets-labs/python-dependency-injector/issues/198
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p1 = providers.Dependency(instance_of=int)
|
||||||
|
|
||||||
|
p2 = providers.Dependency(object)
|
||||||
|
p2.override(providers.Factory(dict, p1=p1))
|
||||||
|
|
||||||
|
container = _Container(p1=1)
|
||||||
|
|
||||||
|
assert container.p2() == {"p1": 1}
|
||||||
|
assert container.p2.last_overriding.kwargs["p1"] is container.p1
|
||||||
|
assert container.p2.last_overriding.kwargs["p1"] is not _Container.p1
|
||||||
|
assert _Container.p2.last_overriding.kwargs["p1"] is _Container.p1
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_chained_dependency():
|
||||||
|
# Bug: https://github.com/ets-labs/python-dependency-injector/issues/200
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p1 = providers.Dependency(instance_of=int)
|
||||||
|
p2 = providers.Factory(p1)
|
||||||
|
|
||||||
|
container = _Container(p1=1)
|
||||||
|
|
||||||
|
assert container.p2() == 1
|
||||||
|
assert container.p2.cls is container.p1
|
||||||
|
assert _Container.p2.cls is _Container.p1
|
||||||
|
assert container.p2.cls is not _Container.p1
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_dependency_delegation():
|
||||||
|
# Bug: https://github.com/ets-labs/python-dependency-injector/issues/235
|
||||||
|
A = collections.namedtuple("A", [])
|
||||||
|
B = collections.namedtuple("B", ["fa"])
|
||||||
|
C = collections.namedtuple("B", ["a"])
|
||||||
|
|
||||||
|
class Services(containers.DeclarativeContainer):
|
||||||
|
a = providers.Dependency()
|
||||||
|
c = providers.Factory(C, a=a)
|
||||||
|
b = providers.Factory(B, fa=a.provider)
|
||||||
|
|
||||||
|
a = providers.Factory(A)
|
||||||
|
assert isinstance(Services(a=a).c().a, A) # OK
|
||||||
|
Services(a=a).b().fa()
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_grand_child_provider():
|
||||||
|
# Bug: https://github.com/ets-labs/python-dependency-injector/issues/350
|
||||||
|
provider = providers.Provider()
|
||||||
|
container = ContainerC(p11=provider)
|
||||||
|
|
||||||
|
assert isinstance(container.p11, providers.Provider)
|
||||||
|
assert isinstance(container.p12, providers.Provider)
|
||||||
|
assert isinstance(container.p21, providers.Provider)
|
||||||
|
assert isinstance(container.p22, providers.Provider)
|
||||||
|
assert isinstance(container.p31, providers.Provider)
|
||||||
|
assert isinstance(container.p32, providers.Provider)
|
||||||
|
assert container.p11.last_overriding is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_set_in__new__():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
dependency = providers.Dependency()
|
||||||
|
dependencies_container = providers.DependenciesContainer()
|
||||||
|
container = providers.Container(ContainerA)
|
||||||
|
|
||||||
|
assert Container.dependency.parent is Container
|
||||||
|
assert Container.dependencies_container.parent is Container
|
||||||
|
assert Container.container.parent is Container
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_set_in__setattr__():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
Container.dependency = providers.Dependency()
|
||||||
|
Container.dependencies_container = providers.DependenciesContainer()
|
||||||
|
Container.container = providers.Container(ContainerA)
|
||||||
|
|
||||||
|
assert Container.dependency.parent is Container
|
||||||
|
assert Container.dependencies_container.parent is Container
|
||||||
|
assert Container.container.parent is Container
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name():
|
||||||
|
assert ContainerA.resolve_provider_name(ContainerA.p11) == "p11"
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name_no_provider():
|
||||||
|
with raises(errors.Error):
|
||||||
|
ContainerA.resolve_provider_name(providers.Provider())
|
||||||
|
|
||||||
|
|
||||||
|
def test_child_dependency_parent_name():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
dependency = providers.Dependency()
|
||||||
|
|
||||||
|
with raises(errors.Error, match="Dependency \"Container.dependency\" is not defined"):
|
||||||
|
Container.dependency()
|
||||||
|
|
||||||
|
|
||||||
|
def test_child_dependencies_container_parent_name():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
dependencies_container = providers.DependenciesContainer()
|
||||||
|
|
||||||
|
with raises(errors.Error, match="Dependency \"Container.dependencies_container.dependency\" is not defined"):
|
||||||
|
Container.dependencies_container.dependency()
|
||||||
|
|
||||||
|
|
||||||
|
def test_child_container_parent_name():
|
||||||
|
class ChildContainer(containers.DeclarativeContainer):
|
||||||
|
dependency = providers.Dependency()
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
child_container = providers.Container(ChildContainer)
|
||||||
|
|
||||||
|
with raises(errors.Error, match="Dependency \"Container.child_container.dependency\" is not defined"):
|
||||||
|
Container.child_container.dependency()
|
1
tests/unit/containers/instance/__init__.py
Normal file
1
tests/unit/containers/instance/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Container instance tests."""
|
147
tests/unit/containers/instance/test_async_resources_py36.py
Normal file
147
tests/unit/containers/instance/test_async_resources_py36.py
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
"""Tests for container async resources."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
from pytest import mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_and_shutdown_ordering():
|
||||||
|
"""Test init and shutdown resources.
|
||||||
|
|
||||||
|
Methods .init_resources() and .shutdown_resources() should respect resources dependencies.
|
||||||
|
Initialization should first initialize resources without dependencies and then provide
|
||||||
|
these resources to other resources. Resources shutdown should follow the same rule: first
|
||||||
|
shutdown resources without initialized dependencies and then continue correspondingly
|
||||||
|
until all resources are shutdown.
|
||||||
|
"""
|
||||||
|
initialized_resources = []
|
||||||
|
shutdown_resources = []
|
||||||
|
|
||||||
|
async def _resource(name, delay, **_):
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
initialized_resources.append(name)
|
||||||
|
|
||||||
|
yield name
|
||||||
|
|
||||||
|
await asyncio.sleep(delay)
|
||||||
|
shutdown_resources.append(name)
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource1 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r1",
|
||||||
|
delay=0.03,
|
||||||
|
)
|
||||||
|
resource2 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r2",
|
||||||
|
delay=0.02,
|
||||||
|
r1=resource1,
|
||||||
|
)
|
||||||
|
resource3 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r3",
|
||||||
|
delay=0.01,
|
||||||
|
r2=resource2,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
await container.init_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == []
|
||||||
|
|
||||||
|
await container.shutdown_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1"]
|
||||||
|
|
||||||
|
await container.init_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3", "r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1"]
|
||||||
|
|
||||||
|
await container.shutdown_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3", "r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1", "r3", "r2", "r1"]
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_shutdown_circular_dependencies_breaker():
|
||||||
|
async def _resource(name, **_):
|
||||||
|
yield name
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource1 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r1",
|
||||||
|
)
|
||||||
|
resource2 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r2",
|
||||||
|
r1=resource1,
|
||||||
|
)
|
||||||
|
resource3 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r3",
|
||||||
|
r2=resource2,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
await container.init_resources()
|
||||||
|
|
||||||
|
# Create circular dependency after initialization (r3 -> r2 -> r1 -> r3 -> ...)
|
||||||
|
container.resource1.add_kwargs(r3=container.resource3)
|
||||||
|
|
||||||
|
with raises(RuntimeError, match="Unable to resolve resources shutdown order"):
|
||||||
|
await container.shutdown_resources()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_shutdown_sync_and_async_ordering():
|
||||||
|
initialized_resources = []
|
||||||
|
shutdown_resources = []
|
||||||
|
|
||||||
|
def _sync_resource(name, **_):
|
||||||
|
initialized_resources.append(name)
|
||||||
|
yield name
|
||||||
|
shutdown_resources.append(name)
|
||||||
|
|
||||||
|
async def _async_resource(name, **_):
|
||||||
|
initialized_resources.append(name)
|
||||||
|
yield name
|
||||||
|
shutdown_resources.append(name)
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource1 = providers.Resource(
|
||||||
|
_sync_resource,
|
||||||
|
name="r1",
|
||||||
|
)
|
||||||
|
resource2 = providers.Resource(
|
||||||
|
_sync_resource,
|
||||||
|
name="r2",
|
||||||
|
r1=resource1,
|
||||||
|
)
|
||||||
|
resource3 = providers.Resource(
|
||||||
|
_async_resource,
|
||||||
|
name="r3",
|
||||||
|
r2=resource2,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
await container.init_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == []
|
||||||
|
|
||||||
|
await container.shutdown_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1"]
|
||||||
|
|
||||||
|
await container.init_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3", "r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1"]
|
||||||
|
|
||||||
|
await container.shutdown_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3", "r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1", "r3", "r2", "r1"]
|
|
@ -0,0 +1,47 @@
|
||||||
|
"""Tests for container with custom string classes as attribute names.
|
||||||
|
|
||||||
|
See: https://github.com/ets-labs/python-dependency-injector/issues/479
|
||||||
|
"""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
|
||||||
|
class CustomString(str):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class CustomClass:
|
||||||
|
thing = None
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def container():
|
||||||
|
return containers.DynamicContainer()
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider():
|
||||||
|
return providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_setattr(container, provider):
|
||||||
|
setattr(container, CustomString("test_attr"), provider)
|
||||||
|
assert container.test_attr is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_delattr(container, provider):
|
||||||
|
setattr(container, CustomString("test_attr"), provider)
|
||||||
|
delattr(container, CustomString("test_attr"))
|
||||||
|
with raises(AttributeError):
|
||||||
|
container.test_attr
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_provider(container, provider):
|
||||||
|
container.set_provider(CustomString("test_attr"), provider)
|
||||||
|
assert container.test_attr is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_providers(container, provider):
|
||||||
|
container.set_providers(**{CustomString("test_attr"): provider})
|
||||||
|
assert container.test_attr is provider
|
493
tests/unit/containers/instance/test_main_py2_py3.py
Normal file
493
tests/unit/containers/instance/test_main_py2_py3.py
Normal file
|
@ -0,0 +1,493 @@
|
||||||
|
"""Main container instance tests."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_attribute():
|
||||||
|
container_1 = Container()
|
||||||
|
container_2 = Container()
|
||||||
|
|
||||||
|
assert container_1.p11 is not container_2.p11
|
||||||
|
assert container_1.p12 is not container_2.p12
|
||||||
|
assert container_1.providers != container_2.providers
|
||||||
|
|
||||||
|
|
||||||
|
def test_dependencies_attribute():
|
||||||
|
container = Container()
|
||||||
|
container.a1 = providers.Dependency()
|
||||||
|
container.a2 = providers.DependenciesContainer()
|
||||||
|
assert container.dependencies == {"a1": container.a1, "a2": container.a2}
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_get_del_providers():
|
||||||
|
p13 = providers.Provider()
|
||||||
|
|
||||||
|
container_1 = Container()
|
||||||
|
container_2 = Container()
|
||||||
|
|
||||||
|
container_1.p13 = p13
|
||||||
|
container_2.p13 = p13
|
||||||
|
|
||||||
|
assert Container.providers == dict(p11=Container.p11, p12=Container.p12)
|
||||||
|
assert Container.cls_providers, dict(p11=Container.p11, p12=Container.p12)
|
||||||
|
|
||||||
|
assert container_1.providers == dict(p11=container_1.p11, p12=container_1.p12, p13=p13)
|
||||||
|
assert container_2.providers == dict(p11=container_2.p11, p12=container_2.p12, p13=p13)
|
||||||
|
|
||||||
|
del container_1.p13
|
||||||
|
assert container_1.providers == dict(p11=container_1.p11, p12=container_1.p12)
|
||||||
|
|
||||||
|
del container_2.p13
|
||||||
|
assert container_2.providers == dict(p11=container_2.p11, p12=container_2.p12)
|
||||||
|
|
||||||
|
del container_1.p11
|
||||||
|
del container_1.p12
|
||||||
|
assert container_1.providers == dict()
|
||||||
|
assert Container.providers == dict(p11=Container.p11, p12=Container.p12)
|
||||||
|
|
||||||
|
del container_2.p11
|
||||||
|
del container_2.p12
|
||||||
|
assert container_2.providers == dict()
|
||||||
|
assert Container.providers == dict(p11=Container.p11, p12=Container.p12)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_invalid_provider_type():
|
||||||
|
container = Container()
|
||||||
|
container.provider_type = providers.Object
|
||||||
|
|
||||||
|
with raises(errors.Error):
|
||||||
|
container.px = providers.Provider()
|
||||||
|
|
||||||
|
assert Container.provider_type is containers.DeclarativeContainer.provider_type
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_providers():
|
||||||
|
p13 = providers.Provider()
|
||||||
|
p14 = providers.Provider()
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
container.set_providers(p13=p13, p14=p14)
|
||||||
|
|
||||||
|
assert container.p13 is p13
|
||||||
|
assert container.p14 is p14
|
||||||
|
|
||||||
|
|
||||||
|
def test_override():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer1(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer2(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
container = _Container()
|
||||||
|
overriding_container1 = _OverridingContainer1()
|
||||||
|
overriding_container2 = _OverridingContainer2()
|
||||||
|
|
||||||
|
container.override(overriding_container1)
|
||||||
|
container.override(overriding_container2)
|
||||||
|
|
||||||
|
assert container.overridden == (overriding_container1, overriding_container2)
|
||||||
|
assert container.p11.overridden == (overriding_container1.p11, overriding_container2.p11)
|
||||||
|
|
||||||
|
assert _Container.overridden == tuple()
|
||||||
|
assert _Container.p11.overridden == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_with_it():
|
||||||
|
container = Container()
|
||||||
|
with raises(errors.Error):
|
||||||
|
container.override(container)
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_providers():
|
||||||
|
p1 = providers.Provider()
|
||||||
|
p2 = providers.Provider()
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
container.override_providers(p11=p1, p12=p2)
|
||||||
|
|
||||||
|
assert container.p11.last_overriding is p1
|
||||||
|
assert container.p12.last_overriding is p2
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_providers_context_manager():
|
||||||
|
p1 = providers.Provider()
|
||||||
|
p2 = providers.Provider()
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with container.override_providers(p11=p1, p12=p2) as context_container:
|
||||||
|
assert container is context_container
|
||||||
|
assert container.p11.last_overriding is p1
|
||||||
|
assert container.p12.last_overriding is p2
|
||||||
|
|
||||||
|
assert container.p11.last_overriding is None
|
||||||
|
assert container.p12.last_overriding is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_providers_with_unknown_provider():
|
||||||
|
container = Container()
|
||||||
|
with raises(AttributeError):
|
||||||
|
container.override_providers(unknown=providers.Provider())
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_last_overriding():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer1(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer2(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
container = _Container()
|
||||||
|
overriding_container1 = _OverridingContainer1()
|
||||||
|
overriding_container2 = _OverridingContainer2()
|
||||||
|
|
||||||
|
container.override(overriding_container1)
|
||||||
|
container.override(overriding_container2)
|
||||||
|
container.reset_last_overriding()
|
||||||
|
|
||||||
|
assert container.overridden == (overriding_container1,)
|
||||||
|
assert container.p11.overridden, (overriding_container1.p11,)
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_last_overriding_when_not_overridden():
|
||||||
|
container = Container()
|
||||||
|
with raises(errors.Error):
|
||||||
|
container.reset_last_overriding()
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_override():
|
||||||
|
class _Container(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer1(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
|
||||||
|
class _OverridingContainer2(containers.DeclarativeContainer):
|
||||||
|
p11 = providers.Provider()
|
||||||
|
p12 = providers.Provider()
|
||||||
|
|
||||||
|
container = _Container()
|
||||||
|
overriding_container1 = _OverridingContainer1()
|
||||||
|
overriding_container2 = _OverridingContainer2()
|
||||||
|
|
||||||
|
container.override(overriding_container1)
|
||||||
|
container.override(overriding_container2)
|
||||||
|
container.reset_override()
|
||||||
|
|
||||||
|
assert container.overridden == tuple()
|
||||||
|
assert container.p11.overridden == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_and_shutdown_resources_ordering():
|
||||||
|
"""Test init and shutdown resources.
|
||||||
|
|
||||||
|
Methods .init_resources() and .shutdown_resources() should respect resources dependencies.
|
||||||
|
Initialization should first initialize resources without dependencies and then provide
|
||||||
|
these resources to other resources. Resources shutdown should follow the same rule: first
|
||||||
|
shutdown resources without initialized dependencies and then continue correspondingly
|
||||||
|
until all resources are shutdown.
|
||||||
|
"""
|
||||||
|
initialized_resources = []
|
||||||
|
shutdown_resources = []
|
||||||
|
|
||||||
|
def _resource(name, **_):
|
||||||
|
initialized_resources.append(name)
|
||||||
|
yield name
|
||||||
|
shutdown_resources.append(name)
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource1 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r1",
|
||||||
|
)
|
||||||
|
resource2 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r2",
|
||||||
|
r1=resource1,
|
||||||
|
)
|
||||||
|
resource3 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r3",
|
||||||
|
r2=resource2,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
container.init_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == []
|
||||||
|
|
||||||
|
container.shutdown_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1"]
|
||||||
|
|
||||||
|
container.init_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3", "r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1"]
|
||||||
|
|
||||||
|
container.shutdown_resources()
|
||||||
|
assert initialized_resources == ["r1", "r2", "r3", "r1", "r2", "r3"]
|
||||||
|
assert shutdown_resources == ["r3", "r2", "r1", "r3", "r2", "r1"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_shutdown_resources_circular_dependencies_breaker():
|
||||||
|
def _resource(name, **_):
|
||||||
|
yield name
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource1 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r1",
|
||||||
|
)
|
||||||
|
resource2 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r2",
|
||||||
|
r1=resource1,
|
||||||
|
)
|
||||||
|
resource3 = providers.Resource(
|
||||||
|
_resource,
|
||||||
|
name="r3",
|
||||||
|
r2=resource2,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
container.init_resources()
|
||||||
|
|
||||||
|
# Create circular dependency after initialization (r3 -> r2 -> r1 -> r3 -> ...)
|
||||||
|
container.resource1.add_kwargs(r3=container.resource3)
|
||||||
|
|
||||||
|
with raises(RuntimeError, match="Unable to resolve resources shutdown order"):
|
||||||
|
container.shutdown_resources()
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_shutdown_nested_resources():
|
||||||
|
def _init1():
|
||||||
|
_init1.init_counter += 1
|
||||||
|
yield
|
||||||
|
_init1.shutdown_counter += 1
|
||||||
|
|
||||||
|
_init1.init_counter = 0
|
||||||
|
_init1.shutdown_counter = 0
|
||||||
|
|
||||||
|
def _init2():
|
||||||
|
_init2.init_counter += 1
|
||||||
|
yield
|
||||||
|
_init2.shutdown_counter += 1
|
||||||
|
|
||||||
|
_init2.init_counter = 0
|
||||||
|
_init2.shutdown_counter = 0
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
service = providers.Factory(
|
||||||
|
dict,
|
||||||
|
resource1=providers.Resource(_init1),
|
||||||
|
resource2=providers.Resource(_init2),
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
assert _init1.init_counter == 0
|
||||||
|
assert _init1.shutdown_counter == 0
|
||||||
|
assert _init2.init_counter == 0
|
||||||
|
assert _init2.shutdown_counter == 0
|
||||||
|
|
||||||
|
container.init_resources()
|
||||||
|
assert _init1.init_counter == 1
|
||||||
|
assert _init1.shutdown_counter == 0
|
||||||
|
assert _init2.init_counter == 1
|
||||||
|
assert _init2.shutdown_counter == 0
|
||||||
|
|
||||||
|
container.shutdown_resources()
|
||||||
|
assert _init1.init_counter == 1
|
||||||
|
assert _init1.shutdown_counter == 1
|
||||||
|
assert _init2.init_counter == 1
|
||||||
|
assert _init2.shutdown_counter == 1
|
||||||
|
|
||||||
|
container.init_resources()
|
||||||
|
container.shutdown_resources()
|
||||||
|
assert _init1.init_counter == 2
|
||||||
|
assert _init1.shutdown_counter == 2
|
||||||
|
assert _init2.init_counter == 2
|
||||||
|
assert _init2.shutdown_counter == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_singletons():
|
||||||
|
class SubSubContainer(containers.DeclarativeContainer):
|
||||||
|
singleton = providers.Singleton(object)
|
||||||
|
|
||||||
|
class SubContainer(containers.DeclarativeContainer):
|
||||||
|
singleton = providers.Singleton(object)
|
||||||
|
sub_sub_container = providers.Container(SubSubContainer)
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
singleton = providers.Singleton(object)
|
||||||
|
sub_container = providers.Container(SubContainer)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
obj11 = container.singleton()
|
||||||
|
obj12 = container.sub_container().singleton()
|
||||||
|
obj13 = container.sub_container().sub_sub_container().singleton()
|
||||||
|
|
||||||
|
obj21 = container.singleton()
|
||||||
|
obj22 = container.sub_container().singleton()
|
||||||
|
obj23 = container.sub_container().sub_sub_container().singleton()
|
||||||
|
|
||||||
|
assert obj11 is obj21
|
||||||
|
assert obj12 is obj22
|
||||||
|
assert obj13 is obj23
|
||||||
|
|
||||||
|
container.reset_singletons()
|
||||||
|
|
||||||
|
obj31 = container.singleton()
|
||||||
|
obj32 = container.sub_container().singleton()
|
||||||
|
obj33 = container.sub_container().sub_sub_container().singleton()
|
||||||
|
|
||||||
|
obj41 = container.singleton()
|
||||||
|
obj42 = container.sub_container().singleton()
|
||||||
|
obj43 = container.sub_container().sub_sub_container().singleton()
|
||||||
|
|
||||||
|
assert obj11 is not obj31
|
||||||
|
assert obj12 is not obj32
|
||||||
|
assert obj13 is not obj33
|
||||||
|
|
||||||
|
assert obj21 is not obj31
|
||||||
|
assert obj22 is not obj32
|
||||||
|
assert obj23 is not obj33
|
||||||
|
|
||||||
|
assert obj31 is obj41
|
||||||
|
assert obj32 is obj42
|
||||||
|
assert obj33 is obj43
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_singletons_context_manager():
|
||||||
|
class Item:
|
||||||
|
def __init__(self, dependency):
|
||||||
|
self.dependency = dependency
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
dependent = providers.Singleton(object)
|
||||||
|
singleton = providers.Singleton(Item, dependency=dependent)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
instance1 = container.singleton()
|
||||||
|
with container.reset_singletons():
|
||||||
|
instance2 = container.singleton()
|
||||||
|
instance3 = container.singleton()
|
||||||
|
|
||||||
|
assert len({instance1, instance2, instance3}) == 3
|
||||||
|
assert len({instance1.dependency, instance2.dependency, instance3.dependency}) == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_singletons_context_manager_as_attribute():
|
||||||
|
container = containers.DeclarativeContainer()
|
||||||
|
with container.reset_singletons() as alias:
|
||||||
|
pass
|
||||||
|
assert container is alias
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_dependencies():
|
||||||
|
class SubContainer(containers.DeclarativeContainer):
|
||||||
|
dependency = providers.Dependency()
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
dependency = providers.Dependency()
|
||||||
|
dependencies_container = providers.DependenciesContainer()
|
||||||
|
provider = providers.List(dependencies_container.dependency)
|
||||||
|
sub_container = providers.Container(SubContainer)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(errors.Error) as exception_info:
|
||||||
|
container.check_dependencies()
|
||||||
|
|
||||||
|
assert "Container \"Container\" has undefined dependencies:" in str(exception_info.value)
|
||||||
|
assert "\"Container.dependency\"" in str(exception_info.value)
|
||||||
|
assert "\"Container.dependencies_container.dependency\"" in str(exception_info.value)
|
||||||
|
assert "\"Container.sub_container.dependency\"" in str(exception_info.value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_check_dependencies_all_defined():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
dependency = providers.Dependency()
|
||||||
|
|
||||||
|
container = Container(dependency="provided")
|
||||||
|
result = container.check_dependencies()
|
||||||
|
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_assign_parent():
|
||||||
|
parent = providers.DependenciesContainer()
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
container.assign_parent(parent)
|
||||||
|
|
||||||
|
assert container.parent is parent
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_declarative_parent():
|
||||||
|
container = Container()
|
||||||
|
assert container.parent_name == "Container"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name():
|
||||||
|
container = Container()
|
||||||
|
assert container.parent_name == "Container"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_with_deep_parenting():
|
||||||
|
class Container2(containers.DeclarativeContainer):
|
||||||
|
name = providers.Container(Container)
|
||||||
|
|
||||||
|
class Container1(containers.DeclarativeContainer):
|
||||||
|
container = providers.Container(Container2)
|
||||||
|
|
||||||
|
container = Container1()
|
||||||
|
assert container.container().name.parent_name == "Container1.container.name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_is_none():
|
||||||
|
container = containers.DynamicContainer()
|
||||||
|
assert container.parent_name is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_deepcopy():
|
||||||
|
class ParentContainer(containers.DeclarativeContainer):
|
||||||
|
child = providers.Container(Container)
|
||||||
|
|
||||||
|
container = ParentContainer()
|
||||||
|
copied = providers.deepcopy(container)
|
||||||
|
|
||||||
|
assert container.child.parent is container
|
||||||
|
assert copied.child.parent is copied
|
||||||
|
|
||||||
|
assert container is not copied
|
||||||
|
assert container.child is not copied.child
|
||||||
|
assert container.child.parent is not copied.child.parent
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name():
|
||||||
|
container = Container()
|
||||||
|
assert container.resolve_provider_name(container.p11) == "p11"
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name_no_provider():
|
||||||
|
container = Container()
|
||||||
|
with raises(errors.Error):
|
||||||
|
container.resolve_provider_name(providers.Provider())
|
215
tests/unit/containers/instance/test_self_py2_py3.py
Normal file
215
tests/unit/containers/instance/test_self_py2_py3.py
Normal file
|
@ -0,0 +1,215 @@
|
||||||
|
"""Tests for container self provier."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
|
||||||
|
def test_self():
|
||||||
|
def call_bar(container):
|
||||||
|
return container.bar()
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
foo = providers.Callable(call_bar, __self__)
|
||||||
|
bar = providers.Object("hello")
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
assert container.foo() is "hello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_self_attribute_implicit():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
pass
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
assert container.__self__() is container
|
||||||
|
|
||||||
|
|
||||||
|
def test_self_attribute_explicit():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
assert container.__self__() is container
|
||||||
|
|
||||||
|
|
||||||
|
def test_single_self():
|
||||||
|
with raises(errors.Error):
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
self1 = providers.Self()
|
||||||
|
self2 = providers.Self()
|
||||||
|
|
||||||
|
|
||||||
|
def test_self_attribute_alt_name_implicit():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Self()
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.__self__ is container.foo
|
||||||
|
assert set(container.__self__.alt_names) == {"foo"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_self_attribute_alt_name_explicit_1():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
foo = __self__
|
||||||
|
bar = __self__
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.__self__ is container.foo
|
||||||
|
assert container.__self__ is container.bar
|
||||||
|
assert set(container.__self__.alt_names) == {"foo", "bar"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_self_attribute_alt_name_explicit_2():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Self()
|
||||||
|
bar = foo
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.__self__ is container.foo
|
||||||
|
assert container.__self__ is container.bar
|
||||||
|
assert set(container.__self__.alt_names) == {"foo", "bar"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_attribute_1():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
foo = __self__
|
||||||
|
bar = __self__
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.providers == {}
|
||||||
|
assert Container.providers == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_attribute_2():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Self()
|
||||||
|
bar = foo
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.providers == {}
|
||||||
|
assert Container.providers == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_container_multiple_instances():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
|
||||||
|
container1 = Container()
|
||||||
|
container2 = Container()
|
||||||
|
|
||||||
|
assert container1 is not container2
|
||||||
|
assert container1.__self__() is container1
|
||||||
|
assert container2.__self__() is container2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy():
|
||||||
|
def call_bar(container):
|
||||||
|
return container.bar()
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
foo = providers.Callable(call_bar, __self__)
|
||||||
|
bar = providers.Object("hello")
|
||||||
|
|
||||||
|
container1 = Container()
|
||||||
|
container2 = providers.deepcopy(container1)
|
||||||
|
container1.bar.override("bye")
|
||||||
|
|
||||||
|
assert container1.foo() == "bye"
|
||||||
|
assert container2.foo() == "hello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_alt_names_1():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
foo = __self__
|
||||||
|
bar = foo
|
||||||
|
|
||||||
|
container1 = Container()
|
||||||
|
container2 = providers.deepcopy(container1)
|
||||||
|
|
||||||
|
assert container2.__self__() is container2
|
||||||
|
assert container2.foo() is container2
|
||||||
|
assert container2.bar() is container2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_alt_names_2():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
self = providers.Self()
|
||||||
|
|
||||||
|
container1 = Container()
|
||||||
|
container2 = providers.deepcopy(container1)
|
||||||
|
|
||||||
|
assert container2.__self__() is container2
|
||||||
|
assert container2.self() is container2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_no_self_dependencies():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
|
||||||
|
container1 = Container()
|
||||||
|
container2 = providers.deepcopy(container1)
|
||||||
|
|
||||||
|
assert container1 is not container2
|
||||||
|
assert container1.__self__ is not container2.__self__
|
||||||
|
assert container1.__self__() is container1
|
||||||
|
assert container2.__self__() is container2
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_container_provider():
|
||||||
|
def call_bar(container):
|
||||||
|
return container.bar()
|
||||||
|
|
||||||
|
class SubContainer(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
foo = providers.Callable(call_bar, __self__)
|
||||||
|
bar = providers.Object("hello")
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
sub_container = providers.Container(SubContainer)
|
||||||
|
|
||||||
|
baz = providers.Callable(lambda value: value, sub_container.foo)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
assert container.baz() == "hello"
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_container_provider_overriding():
|
||||||
|
def call_bar(container):
|
||||||
|
return container.bar()
|
||||||
|
|
||||||
|
class SubContainer(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
foo = providers.Callable(call_bar, __self__)
|
||||||
|
bar = providers.Object("hello")
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
sub_container = providers.Container(SubContainer, bar="bye")
|
||||||
|
|
||||||
|
baz = providers.Callable(lambda value: value, sub_container.foo)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
assert container.baz() == "bye"
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_container_provider_self():
|
||||||
|
class SubContainer(containers.DeclarativeContainer):
|
||||||
|
__self__ = providers.Self()
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
sub_container = providers.Container(SubContainer)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.__self__() is container
|
||||||
|
assert container.sub_container().__self__() is container.sub_container()
|
||||||
|
|
|
@ -1,539 +0,0 @@
|
||||||
"""Dependency injector declarative container unit tests."""
|
|
||||||
|
|
||||||
import collections
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from dependency_injector import (
|
|
||||||
containers,
|
|
||||||
providers,
|
|
||||||
errors,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerA(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerB(ContainerA):
|
|
||||||
p21 = providers.Provider()
|
|
||||||
p22 = providers.Provider()
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerC(ContainerB):
|
|
||||||
p31 = providers.Provider()
|
|
||||||
p32 = providers.Provider()
|
|
||||||
|
|
||||||
|
|
||||||
class DeclarativeContainerTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_providers_attribute(self):
|
|
||||||
self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
self.assertEqual(ContainerB.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12,
|
|
||||||
p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22))
|
|
||||||
self.assertEqual(ContainerC.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12,
|
|
||||||
p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22,
|
|
||||||
p31=ContainerC.p31,
|
|
||||||
p32=ContainerC.p32))
|
|
||||||
|
|
||||||
def test_providers_attribute_with_redefinition(self):
|
|
||||||
p1 = providers.Provider()
|
|
||||||
p2 = providers.Provider()
|
|
||||||
|
|
||||||
class ContainerA2(ContainerA):
|
|
||||||
p11 = p1
|
|
||||||
p12 = p2
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
ContainerA.providers,
|
|
||||||
{
|
|
||||||
"p11": ContainerA.p11,
|
|
||||||
"p12": ContainerA.p12,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
ContainerA2.providers,
|
|
||||||
{
|
|
||||||
"p11": p1,
|
|
||||||
"p12": p2,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_cls_providers_attribute(self):
|
|
||||||
self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
self.assertEqual(ContainerB.cls_providers, dict(p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22))
|
|
||||||
self.assertEqual(ContainerC.cls_providers, dict(p31=ContainerC.p31,
|
|
||||||
p32=ContainerC.p32))
|
|
||||||
|
|
||||||
def test_inherited_providers_attribute(self):
|
|
||||||
self.assertEqual(ContainerA.inherited_providers, dict())
|
|
||||||
self.assertEqual(ContainerB.inherited_providers,
|
|
||||||
dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
self.assertEqual(ContainerC.inherited_providers,
|
|
||||||
dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12,
|
|
||||||
p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22))
|
|
||||||
|
|
||||||
def test_dependencies_attribute(self):
|
|
||||||
class ContainerD(ContainerC):
|
|
||||||
p41 = providers.Dependency()
|
|
||||||
p42 = providers.DependenciesContainer()
|
|
||||||
|
|
||||||
class ContainerE(ContainerD):
|
|
||||||
p51 = providers.Dependency()
|
|
||||||
p52 = providers.DependenciesContainer()
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
ContainerD.dependencies,
|
|
||||||
{
|
|
||||||
"p41": ContainerD.p41,
|
|
||||||
"p42": ContainerD.p42,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
ContainerE.dependencies,
|
|
||||||
{
|
|
||||||
"p41": ContainerD.p41,
|
|
||||||
"p42": ContainerD.p42,
|
|
||||||
"p51": ContainerE.p51,
|
|
||||||
"p52": ContainerE.p52,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_set_get_del_providers(self):
|
|
||||||
a_p13 = providers.Provider()
|
|
||||||
b_p23 = providers.Provider()
|
|
||||||
|
|
||||||
ContainerA.p13 = a_p13
|
|
||||||
ContainerB.p23 = b_p23
|
|
||||||
|
|
||||||
self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12,
|
|
||||||
p13=a_p13))
|
|
||||||
self.assertEqual(ContainerB.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12,
|
|
||||||
p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22,
|
|
||||||
p23=b_p23))
|
|
||||||
|
|
||||||
self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12,
|
|
||||||
p13=a_p13))
|
|
||||||
self.assertEqual(ContainerB.cls_providers, dict(p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22,
|
|
||||||
p23=b_p23))
|
|
||||||
|
|
||||||
del ContainerA.p13
|
|
||||||
del ContainerB.p23
|
|
||||||
|
|
||||||
self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
self.assertEqual(ContainerB.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12,
|
|
||||||
p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22))
|
|
||||||
|
|
||||||
self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
self.assertEqual(ContainerB.cls_providers, dict(p21=ContainerB.p21,
|
|
||||||
p22=ContainerB.p22))
|
|
||||||
|
|
||||||
def test_declare_with_valid_provider_type(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
provider_type = providers.Object
|
|
||||||
px = providers.Object(object())
|
|
||||||
|
|
||||||
self.assertIsInstance(_Container.px, providers.Object)
|
|
||||||
|
|
||||||
def test_declare_with_invalid_provider_type(self):
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
provider_type = providers.Object
|
|
||||||
px = providers.Provider()
|
|
||||||
|
|
||||||
def test_seth_valid_provider_type(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
provider_type = providers.Object
|
|
||||||
|
|
||||||
_Container.px = providers.Object(object())
|
|
||||||
|
|
||||||
self.assertIsInstance(_Container.px, providers.Object)
|
|
||||||
|
|
||||||
def test_set_invalid_provider_type(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
provider_type = providers.Object
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
_Container.px = providers.Provider()
|
|
||||||
|
|
||||||
def test_override(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer1(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer2(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
_Container.override(_OverridingContainer1)
|
|
||||||
_Container.override(_OverridingContainer2)
|
|
||||||
|
|
||||||
self.assertEqual(_Container.overridden,
|
|
||||||
(_OverridingContainer1,
|
|
||||||
_OverridingContainer2))
|
|
||||||
self.assertEqual(_Container.p11.overridden,
|
|
||||||
(_OverridingContainer1.p11,
|
|
||||||
_OverridingContainer2.p11))
|
|
||||||
|
|
||||||
def test_override_with_itself(self):
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
ContainerA.override(ContainerA)
|
|
||||||
|
|
||||||
def test_override_with_parent(self):
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
ContainerB.override(ContainerA)
|
|
||||||
|
|
||||||
def test_override_decorator(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
@containers.override(_Container)
|
|
||||||
class _OverridingContainer1(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
@containers.override(_Container)
|
|
||||||
class _OverridingContainer2(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
self.assertEqual(_Container.overridden,
|
|
||||||
(_OverridingContainer1,
|
|
||||||
_OverridingContainer2))
|
|
||||||
self.assertEqual(_Container.p11.overridden,
|
|
||||||
(_OverridingContainer1.p11,
|
|
||||||
_OverridingContainer2.p11))
|
|
||||||
|
|
||||||
def test_reset_last_overriding(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer1(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer2(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
_Container.override(_OverridingContainer1)
|
|
||||||
_Container.override(_OverridingContainer2)
|
|
||||||
_Container.reset_last_overriding()
|
|
||||||
|
|
||||||
self.assertEqual(_Container.overridden,
|
|
||||||
(_OverridingContainer1,))
|
|
||||||
self.assertEqual(_Container.p11.overridden,
|
|
||||||
(_OverridingContainer1.p11,))
|
|
||||||
|
|
||||||
def test_reset_last_overriding_when_not_overridden(self):
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
ContainerA.reset_last_overriding()
|
|
||||||
|
|
||||||
def test_reset_override(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer1(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer2(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
_Container.override(_OverridingContainer1)
|
|
||||||
_Container.override(_OverridingContainer2)
|
|
||||||
_Container.reset_override()
|
|
||||||
|
|
||||||
self.assertEqual(_Container.overridden, tuple())
|
|
||||||
self.assertEqual(_Container.p11.overridden, tuple())
|
|
||||||
|
|
||||||
def test_copy(self):
|
|
||||||
@containers.copy(ContainerA)
|
|
||||||
class _Container1(ContainerA):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@containers.copy(ContainerA)
|
|
||||||
class _Container2(ContainerA):
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertIsNot(ContainerA.p11, _Container1.p11)
|
|
||||||
self.assertIsNot(ContainerA.p12, _Container1.p12)
|
|
||||||
|
|
||||||
self.assertIsNot(ContainerA.p11, _Container2.p11)
|
|
||||||
self.assertIsNot(ContainerA.p12, _Container2.p12)
|
|
||||||
|
|
||||||
self.assertIsNot(_Container1.p11, _Container2.p11)
|
|
||||||
self.assertIsNot(_Container1.p12, _Container2.p12)
|
|
||||||
|
|
||||||
def test_copy_with_replacing(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Object(0)
|
|
||||||
p12 = providers.Factory(dict, p11=p11)
|
|
||||||
|
|
||||||
@containers.copy(_Container)
|
|
||||||
class _Container1(_Container):
|
|
||||||
p11 = providers.Object(1)
|
|
||||||
p13 = providers.Object(11)
|
|
||||||
|
|
||||||
@containers.copy(_Container)
|
|
||||||
class _Container2(_Container):
|
|
||||||
p11 = providers.Object(2)
|
|
||||||
p13 = providers.Object(22)
|
|
||||||
|
|
||||||
self.assertIsNot(_Container.p11, _Container1.p11)
|
|
||||||
self.assertIsNot(_Container.p12, _Container1.p12)
|
|
||||||
|
|
||||||
self.assertIsNot(_Container.p11, _Container2.p11)
|
|
||||||
self.assertIsNot(_Container.p12, _Container2.p12)
|
|
||||||
|
|
||||||
self.assertIsNot(_Container1.p11, _Container2.p11)
|
|
||||||
self.assertIsNot(_Container1.p12, _Container2.p12)
|
|
||||||
|
|
||||||
self.assertEqual(_Container.p12(), {"p11": 0})
|
|
||||||
self.assertEqual(_Container1.p12(), {"p11": 1})
|
|
||||||
self.assertEqual(_Container2.p12(), {"p11": 2})
|
|
||||||
|
|
||||||
self.assertEqual(_Container1.p13(), 11)
|
|
||||||
self.assertEqual(_Container2.p13(), 22)
|
|
||||||
|
|
||||||
def test_copy_with_parent_dependency(self):
|
|
||||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/477
|
|
||||||
class Base(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Object(0)
|
|
||||||
p12 = providers.Factory(dict, p11=p11)
|
|
||||||
|
|
||||||
@containers.copy(Base)
|
|
||||||
class New(Base):
|
|
||||||
p13 = providers.Factory(dict, p12=Base.p12)
|
|
||||||
|
|
||||||
new1 = New()
|
|
||||||
new2 = New(p11=1)
|
|
||||||
new3 = New(p11=2)
|
|
||||||
|
|
||||||
self.assertEqual(new1.p13(), {"p12": {"p11": 0}})
|
|
||||||
self.assertEqual(new2.p13(), {"p12": {"p11": 1}})
|
|
||||||
self.assertEqual(new3.p13(), {"p12": {"p11": 2}})
|
|
||||||
|
|
||||||
def test_copy_with_replacing_subcontainer_providers(self):
|
|
||||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/374
|
|
||||||
class X(containers.DeclarativeContainer):
|
|
||||||
foo = providers.Dependency(instance_of=str)
|
|
||||||
|
|
||||||
def build_x():
|
|
||||||
return X(foo="1")
|
|
||||||
|
|
||||||
class A(containers.DeclarativeContainer):
|
|
||||||
x = providers.DependenciesContainer(**X.providers)
|
|
||||||
y = x.foo
|
|
||||||
|
|
||||||
@containers.copy(A)
|
|
||||||
class B1(A):
|
|
||||||
x = providers.Container(build_x)
|
|
||||||
|
|
||||||
b1 = B1()
|
|
||||||
|
|
||||||
self.assertEqual(b1.y(), "1")
|
|
||||||
|
|
||||||
def test_containers_attribute(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
class Container1(containers.DeclarativeContainer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Container2(containers.DeclarativeContainer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
Container3 = containers.DynamicContainer()
|
|
||||||
|
|
||||||
self.assertEqual(Container.containers,
|
|
||||||
dict(Container1=Container.Container1,
|
|
||||||
Container2=Container.Container2,
|
|
||||||
Container3=Container.Container3))
|
|
||||||
|
|
||||||
def test_init_with_overriding_providers(self):
|
|
||||||
p1 = providers.Provider()
|
|
||||||
p2 = providers.Provider()
|
|
||||||
|
|
||||||
container = ContainerA(p11=p1, p12=p2)
|
|
||||||
|
|
||||||
self.assertIs(container.p11.last_overriding, p1)
|
|
||||||
self.assertIs(container.p12.last_overriding, p2)
|
|
||||||
|
|
||||||
def test_init_with_overridden_dependency(self):
|
|
||||||
# Bug:
|
|
||||||
# https://github.com/ets-labs/python-dependency-injector/issues/198
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p1 = providers.Dependency(instance_of=int)
|
|
||||||
|
|
||||||
p2 = providers.Dependency(object)
|
|
||||||
p2.override(providers.Factory(dict, p1=p1))
|
|
||||||
|
|
||||||
container = _Container(p1=1)
|
|
||||||
|
|
||||||
self.assertEqual(container.p2(), {"p1": 1})
|
|
||||||
self.assertIs(
|
|
||||||
container.p2.last_overriding.kwargs["p1"],
|
|
||||||
container.p1,
|
|
||||||
)
|
|
||||||
self.assertIsNot(
|
|
||||||
container.p2.last_overriding.kwargs["p1"],
|
|
||||||
_Container.p1,
|
|
||||||
)
|
|
||||||
self.assertIs(
|
|
||||||
_Container.p2.last_overriding.kwargs["p1"],
|
|
||||||
_Container.p1,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_init_with_chained_dependency(self):
|
|
||||||
# Bug:
|
|
||||||
# https://github.com/ets-labs/python-dependency-injector/issues/200
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p1 = providers.Dependency(instance_of=int)
|
|
||||||
p2 = providers.Factory(p1)
|
|
||||||
|
|
||||||
container = _Container(p1=1)
|
|
||||||
|
|
||||||
self.assertEqual(container.p2(), 1)
|
|
||||||
self.assertIs(container.p2.cls, container.p1)
|
|
||||||
self.assertIs(_Container.p2.cls, _Container.p1)
|
|
||||||
self.assertIsNot(container.p2.cls, _Container.p1)
|
|
||||||
|
|
||||||
def test_init_with_dependency_delegation(self):
|
|
||||||
# Bug:
|
|
||||||
# https://github.com/ets-labs/python-dependency-injector/issues/235
|
|
||||||
A = collections.namedtuple("A", [])
|
|
||||||
B = collections.namedtuple("B", ["fa"])
|
|
||||||
C = collections.namedtuple("B", ["a"])
|
|
||||||
|
|
||||||
class Services(containers.DeclarativeContainer):
|
|
||||||
a = providers.Dependency()
|
|
||||||
c = providers.Factory(C, a=a)
|
|
||||||
b = providers.Factory(B, fa=a.provider)
|
|
||||||
|
|
||||||
a = providers.Factory(A)
|
|
||||||
assert isinstance(Services(a=a).c().a, A) # ok
|
|
||||||
Services(a=a).b().fa()
|
|
||||||
|
|
||||||
def test_init_with_grand_child_provider(self):
|
|
||||||
# Bug:
|
|
||||||
# https://github.com/ets-labs/python-dependency-injector/issues/350
|
|
||||||
provider = providers.Provider()
|
|
||||||
container = ContainerC(p11=provider)
|
|
||||||
|
|
||||||
self.assertIsInstance(container.p11, providers.Provider)
|
|
||||||
self.assertIsInstance(container.p12, providers.Provider)
|
|
||||||
self.assertIsInstance(container.p21, providers.Provider)
|
|
||||||
self.assertIsInstance(container.p22, providers.Provider)
|
|
||||||
self.assertIsInstance(container.p31, providers.Provider)
|
|
||||||
self.assertIsInstance(container.p32, providers.Provider)
|
|
||||||
self.assertIs(container.p11.last_overriding, provider)
|
|
||||||
|
|
||||||
def test_parent_set_in__new__(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
dependency = providers.Dependency()
|
|
||||||
dependencies_container = providers.DependenciesContainer()
|
|
||||||
container = providers.Container(ContainerA)
|
|
||||||
|
|
||||||
self.assertIs(Container.dependency.parent, Container)
|
|
||||||
self.assertIs(Container.dependencies_container.parent, Container)
|
|
||||||
self.assertIs(Container.container.parent, Container)
|
|
||||||
|
|
||||||
def test_parent_set_in__setattr__(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
Container.dependency = providers.Dependency()
|
|
||||||
Container.dependencies_container = providers.DependenciesContainer()
|
|
||||||
Container.container = providers.Container(ContainerA)
|
|
||||||
|
|
||||||
self.assertIs(Container.dependency.parent, Container)
|
|
||||||
self.assertIs(Container.dependencies_container.parent, Container)
|
|
||||||
self.assertIs(Container.container.parent, Container)
|
|
||||||
|
|
||||||
def test_resolve_provider_name(self):
|
|
||||||
self.assertEqual(ContainerA.resolve_provider_name(ContainerA.p11), "p11")
|
|
||||||
|
|
||||||
def test_resolve_provider_name_no_provider(self):
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
ContainerA.resolve_provider_name(providers.Provider())
|
|
||||||
|
|
||||||
def test_child_dependency_parent_name(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
dependency = providers.Dependency()
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
Container.dependency()
|
|
||||||
self.assertEqual(
|
|
||||||
str(context.exception),
|
|
||||||
"Dependency \"Container.dependency\" is not defined",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_child_dependencies_container_parent_name(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
dependencies_container = providers.DependenciesContainer()
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
Container.dependencies_container.dependency()
|
|
||||||
self.assertEqual(
|
|
||||||
str(context.exception),
|
|
||||||
"Dependency \"Container.dependencies_container.dependency\" is not defined",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_child_container_parent_name(self):
|
|
||||||
class ChildContainer(containers.DeclarativeContainer):
|
|
||||||
dependency = providers.Dependency()
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
child_container = providers.Container(ChildContainer)
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
Container.child_container.dependency()
|
|
||||||
self.assertEqual(
|
|
||||||
str(context.exception),
|
|
||||||
"Dependency \"Container.child_container.dependency\" is not defined",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class DeclarativeContainerWithCustomStringTests(unittest.TestCase):
|
|
||||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/479
|
|
||||||
|
|
||||||
class CustomString(str):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class CustomClass:
|
|
||||||
thing = None
|
|
||||||
|
|
||||||
class CustomContainer(containers.DeclarativeContainer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.container = self.CustomContainer
|
|
||||||
self.provider = providers.Provider()
|
|
||||||
|
|
||||||
def test_setattr(self):
|
|
||||||
setattr(self.container, self.CustomString("test_attr"), self.provider)
|
|
||||||
self.assertIs(self.container.test_attr, self.provider)
|
|
||||||
|
|
||||||
def test_delattr(self):
|
|
||||||
setattr(self.container, self.CustomString("test_attr"), self.provider)
|
|
||||||
delattr(self.container, self.CustomString("test_attr"))
|
|
||||||
with self.assertRaises(AttributeError):
|
|
||||||
self.container.test_attr
|
|
|
@ -1,159 +0,0 @@
|
||||||
"""Dependency injector dynamic container unit tests for async resources."""
|
|
||||||
import asyncio
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
from dependency_injector import (
|
|
||||||
containers,
|
|
||||||
providers,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class AsyncResourcesTest(AsyncTestCase):
|
|
||||||
|
|
||||||
def test_init_and_shutdown_ordering(self):
|
|
||||||
"""Test init and shutdown resources.
|
|
||||||
|
|
||||||
Methods .init_resources() and .shutdown_resources() should respect resources dependencies.
|
|
||||||
Initialization should first initialize resources without dependencies and then provide
|
|
||||||
these resources to other resources. Resources shutdown should follow the same rule: first
|
|
||||||
shutdown resources without initialized dependencies and then continue correspondingly
|
|
||||||
until all resources are shutdown.
|
|
||||||
"""
|
|
||||||
initialized_resources = []
|
|
||||||
shutdown_resources = []
|
|
||||||
|
|
||||||
async def _resource(name, delay, **_):
|
|
||||||
await asyncio.sleep(delay)
|
|
||||||
initialized_resources.append(name)
|
|
||||||
|
|
||||||
yield name
|
|
||||||
|
|
||||||
await asyncio.sleep(delay)
|
|
||||||
shutdown_resources.append(name)
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
resource1 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r1",
|
|
||||||
delay=0.03,
|
|
||||||
)
|
|
||||||
resource2 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r2",
|
|
||||||
delay=0.02,
|
|
||||||
r1=resource1,
|
|
||||||
)
|
|
||||||
resource3 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r3",
|
|
||||||
delay=0.01,
|
|
||||||
r2=resource2,
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self._run(container.init_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, [])
|
|
||||||
|
|
||||||
self._run(container.shutdown_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1"])
|
|
||||||
|
|
||||||
self._run(container.init_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3", "r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1"])
|
|
||||||
|
|
||||||
self._run(container.shutdown_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3", "r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1", "r3", "r2", "r1"])
|
|
||||||
|
|
||||||
def test_shutdown_circular_dependencies_breaker(self):
|
|
||||||
async def _resource(name, **_):
|
|
||||||
yield name
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
resource1 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r1",
|
|
||||||
)
|
|
||||||
resource2 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r2",
|
|
||||||
r1=resource1,
|
|
||||||
)
|
|
||||||
resource3 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r3",
|
|
||||||
r2=resource2,
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
self._run(container.init_resources())
|
|
||||||
|
|
||||||
# Create circular dependency after initialization (r3 -> r2 -> r1 -> r3 -> ...)
|
|
||||||
container.resource1.add_kwargs(r3=container.resource3)
|
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError) as context:
|
|
||||||
self._run(container.shutdown_resources())
|
|
||||||
self.assertEqual(str(context.exception), "Unable to resolve resources shutdown order")
|
|
||||||
|
|
||||||
def test_shutdown_sync_and_async_ordering(self):
|
|
||||||
initialized_resources = []
|
|
||||||
shutdown_resources = []
|
|
||||||
|
|
||||||
def _sync_resource(name, **_):
|
|
||||||
initialized_resources.append(name)
|
|
||||||
yield name
|
|
||||||
shutdown_resources.append(name)
|
|
||||||
|
|
||||||
async def _async_resource(name, **_):
|
|
||||||
initialized_resources.append(name)
|
|
||||||
yield name
|
|
||||||
shutdown_resources.append(name)
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
resource1 = providers.Resource(
|
|
||||||
_sync_resource,
|
|
||||||
name="r1",
|
|
||||||
)
|
|
||||||
resource2 = providers.Resource(
|
|
||||||
_sync_resource,
|
|
||||||
name="r2",
|
|
||||||
r1=resource1,
|
|
||||||
)
|
|
||||||
resource3 = providers.Resource(
|
|
||||||
_async_resource,
|
|
||||||
name="r3",
|
|
||||||
r2=resource2,
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self._run(container.init_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, [])
|
|
||||||
|
|
||||||
self._run(container.shutdown_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1"])
|
|
||||||
|
|
||||||
self._run(container.init_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3", "r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1"])
|
|
||||||
|
|
||||||
self._run(container.shutdown_resources())
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3", "r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1", "r3", "r2", "r1"])
|
|
|
@ -1,733 +0,0 @@
|
||||||
"""Dependency injector dynamic container unit tests."""
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from dependency_injector import (
|
|
||||||
containers,
|
|
||||||
providers,
|
|
||||||
errors,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ContainerA(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
|
|
||||||
class DeclarativeContainerInstanceTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_providers_attribute(self):
|
|
||||||
container_a1 = ContainerA()
|
|
||||||
container_a2 = ContainerA()
|
|
||||||
|
|
||||||
self.assertIsNot(container_a1.p11, container_a2.p11)
|
|
||||||
self.assertIsNot(container_a1.p12, container_a2.p12)
|
|
||||||
self.assertNotEqual(container_a1.providers, container_a2.providers)
|
|
||||||
|
|
||||||
def test_dependencies_attribute(self):
|
|
||||||
container = ContainerA()
|
|
||||||
container.a1 = providers.Dependency()
|
|
||||||
container.a2 = providers.DependenciesContainer()
|
|
||||||
self.assertEqual(container.dependencies, {"a1": container.a1, "a2": container.a2})
|
|
||||||
|
|
||||||
def test_set_get_del_providers(self):
|
|
||||||
p13 = providers.Provider()
|
|
||||||
|
|
||||||
container_a1 = ContainerA()
|
|
||||||
container_a2 = ContainerA()
|
|
||||||
|
|
||||||
container_a1.p13 = p13
|
|
||||||
container_a2.p13 = p13
|
|
||||||
|
|
||||||
self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
self.assertEqual(ContainerA.cls_providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
|
|
||||||
self.assertEqual(container_a1.providers, dict(p11=container_a1.p11,
|
|
||||||
p12=container_a1.p12,
|
|
||||||
p13=p13))
|
|
||||||
self.assertEqual(container_a2.providers, dict(p11=container_a2.p11,
|
|
||||||
p12=container_a2.p12,
|
|
||||||
p13=p13))
|
|
||||||
|
|
||||||
del container_a1.p13
|
|
||||||
self.assertEqual(container_a1.providers, dict(p11=container_a1.p11,
|
|
||||||
p12=container_a1.p12))
|
|
||||||
|
|
||||||
del container_a2.p13
|
|
||||||
self.assertEqual(container_a2.providers, dict(p11=container_a2.p11,
|
|
||||||
p12=container_a2.p12))
|
|
||||||
|
|
||||||
del container_a1.p11
|
|
||||||
del container_a1.p12
|
|
||||||
self.assertEqual(container_a1.providers, dict())
|
|
||||||
self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
|
|
||||||
del container_a2.p11
|
|
||||||
del container_a2.p12
|
|
||||||
self.assertEqual(container_a2.providers, dict())
|
|
||||||
self.assertEqual(ContainerA.providers, dict(p11=ContainerA.p11,
|
|
||||||
p12=ContainerA.p12))
|
|
||||||
|
|
||||||
def test_set_invalid_provider_type(self):
|
|
||||||
container_a = ContainerA()
|
|
||||||
container_a.provider_type = providers.Object
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
container_a.px = providers.Provider()
|
|
||||||
|
|
||||||
self.assertIs(ContainerA.provider_type,
|
|
||||||
containers.DeclarativeContainer.provider_type)
|
|
||||||
|
|
||||||
def test_set_providers(self):
|
|
||||||
p13 = providers.Provider()
|
|
||||||
p14 = providers.Provider()
|
|
||||||
container_a = ContainerA()
|
|
||||||
|
|
||||||
container_a.set_providers(p13=p13, p14=p14)
|
|
||||||
|
|
||||||
self.assertIs(container_a.p13, p13)
|
|
||||||
self.assertIs(container_a.p14, p14)
|
|
||||||
|
|
||||||
def test_override(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer1(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer2(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
container = _Container()
|
|
||||||
overriding_container1 = _OverridingContainer1()
|
|
||||||
overriding_container2 = _OverridingContainer2()
|
|
||||||
|
|
||||||
container.override(overriding_container1)
|
|
||||||
container.override(overriding_container2)
|
|
||||||
|
|
||||||
self.assertEqual(container.overridden,
|
|
||||||
(overriding_container1,
|
|
||||||
overriding_container2))
|
|
||||||
self.assertEqual(container.p11.overridden,
|
|
||||||
(overriding_container1.p11,
|
|
||||||
overriding_container2.p11))
|
|
||||||
|
|
||||||
self.assertEqual(_Container.overridden, tuple())
|
|
||||||
self.assertEqual(_Container.p11.overridden, tuple())
|
|
||||||
|
|
||||||
def test_override_with_itself(self):
|
|
||||||
container = ContainerA()
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
container.override(container)
|
|
||||||
|
|
||||||
def test_override_providers(self):
|
|
||||||
p1 = providers.Provider()
|
|
||||||
p2 = providers.Provider()
|
|
||||||
container_a = ContainerA()
|
|
||||||
|
|
||||||
container_a.override_providers(p11=p1, p12=p2)
|
|
||||||
|
|
||||||
self.assertIs(container_a.p11.last_overriding, p1)
|
|
||||||
self.assertIs(container_a.p12.last_overriding, p2)
|
|
||||||
|
|
||||||
def test_override_providers_context_manager(self):
|
|
||||||
p1 = providers.Provider()
|
|
||||||
p2 = providers.Provider()
|
|
||||||
container_a = ContainerA()
|
|
||||||
|
|
||||||
with container_a.override_providers(p11=p1, p12=p2) as container:
|
|
||||||
self.assertIs(container, container_a)
|
|
||||||
self.assertIs(container_a.p11.last_overriding, p1)
|
|
||||||
self.assertIs(container_a.p12.last_overriding, p2)
|
|
||||||
|
|
||||||
self.assertIsNone(container_a.p11.last_overriding)
|
|
||||||
self.assertIsNone(container_a.p12.last_overriding)
|
|
||||||
|
|
||||||
def test_override_providers_with_unknown_provider(self):
|
|
||||||
container_a = ContainerA()
|
|
||||||
|
|
||||||
with self.assertRaises(AttributeError):
|
|
||||||
container_a.override_providers(unknown=providers.Provider())
|
|
||||||
|
|
||||||
def test_reset_last_overriding(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer1(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer2(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
container = _Container()
|
|
||||||
overriding_container1 = _OverridingContainer1()
|
|
||||||
overriding_container2 = _OverridingContainer2()
|
|
||||||
|
|
||||||
container.override(overriding_container1)
|
|
||||||
container.override(overriding_container2)
|
|
||||||
container.reset_last_overriding()
|
|
||||||
|
|
||||||
self.assertEqual(container.overridden,
|
|
||||||
(overriding_container1,))
|
|
||||||
self.assertEqual(container.p11.overridden,
|
|
||||||
(overriding_container1.p11,))
|
|
||||||
|
|
||||||
def test_reset_last_overriding_when_not_overridden(self):
|
|
||||||
container = ContainerA()
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
container.reset_last_overriding()
|
|
||||||
|
|
||||||
def test_reset_override(self):
|
|
||||||
class _Container(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer1(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
|
|
||||||
class _OverridingContainer2(containers.DeclarativeContainer):
|
|
||||||
p11 = providers.Provider()
|
|
||||||
p12 = providers.Provider()
|
|
||||||
|
|
||||||
container = _Container()
|
|
||||||
overriding_container1 = _OverridingContainer1()
|
|
||||||
overriding_container2 = _OverridingContainer2()
|
|
||||||
|
|
||||||
container.override(overriding_container1)
|
|
||||||
container.override(overriding_container2)
|
|
||||||
container.reset_override()
|
|
||||||
|
|
||||||
self.assertEqual(container.overridden, tuple())
|
|
||||||
self.assertEqual(container.p11.overridden, tuple())
|
|
||||||
|
|
||||||
def test_init_and_shutdown_resources_ordering(self):
|
|
||||||
"""Test init and shutdown resources.
|
|
||||||
|
|
||||||
Methods .init_resources() and .shutdown_resources() should respect resources dependencies.
|
|
||||||
Initialization should first initialize resources without dependencies and then provide
|
|
||||||
these resources to other resources. Resources shutdown should follow the same rule: first
|
|
||||||
shutdown resources without initialized dependencies and then continue correspondingly
|
|
||||||
until all resources are shutdown.
|
|
||||||
"""
|
|
||||||
initialized_resources = []
|
|
||||||
shutdown_resources = []
|
|
||||||
|
|
||||||
def _resource(name, **_):
|
|
||||||
initialized_resources.append(name)
|
|
||||||
yield name
|
|
||||||
shutdown_resources.append(name)
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
resource1 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r1",
|
|
||||||
)
|
|
||||||
resource2 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r2",
|
|
||||||
r1=resource1,
|
|
||||||
)
|
|
||||||
resource3 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r3",
|
|
||||||
r2=resource2,
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
container.init_resources()
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, [])
|
|
||||||
|
|
||||||
container.shutdown_resources()
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1"])
|
|
||||||
|
|
||||||
container.init_resources()
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3", "r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1"])
|
|
||||||
|
|
||||||
container.shutdown_resources()
|
|
||||||
self.assertEqual(initialized_resources, ["r1", "r2", "r3", "r1", "r2", "r3"])
|
|
||||||
self.assertEqual(shutdown_resources, ["r3", "r2", "r1", "r3", "r2", "r1"])
|
|
||||||
|
|
||||||
def test_shutdown_resources_circular_dependencies_breaker(self):
|
|
||||||
def _resource(name, **_):
|
|
||||||
yield name
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
resource1 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r1",
|
|
||||||
)
|
|
||||||
resource2 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r2",
|
|
||||||
r1=resource1,
|
|
||||||
)
|
|
||||||
resource3 = providers.Resource(
|
|
||||||
_resource,
|
|
||||||
name="r3",
|
|
||||||
r2=resource2,
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
container.init_resources()
|
|
||||||
|
|
||||||
# Create circular dependency after initialization (r3 -> r2 -> r1 -> r3 -> ...)
|
|
||||||
container.resource1.add_kwargs(r3=container.resource3)
|
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError) as context:
|
|
||||||
container.shutdown_resources()
|
|
||||||
self.assertEqual(str(context.exception), "Unable to resolve resources shutdown order")
|
|
||||||
|
|
||||||
def test_init_shutdown_nested_resources(self):
|
|
||||||
def _init1():
|
|
||||||
_init1.init_counter += 1
|
|
||||||
yield
|
|
||||||
_init1.shutdown_counter += 1
|
|
||||||
|
|
||||||
_init1.init_counter = 0
|
|
||||||
_init1.shutdown_counter = 0
|
|
||||||
|
|
||||||
def _init2():
|
|
||||||
_init2.init_counter += 1
|
|
||||||
yield
|
|
||||||
_init2.shutdown_counter += 1
|
|
||||||
|
|
||||||
_init2.init_counter = 0
|
|
||||||
_init2.shutdown_counter = 0
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
|
|
||||||
service = providers.Factory(
|
|
||||||
dict,
|
|
||||||
resource1=providers.Resource(_init1),
|
|
||||||
resource2=providers.Resource(_init2),
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
self.assertEqual(_init1.init_counter, 0)
|
|
||||||
self.assertEqual(_init1.shutdown_counter, 0)
|
|
||||||
self.assertEqual(_init2.init_counter, 0)
|
|
||||||
self.assertEqual(_init2.shutdown_counter, 0)
|
|
||||||
|
|
||||||
container.init_resources()
|
|
||||||
self.assertEqual(_init1.init_counter, 1)
|
|
||||||
self.assertEqual(_init1.shutdown_counter, 0)
|
|
||||||
self.assertEqual(_init2.init_counter, 1)
|
|
||||||
self.assertEqual(_init2.shutdown_counter, 0)
|
|
||||||
|
|
||||||
container.shutdown_resources()
|
|
||||||
self.assertEqual(_init1.init_counter, 1)
|
|
||||||
self.assertEqual(_init1.shutdown_counter, 1)
|
|
||||||
self.assertEqual(_init2.init_counter, 1)
|
|
||||||
self.assertEqual(_init2.shutdown_counter, 1)
|
|
||||||
|
|
||||||
container.init_resources()
|
|
||||||
container.shutdown_resources()
|
|
||||||
self.assertEqual(_init1.init_counter, 2)
|
|
||||||
self.assertEqual(_init1.shutdown_counter, 2)
|
|
||||||
self.assertEqual(_init2.init_counter, 2)
|
|
||||||
self.assertEqual(_init2.shutdown_counter, 2)
|
|
||||||
|
|
||||||
def test_reset_singletons(self):
|
|
||||||
class SubSubContainer(containers.DeclarativeContainer):
|
|
||||||
singleton = providers.Singleton(object)
|
|
||||||
|
|
||||||
class SubContainer(containers.DeclarativeContainer):
|
|
||||||
singleton = providers.Singleton(object)
|
|
||||||
sub_sub_container = providers.Container(SubSubContainer)
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
singleton = providers.Singleton(object)
|
|
||||||
sub_container = providers.Container(SubContainer)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
obj11 = container.singleton()
|
|
||||||
obj12 = container.sub_container().singleton()
|
|
||||||
obj13 = container.sub_container().sub_sub_container().singleton()
|
|
||||||
|
|
||||||
obj21 = container.singleton()
|
|
||||||
obj22 = container.sub_container().singleton()
|
|
||||||
obj23 = container.sub_container().sub_sub_container().singleton()
|
|
||||||
|
|
||||||
self.assertIs(obj11, obj21)
|
|
||||||
self.assertIs(obj12, obj22)
|
|
||||||
self.assertIs(obj13, obj23)
|
|
||||||
|
|
||||||
container.reset_singletons()
|
|
||||||
|
|
||||||
obj31 = container.singleton()
|
|
||||||
obj32 = container.sub_container().singleton()
|
|
||||||
obj33 = container.sub_container().sub_sub_container().singleton()
|
|
||||||
|
|
||||||
obj41 = container.singleton()
|
|
||||||
obj42 = container.sub_container().singleton()
|
|
||||||
obj43 = container.sub_container().sub_sub_container().singleton()
|
|
||||||
|
|
||||||
self.assertIsNot(obj11, obj31)
|
|
||||||
self.assertIsNot(obj12, obj32)
|
|
||||||
self.assertIsNot(obj13, obj33)
|
|
||||||
|
|
||||||
self.assertIsNot(obj21, obj31)
|
|
||||||
self.assertIsNot(obj22, obj32)
|
|
||||||
self.assertIsNot(obj23, obj33)
|
|
||||||
|
|
||||||
self.assertIs(obj31, obj41)
|
|
||||||
self.assertIs(obj32, obj42)
|
|
||||||
self.assertIs(obj33, obj43)
|
|
||||||
|
|
||||||
def test_reset_singletons_context_manager(self):
|
|
||||||
class Item:
|
|
||||||
def __init__(self, dependency):
|
|
||||||
self.dependency = dependency
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
dependent = providers.Singleton(object)
|
|
||||||
singleton = providers.Singleton(Item, dependency=dependent)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
instance1 = container.singleton()
|
|
||||||
with container.reset_singletons():
|
|
||||||
instance2 = container.singleton()
|
|
||||||
instance3 = container.singleton()
|
|
||||||
|
|
||||||
self.assertEqual(len({instance1, instance2, instance3}), 3)
|
|
||||||
self.assertEqual(
|
|
||||||
len({instance1.dependency, instance2.dependency, instance3.dependency}),
|
|
||||||
3,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_reset_singletons_context_manager_as_attribute(self):
|
|
||||||
container = containers.DeclarativeContainer()
|
|
||||||
|
|
||||||
with container.reset_singletons() as alias:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertIs(container, alias)
|
|
||||||
|
|
||||||
def test_check_dependencies(self):
|
|
||||||
class SubContainer(containers.DeclarativeContainer):
|
|
||||||
dependency = providers.Dependency()
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
dependency = providers.Dependency()
|
|
||||||
dependencies_container = providers.DependenciesContainer()
|
|
||||||
provider = providers.List(dependencies_container.dependency)
|
|
||||||
sub_container = providers.Container(SubContainer)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
container.check_dependencies()
|
|
||||||
|
|
||||||
self.assertIn("Container \"Container\" has undefined dependencies:", str(context.exception))
|
|
||||||
self.assertIn("\"Container.dependency\"", str(context.exception))
|
|
||||||
self.assertIn("\"Container.dependencies_container.dependency\"", str(context.exception))
|
|
||||||
self.assertIn("\"Container.sub_container.dependency\"", str(context.exception))
|
|
||||||
|
|
||||||
def test_check_dependencies_all_defined(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
dependency = providers.Dependency()
|
|
||||||
|
|
||||||
container = Container(dependency="provided")
|
|
||||||
result = container.check_dependencies()
|
|
||||||
|
|
||||||
self.assertIsNone(result)
|
|
||||||
|
|
||||||
def test_assign_parent(self):
|
|
||||||
parent = providers.DependenciesContainer()
|
|
||||||
container = ContainerA()
|
|
||||||
|
|
||||||
container.assign_parent(parent)
|
|
||||||
|
|
||||||
self.assertIs(container.parent, parent)
|
|
||||||
|
|
||||||
def test_parent_name_declarative_parent(self):
|
|
||||||
container = ContainerA()
|
|
||||||
self.assertEqual(container.parent_name, "ContainerA")
|
|
||||||
|
|
||||||
def test_parent_name(self):
|
|
||||||
container = ContainerA()
|
|
||||||
self.assertEqual(container.parent_name, "ContainerA")
|
|
||||||
|
|
||||||
def test_parent_name_with_deep_parenting(self):
|
|
||||||
class Container2(containers.DeclarativeContainer):
|
|
||||||
|
|
||||||
name = providers.Container(ContainerA)
|
|
||||||
|
|
||||||
class Container1(containers.DeclarativeContainer):
|
|
||||||
|
|
||||||
container = providers.Container(Container2)
|
|
||||||
|
|
||||||
container = Container1()
|
|
||||||
self.assertEqual(container.container().name.parent_name, "Container1.container.name")
|
|
||||||
|
|
||||||
def test_parent_name_is_none(self):
|
|
||||||
container = containers.DynamicContainer()
|
|
||||||
self.assertIsNone(container.parent_name)
|
|
||||||
|
|
||||||
def test_parent_deepcopy(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
container = providers.Container(ContainerA)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
copied = providers.deepcopy(container)
|
|
||||||
|
|
||||||
self.assertIs(container.container.parent, container)
|
|
||||||
self.assertIs(copied.container.parent, copied)
|
|
||||||
|
|
||||||
self.assertIsNot(container, copied)
|
|
||||||
self.assertIsNot(container.container, copied.container)
|
|
||||||
self.assertIsNot(container.container.parent, copied.container.parent)
|
|
||||||
|
|
||||||
def test_resolve_provider_name(self):
|
|
||||||
container = ContainerA()
|
|
||||||
self.assertEqual(container.resolve_provider_name(container.p11), "p11")
|
|
||||||
|
|
||||||
def test_resolve_provider_name_no_provider(self):
|
|
||||||
container = ContainerA()
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
container.resolve_provider_name(providers.Provider())
|
|
||||||
|
|
||||||
|
|
||||||
class SelfTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_self(self):
|
|
||||||
def call_bar(container):
|
|
||||||
return container.bar()
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
foo = providers.Callable(call_bar, __self__)
|
|
||||||
bar = providers.Object("hello")
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.foo(), "hello")
|
|
||||||
|
|
||||||
def test_self_attribute_implicit(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
pass
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.__self__(), container)
|
|
||||||
|
|
||||||
def test_self_attribute_explicit(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.__self__(), container)
|
|
||||||
|
|
||||||
def test_single_self(self):
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
self1 = providers.Self()
|
|
||||||
self2 = providers.Self()
|
|
||||||
|
|
||||||
def test_self_attribute_alt_name_implicit(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
foo = providers.Self()
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.__self__, container.foo)
|
|
||||||
self.assertEqual(set(container.__self__.alt_names), {"foo"})
|
|
||||||
|
|
||||||
def test_self_attribute_alt_name_explicit_1(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
foo = __self__
|
|
||||||
bar = __self__
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.__self__, container.foo)
|
|
||||||
self.assertIs(container.__self__, container.bar)
|
|
||||||
self.assertEqual(set(container.__self__.alt_names), {"foo", "bar"})
|
|
||||||
|
|
||||||
def test_self_attribute_alt_name_explicit_2(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
foo = providers.Self()
|
|
||||||
bar = foo
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.__self__, container.foo)
|
|
||||||
self.assertIs(container.__self__, container.bar)
|
|
||||||
self.assertEqual(set(container.__self__.alt_names), {"foo", "bar"})
|
|
||||||
|
|
||||||
def test_providers_attribute_1(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
foo = __self__
|
|
||||||
bar = __self__
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertEqual(container.providers, {})
|
|
||||||
self.assertEqual(Container.providers, {})
|
|
||||||
|
|
||||||
def test_providers_attribute_2(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
foo = providers.Self()
|
|
||||||
bar = foo
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertEqual(container.providers, {})
|
|
||||||
self.assertEqual(Container.providers, {})
|
|
||||||
|
|
||||||
def test_container_multiple_instances(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
|
|
||||||
container1 = Container()
|
|
||||||
container2 = Container()
|
|
||||||
|
|
||||||
self.assertIsNot(container1, container2)
|
|
||||||
self.assertIs(container1.__self__(), container1)
|
|
||||||
self.assertIs(container2.__self__(), container2)
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
def call_bar(container):
|
|
||||||
return container.bar()
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
foo = providers.Callable(call_bar, __self__)
|
|
||||||
bar = providers.Object("hello")
|
|
||||||
|
|
||||||
container1 = Container()
|
|
||||||
container2 = providers.deepcopy(container1)
|
|
||||||
container1.bar.override("bye")
|
|
||||||
|
|
||||||
self.assertIs(container1.foo(), "bye")
|
|
||||||
self.assertIs(container2.foo(), "hello")
|
|
||||||
|
|
||||||
def test_deepcopy_alt_names_1(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
foo = __self__
|
|
||||||
bar = foo
|
|
||||||
|
|
||||||
container1 = Container()
|
|
||||||
container2 = providers.deepcopy(container1)
|
|
||||||
|
|
||||||
self.assertIs(container2.__self__(), container2)
|
|
||||||
self.assertIs(container2.foo(), container2)
|
|
||||||
self.assertIs(container2.bar(), container2)
|
|
||||||
|
|
||||||
def test_deepcopy_alt_names_2(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
self = providers.Self()
|
|
||||||
|
|
||||||
container1 = Container()
|
|
||||||
container2 = providers.deepcopy(container1)
|
|
||||||
|
|
||||||
self.assertIs(container2.__self__(), container2)
|
|
||||||
self.assertIs(container2.self(), container2)
|
|
||||||
|
|
||||||
def test_deepcopy_no_self_dependencies(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
|
|
||||||
container1 = Container()
|
|
||||||
container2 = providers.deepcopy(container1)
|
|
||||||
|
|
||||||
self.assertIsNot(container1, container2)
|
|
||||||
self.assertIsNot(container1.__self__, container2.__self__)
|
|
||||||
self.assertIs(container1.__self__(), container1)
|
|
||||||
self.assertIs(container2.__self__(), container2)
|
|
||||||
|
|
||||||
def test_with_container_provider(self):
|
|
||||||
def call_bar(container):
|
|
||||||
return container.bar()
|
|
||||||
|
|
||||||
class SubContainer(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
foo = providers.Callable(call_bar, __self__)
|
|
||||||
bar = providers.Object("hello")
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
sub_container = providers.Container(SubContainer)
|
|
||||||
|
|
||||||
baz = providers.Callable(lambda value: value, sub_container.foo)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.baz(), "hello")
|
|
||||||
|
|
||||||
def test_with_container_provider_overriding(self):
|
|
||||||
def call_bar(container):
|
|
||||||
return container.bar()
|
|
||||||
|
|
||||||
class SubContainer(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
foo = providers.Callable(call_bar, __self__)
|
|
||||||
bar = providers.Object("hello")
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
sub_container = providers.Container(SubContainer, bar="bye")
|
|
||||||
|
|
||||||
baz = providers.Callable(lambda value: value, sub_container.foo)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.baz(), "bye")
|
|
||||||
|
|
||||||
def test_with_container_provider_self(self):
|
|
||||||
class SubContainer(containers.DeclarativeContainer):
|
|
||||||
__self__ = providers.Self()
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
sub_container = providers.Container(SubContainer)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.__self__(), container)
|
|
||||||
self.assertIs(container.sub_container().__self__(), container.sub_container())
|
|
||||||
|
|
||||||
|
|
||||||
class DynamicContainerWithCustomStringTests(unittest.TestCase):
|
|
||||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/479
|
|
||||||
|
|
||||||
class CustomString(str):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class CustomClass:
|
|
||||||
thing = None
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.container = containers.DynamicContainer()
|
|
||||||
self.provider = providers.Provider()
|
|
||||||
|
|
||||||
def test_setattr(self):
|
|
||||||
setattr(self.container, self.CustomString("test_attr"), self.provider)
|
|
||||||
self.assertIs(self.container.test_attr, self.provider)
|
|
||||||
|
|
||||||
def test_delattr(self):
|
|
||||||
setattr(self.container, self.CustomString("test_attr"), self.provider)
|
|
||||||
delattr(self.container, self.CustomString("test_attr"))
|
|
||||||
with self.assertRaises(AttributeError):
|
|
||||||
self.container.test_attr
|
|
||||||
|
|
||||||
def test_set_provider(self):
|
|
||||||
self.container.set_provider(self.CustomString("test_attr"), self.provider)
|
|
||||||
self.assertIs(self.container.test_attr, self.provider)
|
|
||||||
|
|
||||||
def test_set_providers(self):
|
|
||||||
self.container.set_providers(**{self.CustomString("test_attr"): self.provider})
|
|
||||||
self.assertIs(self.container.test_attr, self.provider)
|
|
|
@ -1,93 +1,53 @@
|
||||||
import unittest
|
"""Container traversing tests."""
|
||||||
|
|
||||||
from dependency_injector import containers, providers
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
|
||||||
class TraverseProviderTests(unittest.TestCase):
|
class Container(containers.DeclarativeContainer):
|
||||||
|
obj_factory = providers.DelegatedFactory(
|
||||||
def test_nested_providers(self):
|
dict,
|
||||||
class Container(containers.DeclarativeContainer):
|
foo=providers.Resource(
|
||||||
obj_factory = providers.DelegatedFactory(
|
dict,
|
||||||
dict,
|
foo="bar"
|
||||||
foo=providers.Resource(
|
),
|
||||||
dict,
|
bar=providers.Resource(
|
||||||
foo="bar"
|
dict,
|
||||||
),
|
foo="bar"
|
||||||
bar=providers.Resource(
|
)
|
||||||
dict,
|
)
|
||||||
foo="bar"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
all_providers = list(container.traverse())
|
|
||||||
|
|
||||||
self.assertIn(container.obj_factory, all_providers)
|
|
||||||
self.assertIn(container.obj_factory.kwargs["foo"], all_providers)
|
|
||||||
self.assertIn(container.obj_factory.kwargs["bar"], all_providers)
|
|
||||||
self.assertEqual(len(all_providers), 3)
|
|
||||||
|
|
||||||
def test_nested_providers_with_filtering(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
obj_factory = providers.DelegatedFactory(
|
|
||||||
dict,
|
|
||||||
foo=providers.Resource(
|
|
||||||
dict,
|
|
||||||
foo="bar"
|
|
||||||
),
|
|
||||||
bar=providers.Resource(
|
|
||||||
dict,
|
|
||||||
foo="bar"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
all_providers = list(container.traverse(types=[providers.Resource]))
|
|
||||||
|
|
||||||
self.assertIn(container.obj_factory.kwargs["foo"], all_providers)
|
|
||||||
self.assertIn(container.obj_factory.kwargs["bar"], all_providers)
|
|
||||||
self.assertEqual(len(all_providers), 2)
|
|
||||||
|
|
||||||
|
|
||||||
class TraverseProviderDeclarativeTests(unittest.TestCase):
|
def test_nested_providers():
|
||||||
|
container = Container()
|
||||||
|
all_providers = list(container.traverse())
|
||||||
|
|
||||||
def test_nested_providers(self):
|
assert container.obj_factory in all_providers
|
||||||
class Container(containers.DeclarativeContainer):
|
assert container.obj_factory.kwargs["foo"] in all_providers
|
||||||
obj_factory = providers.DelegatedFactory(
|
assert container.obj_factory.kwargs["bar"] in all_providers
|
||||||
dict,
|
assert len(all_providers) == 3
|
||||||
foo=providers.Resource(
|
|
||||||
dict,
|
|
||||||
foo="bar"
|
|
||||||
),
|
|
||||||
bar=providers.Resource(
|
|
||||||
dict,
|
|
||||||
foo="bar"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
all_providers = list(Container.traverse())
|
|
||||||
|
|
||||||
self.assertIn(Container.obj_factory, all_providers)
|
def test_nested_providers_with_filtering():
|
||||||
self.assertIn(Container.obj_factory.kwargs["foo"], all_providers)
|
container = Container()
|
||||||
self.assertIn(Container.obj_factory.kwargs["bar"], all_providers)
|
all_providers = list(container.traverse(types=[providers.Resource]))
|
||||||
self.assertEqual(len(all_providers), 3)
|
|
||||||
|
|
||||||
def test_nested_providers_with_filtering(self):
|
assert container.obj_factory.kwargs["foo"] in all_providers
|
||||||
class Container(containers.DeclarativeContainer):
|
assert container.obj_factory.kwargs["bar"] in all_providers
|
||||||
obj_factory = providers.DelegatedFactory(
|
assert len(all_providers) == 2
|
||||||
dict,
|
|
||||||
foo=providers.Resource(
|
|
||||||
dict,
|
|
||||||
foo="bar"
|
|
||||||
),
|
|
||||||
bar=providers.Resource(
|
|
||||||
dict,
|
|
||||||
foo="bar"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
all_providers = list(Container.traverse(types=[providers.Resource]))
|
|
||||||
|
|
||||||
self.assertIn(Container.obj_factory.kwargs["foo"], all_providers)
|
def test_container_cls_nested_providers():
|
||||||
self.assertIn(Container.obj_factory.kwargs["bar"], all_providers)
|
all_providers = list(Container.traverse())
|
||||||
self.assertEqual(len(all_providers), 2)
|
|
||||||
|
assert Container.obj_factory in all_providers
|
||||||
|
assert Container.obj_factory.kwargs["foo"] in all_providers
|
||||||
|
assert Container.obj_factory.kwargs["bar"] in all_providers
|
||||||
|
assert len(all_providers) == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_container_cls_nested_providers_with_filtering():
|
||||||
|
all_providers = list(Container.traverse(types=[providers.Resource]))
|
||||||
|
|
||||||
|
assert Container.obj_factory.kwargs["foo"] in all_providers
|
||||||
|
assert Container.obj_factory.kwargs["bar"] in all_providers
|
||||||
|
assert len(all_providers) == 2
|
||||||
|
|
|
@ -1,18 +1,13 @@
|
||||||
import unittest
|
"""Container typing in runtime tests."""
|
||||||
|
|
||||||
from dependency_injector import containers
|
from dependency_injector import containers
|
||||||
|
|
||||||
|
|
||||||
class SomeClass:
|
def test_types_declarative():
|
||||||
...
|
container: containers.Container = containers.DeclarativeContainer()
|
||||||
|
assert isinstance(container, containers.Container)
|
||||||
|
|
||||||
|
|
||||||
class TypesTest(unittest.TestCase):
|
def test_types_dynamic():
|
||||||
|
container: containers.Container = containers.DynamicContainer()
|
||||||
def test_declarative(self):
|
assert isinstance(container, containers.Container)
|
||||||
container: containers.Container = containers.DeclarativeContainer()
|
|
||||||
self.assertIsInstance(container, containers.Container)
|
|
||||||
|
|
||||||
def test_dynamic(self):
|
|
||||||
container: containers.Container = containers.DynamicContainer()
|
|
||||||
self.assertIsInstance(container, containers.Container)
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
"""Dependency injector extension unit tests."""
|
"""Extension tests."""
|
||||||
|
|
|
@ -1,21 +1,20 @@
|
||||||
"""Dependency injector Aiohttp extension unit tests."""
|
"""Aiohttp extension tests."""
|
||||||
|
|
||||||
from aiohttp import web
|
|
||||||
from aiohttp.test_utils import AioHTTPTestCase, unittest_run_loop
|
|
||||||
|
|
||||||
|
from aiohttp import web, test_utils
|
||||||
from dependency_injector import containers, providers
|
from dependency_injector import containers, providers
|
||||||
from dependency_injector.ext import aiohttp
|
from dependency_injector.ext import aiohttp
|
||||||
|
from pytest import fixture, mark
|
||||||
|
|
||||||
|
|
||||||
async def index(_):
|
async def index_view(_):
|
||||||
return web.Response(text="Hello World!")
|
return web.Response(text="Hello World!")
|
||||||
|
|
||||||
|
|
||||||
async def test(_):
|
async def second_view(_):
|
||||||
return web.Response(text="Test!")
|
return web.Response(text="Test!")
|
||||||
|
|
||||||
|
|
||||||
class Test(web.View):
|
class OtherClassBasedView(web.View):
|
||||||
async def get(self):
|
async def get(self):
|
||||||
return web.Response(text="Test class-based!")
|
return web.Response(text="Test class-based!")
|
||||||
|
|
||||||
|
@ -46,48 +45,56 @@ class ApplicationContainer(containers.DeclarativeContainer):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
index_view = aiohttp.View(index)
|
index_view = aiohttp.View(index_view)
|
||||||
test_view = aiohttp.View(test)
|
second_view = aiohttp.View(second_view)
|
||||||
test_class_view = aiohttp.ClassBasedView(Test)
|
other_class_based_view = aiohttp.ClassBasedView(OtherClassBasedView)
|
||||||
|
|
||||||
|
|
||||||
class ApplicationTests(AioHTTPTestCase):
|
@fixture
|
||||||
|
def app():
|
||||||
|
container = ApplicationContainer()
|
||||||
|
app = container.app()
|
||||||
|
app.container = container
|
||||||
|
app.add_routes([
|
||||||
|
web.get("/", container.index_view.as_view()),
|
||||||
|
web.get("/second", container.second_view.as_view(), name="second"),
|
||||||
|
web.get("/class-based", container.other_class_based_view.as_view()),
|
||||||
|
])
|
||||||
|
return app
|
||||||
|
|
||||||
async def get_application(self):
|
|
||||||
"""
|
|
||||||
Override the get_app method to return your application.
|
|
||||||
"""
|
|
||||||
container = ApplicationContainer()
|
|
||||||
app = container.app()
|
|
||||||
app.container = container
|
|
||||||
app.add_routes([
|
|
||||||
web.get("/", container.index_view.as_view()),
|
|
||||||
web.get("/test", container.test_view.as_view(), name="test"),
|
|
||||||
web.get("/test-class", container.test_class_view.as_view()),
|
|
||||||
])
|
|
||||||
return app
|
|
||||||
|
|
||||||
@unittest_run_loop
|
@fixture
|
||||||
async def test_index(self):
|
async def client(app):
|
||||||
response = await self.client.get("/")
|
async with test_utils.TestClient(test_utils.TestServer(app)) as client:
|
||||||
|
yield client
|
||||||
|
|
||||||
self.assertEqual(response.status, 200)
|
|
||||||
self.assertEqual(await response.text(), "Hello World! wink2 wink1")
|
|
||||||
|
|
||||||
@unittest_run_loop
|
@mark.asyncio
|
||||||
async def test_test(self):
|
@mark.filterwarnings("ignore:The loop argument is deprecated:DeprecationWarning")
|
||||||
response = await self.client.get("/test")
|
async def test_index(client):
|
||||||
|
response = await client.get("/")
|
||||||
|
|
||||||
self.assertEqual(response.status, 200)
|
assert response.status == 200
|
||||||
self.assertEqual(await response.text(), "Test! wink2 wink1")
|
assert await response.text() == "Hello World! wink2 wink1"
|
||||||
|
|
||||||
@unittest_run_loop
|
|
||||||
async def test_test_class_based(self):
|
|
||||||
response = await self.client.get("/test-class")
|
|
||||||
|
|
||||||
self.assertEqual(response.status, 200)
|
@mark.asyncio
|
||||||
self.assertEqual(await response.text(), "Test class-based! wink2 wink1")
|
@mark.filterwarnings("ignore:The loop argument is deprecated:DeprecationWarning")
|
||||||
|
async def test_second(client):
|
||||||
|
response = await client.get("/second")
|
||||||
|
|
||||||
@unittest_run_loop
|
assert response.status == 200
|
||||||
async def test_endpoints(self):
|
assert await response.text() == "Test! wink2 wink1"
|
||||||
self.assertEqual(str(self.app.router["test"].url_for()), "/test")
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
@mark.filterwarnings("ignore:The loop argument is deprecated:DeprecationWarning")
|
||||||
|
async def test_class_based(client):
|
||||||
|
response = await client.get("/class-based")
|
||||||
|
|
||||||
|
assert response.status == 200
|
||||||
|
assert await response.text() == "Test class-based! wink2 wink1"
|
||||||
|
|
||||||
|
|
||||||
|
def test_endpoints(app):
|
||||||
|
assert str(app.router["second"].url_for()) == "/second"
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
"""Dependency injector Flask extension unit tests."""
|
"""Flask extension tests."""
|
||||||
|
|
||||||
import unittest
|
|
||||||
from flask import Flask, url_for
|
|
||||||
from flask.views import MethodView
|
|
||||||
|
|
||||||
from dependency_injector import containers
|
from dependency_injector import containers
|
||||||
from dependency_injector.ext import flask
|
from dependency_injector.ext import flask
|
||||||
|
from flask import Flask, url_for
|
||||||
|
from flask.views import MethodView
|
||||||
|
from pytest import fixture
|
||||||
|
|
||||||
|
|
||||||
def index():
|
def index():
|
||||||
|
@ -30,47 +29,47 @@ class ApplicationContainer(containers.DeclarativeContainer):
|
||||||
test_class_view = flask.ClassBasedView(Test)
|
test_class_view = flask.ClassBasedView(Test)
|
||||||
|
|
||||||
|
|
||||||
def create_app():
|
@fixture
|
||||||
|
def app():
|
||||||
container = ApplicationContainer()
|
container = ApplicationContainer()
|
||||||
app = container.app()
|
app = container.app()
|
||||||
app.container = container
|
app.container = container
|
||||||
|
app.config["SERVER_NAME"] = "test-server.com"
|
||||||
app.add_url_rule("/", view_func=container.index_view.as_view())
|
app.add_url_rule("/", view_func=container.index_view.as_view())
|
||||||
app.add_url_rule("/test", "test-test", view_func=container.test_view.as_view())
|
app.add_url_rule("/test", "test-test", view_func=container.test_view.as_view())
|
||||||
app.add_url_rule("/test-class", view_func=container.test_class_view.as_view("test-class"))
|
app.add_url_rule("/test-class", view_func=container.test_class_view.as_view("test-class"))
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
class ApplicationTests(unittest.TestCase):
|
@fixture
|
||||||
|
def client(app):
|
||||||
|
with app.test_client() as client:
|
||||||
|
yield client
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.app = create_app()
|
|
||||||
self.app.config["SERVER_NAME"] = "test-server.com"
|
|
||||||
self.client = self.app.test_client()
|
|
||||||
self.client.__enter__()
|
|
||||||
|
|
||||||
def tearDown(self):
|
def test_index(client):
|
||||||
self.client.__exit__(None, None, None)
|
response = client.get("/")
|
||||||
|
|
||||||
def test_index(self):
|
assert response.status_code == 200
|
||||||
response = self.client.get("/")
|
assert response.data == b"Hello World!"
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
|
||||||
self.assertEqual(response.data, b"Hello World!")
|
|
||||||
|
|
||||||
def test_test(self):
|
def test_test(client):
|
||||||
response = self.client.get("/test")
|
response = client.get("/test")
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
assert response.status_code == 200
|
||||||
self.assertEqual(response.data, b"Test!")
|
assert response.data == b"Test!"
|
||||||
|
|
||||||
def test_test_class_based(self):
|
|
||||||
response = self.client.get("/test-class")
|
|
||||||
|
|
||||||
self.assertEqual(response.status_code, 200)
|
def test_test_class_based(client):
|
||||||
self.assertEqual(response.data, b"Test class-based!")
|
response = client.get("/test-class")
|
||||||
|
|
||||||
def test_endpoints(self):
|
assert response.status_code == 200
|
||||||
with self.app.app_context():
|
assert response.data == b"Test class-based!"
|
||||||
self.assertEqual(url_for("index"), "http://test-server.com/")
|
|
||||||
self.assertEqual(url_for("test-test"), "http://test-server.com/test")
|
|
||||||
self.assertEqual(url_for("test-class"), "http://test-server.com/test-class")
|
def test_endpoints(app):
|
||||||
|
with app.app_context():
|
||||||
|
assert url_for("index") == "http://test-server.com/"
|
||||||
|
assert url_for("test-test") == "http://test-server.com/test"
|
||||||
|
assert url_for("test-class") == "http://test-server.com/test-class"
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
"""Dependency injector providers unit tests."""
|
"""Providers tests."""
|
||||||
|
|
1
tests/unit/providers/async/__init__.py
Normal file
1
tests/unit/providers/async/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Provider asynchronous mode tests."""
|
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
|
423
tests/unit/providers/async/test_factory_py36.py
Normal file
423
tests/unit/providers/async/test_factory_py36.py
Normal file
|
@ -0,0 +1,423 @@
|
||||||
|
"""Factory provider async mode tests."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
from pytest import mark, raises
|
||||||
|
|
||||||
|
from .common import RESOURCE1, RESOURCE2, Client, Service, BaseContainer, Container, init_resource
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_args_injection():
|
||||||
|
class ContainerWithArgs(BaseContainer):
|
||||||
|
client = providers.Factory(
|
||||||
|
Client,
|
||||||
|
BaseContainer.resource1,
|
||||||
|
BaseContainer.resource2,
|
||||||
|
)
|
||||||
|
|
||||||
|
service = providers.Factory(
|
||||||
|
Service,
|
||||||
|
client,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = ContainerWithArgs()
|
||||||
|
|
||||||
|
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.client is not service2.client
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_kwargs_injection():
|
||||||
|
class ContainerWithKwArgs(Container):
|
||||||
|
...
|
||||||
|
|
||||||
|
container = ContainerWithKwArgs()
|
||||||
|
|
||||||
|
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.client is not service2.client
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_context_kwargs_injection():
|
||||||
|
resource2_extra = object()
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
client1 = await container.client(resource2=resource2_extra)
|
||||||
|
client2 = await container.client(resource2=resource2_extra)
|
||||||
|
|
||||||
|
assert isinstance(client1, Client)
|
||||||
|
assert client1.resource1 is RESOURCE1
|
||||||
|
assert client1.resource2 is resource2_extra
|
||||||
|
|
||||||
|
assert isinstance(client2, Client)
|
||||||
|
assert client2.resource1 is RESOURCE1
|
||||||
|
assert client2.resource2 is resource2_extra
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_args_kwargs_injection():
|
||||||
|
class ContainerWithArgsAndKwArgs(BaseContainer):
|
||||||
|
client = providers.Factory(
|
||||||
|
Client,
|
||||||
|
BaseContainer.resource1,
|
||||||
|
resource2=BaseContainer.resource2,
|
||||||
|
)
|
||||||
|
|
||||||
|
service = providers.Factory(
|
||||||
|
Service,
|
||||||
|
client=client,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = ContainerWithArgsAndKwArgs()
|
||||||
|
|
||||||
|
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.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():
|
||||||
|
raise Exception("Something went wrong")
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource_with_error = providers.Resource(init_resource)
|
||||||
|
|
||||||
|
client = providers.Factory(
|
||||||
|
Client,
|
||||||
|
resource1=resource_with_error,
|
||||||
|
resource2=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(Exception, match="Something went wrong"):
|
||||||
|
await container.client()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_injection_runtime_error_async_provides():
|
||||||
|
async def create_client(*args, **kwargs):
|
||||||
|
raise Exception("Something went wrong")
|
||||||
|
|
||||||
|
class Container(BaseContainer):
|
||||||
|
client = providers.Factory(
|
||||||
|
create_client,
|
||||||
|
resource1=BaseContainer.resource1,
|
||||||
|
resource2=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(Exception, match="Something went wrong"):
|
||||||
|
await container.client()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_injection_call_error_async_provides():
|
||||||
|
async def create_client(): # <-- no args defined
|
||||||
|
...
|
||||||
|
|
||||||
|
class Container(BaseContainer):
|
||||||
|
client = providers.Factory(
|
||||||
|
create_client,
|
||||||
|
resource1=BaseContainer.resource1,
|
||||||
|
resource2=None,
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(TypeError) as exception_info:
|
||||||
|
await container.client()
|
||||||
|
assert "create_client() got" in str(exception_info.value)
|
||||||
|
assert "unexpected keyword argument" in str(exception_info.value)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_attributes_injection():
|
||||||
|
class ContainerWithAttributes(BaseContainer):
|
||||||
|
client = providers.Factory(
|
||||||
|
Client,
|
||||||
|
BaseContainer.resource1,
|
||||||
|
resource2=None,
|
||||||
|
)
|
||||||
|
client.add_attributes(resource2=BaseContainer.resource2)
|
||||||
|
|
||||||
|
service = providers.Factory(
|
||||||
|
Service,
|
||||||
|
client=None,
|
||||||
|
)
|
||||||
|
service.add_attributes(client=client)
|
||||||
|
|
||||||
|
container = ContainerWithAttributes()
|
||||||
|
|
||||||
|
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.client is not service2.client
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_attributes_injection_attribute_error():
|
||||||
|
class ClientWithException(Client):
|
||||||
|
@property
|
||||||
|
def attribute_set_error(self):
|
||||||
|
return None
|
||||||
|
|
||||||
|
@attribute_set_error.setter
|
||||||
|
def attribute_set_error(self, value):
|
||||||
|
raise Exception("Something went wrong")
|
||||||
|
|
||||||
|
class Container(BaseContainer):
|
||||||
|
client = providers.Factory(
|
||||||
|
ClientWithException,
|
||||||
|
resource1=BaseContainer.resource1,
|
||||||
|
resource2=BaseContainer.resource2,
|
||||||
|
)
|
||||||
|
client.add_attributes(attribute_set_error=123)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(Exception, match="Something went wrong"):
|
||||||
|
await container.client()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_attributes_injection_runtime_error():
|
||||||
|
async def init_resource():
|
||||||
|
raise Exception("Something went wrong")
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource = providers.Resource(init_resource)
|
||||||
|
|
||||||
|
client = providers.Factory(
|
||||||
|
Client,
|
||||||
|
resource1=None,
|
||||||
|
resource2=None,
|
||||||
|
)
|
||||||
|
client.add_attributes(resource1=resource)
|
||||||
|
client.add_attributes(resource2=resource)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(Exception, match="Something went wrong"):
|
||||||
|
await container.client()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_async_instance_and_sync_attributes_injection():
|
||||||
|
class ContainerWithAttributes(BaseContainer):
|
||||||
|
resource1 = providers.Resource(init_resource, providers.Object(RESOURCE1))
|
||||||
|
|
||||||
|
client = providers.Factory(
|
||||||
|
Client,
|
||||||
|
BaseContainer.resource1,
|
||||||
|
resource2=None,
|
||||||
|
)
|
||||||
|
client.add_attributes(resource2=providers.Object(RESOURCE2))
|
||||||
|
|
||||||
|
service = providers.Factory(
|
||||||
|
Service,
|
||||||
|
client=None,
|
||||||
|
)
|
||||||
|
service.add_attributes(client=client)
|
||||||
|
|
||||||
|
container = ContainerWithAttributes()
|
||||||
|
|
||||||
|
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.client is not service2.client
|
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
tests/unit/providers/callables/__init__.py
Normal file
1
tests/unit/providers/callables/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Tests for callables."""
|
5
tests/unit/providers/callables/common.py
Normal file
5
tests/unit/providers/callables/common.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
"""Common test artifacts."""
|
||||||
|
|
||||||
|
|
||||||
|
def example(arg1, arg2, arg3, arg4):
|
||||||
|
return arg1, arg2, arg3, arg4
|
|
@ -0,0 +1,56 @@
|
||||||
|
"""AbstractCallable provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance():
|
||||||
|
assert isinstance(providers.AbstractCallable(example), providers.Callable)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden_by_callable():
|
||||||
|
def _abstract_example():
|
||||||
|
pass
|
||||||
|
|
||||||
|
provider = providers.AbstractCallable(_abstract_example)
|
||||||
|
provider.override(providers.Callable(example))
|
||||||
|
|
||||||
|
assert provider(1, 2, 3, 4) == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden_by_delegated_callable():
|
||||||
|
def _abstract_example():
|
||||||
|
pass
|
||||||
|
|
||||||
|
provider = providers.AbstractCallable(_abstract_example)
|
||||||
|
provider.override(providers.DelegatedCallable(example))
|
||||||
|
|
||||||
|
assert provider(1, 2, 3, 4) == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_not_overridden():
|
||||||
|
provider = providers.AbstractCallable(example)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider(1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_by_not_callable():
|
||||||
|
provider = providers.AbstractCallable(example)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider.override(providers.Factory(object))
|
||||||
|
|
||||||
|
|
||||||
|
def test_provide_not_implemented():
|
||||||
|
provider = providers.AbstractCallable(example)
|
||||||
|
with raises(NotImplementedError):
|
||||||
|
provider._provide((1, 2, 3, 4), dict())
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.AbstractCallable(example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"AbstractCallable({0}) at {1}>".format(repr(example), hex(id(provider)))
|
||||||
|
)
|
|
@ -0,0 +1,17 @@
|
||||||
|
"""CallableDelegate provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegate():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
delegate = providers.CallableDelegate(provider)
|
||||||
|
assert isinstance(delegate, providers.Delegate)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_callable():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.CallableDelegate(providers.Object(object()))
|
210
tests/unit/providers/callables/test_callable_py2_py3.py
Normal file
210
tests/unit/providers/callables/test_callable_py2_py3.py
Normal file
|
@ -0,0 +1,210 @@
|
||||||
|
"""Callable provider tests."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider():
|
||||||
|
assert providers.is_provider(providers.Callable(example)) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_callable():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.Callable(123)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_optional_provides():
|
||||||
|
provider = providers.Callable()
|
||||||
|
provider.set_provides(object)
|
||||||
|
assert provider.provides is object
|
||||||
|
assert isinstance(provider(), object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_provides_returns_():
|
||||||
|
provider = providers.Callable()
|
||||||
|
assert provider.set_provides(object) is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_provided_instance_provider():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
assert isinstance(provider.provided, providers.ProvidedInstance)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call():
|
||||||
|
provider = providers.Callable(lambda: True)
|
||||||
|
assert provider() is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_positional_args():
|
||||||
|
provider = providers.Callable(example, 1, 2, 3, 4)
|
||||||
|
assert provider() == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_keyword_args():
|
||||||
|
provider = providers.Callable(example, arg1=1, arg2=2, arg3=3, arg4=4)
|
||||||
|
assert provider() == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_positional_and_keyword_args():
|
||||||
|
provider = providers.Callable(example, 1, 2, arg3=3, arg4=4)
|
||||||
|
assert provider() == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_args():
|
||||||
|
provider = providers.Callable(example, 1, 2)
|
||||||
|
assert provider(3, 4) == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_kwargs():
|
||||||
|
provider = providers.Callable(example, arg1=1)
|
||||||
|
assert provider(arg2=2, arg3=3, arg4=4) == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_args_and_kwargs():
|
||||||
|
provider = providers.Callable(example, 1)
|
||||||
|
assert provider(2, arg3=3, arg4=4) == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_fluent_interface():
|
||||||
|
provider = providers.Singleton(example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.add_kwargs(arg3=3, arg4=4)
|
||||||
|
assert provider() == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_args():
|
||||||
|
provider = providers.Callable(example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.set_args(3, 4)
|
||||||
|
assert provider.args == (3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_kwargs():
|
||||||
|
provider = providers.Callable(example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.set_kwargs(init_arg3=4, init_arg4=5)
|
||||||
|
assert provider.kwargs == dict(init_arg3=4, init_arg4=5)
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_args():
|
||||||
|
provider = providers.Callable(example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.clear_args()
|
||||||
|
assert provider.args == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_kwargs():
|
||||||
|
provider = providers.Callable(example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.clear_kwargs()
|
||||||
|
assert provider.kwargs == dict()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
|
||||||
|
provider.override(providers.Object((4, 3, 2, 1)))
|
||||||
|
provider.override(providers.Object((1, 2, 3, 4)))
|
||||||
|
|
||||||
|
assert provider() == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.provides is provider_copy.provides
|
||||||
|
assert isinstance(provider, providers.Callable)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
provider_copy_memo = providers.Callable(example)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider, memo={id(provider): provider_copy_memo})
|
||||||
|
|
||||||
|
assert provider_copy is provider_copy_memo
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_args():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
dependent_provider1 = providers.Callable(list)
|
||||||
|
dependent_provider2 = providers.Callable(dict)
|
||||||
|
|
||||||
|
provider.add_args(dependent_provider1, dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.args[0]
|
||||||
|
dependent_provider_copy2 = provider_copy.args[1]
|
||||||
|
|
||||||
|
assert provider.args != provider_copy.args
|
||||||
|
|
||||||
|
assert dependent_provider1.provides is dependent_provider_copy1.provides
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.provides is dependent_provider_copy2.provides
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_kwargs():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
dependent_provider1 = providers.Callable(list)
|
||||||
|
dependent_provider2 = providers.Callable(dict)
|
||||||
|
|
||||||
|
provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.kwargs["a1"]
|
||||||
|
dependent_provider_copy2 = provider_copy.kwargs["a2"]
|
||||||
|
|
||||||
|
assert provider.kwargs != provider_copy.kwargs
|
||||||
|
|
||||||
|
assert dependent_provider1.provides is dependent_provider_copy1.provides
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.provides is dependent_provider_copy2.provides
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_overridden():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
object_provider = providers.Object(object())
|
||||||
|
|
||||||
|
provider.override(object_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
object_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.provides is provider_copy.provides
|
||||||
|
assert isinstance(provider, providers.Callable)
|
||||||
|
|
||||||
|
assert object_provider is not object_provider_copy
|
||||||
|
assert isinstance(object_provider_copy, providers.Object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_with_sys_streams():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
provider.add_args(sys.stdin)
|
||||||
|
provider.add_kwargs(a2=sys.stdout)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert isinstance(provider_copy, providers.Callable)
|
||||||
|
assert provider.args[0] is sys.stdin
|
||||||
|
assert provider.kwargs["a2"] is sys.stdout
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.Callable(example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"Callable({0}) at {1}>".format(repr(example), hex(id(provider)))
|
||||||
|
)
|
|
@ -0,0 +1,26 @@
|
||||||
|
"""DelegatedCallable provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance():
|
||||||
|
assert isinstance(providers.DelegatedCallable(example), providers.Callable)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider():
|
||||||
|
assert providers.is_provider(providers.DelegatedCallable(example)) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegated_provider():
|
||||||
|
provider = providers.DelegatedCallable(example)
|
||||||
|
assert providers.is_delegated(provider) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.DelegatedCallable(example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"DelegatedCallable({0}) at {1}>".format(repr(example), hex(id(provider)))
|
||||||
|
)
|
1
tests/unit/providers/configuration/__init__.py
Normal file
1
tests/unit/providers/configuration/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Configuration provider tests."""
|
19
tests/unit/providers/configuration/conftest.py
Normal file
19
tests/unit/providers/configuration/conftest.py
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
"""Fixtures module."""
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
from pytest import fixture
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config_type():
|
||||||
|
return "default"
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config(config_type):
|
||||||
|
if config_type == "strict":
|
||||||
|
return providers.Configuration(strict=True)
|
||||||
|
elif config_type == "default":
|
||||||
|
return providers.Configuration()
|
||||||
|
else:
|
||||||
|
raise ValueError("Undefined config type \"{0}\"".format(config_type))
|
|
@ -0,0 +1,130 @@
|
||||||
|
"""Tests for configuration provider linking."""
|
||||||
|
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers
|
||||||
|
|
||||||
|
|
||||||
|
class Core(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration("core")
|
||||||
|
value_getter = providers.Callable(lambda _: _, config.value)
|
||||||
|
|
||||||
|
|
||||||
|
class Services(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration("services")
|
||||||
|
value_getter = providers.Callable(lambda _: _, config.value)
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
root_config = providers.Configuration("main")
|
||||||
|
core = Core(config=root_config.core)
|
||||||
|
services = Services(config=root_config.services)
|
||||||
|
|
||||||
|
root_config.override(
|
||||||
|
{
|
||||||
|
"core": {
|
||||||
|
"value": "core",
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"value": "services",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert core.config() == {"value": "core"}
|
||||||
|
assert core.config.value() == "core"
|
||||||
|
assert core.value_getter() == "core"
|
||||||
|
|
||||||
|
assert services.config() == {"value": "services"}
|
||||||
|
assert services.config.value() == "services"
|
||||||
|
assert services.value_getter() == "services"
|
||||||
|
|
||||||
|
|
||||||
|
def test_double_override():
|
||||||
|
root_config = providers.Configuration("main")
|
||||||
|
core = Core(config=root_config.core)
|
||||||
|
services = Services(config=root_config.services)
|
||||||
|
|
||||||
|
root_config.override(
|
||||||
|
{
|
||||||
|
"core": {
|
||||||
|
"value": "core1",
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"value": "services1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
root_config.override(
|
||||||
|
{
|
||||||
|
"core": {
|
||||||
|
"value": "core2",
|
||||||
|
},
|
||||||
|
"services": {
|
||||||
|
"value": "services2",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert core.config() == {"value": "core2"}
|
||||||
|
assert core.config.value() == "core2"
|
||||||
|
assert core.value_getter() == "core2"
|
||||||
|
|
||||||
|
assert services.config() == {"value": "services2"}
|
||||||
|
assert services.config.value() == "services2"
|
||||||
|
assert services.value_getter() == "services2"
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_overriding_cache():
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/428
|
||||||
|
class Core(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
greetings = providers.Factory(str, config.greeting)
|
||||||
|
|
||||||
|
class Application(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
core = providers.Container(
|
||||||
|
Core,
|
||||||
|
config=config,
|
||||||
|
)
|
||||||
|
|
||||||
|
greetings = providers.Factory(str, config.greeting)
|
||||||
|
|
||||||
|
container = Application()
|
||||||
|
|
||||||
|
container.config.set("greeting", "Hello World")
|
||||||
|
assert container.greetings() == "Hello World"
|
||||||
|
assert container.core.greetings() == "Hello World"
|
||||||
|
|
||||||
|
container.config.set("greeting", "Hello Bob")
|
||||||
|
assert container.greetings() == "Hello Bob"
|
||||||
|
assert container.core.greetings() == "Hello Bob"
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_overriding_cache_for_option():
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/428
|
||||||
|
class Core(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
greetings = providers.Factory(str, config.greeting)
|
||||||
|
|
||||||
|
class Application(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
core = providers.Container(
|
||||||
|
Core,
|
||||||
|
config=config.option,
|
||||||
|
)
|
||||||
|
|
||||||
|
greetings = providers.Factory(str, config.option.greeting)
|
||||||
|
|
||||||
|
container = Application()
|
||||||
|
|
||||||
|
container.config.set("option.greeting", "Hello World")
|
||||||
|
assert container.greetings() == "Hello World"
|
||||||
|
assert container.core.greetings() == "Hello World"
|
||||||
|
|
||||||
|
container.config.set("option.greeting", "Hello Bob")
|
||||||
|
assert container.greetings() == "Hello Bob"
|
||||||
|
assert container.core.greetings() == "Hello Bob"
|
338
tests/unit/providers/configuration/test_config_py2_py3.py
Normal file
338
tests/unit/providers/configuration/test_config_py2_py3.py
Normal file
|
@ -0,0 +1,338 @@
|
||||||
|
"""Configuration provider tests."""
|
||||||
|
|
||||||
|
import decimal
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, errors
|
||||||
|
from pytest import mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_optional(config):
|
||||||
|
config.set_name("myconfig")
|
||||||
|
config.set_default({"foo": "bar"})
|
||||||
|
config.set_strict(True)
|
||||||
|
|
||||||
|
assert config.get_name() == "myconfig"
|
||||||
|
assert config.get_default() == {"foo": "bar"}
|
||||||
|
assert config.get_strict() is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_name_returns_self(config):
|
||||||
|
assert config.set_name("myconfig") is config
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_default_returns_self(config):
|
||||||
|
assert config.set_default({}) is config
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_strict_returns_self(config):
|
||||||
|
assert config.set_strict(True) is config
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_name(config):
|
||||||
|
assert config.get_name() == "config"
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_are_providers(config):
|
||||||
|
assert providers.is_provider(config.a) is True
|
||||||
|
assert providers.is_provider(config.a.b) is True
|
||||||
|
assert providers.is_provider(config.a.b.c) is True
|
||||||
|
assert providers.is_provider(config.a.b.d) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_are_not_delegates(config):
|
||||||
|
assert providers.is_delegated(config.a) is False
|
||||||
|
assert providers.is_delegated(config.a.b) is False
|
||||||
|
assert providers.is_delegated(config.a.b.c) is False
|
||||||
|
assert providers.is_delegated(config.a.b.d) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_identity(config):
|
||||||
|
assert config.a is config.a
|
||||||
|
assert config.a.b is config.a.b
|
||||||
|
assert config.a.b.c is config.a.b.c
|
||||||
|
assert config.a.b.d is config.a.b.d
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_name(config):
|
||||||
|
assert config.a.b.c.get_name() == "config.a.b.c"
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_value_setting(config):
|
||||||
|
a = config.a
|
||||||
|
ab = config.a.b
|
||||||
|
abc = config.a.b.c
|
||||||
|
abd = config.a.b.d
|
||||||
|
|
||||||
|
config.update({"a": {"b": {"c": 1, "d": 2}}})
|
||||||
|
|
||||||
|
assert a() == {"b": {"c": 1, "d": 2}}
|
||||||
|
assert ab() == {"c": 1, "d": 2}
|
||||||
|
assert abc() == 1
|
||||||
|
assert abd() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_with_already_set_value(config):
|
||||||
|
config.update({"a": {"b": {"c": 1, "d": 2}}})
|
||||||
|
|
||||||
|
a = config.a
|
||||||
|
ab = config.a.b
|
||||||
|
abc = config.a.b.c
|
||||||
|
abd = config.a.b.d
|
||||||
|
|
||||||
|
assert a() == {"b": {"c": 1, "d": 2}}
|
||||||
|
assert ab() == {"c": 1, "d": 2}
|
||||||
|
assert abc() == 1
|
||||||
|
assert abd() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_as_int(config):
|
||||||
|
value_provider = providers.Callable(lambda value: value, config.test.as_int())
|
||||||
|
config.from_dict({"test": "123"})
|
||||||
|
|
||||||
|
value = value_provider()
|
||||||
|
assert value == 123
|
||||||
|
|
||||||
|
|
||||||
|
def test_as_float(config):
|
||||||
|
value_provider = providers.Callable(lambda value: value, config.test.as_float())
|
||||||
|
config.from_dict({"test": "123.123"})
|
||||||
|
|
||||||
|
value = value_provider()
|
||||||
|
assert value == 123.123
|
||||||
|
|
||||||
|
|
||||||
|
def test_as_(config):
|
||||||
|
value_provider = providers.Callable(
|
||||||
|
lambda value: value,
|
||||||
|
config.test.as_(decimal.Decimal),
|
||||||
|
)
|
||||||
|
config.from_dict({"test": "123.123"})
|
||||||
|
|
||||||
|
value = value_provider()
|
||||||
|
assert value == decimal.Decimal("123.123")
|
||||||
|
|
||||||
|
|
||||||
|
def test_required(config):
|
||||||
|
provider = providers.Callable(
|
||||||
|
lambda value: value,
|
||||||
|
config.a.required(),
|
||||||
|
)
|
||||||
|
with raises(errors.Error, match="Undefined configuration option \"config.a\""):
|
||||||
|
provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_defined_none(config):
|
||||||
|
provider = providers.Callable(
|
||||||
|
lambda value: value,
|
||||||
|
config.a.required(),
|
||||||
|
)
|
||||||
|
config.from_dict({"a": None})
|
||||||
|
assert provider() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_no_side_effect(config):
|
||||||
|
_ = providers.Callable(
|
||||||
|
lambda value: value,
|
||||||
|
config.a.required(),
|
||||||
|
)
|
||||||
|
assert config.a() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_as_(config):
|
||||||
|
provider = providers.List(
|
||||||
|
config.int_test.required().as_int(),
|
||||||
|
config.float_test.required().as_float(),
|
||||||
|
config._as_test.required().as_(decimal.Decimal),
|
||||||
|
)
|
||||||
|
config.from_dict({"int_test": "1", "float_test": "2.0", "_as_test": "3.0"})
|
||||||
|
assert provider() == [1, 2.0, decimal.Decimal("3.0")]
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_value_override(config):
|
||||||
|
a = config.a
|
||||||
|
ab = config.a.b
|
||||||
|
abc = config.a.b.c
|
||||||
|
abd = config.a.b.d
|
||||||
|
|
||||||
|
config.override({"a": {"b": {"c": 1, "d": 2}}})
|
||||||
|
|
||||||
|
assert a() == {"b": {"c": 1, "d": 2}}
|
||||||
|
assert ab() == {"c": 1, "d": 2}
|
||||||
|
assert abc() == 1
|
||||||
|
assert abd() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_configuration_option_override_and_reset_override(config):
|
||||||
|
# Bug: https://github.com/ets-labs/python-dependency-injector/issues/319
|
||||||
|
config.from_dict({"a": {"b": {"c": 1}}})
|
||||||
|
|
||||||
|
assert config.a.b.c() == 1
|
||||||
|
|
||||||
|
with config.set("a.b.c", "xxx"):
|
||||||
|
assert config.a.b.c() == "xxx"
|
||||||
|
assert config.a.b.c() == 1
|
||||||
|
|
||||||
|
with config.a.b.c.override("yyy"):
|
||||||
|
assert config.a.b.c() == "yyy"
|
||||||
|
|
||||||
|
assert config.a.b.c() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_with_already_overridden_value(config):
|
||||||
|
config.override({"a": {"b": {"c": 1, "d": 2}}})
|
||||||
|
|
||||||
|
a = config.a
|
||||||
|
ab = config.a.b
|
||||||
|
abc = config.a.b.c
|
||||||
|
abd = config.a.b.d
|
||||||
|
|
||||||
|
assert a() == {"b": {"c": 1, "d": 2}}
|
||||||
|
assert ab() == {"c": 1, "d": 2}
|
||||||
|
assert abc() == 1
|
||||||
|
assert abd() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_with_default_value(config):
|
||||||
|
config.set_default({"a": {"b": {"c": 1, "d": 2}}})
|
||||||
|
|
||||||
|
a = config.a
|
||||||
|
ab = config.a.b
|
||||||
|
abc = config.a.b.c
|
||||||
|
abd = config.a.b.d
|
||||||
|
|
||||||
|
assert a() == {"b": {"c": 1, "d": 2}}
|
||||||
|
assert ab() == {"c": 1, "d": 2}
|
||||||
|
assert abc() == 1
|
||||||
|
assert abd() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers_with_default_value_overriding(config):
|
||||||
|
config.set_default({"a": {"b": {"c": 1, "d": 2}}})
|
||||||
|
|
||||||
|
assert config.a() == {"b": {"c": 1, "d": 2}}
|
||||||
|
assert config.a.b() == {"c": 1, "d": 2}
|
||||||
|
assert config.a.b.c() == 1
|
||||||
|
assert config.a.b.d() == 2
|
||||||
|
|
||||||
|
config.override({"a": {"b": {"c": 3, "d": 4}}})
|
||||||
|
assert config.a() == {"b": {"c": 3, "d": 4}}
|
||||||
|
assert config.a.b() == {"c": 3, "d": 4}
|
||||||
|
assert config.a.b.c() == 3
|
||||||
|
assert config.a.b.d() == 4
|
||||||
|
|
||||||
|
config.reset_override()
|
||||||
|
assert config.a() == {"b": {"c": 1, "d": 2}}
|
||||||
|
assert config.a.b() == {"c": 1, "d": 2}
|
||||||
|
assert config.a.b.c() == 1
|
||||||
|
assert config.a.b.d() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_value_of_undefined_option(config):
|
||||||
|
assert config.option() is None
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_value_of_undefined_option_in_strict_mode(config):
|
||||||
|
with raises(errors.Error, match="Undefined configuration option \"config.option\""):
|
||||||
|
config.option()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_value_of_undefined_option_with_root_none_in_strict_mode(config):
|
||||||
|
config.override(None)
|
||||||
|
with raises(errors.Error, match="Undefined configuration option \"config.option\""):
|
||||||
|
config.option()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_value_of_defined_none_option_in_strict_mode(config):
|
||||||
|
config.from_dict({"a": None})
|
||||||
|
assert config.a() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_getting_of_special_attributes(config):
|
||||||
|
with raises(AttributeError):
|
||||||
|
config.__name__
|
||||||
|
|
||||||
|
|
||||||
|
def test_getting_of_special_attributes_from_child(config):
|
||||||
|
with raises(AttributeError):
|
||||||
|
config.child.__name__
|
||||||
|
|
||||||
|
|
||||||
|
def test_context_manager_alias():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with container.config as config:
|
||||||
|
config.override({"foo": "foo", "bar": "bar"})
|
||||||
|
|
||||||
|
assert container.config() == {"foo": "foo", "bar": "bar"}
|
||||||
|
assert config() == {"foo": "foo", "bar": "bar"}
|
||||||
|
assert container.config is config
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_context_manager_alias():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with container.config.option as option:
|
||||||
|
option.override({"foo": "foo", "bar": "bar"})
|
||||||
|
|
||||||
|
assert container.config() == {"option": {"foo": "foo", "bar": "bar"}}
|
||||||
|
assert container.config.option() == {"foo": "foo", "bar": "bar"}
|
||||||
|
assert option() == {"foo": "foo", "bar": "bar"}
|
||||||
|
assert container.config.option is option
|
||||||
|
|
||||||
|
|
||||||
|
def test_missing_key(config):
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/358
|
||||||
|
config.override(None)
|
||||||
|
value = config.key()
|
||||||
|
assert value is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy(config):
|
||||||
|
config_copy = providers.deepcopy(config)
|
||||||
|
assert isinstance(config_copy, providers.Configuration)
|
||||||
|
assert config is not config_copy
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo(config):
|
||||||
|
config_copy_memo = providers.Configuration()
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(config, memo={id(config): config_copy_memo})
|
||||||
|
assert provider_copy is config_copy_memo
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_overridden(config):
|
||||||
|
object_provider = providers.Object(object())
|
||||||
|
|
||||||
|
config.override(object_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(config)
|
||||||
|
object_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
assert config is not provider_copy
|
||||||
|
assert isinstance(config, providers.Configuration)
|
||||||
|
|
||||||
|
assert object_provider is not object_provider_copy
|
||||||
|
assert isinstance(object_provider_copy, providers.Object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr(config):
|
||||||
|
assert repr(config) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"Configuration({0}) at {1}>".format(repr("config"), hex(id(config)))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr_child(config):
|
||||||
|
assert repr(config.a.b.c) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"ConfigurationOption({0}) at {1}>".format(repr("config.a.b.c"), hex(id(config.a.b.c)))
|
||||||
|
)
|
103
tests/unit/providers/configuration/test_from_dict_py2_py3.py
Normal file
103
tests/unit/providers/configuration/test_from_dict_py2_py3.py
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
"""Configuration.from_dict() tests."""
|
||||||
|
|
||||||
|
from pytest import mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
CONFIG_OPTIONS_1 = {
|
||||||
|
"section1": {
|
||||||
|
"value1": "1",
|
||||||
|
},
|
||||||
|
"section2": {
|
||||||
|
"value2": "2",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
CONFIG_OPTIONS_2 = {
|
||||||
|
"section1": {
|
||||||
|
"value1": "11",
|
||||||
|
"value11": "11",
|
||||||
|
},
|
||||||
|
"section3": {
|
||||||
|
"value3": "3",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test(config):
|
||||||
|
config.from_dict(CONFIG_OPTIONS_1)
|
||||||
|
|
||||||
|
assert config() == {"section1": {"value1": "1"}, "section2": {"value2": "2"}}
|
||||||
|
assert config.section1() == {"value1": "1"}
|
||||||
|
assert config.section1.value1() == "1"
|
||||||
|
assert config.section2() == {"value2": "2"}
|
||||||
|
assert config.section2.value2() == "2"
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge(config):
|
||||||
|
config.from_dict(CONFIG_OPTIONS_1)
|
||||||
|
config.from_dict(CONFIG_OPTIONS_2)
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": "11",
|
||||||
|
"value11": "11",
|
||||||
|
},
|
||||||
|
"section2": {
|
||||||
|
"value2": "2",
|
||||||
|
},
|
||||||
|
"section3": {
|
||||||
|
"value3": "3",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {"value1": "11", "value11": "11"}
|
||||||
|
assert config.section1.value1() == "11"
|
||||||
|
assert config.section1.value11() == "11"
|
||||||
|
assert config.section2() == {"value2": "2"}
|
||||||
|
assert config.section2.value2() == "2"
|
||||||
|
assert config.section3() == {"value3": "3"}
|
||||||
|
assert config.section3.value3() == "3"
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_dict(config):
|
||||||
|
config.from_dict({})
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_empty_dict(config):
|
||||||
|
config.option.from_dict({})
|
||||||
|
assert config.option() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_empty_dict_in_strict_mode(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.from_dict({})
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_empty_dict_in_strict_mode(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.option.from_dict({})
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_empty_dict(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.from_dict({}, required=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_option_empty_dict(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.option.from_dict({}, required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_empty_dict_strict_mode(config):
|
||||||
|
config.from_dict({}, required=False)
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_option_empty_dict_strict_mode(config):
|
||||||
|
config.option.from_dict({}, required=False)
|
||||||
|
assert config.option() == {}
|
||||||
|
assert config() == {"option": {}}
|
||||||
|
|
107
tests/unit/providers/configuration/test_from_env_py2_py3.py
Normal file
107
tests/unit/providers/configuration/test_from_env_py2_py3.py
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
"""Configuration.from_env() tests."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture(autouse=True)
|
||||||
|
def environment_variables():
|
||||||
|
os.environ["CONFIG_TEST_ENV"] = "test-value"
|
||||||
|
yield
|
||||||
|
os.environ.pop("CONFIG_TEST_ENV", None)
|
||||||
|
|
||||||
|
|
||||||
|
def test(config):
|
||||||
|
config.from_env("CONFIG_TEST_ENV")
|
||||||
|
assert config() == "test-value"
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_children(config):
|
||||||
|
config.section1.value1.from_env("CONFIG_TEST_ENV")
|
||||||
|
|
||||||
|
assert config() == {"section1": {"value1": "test-value"}}
|
||||||
|
assert config.section1() == {"value1": "test-value"}
|
||||||
|
assert config.section1.value1() == "test-value"
|
||||||
|
|
||||||
|
|
||||||
|
def test_default(config):
|
||||||
|
config.from_env("UNDEFINED_ENV", "default-value")
|
||||||
|
assert config() == "default-value"
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_none(config):
|
||||||
|
config.from_env("UNDEFINED_ENV")
|
||||||
|
assert config() is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_default_none(config):
|
||||||
|
config.option.from_env("UNDEFINED_ENV")
|
||||||
|
assert config.option() is None
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_undefined_in_strict_mode(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.from_env("UNDEFINED_ENV")
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_undefined_in_strict_mode(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.option.from_env("UNDEFINED_ENV")
|
||||||
|
|
||||||
|
|
||||||
|
def test_undefined_in_strict_mode_with_default(config):
|
||||||
|
config.from_env("UNDEFINED_ENV", "default-value")
|
||||||
|
assert config() == "default-value"
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_undefined_in_strict_mode_with_default(config):
|
||||||
|
config.option.from_env("UNDEFINED_ENV", "default-value")
|
||||||
|
assert config.option() == "default-value"
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_undefined(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.from_env("UNDEFINED_ENV", required=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_undefined_with_default(config):
|
||||||
|
config.from_env("UNDEFINED_ENV", default="default-value", required=True)
|
||||||
|
assert config() == "default-value"
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_required_undefined(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.option.from_env("UNDEFINED_ENV", required=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_required_undefined_with_default(config):
|
||||||
|
config.option.from_env("UNDEFINED_ENV", default="default-value", required=True)
|
||||||
|
assert config.option() == "default-value"
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_undefined_in_strict_mode(config):
|
||||||
|
config.from_env("UNDEFINED_ENV", required=False)
|
||||||
|
assert config() is None
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_not_required_undefined_in_strict_mode(config):
|
||||||
|
config.option.from_env("UNDEFINED_ENV", required=False)
|
||||||
|
assert config.option() is None
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_undefined_with_default_in_strict_mode(config):
|
||||||
|
config.from_env("UNDEFINED_ENV", default="default-value", required=False)
|
||||||
|
assert config() == "default-value"
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_not_required_undefined_with_default_in_strict_mode(config):
|
||||||
|
config.option.from_env("UNDEFINED_ENV", default="default-value", required=False)
|
||||||
|
assert config.option() == "default-value"
|
123
tests/unit/providers/configuration/test_from_ini_py2_py3.py
Normal file
123
tests/unit/providers/configuration/test_from_ini_py2_py3.py
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
"""Configuration.from_ini() tests."""
|
||||||
|
|
||||||
|
from dependency_injector import errors
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config_file_1(tmp_path):
|
||||||
|
config_file = str(tmp_path / "config_1.ini")
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section1]\n"
|
||||||
|
"value1=1\n"
|
||||||
|
"\n"
|
||||||
|
"[section2]\n"
|
||||||
|
"value2=2\n"
|
||||||
|
)
|
||||||
|
return config_file
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config_file_2(tmp_path):
|
||||||
|
config_file = str(tmp_path / "config_2.ini")
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section1]\n"
|
||||||
|
"value1=11\n"
|
||||||
|
"value11=11\n"
|
||||||
|
"[section3]\n"
|
||||||
|
"value3=3\n"
|
||||||
|
)
|
||||||
|
return config_file
|
||||||
|
|
||||||
|
|
||||||
|
def test(config, config_file_1):
|
||||||
|
config.from_ini(config_file_1)
|
||||||
|
|
||||||
|
assert config() == {"section1": {"value1": "1"}, "section2": {"value2": "2"}}
|
||||||
|
assert config.section1() == {"value1": "1"}
|
||||||
|
assert config.section1.value1() == "1"
|
||||||
|
assert config.section2() == {"value2": "2"}
|
||||||
|
assert config.section2.value2() == "2"
|
||||||
|
|
||||||
|
|
||||||
|
def test_option(config, config_file_1):
|
||||||
|
config.option.from_ini(config_file_1)
|
||||||
|
|
||||||
|
assert config() == {"option": {"section1": {"value1": "1"}, "section2": {"value2": "2"}}}
|
||||||
|
assert config.option() == {"section1": {"value1": "1"}, "section2": {"value2": "2"}}
|
||||||
|
assert config.option.section1() == {"value1": "1"}
|
||||||
|
assert config.option.section1.value1() == "1"
|
||||||
|
assert config.option.section2() == {"value2": "2"}
|
||||||
|
assert config.option.section2.value2() == "2"
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge(config, config_file_1, config_file_2):
|
||||||
|
config.from_ini(config_file_1)
|
||||||
|
config.from_ini(config_file_2)
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": "11",
|
||||||
|
"value11": "11",
|
||||||
|
},
|
||||||
|
"section2": {
|
||||||
|
"value2": "2",
|
||||||
|
},
|
||||||
|
"section3": {
|
||||||
|
"value3": "3",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {"value1": "11", "value11": "11"}
|
||||||
|
assert config.section1.value1() == "11"
|
||||||
|
assert config.section1.value11() == "11"
|
||||||
|
assert config.section2() == {"value2": "2"}
|
||||||
|
assert config.section2.value2() == "2"
|
||||||
|
assert config.section3() == {"value3": "3"}
|
||||||
|
assert config.section3.value3() == "3"
|
||||||
|
|
||||||
|
|
||||||
|
def test_file_does_not_exist(config):
|
||||||
|
config.from_ini("./does_not_exist.ini")
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_file_does_not_exist_strict_mode(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.from_ini("./does_not_exist.ini")
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_file_does_not_exist(config):
|
||||||
|
config.option.from_ini("does_not_exist.ini")
|
||||||
|
assert config.option.undefined() is None
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_file_does_not_exist_strict_mode(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.option.from_ini("./does_not_exist.ini")
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_file_does_not_exist(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.from_ini("./does_not_exist.ini", required=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_option_file_does_not_exist(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.option.from_ini("./does_not_exist.ini", required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_file_does_not_exist_strict_mode(config):
|
||||||
|
config.from_ini("./does_not_exist.ini", required=False)
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_option_file_does_not_exist_strict_mode(config):
|
||||||
|
config.option.from_ini("./does_not_exist.ini", required=False)
|
||||||
|
with raises(errors.Error):
|
||||||
|
config.option()
|
|
@ -0,0 +1,145 @@
|
||||||
|
"""Configuration.from_ini() with environment variables interpolation tests."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config_file(tmp_path):
|
||||||
|
config_file = str(tmp_path / "config_1.ini")
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section1]\n"
|
||||||
|
"value1=${CONFIG_TEST_ENV}\n"
|
||||||
|
"value2=${CONFIG_TEST_PATH}/path\n"
|
||||||
|
)
|
||||||
|
return config_file
|
||||||
|
|
||||||
|
|
||||||
|
@fixture(autouse=True)
|
||||||
|
def environment_variables():
|
||||||
|
os.environ["CONFIG_TEST_ENV"] = "test-value"
|
||||||
|
os.environ["CONFIG_TEST_PATH"] = "test-path"
|
||||||
|
os.environ["DEFINED"] = "defined"
|
||||||
|
yield
|
||||||
|
os.environ.pop("CONFIG_TEST_ENV", None)
|
||||||
|
os.environ.pop("CONFIG_TEST_PATH", None)
|
||||||
|
os.environ.pop("DEFINED", None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_env_variable_interpolation(config, config_file):
|
||||||
|
config.from_ini(config_file)
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
}
|
||||||
|
assert config.section1.value1() == "test-value"
|
||||||
|
assert config.section1.value2() == "test-path/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_missing_envs_not_required(config, config_file):
|
||||||
|
del os.environ["CONFIG_TEST_ENV"]
|
||||||
|
del os.environ["CONFIG_TEST_PATH"]
|
||||||
|
|
||||||
|
config.from_ini(config_file)
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": "",
|
||||||
|
"value2": "/path",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {
|
||||||
|
"value1": "",
|
||||||
|
"value2": "/path",
|
||||||
|
}
|
||||||
|
assert config.section1.value1() == ""
|
||||||
|
assert config.section1.value2() == "/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_missing_envs_required(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section]\n"
|
||||||
|
"undefined=${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.from_ini(config_file, envs_required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_missing_envs_strict_mode(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section]\n"
|
||||||
|
"undefined=${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.from_ini(config_file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_missing_envs_not_required(config, config_file):
|
||||||
|
del os.environ["CONFIG_TEST_ENV"]
|
||||||
|
del os.environ["CONFIG_TEST_PATH"]
|
||||||
|
|
||||||
|
config.option.from_ini(config_file)
|
||||||
|
|
||||||
|
assert config.option() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": "",
|
||||||
|
"value2": "/path",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.option.section1() == {
|
||||||
|
"value1": "",
|
||||||
|
"value2": "/path",
|
||||||
|
}
|
||||||
|
assert config.option.section1.value1() == ""
|
||||||
|
assert config.option.section1.value2() == "/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_missing_envs_required(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section]\n"
|
||||||
|
"undefined=${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.option.from_ini(config_file, envs_required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_missing_envs_strict_mode(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section]\n"
|
||||||
|
"undefined=${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.option.from_ini(config_file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_values(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"[section]\n"
|
||||||
|
"defined_with_default=${DEFINED:default}\n"
|
||||||
|
"undefined_with_default=${UNDEFINED:default}\n"
|
||||||
|
"complex=${DEFINED}/path/${DEFINED:default}/${UNDEFINED}/${UNDEFINED:default}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
config.from_ini(config_file)
|
||||||
|
|
||||||
|
assert config.section() == {
|
||||||
|
"defined_with_default": "defined",
|
||||||
|
"undefined_with_default": "default",
|
||||||
|
"complex": "defined/path/defined//default",
|
||||||
|
}
|
184
tests/unit/providers/configuration/test_from_pydantic_py36.py
Normal file
184
tests/unit/providers/configuration/test_from_pydantic_py36.py
Normal file
|
@ -0,0 +1,184 @@
|
||||||
|
"""Configuration.from_pydantic() tests."""
|
||||||
|
|
||||||
|
import pydantic
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
class Section11(pydantic.BaseModel):
|
||||||
|
value1 = 1
|
||||||
|
|
||||||
|
|
||||||
|
class Section12(pydantic.BaseModel):
|
||||||
|
value2 = 2
|
||||||
|
|
||||||
|
|
||||||
|
class Settings1(pydantic.BaseSettings):
|
||||||
|
section1 = Section11()
|
||||||
|
section2 = Section12()
|
||||||
|
|
||||||
|
|
||||||
|
class Section21(pydantic.BaseModel):
|
||||||
|
value1 = 11
|
||||||
|
value11 = 11
|
||||||
|
|
||||||
|
|
||||||
|
class Section3(pydantic.BaseModel):
|
||||||
|
value3 = 3
|
||||||
|
|
||||||
|
|
||||||
|
class Settings2(pydantic.BaseSettings):
|
||||||
|
section1 = Section21()
|
||||||
|
section3 = Section3()
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def no_pydantic_module_installed():
|
||||||
|
providers.pydantic = None
|
||||||
|
yield
|
||||||
|
providers.pydantic = pydantic
|
||||||
|
|
||||||
|
|
||||||
|
def test(config):
|
||||||
|
config.from_pydantic(Settings1())
|
||||||
|
|
||||||
|
assert config() == {"section1": {"value1": 1}, "section2": {"value2": 2}}
|
||||||
|
assert config.section1() == {"value1": 1}
|
||||||
|
assert config.section1.value1() == 1
|
||||||
|
assert config.section2() == {"value2": 2}
|
||||||
|
assert config.section2.value2() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_kwarg(config):
|
||||||
|
config.from_pydantic(Settings1(), exclude={"section2"})
|
||||||
|
|
||||||
|
assert config() == {"section1": {"value1": 1}}
|
||||||
|
assert config.section1() == {"value1": 1}
|
||||||
|
assert config.section1.value1() == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge(config):
|
||||||
|
config.from_pydantic(Settings1())
|
||||||
|
config.from_pydantic(Settings2())
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": 11,
|
||||||
|
"value11": 11,
|
||||||
|
},
|
||||||
|
"section2": {
|
||||||
|
"value2": 2,
|
||||||
|
},
|
||||||
|
"section3": {
|
||||||
|
"value3": 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {"value1": 11, "value11": 11}
|
||||||
|
assert config.section1.value1() == 11
|
||||||
|
assert config.section1.value11() == 11
|
||||||
|
assert config.section2() == {"value2": 2}
|
||||||
|
assert config.section2.value2() == 2
|
||||||
|
assert config.section3() == {"value3": 3}
|
||||||
|
assert config.section3.value3() == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_empty_settings(config):
|
||||||
|
config.from_pydantic(pydantic.BaseSettings())
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_empty_settings_strict_mode(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.from_pydantic(pydantic.BaseSettings())
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_empty_settings(config):
|
||||||
|
config.option.from_pydantic(pydantic.BaseSettings())
|
||||||
|
assert config.option() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_empty_settings_strict_mode(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.option.from_pydantic(pydantic.BaseSettings())
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_empty_settings(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.from_pydantic(pydantic.BaseSettings(), required=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_option_empty_settings(config):
|
||||||
|
with raises(ValueError):
|
||||||
|
config.option.from_pydantic(pydantic.BaseSettings(), required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_empty_settings_strict_mode(config):
|
||||||
|
config.from_pydantic(pydantic.BaseSettings(), required=False)
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_option_empty_settings_strict_mode(config):
|
||||||
|
config.option.from_pydantic(pydantic.BaseSettings(), required=False)
|
||||||
|
assert config.option() == {}
|
||||||
|
assert config() == {"option": {}}
|
||||||
|
|
||||||
|
|
||||||
|
def test_not_instance_of_settings(config):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.from_pydantic({})
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Unable to recognize settings instance, expect \"pydantic.BaseSettings\", "
|
||||||
|
"got {0} instead".format({})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_not_instance_of_settings(config):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.option.from_pydantic({})
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Unable to recognize settings instance, expect \"pydantic.BaseSettings\", "
|
||||||
|
"got {0} instead".format({})
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_subclass_instead_of_instance(config):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.from_pydantic(Settings1)
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Got settings class, but expect instance: "
|
||||||
|
"instead \"Settings1\" use \"Settings1()\""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_subclass_instead_of_instance(config):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.option.from_pydantic(Settings1)
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Got settings class, but expect instance: "
|
||||||
|
"instead \"Settings1\" use \"Settings1()\""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.usefixtures("no_pydantic_module_installed")
|
||||||
|
def test_no_pydantic_installed(config):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.from_pydantic(Settings1())
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Unable to load pydantic configuration - pydantic is not installed. "
|
||||||
|
"Install pydantic or install Dependency Injector with pydantic extras: "
|
||||||
|
"\"pip install dependency-injector[pydantic]\""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.usefixtures("no_pydantic_module_installed")
|
||||||
|
def test_option_no_pydantic_installed(config):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.option.from_pydantic(Settings1())
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Unable to load pydantic configuration - pydantic is not installed. "
|
||||||
|
"Install pydantic or install Dependency Injector with pydantic extras: "
|
||||||
|
"\"pip install dependency-injector[pydantic]\""
|
||||||
|
)
|
|
@ -0,0 +1,19 @@
|
||||||
|
"""Configuration.from_value() tests."""
|
||||||
|
|
||||||
|
|
||||||
|
def test_from_value(config):
|
||||||
|
test_value = 123321
|
||||||
|
config.from_value(test_value)
|
||||||
|
assert config() == test_value
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_from_value(config):
|
||||||
|
test_value_1 = 123
|
||||||
|
test_value_2 = 321
|
||||||
|
|
||||||
|
config.option1.from_value(test_value_1)
|
||||||
|
config.option2.from_value(test_value_2)
|
||||||
|
|
||||||
|
assert config() == {"option1": test_value_1, "option2": test_value_2}
|
||||||
|
assert config.option1() == test_value_1
|
||||||
|
assert config.option2() == test_value_2
|
142
tests/unit/providers/configuration/test_from_yaml_py2_py3.py
Normal file
142
tests/unit/providers/configuration/test_from_yaml_py2_py3.py
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
"""Configuration.from_yaml() tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config_file_1(tmp_path):
|
||||||
|
config_file = str(tmp_path / "config_1.ini")
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section1:\n"
|
||||||
|
" value1: 1\n"
|
||||||
|
"\n"
|
||||||
|
"section2:\n"
|
||||||
|
" value2: 2\n"
|
||||||
|
)
|
||||||
|
return config_file
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config_file_2(tmp_path):
|
||||||
|
config_file = str(tmp_path / "config_2.ini")
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section1:\n"
|
||||||
|
" value1: 11\n"
|
||||||
|
" value11: 11\n"
|
||||||
|
"section3:\n"
|
||||||
|
" value3: 3\n"
|
||||||
|
)
|
||||||
|
return config_file
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def no_yaml_module_installed():
|
||||||
|
yaml = providers.yaml
|
||||||
|
providers.yaml = None
|
||||||
|
yield
|
||||||
|
providers.yaml = yaml
|
||||||
|
|
||||||
|
|
||||||
|
def test(config, config_file_1):
|
||||||
|
config.from_yaml(config_file_1)
|
||||||
|
|
||||||
|
assert config() == {"section1": {"value1": 1}, "section2": {"value2": 2}}
|
||||||
|
assert config.section1() == {"value1": 1}
|
||||||
|
assert config.section1.value1() == 1
|
||||||
|
assert config.section2() == {"value2": 2}
|
||||||
|
assert config.section2.value2() == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge(config, config_file_1, config_file_2):
|
||||||
|
config.from_yaml(config_file_1)
|
||||||
|
config.from_yaml(config_file_2)
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": 11,
|
||||||
|
"value11": 11,
|
||||||
|
},
|
||||||
|
"section2": {
|
||||||
|
"value2": 2,
|
||||||
|
},
|
||||||
|
"section3": {
|
||||||
|
"value3": 3,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {"value1": 11, "value11": 11}
|
||||||
|
assert config.section1.value1() == 11
|
||||||
|
assert config.section1.value11() == 11
|
||||||
|
assert config.section2() == {"value2": 2}
|
||||||
|
assert config.section2.value2() == 2
|
||||||
|
assert config.section3() == {"value3": 3}
|
||||||
|
assert config.section3.value3() == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_file_does_not_exist(config):
|
||||||
|
config.from_yaml("./does_not_exist.yml")
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_file_does_not_exist_strict_mode(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.from_yaml("./does_not_exist.yml")
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_file_does_not_exist(config):
|
||||||
|
config.option.from_yaml("./does_not_exist.yml")
|
||||||
|
assert config.option() is None
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_file_does_not_exist_strict_mode(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.option.from_yaml("./does_not_exist.yml")
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_file_does_not_exist(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.from_yaml("./does_not_exist.yml", required=True)
|
||||||
|
|
||||||
|
|
||||||
|
def test_required_option_file_does_not_exist(config):
|
||||||
|
with raises(IOError):
|
||||||
|
config.option.from_yaml("./does_not_exist.yml", required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_file_does_not_exist_strict_mode(config):
|
||||||
|
config.from_yaml("./does_not_exist.yml", required=False)
|
||||||
|
assert config() == {}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_not_required_option_file_does_not_exist_strict_mode(config):
|
||||||
|
config.option.from_yaml("./does_not_exist.yml", required=False)
|
||||||
|
with raises(errors.Error):
|
||||||
|
config.option()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.usefixtures("no_yaml_module_installed")
|
||||||
|
def test_no_yaml_installed(config, config_file_1):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.from_yaml(config_file_1)
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Unable to load yaml configuration - PyYAML is not installed. "
|
||||||
|
"Install PyYAML or install Dependency Injector with yaml extras: "
|
||||||
|
"\"pip install dependency-injector[yaml]\""
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.usefixtures("no_yaml_module_installed")
|
||||||
|
def test_option_no_yaml_installed(config, config_file_1):
|
||||||
|
with raises(errors.Error) as error:
|
||||||
|
config.option.from_yaml(config_file_1)
|
||||||
|
assert error.value.args[0] == (
|
||||||
|
"Unable to load yaml configuration - PyYAML is not installed. "
|
||||||
|
"Install PyYAML or install Dependency Injector with yaml extras: "
|
||||||
|
"\"pip install dependency-injector[yaml]\""
|
||||||
|
)
|
|
@ -0,0 +1,185 @@
|
||||||
|
"""Configuration.from_yaml() with environment variables interpolation tests."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
import yaml
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def config_file(tmp_path):
|
||||||
|
config_file = str(tmp_path / "config_1.ini")
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section1:\n"
|
||||||
|
" value1: ${CONFIG_TEST_ENV}\n"
|
||||||
|
" value2: ${CONFIG_TEST_PATH}/path\n"
|
||||||
|
)
|
||||||
|
return config_file
|
||||||
|
|
||||||
|
|
||||||
|
@fixture(autouse=True)
|
||||||
|
def environment_variables():
|
||||||
|
os.environ["CONFIG_TEST_ENV"] = "test-value"
|
||||||
|
os.environ["CONFIG_TEST_PATH"] = "test-path"
|
||||||
|
os.environ["DEFINED"] = "defined"
|
||||||
|
yield
|
||||||
|
os.environ.pop("CONFIG_TEST_ENV", None)
|
||||||
|
os.environ.pop("CONFIG_TEST_PATH", None)
|
||||||
|
os.environ.pop("DEFINED", None)
|
||||||
|
|
||||||
|
|
||||||
|
def test_env_variable_interpolation(config, config_file):
|
||||||
|
config.from_yaml(config_file)
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
}
|
||||||
|
assert config.section1.value1() == "test-value"
|
||||||
|
assert config.section1.value2() == "test-path/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_missing_envs_not_required(config, config_file):
|
||||||
|
del os.environ["CONFIG_TEST_ENV"]
|
||||||
|
del os.environ["CONFIG_TEST_PATH"]
|
||||||
|
|
||||||
|
config.from_yaml(config_file)
|
||||||
|
|
||||||
|
assert config() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": None,
|
||||||
|
"value2": "/path",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.section1() == {
|
||||||
|
"value1": None,
|
||||||
|
"value2": "/path",
|
||||||
|
}
|
||||||
|
assert config.section1.value1() is None
|
||||||
|
assert config.section1.value2() == "/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_missing_envs_required(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section:\n"
|
||||||
|
" undefined: ${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.from_yaml(config_file, envs_required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_missing_envs_strict_mode(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section:\n"
|
||||||
|
" undefined: ${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.from_yaml(config_file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_missing_envs_not_required(config, config_file):
|
||||||
|
del os.environ["CONFIG_TEST_ENV"]
|
||||||
|
del os.environ["CONFIG_TEST_PATH"]
|
||||||
|
|
||||||
|
config.option.from_yaml(config_file)
|
||||||
|
|
||||||
|
assert config.option() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": None,
|
||||||
|
"value2": "/path",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.option.section1() == {
|
||||||
|
"value1": None,
|
||||||
|
"value2": "/path",
|
||||||
|
}
|
||||||
|
assert config.option.section1.value1() is None
|
||||||
|
assert config.option.section1.value2() == "/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_missing_envs_required(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section:\n"
|
||||||
|
" undefined: ${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.option.from_yaml(config_file, envs_required=True)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("config_type", ["strict"])
|
||||||
|
def test_option_missing_envs_strict_mode(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section:\n"
|
||||||
|
" undefined: ${UNDEFINED}\n"
|
||||||
|
)
|
||||||
|
with raises(ValueError, match="Missing required environment variable \"UNDEFINED\""):
|
||||||
|
config.option.from_yaml(config_file)
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_values(config, config_file):
|
||||||
|
with open(config_file, "w") as file:
|
||||||
|
file.write(
|
||||||
|
"section:\n"
|
||||||
|
" defined_with_default: ${DEFINED:default}\n"
|
||||||
|
" undefined_with_default: ${UNDEFINED:default}\n"
|
||||||
|
" complex: ${DEFINED}/path/${DEFINED:default}/${UNDEFINED}/${UNDEFINED:default}\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
config.from_yaml(config_file)
|
||||||
|
|
||||||
|
assert config.section() == {
|
||||||
|
"defined_with_default": "defined",
|
||||||
|
"undefined_with_default": "default",
|
||||||
|
"complex": "defined/path/defined//default",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_env_variable_interpolation(config, config_file):
|
||||||
|
config.option.from_yaml(config_file)
|
||||||
|
|
||||||
|
assert config.option() == {
|
||||||
|
"section1": {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
assert config.option.section1() == {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
}
|
||||||
|
assert config.option.section1.value1() == "test-value"
|
||||||
|
assert config.option.section1.value2() == "test-path/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_env_variable_interpolation_custom_loader(config, config_file):
|
||||||
|
config.from_yaml(config_file, loader=yaml.UnsafeLoader)
|
||||||
|
|
||||||
|
assert config.section1() == {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
}
|
||||||
|
assert config.section1.value1() == "test-value"
|
||||||
|
assert config.section1.value2() == "test-path/path"
|
||||||
|
|
||||||
|
|
||||||
|
def test_option_env_variable_interpolation_custom_loader(config, config_file):
|
||||||
|
config.option.from_yaml(config_file, loader=yaml.UnsafeLoader)
|
||||||
|
|
||||||
|
assert config.option.section1() == {
|
||||||
|
"value1": "test-value",
|
||||||
|
"value2": "test-path/path",
|
||||||
|
}
|
||||||
|
assert config.option.section1.value1() == "test-value"
|
||||||
|
assert config.option.section1.value2() == "test-path/path"
|
1
tests/unit/providers/coroutines/__init__.py
Normal file
1
tests/unit/providers/coroutines/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Tests for coroutine providers."""
|
5
tests/unit/providers/coroutines/common.py
Normal file
5
tests/unit/providers/coroutines/common.py
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
"""Common test artifacts."""
|
||||||
|
|
||||||
|
|
||||||
|
async def example(arg1, arg2, arg3, arg4):
|
||||||
|
return arg1, arg2, arg3, arg4
|
|
@ -0,0 +1,66 @@
|
||||||
|
"""AbstractCoroutine provider tests."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import mark, raises
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance():
|
||||||
|
assert isinstance(providers.AbstractCoroutine(example), providers.Coroutine)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
@mark.filterwarnings("ignore")
|
||||||
|
async def test_call_overridden_by_coroutine():
|
||||||
|
@asyncio.coroutine
|
||||||
|
def abstract_example():
|
||||||
|
raise RuntimeError("Should not be raised")
|
||||||
|
|
||||||
|
provider = providers.AbstractCoroutine(abstract_example)
|
||||||
|
provider.override(providers.Coroutine(example))
|
||||||
|
|
||||||
|
result = await provider(1, 2, 3, 4)
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
@mark.filterwarnings("ignore")
|
||||||
|
async def test_call_overridden_by_delegated_coroutine():
|
||||||
|
@asyncio.coroutine
|
||||||
|
def abstract_example():
|
||||||
|
raise RuntimeError("Should not be raised")
|
||||||
|
|
||||||
|
provider = providers.AbstractCoroutine(abstract_example)
|
||||||
|
provider.override(providers.DelegatedCoroutine(example))
|
||||||
|
|
||||||
|
result = await provider(1, 2, 3, 4)
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_not_overridden():
|
||||||
|
provider = providers.AbstractCoroutine(example)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider(1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_by_not_coroutine():
|
||||||
|
provider = providers.AbstractCoroutine(example)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider.override(providers.Factory(object))
|
||||||
|
|
||||||
|
|
||||||
|
def test_provide_not_implemented():
|
||||||
|
provider = providers.AbstractCoroutine(example)
|
||||||
|
with raises(NotImplementedError):
|
||||||
|
provider._provide((1, 2, 3, 4), dict())
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.AbstractCoroutine(example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"AbstractCoroutine({0}) at {1}>".format(repr(example), hex(id(provider)))
|
||||||
|
)
|
|
@ -0,0 +1,17 @@
|
||||||
|
"""CoroutineDelegate provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegate():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
delegate = providers.CoroutineDelegate(provider)
|
||||||
|
assert isinstance(delegate, providers.Delegate)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_coroutine():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.CoroutineDelegate(providers.Object(object()))
|
199
tests/unit/providers/coroutines/test_coroutine_py35.py
Normal file
199
tests/unit/providers/coroutines/test_coroutine_py35.py
Normal file
|
@ -0,0 +1,199 @@
|
||||||
|
"""Coroutine provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import mark, raises
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_coroutine():
|
||||||
|
assert isinstance(providers.Coroutine(example), providers.Coroutine)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_coroutine():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.Coroutine(lambda: None)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_optional_provides():
|
||||||
|
provider = providers.Coroutine()
|
||||||
|
provider.set_provides(example)
|
||||||
|
|
||||||
|
result = await provider(1, 2, 3, 4)
|
||||||
|
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
assert provider.provides is example
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_provides_returns_self():
|
||||||
|
provider = providers.Coroutine()
|
||||||
|
assert provider.set_provides(example) is provider
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_call_with_positional_args():
|
||||||
|
provider = providers.Coroutine(example, 1, 2, 3, 4)
|
||||||
|
result = await provider()
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_call_with_keyword_args():
|
||||||
|
provider = providers.Coroutine(example, arg1=1, arg2=2, arg3=3, arg4=4)
|
||||||
|
result = await provider()
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_call_with_positional_and_keyword_args():
|
||||||
|
provider = providers.Coroutine(example, 1, 2, arg3=3, arg4=4)
|
||||||
|
result = await provider()
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_call_with_context_args():
|
||||||
|
provider = providers.Coroutine(example, 1, 2)
|
||||||
|
result = await provider(3, 4)
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_call_with_context_kwargs():
|
||||||
|
provider = providers.Coroutine(example, arg1=1)
|
||||||
|
result = await provider(arg2=2, arg3=3, arg4=4)
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_call_with_context_args_and_kwargs():
|
||||||
|
provider = providers.Coroutine(example, 1)
|
||||||
|
result = await provider(2, arg3=3, arg4=4)
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_fluent_interface():
|
||||||
|
provider = providers.Coroutine(example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.add_kwargs(arg3=3, arg4=4)
|
||||||
|
result = await provider()
|
||||||
|
assert result == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_args():
|
||||||
|
provider = providers.Coroutine(example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.set_args(3, 4)
|
||||||
|
assert provider.args == (3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_kwargs():
|
||||||
|
provider = providers.Coroutine(example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.set_kwargs(init_arg3=4, init_arg4=5)
|
||||||
|
assert provider.kwargs == dict(init_arg3=4, init_arg4=5)
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_args():
|
||||||
|
provider = providers.Coroutine(example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.clear_args()
|
||||||
|
assert provider.args == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_kwargs():
|
||||||
|
provider = providers.Coroutine(example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.clear_kwargs()
|
||||||
|
assert provider.kwargs == dict()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
|
||||||
|
provider.override(providers.Object((4, 3, 2, 1)))
|
||||||
|
provider.override(providers.Object((1, 2, 3, 4)))
|
||||||
|
|
||||||
|
assert provider() == (1, 2, 3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.provides is provider_copy.provides
|
||||||
|
assert isinstance(provider, providers.Coroutine)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
provider_copy_memo = providers.Coroutine(example)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider, memo={id(provider): provider_copy_memo})
|
||||||
|
|
||||||
|
assert provider_copy is provider_copy_memo
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_args():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
dependent_provider1 = providers.Callable(list)
|
||||||
|
dependent_provider2 = providers.Callable(dict)
|
||||||
|
|
||||||
|
provider.add_args(dependent_provider1, dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.args[0]
|
||||||
|
dependent_provider_copy2 = provider_copy.args[1]
|
||||||
|
|
||||||
|
assert dependent_provider1.provides is dependent_provider_copy1.provides
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.provides is dependent_provider_copy2.provides
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_kwargs():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
dependent_provider1 = providers.Callable(list)
|
||||||
|
dependent_provider2 = providers.Callable(dict)
|
||||||
|
|
||||||
|
provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.kwargs["a1"]
|
||||||
|
dependent_provider_copy2 = provider_copy.kwargs["a2"]
|
||||||
|
|
||||||
|
assert dependent_provider1.provides is dependent_provider_copy1.provides
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.provides is dependent_provider_copy2.provides
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_overridden():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
object_provider = providers.Object(object())
|
||||||
|
|
||||||
|
provider.override(object_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
object_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.provides is provider_copy.provides
|
||||||
|
assert isinstance(provider, providers.Callable)
|
||||||
|
|
||||||
|
assert object_provider is not object_provider_copy
|
||||||
|
assert isinstance(object_provider_copy, providers.Object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.Coroutine(example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"Coroutine({0}) at {1}>".format(repr(example), hex(id(provider)))
|
||||||
|
)
|
|
@ -0,0 +1,26 @@
|
||||||
|
"""DelegatedCoroutine provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
from .common import example
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance():
|
||||||
|
assert isinstance(providers.DelegatedCoroutine(example), providers.Coroutine)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider():
|
||||||
|
assert providers.is_provider(providers.DelegatedCoroutine(example)) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegated_provider():
|
||||||
|
provider = providers.DelegatedCoroutine(example)
|
||||||
|
assert providers.is_delegated(provider) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.DelegatedCoroutine(example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"DelegatedCoroutine({0}) at {1}>".format(repr(example), hex(id(provider)))
|
||||||
|
)
|
1
tests/unit/providers/factories/__init__.py
Normal file
1
tests/unit/providers/factories/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Tests for factories."""
|
20
tests/unit/providers/factories/common.py
Normal file
20
tests/unit/providers/factories/common.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
"""Common test artifacts."""
|
||||||
|
|
||||||
|
|
||||||
|
class Example:
|
||||||
|
def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None, init_arg4=None):
|
||||||
|
self.init_arg1 = init_arg1
|
||||||
|
self.init_arg2 = init_arg2
|
||||||
|
self.init_arg3 = init_arg3
|
||||||
|
self.init_arg4 = init_arg4
|
||||||
|
|
||||||
|
self.attribute1 = None
|
||||||
|
self.attribute2 = None
|
||||||
|
|
||||||
|
|
||||||
|
class ExampleA(Example):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class ExampleB(Example):
|
||||||
|
pass
|
|
@ -0,0 +1,48 @@
|
||||||
|
"""AbstractFactory provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from .common import Example
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance():
|
||||||
|
assert isinstance(providers.AbstractFactory(Example), providers.Factory)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden_by_factory():
|
||||||
|
provider = providers.AbstractFactory(object)
|
||||||
|
provider.override(providers.Factory(Example))
|
||||||
|
assert isinstance(provider(), Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden_by_delegated_factory():
|
||||||
|
provider = providers.AbstractFactory(object)
|
||||||
|
provider.override(providers.DelegatedFactory(Example))
|
||||||
|
assert isinstance(provider(), Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_not_overridden():
|
||||||
|
provider = providers.AbstractFactory(object)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_by_not_factory():
|
||||||
|
provider = providers.AbstractFactory(object)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider.override(providers.Callable(object))
|
||||||
|
|
||||||
|
|
||||||
|
def test_provide_not_implemented():
|
||||||
|
provider = providers.AbstractFactory(Example)
|
||||||
|
with raises(NotImplementedError):
|
||||||
|
provider._provide(tuple(), dict())
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.AbstractFactory(Example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"AbstractFactory({0}) at {1}>".format(repr(Example), hex(id(provider)))
|
||||||
|
)
|
|
@ -0,0 +1,25 @@
|
||||||
|
"""DelegatedFactory provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
from .common import Example
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance():
|
||||||
|
assert isinstance(providers.DelegatedFactory(object), providers.Factory)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider():
|
||||||
|
assert providers.is_provider(providers.DelegatedFactory(object)) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegated_provider():
|
||||||
|
assert providers.is_delegated(providers.DelegatedFactory(object)) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.DelegatedFactory(Example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"DelegatedFactory({0}) at {1}>".format(repr(Example), hex(id(provider)))
|
||||||
|
)
|
229
tests/unit/providers/factories/test_factory_aggregate_py2_py3.py
Normal file
229
tests/unit/providers/factories/test_factory_aggregate_py2_py3.py
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
"""FactoryAggregate provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import fixture, mark, raises
|
||||||
|
|
||||||
|
from .common import ExampleA, ExampleB
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def factory_a():
|
||||||
|
return providers.Factory(ExampleA)
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def factory_b():
|
||||||
|
return providers.Factory(ExampleB)
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def factory_type():
|
||||||
|
return "default"
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def factory_aggregate(factory_type, factory_a, factory_b):
|
||||||
|
if factory_type == "empty":
|
||||||
|
return providers.FactoryAggregate()
|
||||||
|
elif factory_type == "non-string-keys":
|
||||||
|
return providers.FactoryAggregate({
|
||||||
|
ExampleA: factory_a,
|
||||||
|
ExampleB: factory_b,
|
||||||
|
})
|
||||||
|
elif factory_type == "default":
|
||||||
|
return providers.FactoryAggregate(
|
||||||
|
example_a=factory_a,
|
||||||
|
example_b=factory_b,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknown factory type \"{0}\"".format(factory_type))
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider(factory_aggregate):
|
||||||
|
assert providers.is_provider(factory_aggregate) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegated_provider(factory_aggregate):
|
||||||
|
assert providers.is_delegated(factory_aggregate) is True
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("factory_type", ["non-string-keys"])
|
||||||
|
def test_init_with_non_string_keys(factory_aggregate, factory_a, factory_b):
|
||||||
|
object_a = factory_aggregate(ExampleA, 1, 2, init_arg3=3, init_arg4=4)
|
||||||
|
object_b = factory_aggregate(ExampleB, 11, 22, init_arg3=33, init_arg4=44)
|
||||||
|
|
||||||
|
assert isinstance(object_a, ExampleA)
|
||||||
|
assert object_a.init_arg1 == 1
|
||||||
|
assert object_a.init_arg2 == 2
|
||||||
|
assert object_a.init_arg3 == 3
|
||||||
|
assert object_a.init_arg4 == 4
|
||||||
|
|
||||||
|
assert isinstance(object_b, ExampleB)
|
||||||
|
assert object_b.init_arg1 == 11
|
||||||
|
assert object_b.init_arg2 == 22
|
||||||
|
assert object_b.init_arg3 == 33
|
||||||
|
assert object_b.init_arg4 == 44
|
||||||
|
|
||||||
|
assert factory_aggregate.factories == {
|
||||||
|
ExampleA: factory_a,
|
||||||
|
ExampleB: factory_b,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_a_factory():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.FactoryAggregate(
|
||||||
|
example_a=providers.Factory(ExampleA),
|
||||||
|
example_b=object(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("factory_type", ["empty"])
|
||||||
|
def test_init_optional_factories(factory_aggregate, factory_a, factory_b):
|
||||||
|
factory_aggregate.set_factories(
|
||||||
|
example_a=factory_a,
|
||||||
|
example_b=factory_b,
|
||||||
|
)
|
||||||
|
assert factory_aggregate.factories == {
|
||||||
|
"example_a": factory_a,
|
||||||
|
"example_b": factory_b,
|
||||||
|
}
|
||||||
|
assert isinstance(factory_aggregate("example_a"), ExampleA)
|
||||||
|
assert isinstance(factory_aggregate("example_b"), ExampleB)
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("factory_type", ["non-string-keys"])
|
||||||
|
def test_set_factories_with_non_string_keys(factory_aggregate, factory_a, factory_b):
|
||||||
|
factory_aggregate.set_factories({
|
||||||
|
ExampleA: factory_a,
|
||||||
|
ExampleB: factory_b,
|
||||||
|
})
|
||||||
|
|
||||||
|
object_a = factory_aggregate(ExampleA, 1, 2, init_arg3=3, init_arg4=4)
|
||||||
|
object_b = factory_aggregate(ExampleB, 11, 22, init_arg3=33, init_arg4=44)
|
||||||
|
|
||||||
|
assert isinstance(object_a, ExampleA)
|
||||||
|
assert object_a.init_arg1 == 1
|
||||||
|
assert object_a.init_arg2 == 2
|
||||||
|
assert object_a.init_arg3 == 3
|
||||||
|
assert object_a.init_arg4 == 4
|
||||||
|
|
||||||
|
assert isinstance(object_b, ExampleB)
|
||||||
|
assert object_b.init_arg1 == 11
|
||||||
|
assert object_b.init_arg2 == 22
|
||||||
|
assert object_b.init_arg3 == 33
|
||||||
|
assert object_b.init_arg4 == 44
|
||||||
|
|
||||||
|
assert factory_aggregate.factories == {
|
||||||
|
ExampleA: factory_a,
|
||||||
|
ExampleB: factory_b,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_factories_returns_self(factory_aggregate, factory_a):
|
||||||
|
assert factory_aggregate.set_factories(example_a=factory_a) is factory_aggregate
|
||||||
|
|
||||||
|
|
||||||
|
def test_call(factory_aggregate):
|
||||||
|
object_a = factory_aggregate("example_a", 1, 2, init_arg3=3, init_arg4=4)
|
||||||
|
object_b = factory_aggregate("example_b", 11, 22, init_arg3=33, init_arg4=44)
|
||||||
|
|
||||||
|
assert isinstance(object_a, ExampleA)
|
||||||
|
assert object_a.init_arg1 == 1
|
||||||
|
assert object_a.init_arg2 == 2
|
||||||
|
assert object_a.init_arg3 == 3
|
||||||
|
assert object_a.init_arg4 == 4
|
||||||
|
|
||||||
|
assert isinstance(object_b, ExampleB)
|
||||||
|
assert object_b.init_arg1 == 11
|
||||||
|
assert object_b.init_arg2 == 22
|
||||||
|
assert object_b.init_arg3 == 33
|
||||||
|
assert object_b.init_arg4 == 44
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_factory_name_as_kwarg(factory_aggregate):
|
||||||
|
object_a = factory_aggregate(
|
||||||
|
factory_name="example_a",
|
||||||
|
init_arg1=1,
|
||||||
|
init_arg2=2,
|
||||||
|
init_arg3=3,
|
||||||
|
init_arg4=4,
|
||||||
|
)
|
||||||
|
assert isinstance(object_a, ExampleA)
|
||||||
|
assert object_a.init_arg1 == 1
|
||||||
|
assert object_a.init_arg2 == 2
|
||||||
|
assert object_a.init_arg3 == 3
|
||||||
|
assert object_a.init_arg4 == 4
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_no_factory_name(factory_aggregate):
|
||||||
|
with raises(TypeError):
|
||||||
|
factory_aggregate()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_no_such_provider(factory_aggregate):
|
||||||
|
with raises(errors.NoSuchProviderError):
|
||||||
|
factory_aggregate("unknown")
|
||||||
|
|
||||||
|
|
||||||
|
def test_overridden(factory_aggregate):
|
||||||
|
with raises(errors.Error):
|
||||||
|
factory_aggregate.override(providers.Object(object()))
|
||||||
|
|
||||||
|
|
||||||
|
def test_getattr(factory_aggregate, factory_a, factory_b):
|
||||||
|
assert factory_aggregate.example_a is factory_a
|
||||||
|
assert factory_aggregate.example_b is factory_b
|
||||||
|
|
||||||
|
|
||||||
|
def test_getattr_no_such_provider(factory_aggregate):
|
||||||
|
with raises(errors.NoSuchProviderError):
|
||||||
|
factory_aggregate.unknown
|
||||||
|
|
||||||
|
|
||||||
|
def test_factories(factory_aggregate, factory_a, factory_b):
|
||||||
|
assert factory_aggregate.factories == dict(
|
||||||
|
example_a=factory_a,
|
||||||
|
example_b=factory_b,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy(factory_aggregate):
|
||||||
|
provider_copy = providers.deepcopy(factory_aggregate)
|
||||||
|
|
||||||
|
assert factory_aggregate is not provider_copy
|
||||||
|
assert isinstance(provider_copy, type(factory_aggregate))
|
||||||
|
|
||||||
|
assert factory_aggregate.example_a is not provider_copy.example_a
|
||||||
|
assert isinstance(factory_aggregate.example_a, type(provider_copy.example_a))
|
||||||
|
assert factory_aggregate.example_a.cls is provider_copy.example_a.cls
|
||||||
|
|
||||||
|
assert factory_aggregate.example_b is not provider_copy.example_b
|
||||||
|
assert isinstance(factory_aggregate.example_b, type(provider_copy.example_b))
|
||||||
|
assert factory_aggregate.example_b.cls is provider_copy.example_b.cls
|
||||||
|
|
||||||
|
|
||||||
|
@mark.parametrize("factory_type", ["non-string-keys"])
|
||||||
|
def test_deepcopy_with_non_string_keys(factory_aggregate):
|
||||||
|
provider_copy = providers.deepcopy(factory_aggregate)
|
||||||
|
|
||||||
|
assert factory_aggregate is not provider_copy
|
||||||
|
assert isinstance(provider_copy, type(factory_aggregate))
|
||||||
|
|
||||||
|
assert factory_aggregate.factories[ExampleA] is not provider_copy.factories[ExampleA]
|
||||||
|
assert isinstance(factory_aggregate.factories[ExampleA], type(provider_copy.factories[ExampleA]))
|
||||||
|
assert factory_aggregate.factories[ExampleA].cls is provider_copy.factories[ExampleA].cls
|
||||||
|
|
||||||
|
assert factory_aggregate.factories[ExampleB] is not provider_copy.factories[ExampleB]
|
||||||
|
assert isinstance(factory_aggregate.factories[ExampleB], type(provider_copy.factories[ExampleB]))
|
||||||
|
assert factory_aggregate.factories[ExampleB].cls is provider_copy.factories[ExampleB].cls
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr(factory_aggregate):
|
||||||
|
assert repr(factory_aggregate) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"FactoryAggregate({0}) at {1}>".format(
|
||||||
|
repr(factory_aggregate.factories),
|
||||||
|
hex(id(factory_aggregate)),
|
||||||
|
)
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
"""Factory delegate provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def factory():
|
||||||
|
return providers.Factory(object)
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def delegate(factory):
|
||||||
|
return providers.FactoryDelegate(factory)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegate(delegate):
|
||||||
|
assert isinstance(delegate, providers.Delegate)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_factory():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.FactoryDelegate(providers.Object(object()))
|
408
tests/unit/providers/factories/test_factory_py2_py3.py
Normal file
408
tests/unit/providers/factories/test_factory_py2_py3.py
Normal file
|
@ -0,0 +1,408 @@
|
||||||
|
"""Factory provider tests."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from .common import Example
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider():
|
||||||
|
assert providers.is_provider(providers.Factory(Example)) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_callable():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.Factory(123)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_optional_provides():
|
||||||
|
provider = providers.Factory()
|
||||||
|
provider.set_provides(object)
|
||||||
|
assert provider.provides is object
|
||||||
|
assert isinstance(provider(), object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_provides_returns_():
|
||||||
|
provider = providers.Factory()
|
||||||
|
assert provider.set_provides(object) is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_valid_provided_type():
|
||||||
|
class ExampleProvider(providers.Factory):
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
example_provider = ExampleProvider(Example, 1, 2)
|
||||||
|
|
||||||
|
assert isinstance(example_provider(), Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_valid_provided_subtype():
|
||||||
|
class ExampleProvider(providers.Factory):
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
class NewExample(Example):
|
||||||
|
pass
|
||||||
|
|
||||||
|
example_provider = ExampleProvider(NewExample, 1, 2)
|
||||||
|
assert isinstance(example_provider(), NewExample)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_invalid_provided_type():
|
||||||
|
class ExampleProvider(providers.Factory):
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
with raises(errors.Error):
|
||||||
|
ExampleProvider(list)
|
||||||
|
|
||||||
|
|
||||||
|
def test_provided_instance_provider():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
assert isinstance(provider.provided, providers.ProvidedInstance)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1 is not instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_init_positional_args():
|
||||||
|
provider = providers.Factory(Example, "i1", "i2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.init_arg1 == "i1"
|
||||||
|
assert instance1.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance2.init_arg1 == "i1"
|
||||||
|
assert instance2.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance1 is not instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_init_keyword_args():
|
||||||
|
provider = providers.Factory(Example, init_arg1="i1", init_arg2="i2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.init_arg1 == "i1"
|
||||||
|
assert instance1.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance2.init_arg1 == "i1"
|
||||||
|
assert instance2.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance1 is not instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_init_positional_and_keyword_args():
|
||||||
|
provider = providers.Factory(Example, "i1", init_arg2="i2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.init_arg1 == "i1"
|
||||||
|
assert instance1.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance2.init_arg1 == "i1"
|
||||||
|
assert instance2.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance1 is not instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_attributes():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
provider.add_attributes(attribute1="a1", attribute2="a2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.attribute1 == "a1"
|
||||||
|
assert instance1.attribute2 == "a2"
|
||||||
|
|
||||||
|
assert instance2.attribute1 == "a1"
|
||||||
|
assert instance2.attribute2 == "a2"
|
||||||
|
|
||||||
|
assert instance1 is not instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_args():
|
||||||
|
provider = providers.Factory(Example, 11, 22)
|
||||||
|
|
||||||
|
instance = provider(33, 44)
|
||||||
|
|
||||||
|
assert instance.init_arg1 == 11
|
||||||
|
assert instance.init_arg2 == 22
|
||||||
|
assert instance.init_arg3 == 33
|
||||||
|
assert instance.init_arg4 == 44
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_kwargs():
|
||||||
|
provider = providers.Factory(Example, init_arg1=1)
|
||||||
|
|
||||||
|
instance1 = provider(init_arg2=22)
|
||||||
|
assert instance1.init_arg1 == 1
|
||||||
|
assert instance1.init_arg2 == 22
|
||||||
|
|
||||||
|
instance2 = provider(init_arg1=11, init_arg2=22)
|
||||||
|
assert instance2.init_arg1 == 11
|
||||||
|
assert instance2.init_arg2 == 22
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_args_and_kwargs():
|
||||||
|
provider = providers.Factory(Example, 11)
|
||||||
|
|
||||||
|
instance = provider(22, init_arg3=33, init_arg4=44)
|
||||||
|
|
||||||
|
assert instance.init_arg1 == 11
|
||||||
|
assert instance.init_arg2 == 22
|
||||||
|
assert instance.init_arg3 == 33
|
||||||
|
assert instance.init_arg4 == 44
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_deep_context_kwargs():
|
||||||
|
class Regularizer:
|
||||||
|
def __init__(self, alpha):
|
||||||
|
self.alpha = alpha
|
||||||
|
|
||||||
|
class Loss:
|
||||||
|
def __init__(self, regularizer):
|
||||||
|
self.regularizer = regularizer
|
||||||
|
|
||||||
|
class ClassificationTask:
|
||||||
|
def __init__(self, loss):
|
||||||
|
self.loss = loss
|
||||||
|
|
||||||
|
class Algorithm:
|
||||||
|
def __init__(self, task):
|
||||||
|
self.task = task
|
||||||
|
|
||||||
|
algorithm_factory = providers.Factory(
|
||||||
|
Algorithm,
|
||||||
|
task=providers.Factory(
|
||||||
|
ClassificationTask,
|
||||||
|
loss=providers.Factory(
|
||||||
|
Loss,
|
||||||
|
regularizer=providers.Factory(
|
||||||
|
Regularizer,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
algorithm_1 = algorithm_factory(task__loss__regularizer__alpha=0.5)
|
||||||
|
algorithm_2 = algorithm_factory(task__loss__regularizer__alpha=0.7)
|
||||||
|
algorithm_3 = algorithm_factory(task__loss__regularizer=Regularizer(alpha=0.8))
|
||||||
|
|
||||||
|
assert algorithm_1.task.loss.regularizer.alpha == 0.5
|
||||||
|
assert algorithm_2.task.loss.regularizer.alpha == 0.7
|
||||||
|
assert algorithm_3.task.loss.regularizer.alpha == 0.8
|
||||||
|
|
||||||
|
|
||||||
|
def test_fluent_interface():
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.add_attributes(attribute1=5, attribute2=6)
|
||||||
|
|
||||||
|
instance = provider()
|
||||||
|
|
||||||
|
assert instance.init_arg1 == 1
|
||||||
|
assert instance.init_arg2 == 2
|
||||||
|
assert instance.init_arg3 == 3
|
||||||
|
assert instance.init_arg4 == 4
|
||||||
|
assert instance.attribute1 == 5
|
||||||
|
assert instance.attribute2 == 6
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_args():
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.set_args(3, 4)
|
||||||
|
assert provider.args == (3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_kwargs():
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.set_kwargs(init_arg3=4, init_arg4=5)
|
||||||
|
assert provider.kwargs == dict(init_arg3=4, init_arg4=5)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_attributes():
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
|
.add_attributes(attribute1=5, attribute2=6) \
|
||||||
|
.set_attributes(attribute1=6, attribute2=7)
|
||||||
|
assert provider.attributes == dict(attribute1=6, attribute2=7)
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_args():
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.clear_args()
|
||||||
|
assert provider.args == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_kwargs():
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.clear_kwargs()
|
||||||
|
assert provider.kwargs == dict()
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_attributes():
|
||||||
|
provider = providers.Factory(Example) \
|
||||||
|
.add_attributes(attribute1=5, attribute2=6) \
|
||||||
|
.clear_attributes()
|
||||||
|
assert provider.attributes == dict()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
overriding_provider1 = providers.Factory(dict)
|
||||||
|
overriding_provider2 = providers.Factory(list)
|
||||||
|
|
||||||
|
provider.override(overriding_provider1)
|
||||||
|
provider.override(overriding_provider2)
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1 is not instance2
|
||||||
|
assert isinstance(instance1, list)
|
||||||
|
assert isinstance(instance2, list)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.cls is provider_copy.cls
|
||||||
|
assert isinstance(provider, providers.Factory)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
provider_copy_memo = providers.Factory(Example)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider, memo={id(provider): provider_copy_memo})
|
||||||
|
|
||||||
|
assert provider_copy is provider_copy_memo
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_args():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
dependent_provider1 = providers.Factory(list)
|
||||||
|
dependent_provider2 = providers.Factory(dict)
|
||||||
|
|
||||||
|
provider.add_args(dependent_provider1, dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.args[0]
|
||||||
|
dependent_provider_copy2 = provider_copy.args[1]
|
||||||
|
|
||||||
|
assert provider.args != provider_copy.args
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_kwargs():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
dependent_provider1 = providers.Factory(list)
|
||||||
|
dependent_provider2 = providers.Factory(dict)
|
||||||
|
|
||||||
|
provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.kwargs["a1"]
|
||||||
|
dependent_provider_copy2 = provider_copy.kwargs["a2"]
|
||||||
|
|
||||||
|
assert provider.kwargs != provider_copy.kwargs
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_attributes():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
dependent_provider1 = providers.Factory(list)
|
||||||
|
dependent_provider2 = providers.Factory(dict)
|
||||||
|
|
||||||
|
provider.add_attributes(a1=dependent_provider1, a2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.attributes["a1"]
|
||||||
|
dependent_provider_copy2 = provider_copy.attributes["a2"]
|
||||||
|
|
||||||
|
assert provider.attributes != provider_copy.attributes
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_overridden():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
object_provider = providers.Object(object())
|
||||||
|
|
||||||
|
provider.override(object_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
object_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.cls is provider_copy.cls
|
||||||
|
assert isinstance(provider, providers.Factory)
|
||||||
|
|
||||||
|
assert object_provider is not object_provider_copy
|
||||||
|
assert isinstance(object_provider_copy, providers.Object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_with_sys_streams():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
provider.add_args(sys.stdin)
|
||||||
|
provider.add_kwargs(a2=sys.stdout)
|
||||||
|
provider.add_attributes(a3=sys.stderr)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert isinstance(provider_copy, providers.Factory)
|
||||||
|
assert provider.args[0] is sys.stdin
|
||||||
|
assert provider.kwargs["a2"] is sys.stdout
|
||||||
|
assert provider.attributes["a3"] is sys.stderr
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.Factory(Example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"Factory({0}) at {1}>".format(repr(Example), hex(id(provider)))
|
||||||
|
)
|
1
tests/unit/providers/injections/__init__.py
Normal file
1
tests/unit/providers/injections/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Tests for injection objects."""
|
55
tests/unit/providers/injections/test_named_py2_py3.py
Normal file
55
tests/unit/providers/injections/test_named_py2_py3.py
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
"""Named injection tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
|
||||||
|
def test_isinstance():
|
||||||
|
injection = providers.NamedInjection("name", 1)
|
||||||
|
assert isinstance(injection, providers.Injection)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_name():
|
||||||
|
injection = providers.NamedInjection("name", 123)
|
||||||
|
assert injection.get_name() == "name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_value_with_not_provider():
|
||||||
|
injection = providers.NamedInjection("name", 123)
|
||||||
|
assert injection.get_value() == 123
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_value_with_factory():
|
||||||
|
injection = providers.NamedInjection("name", providers.Factory(object))
|
||||||
|
|
||||||
|
obj1 = injection.get_value()
|
||||||
|
obj2 = injection.get_value()
|
||||||
|
|
||||||
|
assert type(obj1) is object
|
||||||
|
assert type(obj2) is object
|
||||||
|
assert obj1 is not obj2
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_original_value():
|
||||||
|
provider = providers.Factory(object)
|
||||||
|
injection = providers.NamedInjection("name", provider)
|
||||||
|
assert injection.get_original_value() is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy():
|
||||||
|
provider = providers.Factory(object)
|
||||||
|
injection = providers.NamedInjection("name", provider)
|
||||||
|
|
||||||
|
injection_copy = providers.deepcopy(injection)
|
||||||
|
|
||||||
|
assert injection_copy is not injection
|
||||||
|
assert injection_copy.get_original_value() is not injection.get_original_value()
|
||||||
|
|
||||||
|
def test_deepcopy_memo():
|
||||||
|
provider = providers.Factory(object)
|
||||||
|
injection = providers.NamedInjection("name", provider)
|
||||||
|
injection_copy_orig = providers.NamedInjection("name", provider)
|
||||||
|
|
||||||
|
injection_copy = providers.deepcopy(injection, {id(injection): injection_copy_orig})
|
||||||
|
|
||||||
|
assert injection_copy is injection_copy_orig
|
||||||
|
assert injection_copy.get_original_value() is injection.get_original_value()
|
51
tests/unit/providers/injections/test_positional_py2_py3.py
Normal file
51
tests/unit/providers/injections/test_positional_py2_py3.py
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
"""Positional injection tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
|
||||||
|
|
||||||
|
def test_isinstance():
|
||||||
|
injection = providers.PositionalInjection(1)
|
||||||
|
assert isinstance(injection, providers.Injection)
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_value_with_not_provider():
|
||||||
|
injection = providers.PositionalInjection(123)
|
||||||
|
assert injection.get_value() == 123
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_value_with_factory():
|
||||||
|
injection = providers.PositionalInjection(providers.Factory(object))
|
||||||
|
|
||||||
|
obj1 = injection.get_value()
|
||||||
|
obj2 = injection.get_value()
|
||||||
|
|
||||||
|
assert type(obj1) is object
|
||||||
|
assert type(obj2) is object
|
||||||
|
assert obj1 is not obj2
|
||||||
|
|
||||||
|
|
||||||
|
def test_get_original_value():
|
||||||
|
provider = providers.Factory(object)
|
||||||
|
injection = providers.PositionalInjection(provider)
|
||||||
|
assert injection.get_original_value() is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy():
|
||||||
|
provider = providers.Factory(object)
|
||||||
|
injection = providers.PositionalInjection(provider)
|
||||||
|
|
||||||
|
injection_copy = providers.deepcopy(injection)
|
||||||
|
|
||||||
|
assert injection_copy is not injection
|
||||||
|
assert injection_copy.get_original_value() is not injection.get_original_value()
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_memo():
|
||||||
|
provider = providers.Factory(object)
|
||||||
|
injection = providers.PositionalInjection(provider)
|
||||||
|
injection_copy_orig = providers.PositionalInjection(provider)
|
||||||
|
|
||||||
|
injection_copy = providers.deepcopy(injection, {id(injection): injection_copy_orig})
|
||||||
|
|
||||||
|
assert injection_copy is injection_copy_orig
|
||||||
|
assert injection_copy.get_original_value() is injection.get_original_value()
|
1
tests/unit/providers/resource/__init__.py
Normal file
1
tests/unit/providers/resource/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Resource provider tests."""
|
308
tests/unit/providers/resource/test_async_resource_py35.py
Normal file
308
tests/unit/providers/resource/test_async_resource_py35.py
Normal file
|
@ -0,0 +1,308 @@
|
||||||
|
"""Resource provider async tests."""
|
||||||
|
|
||||||
|
import asyncio
|
||||||
|
import inspect
|
||||||
|
import sys
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, resources
|
||||||
|
from pytest import mark, raises
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_async_function():
|
||||||
|
resource = object()
|
||||||
|
|
||||||
|
async def _init():
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
_init.counter += 1
|
||||||
|
return resource
|
||||||
|
|
||||||
|
_init.counter = 0
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
result1 = await provider()
|
||||||
|
assert result1 is resource
|
||||||
|
assert _init.counter == 1
|
||||||
|
|
||||||
|
result2 = await provider()
|
||||||
|
assert result2 is resource
|
||||||
|
assert _init.counter == 1
|
||||||
|
|
||||||
|
await provider.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
@mark.skipif(sys.version_info < (3, 6), reason="requires Python 3.6+")
|
||||||
|
async def test_init_async_generator():
|
||||||
|
resource = object()
|
||||||
|
|
||||||
|
async def _init():
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
_init.init_counter += 1
|
||||||
|
|
||||||
|
yield resource
|
||||||
|
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
_init.shutdown_counter += 1
|
||||||
|
|
||||||
|
_init.init_counter = 0
|
||||||
|
_init.shutdown_counter = 0
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
result1 = await provider()
|
||||||
|
assert result1 is resource
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 0
|
||||||
|
|
||||||
|
await provider.shutdown()
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
result2 = await provider()
|
||||||
|
assert result2 is resource
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
await provider.shutdown()
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 2
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_async_class():
|
||||||
|
resource = object()
|
||||||
|
|
||||||
|
class TestResource(resources.AsyncResource):
|
||||||
|
init_counter = 0
|
||||||
|
shutdown_counter = 0
|
||||||
|
|
||||||
|
async def init(self):
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
self.__class__.init_counter += 1
|
||||||
|
return resource
|
||||||
|
|
||||||
|
async def shutdown(self, resource_):
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
self.__class__.shutdown_counter += 1
|
||||||
|
assert resource_ is resource
|
||||||
|
|
||||||
|
provider = providers.Resource(TestResource)
|
||||||
|
|
||||||
|
result1 = await provider()
|
||||||
|
assert result1 is resource
|
||||||
|
assert TestResource.init_counter == 1
|
||||||
|
assert TestResource.shutdown_counter == 0
|
||||||
|
|
||||||
|
await provider.shutdown()
|
||||||
|
assert TestResource.init_counter == 1
|
||||||
|
assert TestResource.shutdown_counter == 1
|
||||||
|
|
||||||
|
result2 = await provider()
|
||||||
|
assert result2 is resource
|
||||||
|
assert TestResource.init_counter == 2
|
||||||
|
assert TestResource.shutdown_counter == 1
|
||||||
|
|
||||||
|
await provider.shutdown()
|
||||||
|
assert TestResource.init_counter == 2
|
||||||
|
assert TestResource.shutdown_counter == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_async_class_generic_typing():
|
||||||
|
# See issue: https://github.com/ets-labs/python-dependency-injector/issues/488
|
||||||
|
class TestDependency:
|
||||||
|
...
|
||||||
|
|
||||||
|
class TestAsyncResource(resources.AsyncResource[TestDependency]):
|
||||||
|
async def init(self, *args: Any, **kwargs: Any) -> TestDependency:
|
||||||
|
return TestDependency()
|
||||||
|
|
||||||
|
async def shutdown(self, resource: TestDependency) -> None: ...
|
||||||
|
|
||||||
|
assert issubclass(TestAsyncResource, resources.AsyncResource) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_async_class_abc_init_definition_is_required():
|
||||||
|
class TestAsyncResource(resources.AsyncResource):
|
||||||
|
...
|
||||||
|
|
||||||
|
with raises(TypeError) as context:
|
||||||
|
TestAsyncResource()
|
||||||
|
|
||||||
|
assert "Can't instantiate abstract class TestAsyncResource" in str(context.value)
|
||||||
|
assert "init" in str(context.value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_async_class_abc_shutdown_definition_is_not_required():
|
||||||
|
class TestAsyncResource(resources.AsyncResource):
|
||||||
|
async def init(self):
|
||||||
|
...
|
||||||
|
|
||||||
|
assert hasattr(TestAsyncResource(), "shutdown") is True
|
||||||
|
assert inspect.iscoroutinefunction(TestAsyncResource.shutdown) is True
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_with_error():
|
||||||
|
async def _init():
|
||||||
|
raise RuntimeError()
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
future = provider()
|
||||||
|
assert provider.initialized is True
|
||||||
|
assert provider.is_async_mode_enabled() is True
|
||||||
|
|
||||||
|
with raises(RuntimeError):
|
||||||
|
await future
|
||||||
|
|
||||||
|
assert provider.initialized is False
|
||||||
|
assert provider.is_async_mode_enabled() is True
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_async_gen_with_error():
|
||||||
|
async def _init():
|
||||||
|
raise RuntimeError()
|
||||||
|
yield
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
future = provider()
|
||||||
|
assert provider.initialized is True
|
||||||
|
assert provider.is_async_mode_enabled() is True
|
||||||
|
|
||||||
|
with raises(RuntimeError):
|
||||||
|
await future
|
||||||
|
|
||||||
|
assert provider.initialized is False
|
||||||
|
assert provider.is_async_mode_enabled() is True
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_async_subclass_with_error():
|
||||||
|
class _Resource(resources.AsyncResource):
|
||||||
|
async def init(self):
|
||||||
|
raise RuntimeError()
|
||||||
|
|
||||||
|
async def shutdown(self, resource):
|
||||||
|
pass
|
||||||
|
|
||||||
|
provider = providers.Resource(_Resource)
|
||||||
|
|
||||||
|
future = provider()
|
||||||
|
assert provider.initialized is True
|
||||||
|
assert provider.is_async_mode_enabled() is True
|
||||||
|
|
||||||
|
with raises(RuntimeError):
|
||||||
|
await future
|
||||||
|
|
||||||
|
assert provider.initialized is False
|
||||||
|
assert provider.is_async_mode_enabled() is True
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_with_dependency_to_other_resource():
|
||||||
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/361
|
||||||
|
async def init_db_connection(db_url: str):
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
yield {"connection": "OK", "url": db_url}
|
||||||
|
|
||||||
|
async def init_user_session(db):
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
yield {"session": "OK", "db": db}
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
config = providers.Configuration()
|
||||||
|
|
||||||
|
db_connection = providers.Resource(
|
||||||
|
init_db_connection,
|
||||||
|
db_url=config.db_url,
|
||||||
|
)
|
||||||
|
|
||||||
|
user_session = providers.Resource(
|
||||||
|
init_user_session,
|
||||||
|
db=db_connection
|
||||||
|
)
|
||||||
|
|
||||||
|
async def main():
|
||||||
|
container = Container(config={"db_url": "postgres://..."})
|
||||||
|
try:
|
||||||
|
return await container.user_session()
|
||||||
|
finally:
|
||||||
|
await container.shutdown_resources()
|
||||||
|
|
||||||
|
result = await main()
|
||||||
|
assert result == {"session": "OK", "db": {"connection": "OK", "url": "postgres://..."}}
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_init_and_shutdown_methods():
|
||||||
|
async def _init():
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
_init.init_counter += 1
|
||||||
|
|
||||||
|
yield
|
||||||
|
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
_init.shutdown_counter += 1
|
||||||
|
|
||||||
|
_init.init_counter = 0
|
||||||
|
_init.shutdown_counter = 0
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
await provider.init()
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 0
|
||||||
|
|
||||||
|
await provider.shutdown()
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
await provider.init()
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
await provider.shutdown()
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 2
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_shutdown_of_not_initialized():
|
||||||
|
async def _init():
|
||||||
|
yield
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
provider.enable_async_mode()
|
||||||
|
|
||||||
|
result = await provider.shutdown()
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
|
||||||
|
@mark.asyncio
|
||||||
|
async def test_concurrent_init():
|
||||||
|
resource = object()
|
||||||
|
|
||||||
|
async def _init():
|
||||||
|
await asyncio.sleep(0.001)
|
||||||
|
_init.counter += 1
|
||||||
|
return resource
|
||||||
|
|
||||||
|
_init.counter = 0
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
result1, result2 = await asyncio.gather(
|
||||||
|
provider(),
|
||||||
|
provider()
|
||||||
|
)
|
||||||
|
|
||||||
|
assert result1 is resource
|
||||||
|
assert _init.counter == 1
|
||||||
|
|
||||||
|
assert result2 is resource
|
||||||
|
assert _init.counter == 1
|
398
tests/unit/providers/resource/test_resource_py35.py
Normal file
398
tests/unit/providers/resource/test_resource_py35.py
Normal file
|
@ -0,0 +1,398 @@
|
||||||
|
"""Resource provider tests."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, resources, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
|
||||||
|
def init_fn(*args, **kwargs):
|
||||||
|
return args, kwargs
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider():
|
||||||
|
assert providers.is_provider(providers.Resource(init_fn)) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_optional_provides():
|
||||||
|
provider = providers.Resource()
|
||||||
|
provider.set_provides(init_fn)
|
||||||
|
assert provider.provides is init_fn
|
||||||
|
assert provider() == (tuple(), dict())
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_provides_returns_():
|
||||||
|
provider = providers.Resource()
|
||||||
|
assert provider.set_provides(init_fn) is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_provided_instance_provider():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
assert isinstance(provider.provided, providers.ProvidedInstance)
|
||||||
|
|
||||||
|
|
||||||
|
def test_injection():
|
||||||
|
resource = object()
|
||||||
|
|
||||||
|
def _init():
|
||||||
|
_init.counter += 1
|
||||||
|
return resource
|
||||||
|
|
||||||
|
_init.counter = 0
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
resource = providers.Resource(_init)
|
||||||
|
dependency1 = providers.List(resource)
|
||||||
|
dependency2 = providers.List(resource)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
list1 = container.dependency1()
|
||||||
|
list2 = container.dependency2()
|
||||||
|
|
||||||
|
assert list1 == [resource]
|
||||||
|
assert list1[0] is resource
|
||||||
|
|
||||||
|
assert list2 == [resource]
|
||||||
|
assert list2[0] is resource
|
||||||
|
|
||||||
|
assert _init.counter == 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_function():
|
||||||
|
def _init():
|
||||||
|
_init.counter += 1
|
||||||
|
|
||||||
|
_init.counter = 0
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
result1 = provider()
|
||||||
|
assert result1 is None
|
||||||
|
assert _init.counter == 1
|
||||||
|
|
||||||
|
result2 = provider()
|
||||||
|
assert result2 is None
|
||||||
|
assert _init.counter == 1
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_generator():
|
||||||
|
def _init():
|
||||||
|
_init.init_counter += 1
|
||||||
|
yield
|
||||||
|
_init.shutdown_counter += 1
|
||||||
|
|
||||||
|
_init.init_counter = 0
|
||||||
|
_init.shutdown_counter = 0
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
result1 = provider()
|
||||||
|
assert result1 is None
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 0
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
result2 = provider()
|
||||||
|
assert result2 is None
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_class():
|
||||||
|
class TestResource(resources.Resource):
|
||||||
|
init_counter = 0
|
||||||
|
shutdown_counter = 0
|
||||||
|
|
||||||
|
def init(self):
|
||||||
|
self.__class__.init_counter += 1
|
||||||
|
|
||||||
|
def shutdown(self, _):
|
||||||
|
self.__class__.shutdown_counter += 1
|
||||||
|
|
||||||
|
provider = providers.Resource(TestResource)
|
||||||
|
|
||||||
|
result1 = provider()
|
||||||
|
assert result1 is None
|
||||||
|
assert TestResource.init_counter == 1
|
||||||
|
assert TestResource.shutdown_counter == 0
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
assert TestResource.init_counter == 1
|
||||||
|
assert TestResource.shutdown_counter == 1
|
||||||
|
|
||||||
|
result2 = provider()
|
||||||
|
assert result2 is None
|
||||||
|
assert TestResource.init_counter == 2
|
||||||
|
assert TestResource.shutdown_counter == 1
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
assert TestResource.init_counter == 2
|
||||||
|
assert TestResource.shutdown_counter == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_class_generic_typing():
|
||||||
|
# See issue: https://github.com/ets-labs/python-dependency-injector/issues/488
|
||||||
|
class TestDependency:
|
||||||
|
...
|
||||||
|
|
||||||
|
class TestResource(resources.Resource[TestDependency]):
|
||||||
|
def init(self, *args: Any, **kwargs: Any) -> TestDependency:
|
||||||
|
return TestDependency()
|
||||||
|
|
||||||
|
def shutdown(self, resource: TestDependency) -> None: ...
|
||||||
|
|
||||||
|
assert issubclass(TestResource, resources.Resource) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_class_abc_init_definition_is_required():
|
||||||
|
class TestResource(resources.Resource):
|
||||||
|
...
|
||||||
|
|
||||||
|
with raises(TypeError) as context:
|
||||||
|
TestResource()
|
||||||
|
|
||||||
|
assert "Can't instantiate abstract class TestResource" in str(context.value)
|
||||||
|
assert "init" in str(context.value)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_class_abc_shutdown_definition_is_not_required():
|
||||||
|
class TestResource(resources.Resource):
|
||||||
|
def init(self):
|
||||||
|
...
|
||||||
|
|
||||||
|
assert hasattr(TestResource(), "shutdown") is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_not_callable():
|
||||||
|
provider = providers.Resource(1)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider.init()
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_and_shutdown():
|
||||||
|
def _init():
|
||||||
|
_init.init_counter += 1
|
||||||
|
yield
|
||||||
|
_init.shutdown_counter += 1
|
||||||
|
|
||||||
|
_init.init_counter = 0
|
||||||
|
_init.shutdown_counter = 0
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
result1 = provider.init()
|
||||||
|
assert result1 is None
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 0
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
assert _init.init_counter == 1
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
result2 = provider.init()
|
||||||
|
assert result2 is None
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 1
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
assert _init.init_counter == 2
|
||||||
|
assert _init.shutdown_counter == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_shutdown_of_not_initialized():
|
||||||
|
def _init():
|
||||||
|
yield
|
||||||
|
|
||||||
|
provider = providers.Resource(_init)
|
||||||
|
|
||||||
|
result = provider.shutdown()
|
||||||
|
assert result is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_initialized():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
assert provider.initialized is False
|
||||||
|
|
||||||
|
provider.init()
|
||||||
|
assert provider.initialized is True
|
||||||
|
|
||||||
|
provider.shutdown()
|
||||||
|
assert provider.initialized is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_args():
|
||||||
|
provider = providers.Resource(init_fn, "i1", "i2")
|
||||||
|
assert provider("i3", i4=4) == (("i1", "i2", "i3"), {"i4": 4})
|
||||||
|
|
||||||
|
|
||||||
|
def test_fluent_interface():
|
||||||
|
provider = providers.Resource(init_fn) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.add_kwargs(a3=3, a4=4)
|
||||||
|
assert provider() == ((1, 2), {"a3": 3, "a4": 4})
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_args():
|
||||||
|
provider = providers.Resource(init_fn) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.set_args(3, 4)
|
||||||
|
assert provider.args == (3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_args():
|
||||||
|
provider = providers.Resource(init_fn) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.clear_args()
|
||||||
|
assert provider.args == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_kwargs():
|
||||||
|
provider = providers.Resource(init_fn) \
|
||||||
|
.add_kwargs(a1="i1", a2="i2") \
|
||||||
|
.set_kwargs(a3="i3", a4="i4")
|
||||||
|
assert provider.kwargs == {"a3": "i3", "a4": "i4"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_kwargs():
|
||||||
|
provider = providers.Resource(init_fn) \
|
||||||
|
.add_kwargs(a1="i1", a2="i2") \
|
||||||
|
.clear_kwargs()
|
||||||
|
assert provider.kwargs == {}
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden():
|
||||||
|
provider = providers.Resource(init_fn, 1)
|
||||||
|
overriding_provider1 = providers.Resource(init_fn, 2)
|
||||||
|
overriding_provider2 = providers.Resource(init_fn, 3)
|
||||||
|
|
||||||
|
provider.override(overriding_provider1)
|
||||||
|
provider.override(overriding_provider2)
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1 is instance2
|
||||||
|
assert instance1 == ((3,), {})
|
||||||
|
assert instance2 == ((3,), {})
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy():
|
||||||
|
provider = providers.Resource(init_fn, 1, 2, a3=3, a4=4)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.args == provider_copy.args
|
||||||
|
assert provider.kwargs == provider_copy.kwargs
|
||||||
|
assert isinstance(provider, providers.Resource)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_initialized():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
provider.init()
|
||||||
|
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.deepcopy(provider)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
provider_copy_memo = providers.Resource(init_fn)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(
|
||||||
|
provider,
|
||||||
|
memo={id(provider): provider_copy_memo},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert provider_copy is provider_copy_memo
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_args():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
dependent_provider1 = providers.Factory(list)
|
||||||
|
dependent_provider2 = providers.Factory(dict)
|
||||||
|
|
||||||
|
provider.add_args(dependent_provider1, dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.args[0]
|
||||||
|
dependent_provider_copy2 = provider_copy.args[1]
|
||||||
|
|
||||||
|
assert provider.args != provider_copy.args
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_kwargs():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
dependent_provider1 = providers.Factory(list)
|
||||||
|
dependent_provider2 = providers.Factory(dict)
|
||||||
|
|
||||||
|
provider.add_kwargs(d1=dependent_provider1, d2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.kwargs["d1"]
|
||||||
|
dependent_provider_copy2 = provider_copy.kwargs["d2"]
|
||||||
|
|
||||||
|
assert provider.kwargs != provider_copy.kwargs
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_overridden():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
object_provider = providers.Object(object())
|
||||||
|
|
||||||
|
provider.override(object_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
object_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.args == provider_copy.args
|
||||||
|
assert isinstance(provider, providers.Resource)
|
||||||
|
|
||||||
|
assert object_provider is not object_provider_copy
|
||||||
|
assert isinstance(object_provider_copy, providers.Object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_with_sys_streams():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
provider.add_args(sys.stdin, sys.stdout, sys.stderr)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert isinstance(provider_copy, providers.Resource)
|
||||||
|
assert provider.args[0] is sys.stdin
|
||||||
|
assert provider.args[1] is sys.stdout
|
||||||
|
assert provider.args[2] is sys.stderr
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.Resource(init_fn)
|
||||||
|
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers.Resource({0}) at {1}>".format(
|
||||||
|
repr(init_fn),
|
||||||
|
hex(id(provider)),
|
||||||
|
)
|
||||||
|
)
|
1
tests/unit/providers/singleton/__init__.py
Normal file
1
tests/unit/providers/singleton/__init__.py
Normal file
|
@ -0,0 +1 @@
|
||||||
|
"""Singleton provider tests."""
|
13
tests/unit/providers/singleton/common.py
Normal file
13
tests/unit/providers/singleton/common.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
"""Common test artifacts."""
|
||||||
|
|
||||||
|
|
||||||
|
class Example:
|
||||||
|
|
||||||
|
def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None, init_arg4=None):
|
||||||
|
self.init_arg1 = init_arg1
|
||||||
|
self.init_arg2 = init_arg2
|
||||||
|
self.init_arg3 = init_arg3
|
||||||
|
self.init_arg4 = init_arg4
|
||||||
|
|
||||||
|
self.attribute1 = None
|
||||||
|
self.attribute2 = None
|
|
@ -0,0 +1,63 @@
|
||||||
|
"""AbstractSingleton provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
from .common import Example
|
||||||
|
|
||||||
|
|
||||||
|
def test_inheritance():
|
||||||
|
assert isinstance(providers.AbstractSingleton(Example), providers.BaseSingleton)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden_by_singleton():
|
||||||
|
provider = providers.AbstractSingleton(object)
|
||||||
|
provider.override(providers.Singleton(Example))
|
||||||
|
assert isinstance(provider(), Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden_by_delegated_singleton():
|
||||||
|
provider = providers.AbstractSingleton(object)
|
||||||
|
provider.override(providers.DelegatedSingleton(Example))
|
||||||
|
assert isinstance(provider(), Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_not_overridden():
|
||||||
|
provider = providers.AbstractSingleton(object)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_overridden():
|
||||||
|
provider = providers.AbstractSingleton(object)
|
||||||
|
provider.override(providers.Singleton(Example))
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
|
||||||
|
provider.reset()
|
||||||
|
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1 is not instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_not_overridden():
|
||||||
|
provider = providers.AbstractSingleton(object)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider.reset()
|
||||||
|
|
||||||
|
|
||||||
|
def test_override_by_not_singleton():
|
||||||
|
provider = providers.AbstractSingleton(object)
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider.override(providers.Factory(object))
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr():
|
||||||
|
provider = providers.AbstractSingleton(Example)
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"AbstractSingleton({0}) at {1}>".format(repr(Example), hex(id(provider)))
|
||||||
|
)
|
|
@ -0,0 +1,27 @@
|
||||||
|
"""Delegated singleton provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers
|
||||||
|
from pytest import fixture
|
||||||
|
|
||||||
|
from .common import Example
|
||||||
|
|
||||||
|
|
||||||
|
PROVIDER_CLASSES = [
|
||||||
|
providers.DelegatedSingleton,
|
||||||
|
providers.DelegatedThreadLocalSingleton,
|
||||||
|
providers.DelegatedThreadSafeSingleton,
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@fixture(params=PROVIDER_CLASSES)
|
||||||
|
def singleton_cls(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider(singleton_cls):
|
||||||
|
return singleton_cls(Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegated_provider(provider):
|
||||||
|
assert providers.is_delegated(provider) is True
|
|
@ -0,0 +1,23 @@
|
||||||
|
"""SingletonDelegate provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider():
|
||||||
|
return providers.Singleton(object)
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def delegate(provider):
|
||||||
|
return providers.SingletonDelegate(provider)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_delegate(delegate):
|
||||||
|
assert isinstance(delegate, providers.Delegate)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_factory():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.SingletonDelegate(providers.Object(object()))
|
470
tests/unit/providers/singleton/test_singleton_py2_py3.py
Normal file
470
tests/unit/providers/singleton/test_singleton_py2_py3.py
Normal file
|
@ -0,0 +1,470 @@
|
||||||
|
"""Singleton provider tests."""
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
from .common import Example
|
||||||
|
|
||||||
|
|
||||||
|
PROVIDER_CLASSES = [
|
||||||
|
providers.Singleton,
|
||||||
|
providers.DelegatedSingleton,
|
||||||
|
providers.ThreadLocalSingleton,
|
||||||
|
providers.DelegatedThreadLocalSingleton,
|
||||||
|
providers.ThreadSafeSingleton,
|
||||||
|
providers.DelegatedThreadSafeSingleton,
|
||||||
|
]
|
||||||
|
if sys.version_info >= (3, 5):
|
||||||
|
PROVIDER_CLASSES.append(providers.ContextLocalSingleton)
|
||||||
|
|
||||||
|
|
||||||
|
@fixture(params=PROVIDER_CLASSES)
|
||||||
|
def singleton_cls(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider(singleton_cls):
|
||||||
|
return singleton_cls(Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider(provider):
|
||||||
|
assert providers.is_provider(provider) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_callable(singleton_cls):
|
||||||
|
with raises(errors.Error):
|
||||||
|
singleton_cls(123)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_optional_provides(provider):
|
||||||
|
provider.set_provides(object)
|
||||||
|
assert provider.provides is object
|
||||||
|
assert isinstance(provider(), object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_provides_returns_self(provider):
|
||||||
|
assert provider.set_provides(object) is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_valid_provided_type(singleton_cls):
|
||||||
|
class ExampleProvider(singleton_cls):
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
example_provider = ExampleProvider(Example, 1, 2)
|
||||||
|
assert isinstance(example_provider(), Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_valid_provided_subtype(singleton_cls):
|
||||||
|
class ExampleProvider(singleton_cls):
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
class NewExample(Example):
|
||||||
|
pass
|
||||||
|
|
||||||
|
example_provider = ExampleProvider(NewExample, 1, 2)
|
||||||
|
assert isinstance(example_provider(), NewExample)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_invalid_provided_type(singleton_cls):
|
||||||
|
class ExampleProvider(singleton_cls):
|
||||||
|
provided_type = Example
|
||||||
|
|
||||||
|
with raises(errors.Error):
|
||||||
|
ExampleProvider(list)
|
||||||
|
|
||||||
|
|
||||||
|
def test_provided_instance_provider(provider):
|
||||||
|
assert isinstance(provider.provided, providers.ProvidedInstance)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call(provider):
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1 is instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_init_positional_args(singleton_cls):
|
||||||
|
provider = singleton_cls(Example, "i1", "i2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.init_arg1 == "i1"
|
||||||
|
assert instance1.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance2.init_arg1 == "i1"
|
||||||
|
assert instance2.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance1 is instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_init_keyword_args(singleton_cls):
|
||||||
|
provider = singleton_cls(Example, init_arg1="i1", init_arg2="i2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.init_arg1 == "i1"
|
||||||
|
assert instance1.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance2.init_arg1 == "i1"
|
||||||
|
assert instance2.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance1 is instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_init_positional_and_keyword_args(singleton_cls):
|
||||||
|
provider = singleton_cls(Example, "i1", init_arg2="i2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.init_arg1 == "i1"
|
||||||
|
assert instance1.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance2.init_arg1 == "i1"
|
||||||
|
assert instance2.init_arg2 == "i2"
|
||||||
|
|
||||||
|
assert instance1 is instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_attributes(provider):
|
||||||
|
provider.add_attributes(attribute1="a1", attribute2="a2")
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1.attribute1 == "a1"
|
||||||
|
assert instance1.attribute2 == "a2"
|
||||||
|
|
||||||
|
assert instance2.attribute1 == "a1"
|
||||||
|
assert instance2.attribute2 == "a2"
|
||||||
|
|
||||||
|
assert instance1 is instance2
|
||||||
|
assert isinstance(instance1, Example)
|
||||||
|
assert isinstance(instance2, Example)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_args(provider):
|
||||||
|
instance = provider(11, 22)
|
||||||
|
|
||||||
|
assert instance.init_arg1 == 11
|
||||||
|
assert instance.init_arg2 == 22
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_kwargs(singleton_cls):
|
||||||
|
provider = singleton_cls(Example, init_arg1=1)
|
||||||
|
|
||||||
|
instance1 = provider(init_arg2=22)
|
||||||
|
assert instance1.init_arg1 == 1
|
||||||
|
assert instance1.init_arg2 == 22
|
||||||
|
|
||||||
|
# Instance is created earlier
|
||||||
|
instance1 = provider(init_arg1=11, init_arg2=22)
|
||||||
|
assert instance1.init_arg1 == 1
|
||||||
|
assert instance1.init_arg2 == 22
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_with_context_args_and_kwargs(singleton_cls):
|
||||||
|
provider = singleton_cls(Example, 11)
|
||||||
|
|
||||||
|
instance = provider(22, init_arg3=33, init_arg4=44)
|
||||||
|
|
||||||
|
assert instance.init_arg1 == 11
|
||||||
|
assert instance.init_arg2 == 22
|
||||||
|
assert instance.init_arg3 == 33
|
||||||
|
assert instance.init_arg4 == 44
|
||||||
|
|
||||||
|
|
||||||
|
def test_fluent_interface(singleton_cls):
|
||||||
|
provider = singleton_cls(Example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.add_attributes(attribute1=5, attribute2=6)
|
||||||
|
|
||||||
|
instance = provider()
|
||||||
|
|
||||||
|
assert instance.init_arg1 == 1
|
||||||
|
assert instance.init_arg2 == 2
|
||||||
|
assert instance.init_arg3 == 3
|
||||||
|
assert instance.init_arg4 == 4
|
||||||
|
assert instance.attribute1 == 5
|
||||||
|
assert instance.attribute2 == 6
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_args(singleton_cls):
|
||||||
|
provider = singleton_cls(Example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.set_args(3, 4)
|
||||||
|
assert provider.args == (3, 4)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_kwargs(singleton_cls):
|
||||||
|
provider = singleton_cls(Example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.set_kwargs(init_arg3=4, init_arg4=5)
|
||||||
|
assert provider.kwargs == dict(init_arg3=4, init_arg4=5)
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_attributes(singleton_cls):
|
||||||
|
provider = singleton_cls(Example) \
|
||||||
|
.add_attributes(attribute1=5, attribute2=6) \
|
||||||
|
.set_attributes(attribute1=6, attribute2=7)
|
||||||
|
assert provider.attributes == dict(attribute1=6, attribute2=7)
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_args(singleton_cls):
|
||||||
|
provider = singleton_cls(Example) \
|
||||||
|
.add_args(1, 2) \
|
||||||
|
.clear_args()
|
||||||
|
assert provider.args == tuple()
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_kwargs(singleton_cls):
|
||||||
|
provider = singleton_cls(Example) \
|
||||||
|
.add_kwargs(init_arg3=3, init_arg4=4) \
|
||||||
|
.clear_kwargs()
|
||||||
|
assert provider.kwargs == dict()
|
||||||
|
|
||||||
|
|
||||||
|
def test_clear_attributes(singleton_cls):
|
||||||
|
provider = singleton_cls(Example) \
|
||||||
|
.add_attributes(attribute1=5, attribute2=6) \
|
||||||
|
.clear_attributes()
|
||||||
|
assert provider.attributes == dict()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
overriding_provider1 = singleton_cls(dict)
|
||||||
|
overriding_provider2 = singleton_cls(list)
|
||||||
|
|
||||||
|
provider.override(overriding_provider1)
|
||||||
|
provider.override(overriding_provider2)
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
instance2 = provider()
|
||||||
|
|
||||||
|
assert instance1 is instance2
|
||||||
|
assert isinstance(instance1, list)
|
||||||
|
assert isinstance(instance2, list)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.cls is provider_copy.cls
|
||||||
|
assert isinstance(provider, singleton_cls)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
provider_copy_memo = singleton_cls(Example)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider, memo={id(provider): provider_copy_memo})
|
||||||
|
assert provider_copy is provider_copy_memo
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_args(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
dependent_provider1 = singleton_cls(list)
|
||||||
|
dependent_provider2 = singleton_cls(dict)
|
||||||
|
|
||||||
|
provider.add_args(dependent_provider1, dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.args[0]
|
||||||
|
dependent_provider_copy2 = provider_copy.args[1]
|
||||||
|
|
||||||
|
assert provider.args != provider_copy.args
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_kwargs(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
dependent_provider1 = singleton_cls(list)
|
||||||
|
dependent_provider2 = singleton_cls(dict)
|
||||||
|
|
||||||
|
provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.kwargs["a1"]
|
||||||
|
dependent_provider_copy2 = provider_copy.kwargs["a2"]
|
||||||
|
|
||||||
|
assert provider.kwargs != provider_copy.kwargs
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_attributes(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
dependent_provider1 = singleton_cls(list)
|
||||||
|
dependent_provider2 = singleton_cls(dict)
|
||||||
|
|
||||||
|
provider.add_attributes(a1=dependent_provider1, a2=dependent_provider2)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
dependent_provider_copy1 = provider_copy.attributes["a1"]
|
||||||
|
dependent_provider_copy2 = provider_copy.attributes["a2"]
|
||||||
|
|
||||||
|
assert provider.attributes != provider_copy.attributes
|
||||||
|
|
||||||
|
assert dependent_provider1.cls is dependent_provider_copy1.cls
|
||||||
|
assert dependent_provider1 is not dependent_provider_copy1
|
||||||
|
|
||||||
|
assert dependent_provider2.cls is dependent_provider_copy2.cls
|
||||||
|
assert dependent_provider2 is not dependent_provider_copy2
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_overridden(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
object_provider = providers.Object(object())
|
||||||
|
|
||||||
|
provider.override(object_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
object_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert provider.cls is provider_copy.cls
|
||||||
|
assert isinstance(provider, singleton_cls)
|
||||||
|
|
||||||
|
assert object_provider is not object_provider_copy
|
||||||
|
assert isinstance(object_provider_copy, providers.Object)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_with_sys_streams(singleton_cls):
|
||||||
|
provider = singleton_cls(Example)
|
||||||
|
provider.add_args(sys.stdin)
|
||||||
|
provider.add_kwargs(a2=sys.stdout)
|
||||||
|
provider.add_attributes(a3=sys.stderr)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert isinstance(provider_copy, singleton_cls)
|
||||||
|
assert provider.args[0] is sys.stdin
|
||||||
|
assert provider.kwargs["a2"] is sys.stdout
|
||||||
|
assert provider.attributes["a3"] is sys.stderr
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset(singleton_cls):
|
||||||
|
provider = singleton_cls(object)
|
||||||
|
|
||||||
|
instance1 = provider()
|
||||||
|
assert isinstance(instance1, object)
|
||||||
|
|
||||||
|
provider.reset()
|
||||||
|
|
||||||
|
instance2 = provider()
|
||||||
|
assert isinstance(instance2, object)
|
||||||
|
assert instance1 is not instance2
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_clean(provider):
|
||||||
|
instance1 = provider()
|
||||||
|
|
||||||
|
provider.reset()
|
||||||
|
provider.reset()
|
||||||
|
|
||||||
|
instance2 = provider()
|
||||||
|
assert instance1 is not instance2
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_with_singleton(singleton_cls):
|
||||||
|
dependent_singleton = providers.Singleton(object)
|
||||||
|
provider = singleton_cls(dict, dependency=dependent_singleton)
|
||||||
|
|
||||||
|
dependent_instance = dependent_singleton()
|
||||||
|
instance1 = provider()
|
||||||
|
assert instance1["dependency"] is dependent_instance
|
||||||
|
|
||||||
|
provider.reset()
|
||||||
|
|
||||||
|
instance2 = provider()
|
||||||
|
assert instance2["dependency"] is dependent_instance
|
||||||
|
assert instance1 is not instance2
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_context_manager(provider):
|
||||||
|
instance1 = provider()
|
||||||
|
with provider.reset():
|
||||||
|
instance2 = provider()
|
||||||
|
instance3 = provider()
|
||||||
|
assert len({instance1, instance2, instance3}) == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_context_manager_as_attribute(provider):
|
||||||
|
with provider.reset() as alias:
|
||||||
|
pass
|
||||||
|
assert provider is alias
|
||||||
|
|
||||||
|
|
||||||
|
def test_full_reset(singleton_cls):
|
||||||
|
dependent_singleton = providers.Singleton(object)
|
||||||
|
provider = singleton_cls(dict, dependency=dependent_singleton)
|
||||||
|
|
||||||
|
dependent_instance1 = dependent_singleton()
|
||||||
|
instance1 = provider()
|
||||||
|
assert instance1["dependency"] is dependent_instance1
|
||||||
|
|
||||||
|
provider.full_reset()
|
||||||
|
|
||||||
|
dependent_instance2 = dependent_singleton()
|
||||||
|
instance2 = provider()
|
||||||
|
assert instance2["dependency"] is not dependent_instance1
|
||||||
|
assert dependent_instance1 is not dependent_instance2
|
||||||
|
assert instance1 is not instance2
|
||||||
|
|
||||||
|
|
||||||
|
def test_full_reset_context_manager(singleton_cls):
|
||||||
|
class Item:
|
||||||
|
def __init__(self, dependency):
|
||||||
|
self.dependency = dependency
|
||||||
|
|
||||||
|
dependent_singleton = providers.Singleton(object)
|
||||||
|
singleton = singleton_cls(Item, dependency=dependent_singleton)
|
||||||
|
|
||||||
|
instance1 = singleton()
|
||||||
|
with singleton.full_reset():
|
||||||
|
instance2 = singleton()
|
||||||
|
instance3 = singleton()
|
||||||
|
|
||||||
|
assert len({instance1, instance2, instance3}) == 3
|
||||||
|
assert len({instance1.dependency, instance2.dependency, instance3.dependency}) == 3
|
||||||
|
|
||||||
|
|
||||||
|
def test_full_reset_context_manager_as_attribute(provider):
|
||||||
|
with provider.full_reset() as alias:
|
||||||
|
pass
|
||||||
|
assert provider is alias
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr(provider):
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"{0}({1}) at {2}>".format(provider.__class__.__name__, repr(Example), hex(id(provider)))
|
||||||
|
)
|
|
@ -1,434 +0,0 @@
|
||||||
import sys
|
|
||||||
|
|
||||||
from dependency_injector import providers, errors
|
|
||||||
|
|
||||||
|
|
||||||
class Example(object):
|
|
||||||
|
|
||||||
def __init__(self, init_arg1=None, init_arg2=None, init_arg3=None,
|
|
||||||
init_arg4=None):
|
|
||||||
self.init_arg1 = init_arg1
|
|
||||||
self.init_arg2 = init_arg2
|
|
||||||
self.init_arg3 = init_arg3
|
|
||||||
self.init_arg4 = init_arg4
|
|
||||||
|
|
||||||
self.attribute1 = None
|
|
||||||
self.attribute2 = None
|
|
||||||
|
|
||||||
|
|
||||||
class _BaseSingletonTestCase(object):
|
|
||||||
|
|
||||||
singleton_cls = None
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(providers.is_provider(self.singleton_cls(Example)))
|
|
||||||
|
|
||||||
def test_init_with_callable(self):
|
|
||||||
self.assertTrue(self.singleton_cls(credits))
|
|
||||||
|
|
||||||
def test_init_with_not_callable(self):
|
|
||||||
self.assertRaises(errors.Error, self.singleton_cls, 123)
|
|
||||||
|
|
||||||
def test_init_optional_provides(self):
|
|
||||||
provider = self.singleton_cls()
|
|
||||||
provider.set_provides(object)
|
|
||||||
self.assertIs(provider.provides, object)
|
|
||||||
self.assertIsInstance(provider(), object)
|
|
||||||
|
|
||||||
def test_set_provides_returns_self(self):
|
|
||||||
provider = self.singleton_cls()
|
|
||||||
self.assertIs(provider.set_provides(object), provider)
|
|
||||||
|
|
||||||
def test_init_with_valid_provided_type(self):
|
|
||||||
class ExampleProvider(self.singleton_cls):
|
|
||||||
provided_type = Example
|
|
||||||
|
|
||||||
example_provider = ExampleProvider(Example, 1, 2)
|
|
||||||
|
|
||||||
self.assertIsInstance(example_provider(), Example)
|
|
||||||
|
|
||||||
def test_init_with_valid_provided_subtype(self):
|
|
||||||
class ExampleProvider(self.singleton_cls):
|
|
||||||
provided_type = Example
|
|
||||||
|
|
||||||
class NewExampe(Example):
|
|
||||||
pass
|
|
||||||
|
|
||||||
example_provider = ExampleProvider(NewExampe, 1, 2)
|
|
||||||
|
|
||||||
self.assertIsInstance(example_provider(), NewExampe)
|
|
||||||
|
|
||||||
def test_init_with_invalid_provided_type(self):
|
|
||||||
class ExampleProvider(self.singleton_cls):
|
|
||||||
provided_type = Example
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
ExampleProvider(list)
|
|
||||||
|
|
||||||
def test_provided_instance_provider(self):
|
|
||||||
provider = providers.Singleton(Example)
|
|
||||||
self.assertIsInstance(provider.provided, providers.ProvidedInstance)
|
|
||||||
|
|
||||||
def test_call(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertIs(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, Example)
|
|
||||||
self.assertIsInstance(instance2, Example)
|
|
||||||
|
|
||||||
def test_call_with_init_positional_args(self):
|
|
||||||
provider = self.singleton_cls(Example, "i1", "i2")
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertEqual(instance1.init_arg1, "i1")
|
|
||||||
self.assertEqual(instance1.init_arg2, "i2")
|
|
||||||
|
|
||||||
self.assertEqual(instance2.init_arg1, "i1")
|
|
||||||
self.assertEqual(instance2.init_arg2, "i2")
|
|
||||||
|
|
||||||
self.assertIs(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, Example)
|
|
||||||
self.assertIsInstance(instance2, Example)
|
|
||||||
|
|
||||||
def test_call_with_init_keyword_args(self):
|
|
||||||
provider = self.singleton_cls(Example, init_arg1="i1", init_arg2="i2")
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertEqual(instance1.init_arg1, "i1")
|
|
||||||
self.assertEqual(instance1.init_arg2, "i2")
|
|
||||||
|
|
||||||
self.assertEqual(instance2.init_arg1, "i1")
|
|
||||||
self.assertEqual(instance2.init_arg2, "i2")
|
|
||||||
|
|
||||||
self.assertIs(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, Example)
|
|
||||||
self.assertIsInstance(instance2, Example)
|
|
||||||
|
|
||||||
def test_call_with_init_positional_and_keyword_args(self):
|
|
||||||
provider = self.singleton_cls(Example, "i1", init_arg2="i2")
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertEqual(instance1.init_arg1, "i1")
|
|
||||||
self.assertEqual(instance1.init_arg2, "i2")
|
|
||||||
|
|
||||||
self.assertEqual(instance2.init_arg1, "i1")
|
|
||||||
self.assertEqual(instance2.init_arg2, "i2")
|
|
||||||
|
|
||||||
self.assertIs(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, Example)
|
|
||||||
self.assertIsInstance(instance2, Example)
|
|
||||||
|
|
||||||
def test_call_with_attributes(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
provider.add_attributes(attribute1="a1", attribute2="a2")
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertEqual(instance1.attribute1, "a1")
|
|
||||||
self.assertEqual(instance1.attribute2, "a2")
|
|
||||||
|
|
||||||
self.assertEqual(instance2.attribute1, "a1")
|
|
||||||
self.assertEqual(instance2.attribute2, "a2")
|
|
||||||
|
|
||||||
self.assertIs(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, Example)
|
|
||||||
self.assertIsInstance(instance2, Example)
|
|
||||||
|
|
||||||
def test_call_with_context_args(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
|
|
||||||
instance = provider(11, 22)
|
|
||||||
|
|
||||||
self.assertEqual(instance.init_arg1, 11)
|
|
||||||
self.assertEqual(instance.init_arg2, 22)
|
|
||||||
|
|
||||||
def test_call_with_context_kwargs(self):
|
|
||||||
provider = self.singleton_cls(Example, init_arg1=1)
|
|
||||||
|
|
||||||
instance1 = provider(init_arg2=22)
|
|
||||||
self.assertEqual(instance1.init_arg1, 1)
|
|
||||||
self.assertEqual(instance1.init_arg2, 22)
|
|
||||||
|
|
||||||
# Instance is created earlier
|
|
||||||
instance1 = provider(init_arg1=11, init_arg2=22)
|
|
||||||
self.assertEqual(instance1.init_arg1, 1)
|
|
||||||
self.assertEqual(instance1.init_arg2, 22)
|
|
||||||
|
|
||||||
def test_call_with_context_args_and_kwargs(self):
|
|
||||||
provider = self.singleton_cls(Example, 11)
|
|
||||||
|
|
||||||
instance = provider(22, init_arg3=33, init_arg4=44)
|
|
||||||
|
|
||||||
self.assertEqual(instance.init_arg1, 11)
|
|
||||||
self.assertEqual(instance.init_arg2, 22)
|
|
||||||
self.assertEqual(instance.init_arg3, 33)
|
|
||||||
self.assertEqual(instance.init_arg4, 44)
|
|
||||||
|
|
||||||
def test_fluent_interface(self):
|
|
||||||
provider = self.singleton_cls(Example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.add_kwargs(init_arg3=3, init_arg4=4) \
|
|
||||||
.add_attributes(attribute1=5, attribute2=6)
|
|
||||||
|
|
||||||
instance = provider()
|
|
||||||
|
|
||||||
self.assertEqual(instance.init_arg1, 1)
|
|
||||||
self.assertEqual(instance.init_arg2, 2)
|
|
||||||
self.assertEqual(instance.init_arg3, 3)
|
|
||||||
self.assertEqual(instance.init_arg4, 4)
|
|
||||||
self.assertEqual(instance.attribute1, 5)
|
|
||||||
self.assertEqual(instance.attribute2, 6)
|
|
||||||
|
|
||||||
def test_set_args(self):
|
|
||||||
provider = self.singleton_cls(Example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.set_args(3, 4)
|
|
||||||
self.assertEqual(provider.args, (3, 4))
|
|
||||||
|
|
||||||
def test_set_kwargs(self):
|
|
||||||
provider = self.singleton_cls(Example) \
|
|
||||||
.add_kwargs(init_arg3=3, init_arg4=4) \
|
|
||||||
.set_kwargs(init_arg3=4, init_arg4=5)
|
|
||||||
self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5))
|
|
||||||
|
|
||||||
def test_set_attributes(self):
|
|
||||||
provider = self.singleton_cls(Example) \
|
|
||||||
.add_attributes(attribute1=5, attribute2=6) \
|
|
||||||
.set_attributes(attribute1=6, attribute2=7)
|
|
||||||
self.assertEqual(provider.attributes, dict(attribute1=6, attribute2=7))
|
|
||||||
|
|
||||||
def test_clear_args(self):
|
|
||||||
provider = self.singleton_cls(Example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.clear_args()
|
|
||||||
self.assertEqual(provider.args, tuple())
|
|
||||||
|
|
||||||
def test_clear_kwargs(self):
|
|
||||||
provider = self.singleton_cls(Example) \
|
|
||||||
.add_kwargs(init_arg3=3, init_arg4=4) \
|
|
||||||
.clear_kwargs()
|
|
||||||
self.assertEqual(provider.kwargs, dict())
|
|
||||||
|
|
||||||
def test_clear_attributes(self):
|
|
||||||
provider = self.singleton_cls(Example) \
|
|
||||||
.add_attributes(attribute1=5, attribute2=6) \
|
|
||||||
.clear_attributes()
|
|
||||||
self.assertEqual(provider.attributes, dict())
|
|
||||||
|
|
||||||
def test_call_overridden(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
overriding_provider1 = self.singleton_cls(dict)
|
|
||||||
overriding_provider2 = self.singleton_cls(list)
|
|
||||||
|
|
||||||
provider.override(overriding_provider1)
|
|
||||||
provider.override(overriding_provider2)
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
instance2 = provider()
|
|
||||||
|
|
||||||
self.assertIs(instance1, instance2)
|
|
||||||
self.assertIsInstance(instance1, list)
|
|
||||||
self.assertIsInstance(instance2, list)
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIs(provider.cls, provider_copy.cls)
|
|
||||||
self.assertIsInstance(provider, self.singleton_cls)
|
|
||||||
|
|
||||||
def test_deepcopy_from_memo(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
provider_copy_memo = self.singleton_cls(Example)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(
|
|
||||||
provider, memo={id(provider): provider_copy_memo})
|
|
||||||
|
|
||||||
self.assertIs(provider_copy, provider_copy_memo)
|
|
||||||
|
|
||||||
def test_deepcopy_args(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
dependent_provider1 = self.singleton_cls(list)
|
|
||||||
dependent_provider2 = self.singleton_cls(dict)
|
|
||||||
|
|
||||||
provider.add_args(dependent_provider1, dependent_provider2)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
dependent_provider_copy1 = provider_copy.args[0]
|
|
||||||
dependent_provider_copy2 = provider_copy.args[1]
|
|
||||||
|
|
||||||
self.assertNotEqual(provider.args, provider_copy.args)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
|
|
||||||
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
|
|
||||||
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
|
||||||
|
|
||||||
def test_deepcopy_kwargs(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
dependent_provider1 = self.singleton_cls(list)
|
|
||||||
dependent_provider2 = self.singleton_cls(dict)
|
|
||||||
|
|
||||||
provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
dependent_provider_copy1 = provider_copy.kwargs["a1"]
|
|
||||||
dependent_provider_copy2 = provider_copy.kwargs["a2"]
|
|
||||||
|
|
||||||
self.assertNotEqual(provider.kwargs, provider_copy.kwargs)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
|
|
||||||
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
|
|
||||||
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
|
||||||
|
|
||||||
def test_deepcopy_attributes(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
dependent_provider1 = self.singleton_cls(list)
|
|
||||||
dependent_provider2 = self.singleton_cls(dict)
|
|
||||||
|
|
||||||
provider.add_attributes(a1=dependent_provider1, a2=dependent_provider2)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
dependent_provider_copy1 = provider_copy.attributes["a1"]
|
|
||||||
dependent_provider_copy2 = provider_copy.attributes["a2"]
|
|
||||||
|
|
||||||
self.assertNotEqual(provider.attributes, provider_copy.attributes)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider1.cls, dependent_provider_copy1.cls)
|
|
||||||
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider2.cls, dependent_provider_copy2.cls)
|
|
||||||
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
|
||||||
|
|
||||||
def test_deepcopy_overridden(self):
|
|
||||||
provider = self.singleton_cls(Example)
|
|
||||||
object_provider = providers.Object(object())
|
|
||||||
|
|
||||||
provider.override(object_provider)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
object_provider_copy = provider_copy.overridden[0]
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIs(provider.cls, provider_copy.cls)
|
|
||||||
self.assertIsInstance(provider, self.singleton_cls)
|
|
||||||
|
|
||||||
self.assertIsNot(object_provider, object_provider_copy)
|
|
||||||
self.assertIsInstance(object_provider_copy, providers.Object)
|
|
||||||
|
|
||||||
def test_deepcopy_with_sys_streams(self):
|
|
||||||
provider = providers.Singleton(Example)
|
|
||||||
provider.add_args(sys.stdin)
|
|
||||||
provider.add_kwargs(a2=sys.stdout)
|
|
||||||
provider.add_attributes(a3=sys.stderr)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider_copy, providers.Singleton)
|
|
||||||
self.assertIs(provider.args[0], sys.stdin)
|
|
||||||
self.assertIs(provider.kwargs["a2"], sys.stdout)
|
|
||||||
self.assertIs(provider.attributes["a3"], sys.stderr)
|
|
||||||
|
|
||||||
def test_reset(self):
|
|
||||||
provider = self.singleton_cls(object)
|
|
||||||
|
|
||||||
instance1 = provider()
|
|
||||||
self.assertIsInstance(instance1, object)
|
|
||||||
|
|
||||||
provider.reset()
|
|
||||||
|
|
||||||
instance2 = provider()
|
|
||||||
self.assertIsInstance(instance2, object)
|
|
||||||
|
|
||||||
self.assertIsNot(instance1, instance2)
|
|
||||||
|
|
||||||
def test_reset_with_singleton(self):
|
|
||||||
dependent_singleton = providers.Singleton(object)
|
|
||||||
provider = self.singleton_cls(dict, dependency=dependent_singleton)
|
|
||||||
|
|
||||||
dependent_instance = dependent_singleton()
|
|
||||||
instance1 = provider()
|
|
||||||
self.assertIs(instance1["dependency"], dependent_instance)
|
|
||||||
|
|
||||||
provider.reset()
|
|
||||||
|
|
||||||
instance2 = provider()
|
|
||||||
self.assertIs(instance1["dependency"], dependent_instance)
|
|
||||||
|
|
||||||
self.assertIsNot(instance1, instance2)
|
|
||||||
|
|
||||||
def test_reset_context_manager(self):
|
|
||||||
singleton = self.singleton_cls(object)
|
|
||||||
|
|
||||||
instance1 = singleton()
|
|
||||||
with singleton.reset():
|
|
||||||
instance2 = singleton()
|
|
||||||
instance3 = singleton()
|
|
||||||
self.assertEqual(len({instance1, instance2, instance3}), 3)
|
|
||||||
|
|
||||||
def test_reset_context_manager_as_attribute(self):
|
|
||||||
singleton = self.singleton_cls(object)
|
|
||||||
|
|
||||||
with singleton.reset() as alias:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertIs(singleton, alias)
|
|
||||||
|
|
||||||
def test_full_reset(self):
|
|
||||||
dependent_singleton = providers.Singleton(object)
|
|
||||||
provider = self.singleton_cls(dict, dependency=dependent_singleton)
|
|
||||||
|
|
||||||
dependent_instance1 = dependent_singleton()
|
|
||||||
instance1 = provider()
|
|
||||||
self.assertIs(instance1["dependency"], dependent_instance1)
|
|
||||||
|
|
||||||
provider.full_reset()
|
|
||||||
|
|
||||||
dependent_instance2 = dependent_singleton()
|
|
||||||
instance2 = provider()
|
|
||||||
self.assertIsNot(instance2["dependency"], dependent_instance1)
|
|
||||||
self.assertIsNot(dependent_instance1, dependent_instance2)
|
|
||||||
self.assertIsNot(instance1, instance2)
|
|
||||||
|
|
||||||
def test_full_reset_context_manager(self):
|
|
||||||
class Item:
|
|
||||||
def __init__(self, dependency):
|
|
||||||
self.dependency = dependency
|
|
||||||
|
|
||||||
dependent_singleton = providers.Singleton(object)
|
|
||||||
singleton = self.singleton_cls(Item, dependency=dependent_singleton)
|
|
||||||
|
|
||||||
instance1 = singleton()
|
|
||||||
with singleton.full_reset():
|
|
||||||
instance2 = singleton()
|
|
||||||
instance3 = singleton()
|
|
||||||
|
|
||||||
self.assertEqual(len({instance1, instance2, instance3}), 3)
|
|
||||||
self.assertEqual(
|
|
||||||
len({instance1.dependency, instance2.dependency, instance3.dependency}),
|
|
||||||
3,
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_full_reset_context_manager_as_attribute(self):
|
|
||||||
singleton = self.singleton_cls(object)
|
|
||||||
|
|
||||||
with singleton.full_reset() as alias:
|
|
||||||
pass
|
|
||||||
|
|
||||||
self.assertIs(singleton, alias)
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,791 +0,0 @@
|
||||||
"""Dependency injector base providers unit tests."""
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from dependency_injector import (
|
|
||||||
containers,
|
|
||||||
providers,
|
|
||||||
errors,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class ProviderTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.provider = providers.Provider()
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(providers.is_provider(self.provider))
|
|
||||||
|
|
||||||
def test_call(self):
|
|
||||||
self.assertRaises(NotImplementedError, self.provider.__call__)
|
|
||||||
|
|
||||||
def test_delegate(self):
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.simplefilter("ignore")
|
|
||||||
delegate1 = self.provider.delegate()
|
|
||||||
delegate2 = self.provider.delegate()
|
|
||||||
|
|
||||||
self.assertIsInstance(delegate1, providers.Delegate)
|
|
||||||
self.assertIs(delegate1(), self.provider)
|
|
||||||
|
|
||||||
self.assertIsInstance(delegate2, providers.Delegate)
|
|
||||||
self.assertIs(delegate2(), self.provider)
|
|
||||||
|
|
||||||
self.assertIsNot(delegate1, delegate2)
|
|
||||||
|
|
||||||
def test_provider(self):
|
|
||||||
delegate1 = self.provider.provider
|
|
||||||
|
|
||||||
self.assertIsInstance(delegate1, providers.Delegate)
|
|
||||||
self.assertIs(delegate1(), self.provider)
|
|
||||||
|
|
||||||
delegate2 = self.provider.provider
|
|
||||||
|
|
||||||
self.assertIsInstance(delegate2, providers.Delegate)
|
|
||||||
self.assertIs(delegate2(), self.provider)
|
|
||||||
|
|
||||||
self.assertIsNot(delegate1, delegate2)
|
|
||||||
|
|
||||||
def test_override(self):
|
|
||||||
overriding_provider = providers.Provider()
|
|
||||||
self.provider.override(overriding_provider)
|
|
||||||
self.assertTrue(self.provider.overridden)
|
|
||||||
self.assertIs(self.provider.last_overriding, overriding_provider)
|
|
||||||
|
|
||||||
def test_double_override(self):
|
|
||||||
overriding_provider1 = providers.Object(1)
|
|
||||||
overriding_provider2 = providers.Object(2)
|
|
||||||
|
|
||||||
self.provider.override(overriding_provider1)
|
|
||||||
overriding_provider1.override(overriding_provider2)
|
|
||||||
|
|
||||||
self.assertEqual(self.provider(), overriding_provider2())
|
|
||||||
|
|
||||||
def test_overriding_context(self):
|
|
||||||
overriding_provider = providers.Provider()
|
|
||||||
with self.provider.override(overriding_provider):
|
|
||||||
self.assertTrue(self.provider.overridden)
|
|
||||||
self.assertFalse(self.provider.overridden)
|
|
||||||
|
|
||||||
def test_override_with_itself(self):
|
|
||||||
self.assertRaises(errors.Error, self.provider.override, self.provider)
|
|
||||||
|
|
||||||
def test_override_with_not_provider(self):
|
|
||||||
obj = object()
|
|
||||||
self.provider.override(obj)
|
|
||||||
self.assertIs(self.provider(), obj)
|
|
||||||
|
|
||||||
def test_reset_last_overriding(self):
|
|
||||||
overriding_provider1 = providers.Provider()
|
|
||||||
overriding_provider2 = providers.Provider()
|
|
||||||
|
|
||||||
self.provider.override(overriding_provider1)
|
|
||||||
self.provider.override(overriding_provider2)
|
|
||||||
|
|
||||||
self.assertIs(self.provider.overridden[-1], overriding_provider2)
|
|
||||||
self.assertIs(self.provider.last_overriding, overriding_provider2)
|
|
||||||
|
|
||||||
self.provider.reset_last_overriding()
|
|
||||||
self.assertIs(self.provider.overridden[-1], overriding_provider1)
|
|
||||||
self.assertIs(self.provider.last_overriding, overriding_provider1)
|
|
||||||
|
|
||||||
self.provider.reset_last_overriding()
|
|
||||||
self.assertFalse(self.provider.overridden)
|
|
||||||
self.assertIsNone(self.provider.last_overriding)
|
|
||||||
|
|
||||||
def test_reset_last_overriding_of_not_overridden_provider(self):
|
|
||||||
self.assertRaises(errors.Error, self.provider.reset_last_overriding)
|
|
||||||
|
|
||||||
def test_reset_override(self):
|
|
||||||
overriding_provider = providers.Provider()
|
|
||||||
self.provider.override(overriding_provider)
|
|
||||||
|
|
||||||
self.assertTrue(self.provider.overridden)
|
|
||||||
self.assertEqual(self.provider.overridden, (overriding_provider,))
|
|
||||||
|
|
||||||
self.provider.reset_override()
|
|
||||||
|
|
||||||
self.assertEqual(self.provider.overridden, tuple())
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
provider = providers.Provider()
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Provider)
|
|
||||||
|
|
||||||
def test_deepcopy_from_memo(self):
|
|
||||||
provider = providers.Provider()
|
|
||||||
provider_copy_memo = providers.Provider()
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(
|
|
||||||
provider, memo={id(provider): provider_copy_memo})
|
|
||||||
|
|
||||||
self.assertIs(provider_copy, provider_copy_memo)
|
|
||||||
|
|
||||||
def test_deepcopy_overridden(self):
|
|
||||||
provider = providers.Provider()
|
|
||||||
overriding_provider = providers.Provider()
|
|
||||||
|
|
||||||
provider.override(overriding_provider)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
overriding_provider_copy = provider_copy.overridden[0]
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Provider)
|
|
||||||
|
|
||||||
self.assertIsNot(overriding_provider, overriding_provider_copy)
|
|
||||||
self.assertIsInstance(overriding_provider_copy, providers.Provider)
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
self.assertEqual(repr(self.provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Provider() at {0}>".format(hex(id(self.provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class ObjectProviderTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(providers.is_provider(providers.Object(object())))
|
|
||||||
|
|
||||||
def test_init_optional_provides(self):
|
|
||||||
instance = object()
|
|
||||||
provider = providers.Object()
|
|
||||||
provider.set_provides(instance)
|
|
||||||
self.assertIs(provider.provides, instance)
|
|
||||||
self.assertIs(provider(), instance)
|
|
||||||
|
|
||||||
def test_set_provides_returns_self(self):
|
|
||||||
provider = providers.Object()
|
|
||||||
self.assertIs(provider.set_provides(object()), provider)
|
|
||||||
|
|
||||||
def test_provided_instance_provider(self):
|
|
||||||
provider = providers.Object(object())
|
|
||||||
self.assertIsInstance(provider.provided, providers.ProvidedInstance)
|
|
||||||
|
|
||||||
def test_call_object_provider(self):
|
|
||||||
obj = object()
|
|
||||||
self.assertIs(providers.Object(obj)(), obj)
|
|
||||||
|
|
||||||
def test_call_overridden_object_provider(self):
|
|
||||||
obj1 = object()
|
|
||||||
obj2 = object()
|
|
||||||
provider = providers.Object(obj1)
|
|
||||||
provider.override(providers.Object(obj2))
|
|
||||||
self.assertIs(provider(), obj2)
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
provider = providers.Object(1)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Object)
|
|
||||||
|
|
||||||
def test_deepcopy_from_memo(self):
|
|
||||||
provider = providers.Object(1)
|
|
||||||
provider_copy_memo = providers.Provider()
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(
|
|
||||||
provider, memo={id(provider): provider_copy_memo})
|
|
||||||
|
|
||||||
self.assertIs(provider_copy, provider_copy_memo)
|
|
||||||
|
|
||||||
def test_deepcopy_overridden(self):
|
|
||||||
provider = providers.Object(1)
|
|
||||||
overriding_provider = providers.Provider()
|
|
||||||
|
|
||||||
provider.override(overriding_provider)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
overriding_provider_copy = provider_copy.overridden[0]
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Object)
|
|
||||||
|
|
||||||
self.assertIsNot(overriding_provider, overriding_provider_copy)
|
|
||||||
self.assertIsInstance(overriding_provider_copy, providers.Provider)
|
|
||||||
|
|
||||||
def test_deepcopy_doesnt_copy_provided_object(self):
|
|
||||||
# Fixes bug #231
|
|
||||||
# Details: https://github.com/ets-labs/python-dependency-injector/issues/231
|
|
||||||
some_object = object()
|
|
||||||
provider = providers.Object(some_object)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIs(provider(), some_object)
|
|
||||||
self.assertIs(provider_copy(), some_object)
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
some_object = object()
|
|
||||||
provider = providers.Object(some_object)
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Object({0}) at {1}>".format(
|
|
||||||
repr(some_object),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class SelfProviderTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(providers.is_provider(providers.Self()))
|
|
||||||
|
|
||||||
def test_call_object_provider(self):
|
|
||||||
container = containers.DeclarativeContainer()
|
|
||||||
self.assertIs(providers.Self(container)(), container)
|
|
||||||
|
|
||||||
def test_set_container(self):
|
|
||||||
container = containers.DeclarativeContainer()
|
|
||||||
provider = providers.Self()
|
|
||||||
provider.set_container(container)
|
|
||||||
self.assertIs(provider(), container)
|
|
||||||
|
|
||||||
def test_set_alt_names(self):
|
|
||||||
provider = providers.Self()
|
|
||||||
provider.set_alt_names({"foo", "bar", "baz"})
|
|
||||||
self.assertEqual(set(provider.alt_names), {"foo", "bar", "baz"})
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
provider = providers.Self()
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Self)
|
|
||||||
|
|
||||||
def test_deepcopy_from_memo(self):
|
|
||||||
provider = providers.Self()
|
|
||||||
provider_copy_memo = providers.Provider()
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(
|
|
||||||
provider, memo={id(provider): provider_copy_memo})
|
|
||||||
|
|
||||||
self.assertIs(provider_copy, provider_copy_memo)
|
|
||||||
|
|
||||||
def test_deepcopy_overridden(self):
|
|
||||||
provider = providers.Self()
|
|
||||||
overriding_provider = providers.Provider()
|
|
||||||
|
|
||||||
provider.override(overriding_provider)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
overriding_provider_copy = provider_copy.overridden[0]
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Self)
|
|
||||||
|
|
||||||
self.assertIsNot(overriding_provider, overriding_provider_copy)
|
|
||||||
self.assertIsInstance(overriding_provider_copy, providers.Provider)
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
container = containers.DeclarativeContainer()
|
|
||||||
provider = providers.Self(container)
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Self({0}) at {1}>".format(
|
|
||||||
repr(container),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class DelegateTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.delegated = providers.Provider()
|
|
||||||
self.delegate = providers.Delegate(self.delegated)
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(providers.is_provider(self.delegate))
|
|
||||||
|
|
||||||
def test_init_optional_provides(self):
|
|
||||||
provider = providers.Delegate()
|
|
||||||
provider.set_provides(self.delegated)
|
|
||||||
self.assertIs(provider.provides, self.delegated)
|
|
||||||
self.assertIs(provider(), self.delegated)
|
|
||||||
|
|
||||||
def test_set_provides_returns_self(self):
|
|
||||||
provider = providers.Delegate()
|
|
||||||
self.assertIs(provider.set_provides(self.delegated), provider)
|
|
||||||
|
|
||||||
def test_init_with_not_provider(self):
|
|
||||||
self.assertRaises(errors.Error, providers.Delegate, object())
|
|
||||||
|
|
||||||
def test_call(self):
|
|
||||||
delegated1 = self.delegate()
|
|
||||||
delegated2 = self.delegate()
|
|
||||||
|
|
||||||
self.assertIs(delegated1, self.delegated)
|
|
||||||
self.assertIs(delegated2, self.delegated)
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
self.assertEqual(repr(self.delegate),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Delegate({0}) at {1}>".format(
|
|
||||||
repr(self.delegated),
|
|
||||||
hex(id(self.delegate))))
|
|
||||||
|
|
||||||
|
|
||||||
class DependencyTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.provider = providers.Dependency(instance_of=list)
|
|
||||||
|
|
||||||
def test_init_optional(self):
|
|
||||||
list_provider = providers.List(1, 2, 3)
|
|
||||||
provider = providers.Dependency()
|
|
||||||
provider.set_instance_of(list)
|
|
||||||
provider.set_default(list_provider)
|
|
||||||
|
|
||||||
self.assertIs(provider.instance_of, list)
|
|
||||||
self.assertIs(provider.default, list_provider)
|
|
||||||
self.assertEqual(provider(), [1, 2, 3])
|
|
||||||
|
|
||||||
def test_set_instance_of_returns_self(self):
|
|
||||||
provider = providers.Dependency()
|
|
||||||
self.assertIs(provider.set_instance_of(list), provider)
|
|
||||||
|
|
||||||
def test_set_default_returns_self(self):
|
|
||||||
provider = providers.Dependency()
|
|
||||||
self.assertIs(provider.set_default(providers.Provider()), provider)
|
|
||||||
|
|
||||||
def test_init_with_not_class(self):
|
|
||||||
self.assertRaises(TypeError, providers.Dependency, object())
|
|
||||||
|
|
||||||
def test_with_abc(self):
|
|
||||||
try:
|
|
||||||
import collections.abc as collections_abc
|
|
||||||
except ImportError:
|
|
||||||
import collections as collections_abc
|
|
||||||
|
|
||||||
provider = providers.Dependency(collections_abc.Mapping)
|
|
||||||
provider.provided_by(providers.Factory(dict))
|
|
||||||
|
|
||||||
self.assertIsInstance(provider(), collections_abc.Mapping)
|
|
||||||
self.assertIsInstance(provider(), dict)
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(providers.is_provider(self.provider))
|
|
||||||
|
|
||||||
def test_provided_instance_provider(self):
|
|
||||||
self.assertIsInstance(self.provider.provided, providers.ProvidedInstance)
|
|
||||||
|
|
||||||
def test_default(self):
|
|
||||||
provider = providers.Dependency(instance_of=dict, default={"foo": "bar"})
|
|
||||||
self.assertEqual(provider(), {"foo": "bar"})
|
|
||||||
|
|
||||||
def test_default_attribute(self):
|
|
||||||
provider = providers.Dependency(instance_of=dict, default={"foo": "bar"})
|
|
||||||
self.assertEqual(provider.default(), {"foo": "bar"})
|
|
||||||
|
|
||||||
def test_default_provider(self):
|
|
||||||
provider = providers.Dependency(instance_of=dict, default=providers.Factory(dict, foo="bar"))
|
|
||||||
self.assertEqual(provider.default(), {"foo": "bar"})
|
|
||||||
|
|
||||||
def test_default_attribute_provider(self):
|
|
||||||
default = providers.Factory(dict, foo="bar")
|
|
||||||
provider = providers.Dependency(instance_of=dict, default=default)
|
|
||||||
|
|
||||||
self.assertEqual(provider.default(), {"foo": "bar"})
|
|
||||||
self.assertIs(provider.default, default)
|
|
||||||
|
|
||||||
def test_is_defined(self):
|
|
||||||
provider = providers.Dependency()
|
|
||||||
self.assertFalse(provider.is_defined)
|
|
||||||
|
|
||||||
def test_is_defined_when_overridden(self):
|
|
||||||
provider = providers.Dependency()
|
|
||||||
provider.override("value")
|
|
||||||
self.assertTrue(provider.is_defined)
|
|
||||||
|
|
||||||
def test_is_defined_with_default(self):
|
|
||||||
provider = providers.Dependency(default="value")
|
|
||||||
self.assertTrue(provider.is_defined)
|
|
||||||
|
|
||||||
def test_call_overridden(self):
|
|
||||||
self.provider.provided_by(providers.Factory(list))
|
|
||||||
self.assertIsInstance(self.provider(), list)
|
|
||||||
|
|
||||||
def test_call_overridden_but_not_instance_of(self):
|
|
||||||
self.provider.provided_by(providers.Factory(dict))
|
|
||||||
self.assertRaises(errors.Error, self.provider)
|
|
||||||
|
|
||||||
def test_call_undefined(self):
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
self.provider()
|
|
||||||
self.assertEqual(str(context.exception), "Dependency is not defined")
|
|
||||||
|
|
||||||
def test_call_undefined_error_message_with_container_instance_parent(self):
|
|
||||||
class UserService:
|
|
||||||
def __init__(self, database):
|
|
||||||
self.database = database
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
database = providers.Dependency()
|
|
||||||
|
|
||||||
user_service = providers.Factory(
|
|
||||||
UserService,
|
|
||||||
database=database, # <---- missing dependency
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
container.user_service()
|
|
||||||
|
|
||||||
self.assertEqual(str(context.exception), "Dependency \"Container.database\" is not defined")
|
|
||||||
|
|
||||||
def test_call_undefined_error_message_with_container_provider_parent_deep(self):
|
|
||||||
class Database:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class UserService:
|
|
||||||
def __init__(self, db):
|
|
||||||
self.db = db
|
|
||||||
|
|
||||||
class Gateways(containers.DeclarativeContainer):
|
|
||||||
database_client = providers.Singleton(Database)
|
|
||||||
|
|
||||||
class Services(containers.DeclarativeContainer):
|
|
||||||
gateways = providers.DependenciesContainer()
|
|
||||||
|
|
||||||
user = providers.Factory(
|
|
||||||
UserService,
|
|
||||||
db=gateways.database_client,
|
|
||||||
)
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
gateways = providers.Container(Gateways)
|
|
||||||
|
|
||||||
services = providers.Container(
|
|
||||||
Services,
|
|
||||||
# gateways=gateways, # <---- missing dependency
|
|
||||||
)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
container.services().user()
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
str(context.exception),
|
|
||||||
"Dependency \"Container.services.gateways.database_client\" is not defined",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_call_undefined_error_message_with_dependenciescontainer_provider_parent(self):
|
|
||||||
class UserService:
|
|
||||||
def __init__(self, db):
|
|
||||||
self.db = db
|
|
||||||
|
|
||||||
class Services(containers.DeclarativeContainer):
|
|
||||||
gateways = providers.DependenciesContainer()
|
|
||||||
|
|
||||||
user = providers.Factory(
|
|
||||||
UserService,
|
|
||||||
db=gateways.database_client, # <---- missing dependency
|
|
||||||
)
|
|
||||||
|
|
||||||
services = Services()
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error) as context:
|
|
||||||
services.user()
|
|
||||||
|
|
||||||
self.assertEqual(
|
|
||||||
str(context.exception),
|
|
||||||
"Dependency \"Services.gateways.database_client\" is not defined",
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_assign_parent(self):
|
|
||||||
parent = providers.DependenciesContainer()
|
|
||||||
provider = providers.Dependency()
|
|
||||||
|
|
||||||
provider.assign_parent(parent)
|
|
||||||
|
|
||||||
self.assertIs(provider.parent, parent)
|
|
||||||
|
|
||||||
def test_parent_name(self):
|
|
||||||
container = containers.DynamicContainer()
|
|
||||||
provider = providers.Dependency()
|
|
||||||
container.name = provider
|
|
||||||
self.assertEqual(provider.parent_name, "name")
|
|
||||||
|
|
||||||
def test_parent_name_with_deep_parenting(self):
|
|
||||||
provider = providers.Dependency()
|
|
||||||
container = providers.DependenciesContainer(name=provider)
|
|
||||||
_ = providers.DependenciesContainer(container=container)
|
|
||||||
self.assertEqual(provider.parent_name, "container.name")
|
|
||||||
|
|
||||||
def test_parent_name_is_none(self):
|
|
||||||
provider = providers.DependenciesContainer()
|
|
||||||
self.assertIsNone(provider.parent_name)
|
|
||||||
|
|
||||||
def test_parent_deepcopy(self):
|
|
||||||
container = containers.DynamicContainer()
|
|
||||||
provider = providers.Dependency()
|
|
||||||
container.name = provider
|
|
||||||
|
|
||||||
copied = providers.deepcopy(container)
|
|
||||||
|
|
||||||
self.assertIs(container.name.parent, container)
|
|
||||||
self.assertIs(copied.name.parent, copied)
|
|
||||||
|
|
||||||
self.assertIsNot(container, copied)
|
|
||||||
self.assertIsNot(container.name, copied.name)
|
|
||||||
self.assertIsNot(container.name.parent, copied.name.parent)
|
|
||||||
|
|
||||||
def test_forward_attr_to_default(self):
|
|
||||||
default = providers.Configuration()
|
|
||||||
|
|
||||||
provider = providers.Dependency(default=default)
|
|
||||||
provider.from_dict({"foo": "bar"})
|
|
||||||
|
|
||||||
self.assertEqual(default(), {"foo": "bar"})
|
|
||||||
|
|
||||||
def test_forward_attr_to_overriding(self):
|
|
||||||
overriding = providers.Configuration()
|
|
||||||
|
|
||||||
provider = providers.Dependency()
|
|
||||||
provider.override(overriding)
|
|
||||||
provider.from_dict({"foo": "bar"})
|
|
||||||
|
|
||||||
self.assertEqual(overriding(), {"foo": "bar"})
|
|
||||||
|
|
||||||
def test_forward_attr_to_none(self):
|
|
||||||
provider = providers.Dependency()
|
|
||||||
with self.assertRaises(AttributeError):
|
|
||||||
provider.from_dict
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
provider = providers.Dependency(int)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Dependency)
|
|
||||||
|
|
||||||
def test_deepcopy_from_memo(self):
|
|
||||||
provider = providers.Dependency(int)
|
|
||||||
provider_copy_memo = providers.Provider()
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(
|
|
||||||
provider, memo={id(provider): provider_copy_memo})
|
|
||||||
|
|
||||||
self.assertIs(provider_copy, provider_copy_memo)
|
|
||||||
|
|
||||||
def test_deepcopy_overridden(self):
|
|
||||||
provider = providers.Dependency(int)
|
|
||||||
overriding_provider = providers.Provider()
|
|
||||||
|
|
||||||
provider.override(overriding_provider)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
overriding_provider_copy = provider_copy.overridden[0]
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider, providers.Dependency)
|
|
||||||
|
|
||||||
self.assertIsNot(overriding_provider, overriding_provider_copy)
|
|
||||||
self.assertIsInstance(overriding_provider_copy, providers.Provider)
|
|
||||||
|
|
||||||
def test_deep_copy_default_object(self):
|
|
||||||
default = {"foo": "bar"}
|
|
||||||
provider = providers.Dependency(dict, default=default)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIs(provider_copy(), default)
|
|
||||||
self.assertIs(provider_copy.default(), default)
|
|
||||||
|
|
||||||
def test_deep_copy_default_provider(self):
|
|
||||||
bar = object()
|
|
||||||
default = providers.Factory(dict, foo=providers.Object(bar))
|
|
||||||
provider = providers.Dependency(dict, default=default)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertEqual(provider_copy(), {"foo": bar})
|
|
||||||
self.assertEqual(provider_copy.default(), {"foo": bar})
|
|
||||||
self.assertIs(provider_copy()["foo"], bar)
|
|
||||||
|
|
||||||
def test_with_container_default_object(self):
|
|
||||||
default = {"foo": "bar"}
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
provider = providers.Dependency(dict, default=default)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertIs(container.provider(), default)
|
|
||||||
self.assertIs(container.provider.default(), default)
|
|
||||||
|
|
||||||
def test_with_container_default_provider(self):
|
|
||||||
bar = object()
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
provider = providers.Dependency(dict, default=providers.Factory(dict, foo=providers.Object(bar)))
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertEqual(container.provider(), {"foo": bar})
|
|
||||||
self.assertEqual(container.provider.default(), {"foo": bar})
|
|
||||||
self.assertIs(container.provider()["foo"], bar)
|
|
||||||
|
|
||||||
def test_with_container_default_provider_with_overriding(self):
|
|
||||||
bar = object()
|
|
||||||
baz = object()
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
provider = providers.Dependency(dict, default=providers.Factory(dict, foo=providers.Object(bar)))
|
|
||||||
|
|
||||||
container = Container(provider=providers.Factory(dict, foo=providers.Object(baz)))
|
|
||||||
|
|
||||||
self.assertEqual(container.provider(), {"foo": baz})
|
|
||||||
self.assertEqual(container.provider.default(), {"foo": bar})
|
|
||||||
self.assertIs(container.provider()["foo"], baz)
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
self.assertEqual(repr(self.provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Dependency({0}) at {1}>".format(
|
|
||||||
repr(list),
|
|
||||||
hex(id(self.provider))))
|
|
||||||
|
|
||||||
def test_repr_in_container(self):
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
dependency = providers.Dependency(instance_of=int)
|
|
||||||
|
|
||||||
container = Container()
|
|
||||||
|
|
||||||
self.assertEqual(repr(container.dependency),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Dependency({0}) at {1}, container name: \"Container.dependency\">".format(
|
|
||||||
repr(int),
|
|
||||||
hex(id(container.dependency))))
|
|
||||||
|
|
||||||
|
|
||||||
class ExternalDependencyTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.provider = providers.ExternalDependency(instance_of=list)
|
|
||||||
|
|
||||||
def test_is_instance(self):
|
|
||||||
self.assertIsInstance(self.provider, providers.Dependency)
|
|
||||||
|
|
||||||
|
|
||||||
class DependenciesContainerTests(unittest.TestCase):
|
|
||||||
|
|
||||||
class Container(containers.DeclarativeContainer):
|
|
||||||
|
|
||||||
dependency = providers.Provider()
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.provider = providers.DependenciesContainer()
|
|
||||||
self.container = self.Container()
|
|
||||||
|
|
||||||
def test_getattr(self):
|
|
||||||
has_dependency = hasattr(self.provider, "dependency")
|
|
||||||
dependency = self.provider.dependency
|
|
||||||
|
|
||||||
self.assertIsInstance(dependency, providers.Dependency)
|
|
||||||
self.assertIs(dependency, self.provider.dependency)
|
|
||||||
self.assertTrue(has_dependency)
|
|
||||||
self.assertIsNone(dependency.last_overriding)
|
|
||||||
|
|
||||||
def test_getattr_with_container(self):
|
|
||||||
self.provider.override(self.container)
|
|
||||||
|
|
||||||
dependency = self.provider.dependency
|
|
||||||
|
|
||||||
self.assertTrue(dependency.overridden)
|
|
||||||
self.assertIs(dependency.last_overriding, self.container.dependency)
|
|
||||||
|
|
||||||
def test_providers(self):
|
|
||||||
dependency1 = self.provider.dependency1
|
|
||||||
dependency2 = self.provider.dependency2
|
|
||||||
self.assertEqual(self.provider.providers, {"dependency1": dependency1,
|
|
||||||
"dependency2": dependency2})
|
|
||||||
|
|
||||||
def test_override(self):
|
|
||||||
dependency = self.provider.dependency
|
|
||||||
self.provider.override(self.container)
|
|
||||||
|
|
||||||
self.assertTrue(dependency.overridden)
|
|
||||||
self.assertIs(dependency.last_overriding, self.container.dependency)
|
|
||||||
|
|
||||||
def test_reset_last_overriding(self):
|
|
||||||
dependency = self.provider.dependency
|
|
||||||
self.provider.override(self.container)
|
|
||||||
self.provider.reset_last_overriding()
|
|
||||||
|
|
||||||
self.assertIsNone(dependency.last_overriding)
|
|
||||||
self.assertIsNone(dependency.last_overriding)
|
|
||||||
|
|
||||||
def test_reset_override(self):
|
|
||||||
dependency = self.provider.dependency
|
|
||||||
self.provider.override(self.container)
|
|
||||||
self.provider.reset_override()
|
|
||||||
|
|
||||||
self.assertFalse(dependency.overridden)
|
|
||||||
self.assertFalse(dependency.overridden)
|
|
||||||
|
|
||||||
def test_assign_parent(self):
|
|
||||||
parent = providers.DependenciesContainer()
|
|
||||||
provider = providers.DependenciesContainer()
|
|
||||||
|
|
||||||
provider.assign_parent(parent)
|
|
||||||
|
|
||||||
self.assertIs(provider.parent, parent)
|
|
||||||
|
|
||||||
def test_parent_name(self):
|
|
||||||
container = containers.DynamicContainer()
|
|
||||||
provider = providers.DependenciesContainer()
|
|
||||||
container.name = provider
|
|
||||||
self.assertEqual(provider.parent_name, "name")
|
|
||||||
|
|
||||||
def test_parent_name_with_deep_parenting(self):
|
|
||||||
provider = providers.DependenciesContainer()
|
|
||||||
container = providers.DependenciesContainer(name=provider)
|
|
||||||
_ = providers.DependenciesContainer(container=container)
|
|
||||||
self.assertEqual(provider.parent_name, "container.name")
|
|
||||||
|
|
||||||
def test_parent_name_is_none(self):
|
|
||||||
provider = providers.DependenciesContainer()
|
|
||||||
self.assertIsNone(provider.parent_name)
|
|
||||||
|
|
||||||
def test_parent_deepcopy(self):
|
|
||||||
container = containers.DynamicContainer()
|
|
||||||
provider = providers.DependenciesContainer()
|
|
||||||
container.name = provider
|
|
||||||
|
|
||||||
copied = providers.deepcopy(container)
|
|
||||||
|
|
||||||
self.assertIs(container.name.parent, container)
|
|
||||||
self.assertIs(copied.name.parent, copied)
|
|
||||||
|
|
||||||
self.assertIsNot(container, copied)
|
|
||||||
self.assertIsNot(container.name, copied.name)
|
|
||||||
self.assertIsNot(container.name.parent, copied.name.parent)
|
|
||||||
|
|
||||||
def test_parent_set_on__getattr__(self):
|
|
||||||
provider = providers.DependenciesContainer()
|
|
||||||
self.assertIsInstance(provider.name, providers.Dependency)
|
|
||||||
self.assertIs(provider.name.parent, provider)
|
|
||||||
|
|
||||||
def test_parent_set_on__init__(self):
|
|
||||||
provider = providers.Dependency()
|
|
||||||
container = providers.DependenciesContainer(name=provider)
|
|
||||||
self.assertIs(container.name, provider)
|
|
||||||
self.assertIs(container.name.parent, container)
|
|
||||||
|
|
||||||
def test_resolve_provider_name(self):
|
|
||||||
container = providers.DependenciesContainer()
|
|
||||||
self.assertEqual(container.resolve_provider_name(container.name), "name")
|
|
||||||
|
|
||||||
def test_resolve_provider_name_no_provider(self):
|
|
||||||
container = providers.DependenciesContainer()
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
container.resolve_provider_name(providers.Provider())
|
|
|
@ -1,296 +0,0 @@
|
||||||
"""Dependency injector callable providers unit tests."""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from dependency_injector import (
|
|
||||||
providers,
|
|
||||||
errors,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def _example(arg1, arg2, arg3, arg4):
|
|
||||||
return arg1, arg2, arg3, arg4
|
|
||||||
|
|
||||||
|
|
||||||
class CallableTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_init_with_callable(self):
|
|
||||||
self.assertTrue(providers.Callable(_example))
|
|
||||||
|
|
||||||
def test_init_with_not_callable(self):
|
|
||||||
self.assertRaises(errors.Error, providers.Callable, 123)
|
|
||||||
|
|
||||||
def test_init_optional_provides(self):
|
|
||||||
provider = providers.Callable()
|
|
||||||
provider.set_provides(object)
|
|
||||||
self.assertIs(provider.provides, object)
|
|
||||||
self.assertIsInstance(provider(), object)
|
|
||||||
|
|
||||||
def test_set_provides_returns_self(self):
|
|
||||||
provider = providers.Callable()
|
|
||||||
self.assertIs(provider.set_provides(object), provider)
|
|
||||||
|
|
||||||
def test_provided_instance_provider(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
self.assertIsInstance(provider.provided, providers.ProvidedInstance)
|
|
||||||
|
|
||||||
def test_call(self):
|
|
||||||
provider = providers.Callable(lambda: True)
|
|
||||||
self.assertTrue(provider())
|
|
||||||
|
|
||||||
def test_call_with_positional_args(self):
|
|
||||||
provider = providers.Callable(_example,
|
|
||||||
1, 2, 3, 4)
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_keyword_args(self):
|
|
||||||
provider = providers.Callable(_example,
|
|
||||||
arg1=1, arg2=2, arg3=3, arg4=4)
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_positional_and_keyword_args(self):
|
|
||||||
provider = providers.Callable(_example,
|
|
||||||
1, 2,
|
|
||||||
arg3=3, arg4=4)
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_context_args(self):
|
|
||||||
provider = providers.Callable(_example, 1, 2)
|
|
||||||
self.assertTupleEqual(provider(3, 4), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_context_kwargs(self):
|
|
||||||
provider = providers.Callable(_example, arg1=1)
|
|
||||||
self.assertTupleEqual(provider(arg2=2, arg3=3, arg4=4), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_context_args_and_kwargs(self):
|
|
||||||
provider = providers.Callable(_example, 1)
|
|
||||||
self.assertTupleEqual(provider(2, arg3=3, arg4=4), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_fluent_interface(self):
|
|
||||||
provider = providers.Singleton(_example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.add_kwargs(arg3=3, arg4=4)
|
|
||||||
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_set_args(self):
|
|
||||||
provider = providers.Callable(_example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.set_args(3, 4)
|
|
||||||
self.assertEqual(provider.args, (3, 4))
|
|
||||||
|
|
||||||
def test_set_kwargs(self):
|
|
||||||
provider = providers.Callable(_example) \
|
|
||||||
.add_kwargs(init_arg3=3, init_arg4=4) \
|
|
||||||
.set_kwargs(init_arg3=4, init_arg4=5)
|
|
||||||
self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5))
|
|
||||||
|
|
||||||
def test_clear_args(self):
|
|
||||||
provider = providers.Callable(_example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.clear_args()
|
|
||||||
self.assertEqual(provider.args, tuple())
|
|
||||||
|
|
||||||
def test_clear_kwargs(self):
|
|
||||||
provider = providers.Callable(_example) \
|
|
||||||
.add_kwargs(init_arg3=3, init_arg4=4) \
|
|
||||||
.clear_kwargs()
|
|
||||||
self.assertEqual(provider.kwargs, dict())
|
|
||||||
|
|
||||||
def test_call_overridden(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
|
|
||||||
provider.override(providers.Object((4, 3, 2, 1)))
|
|
||||||
provider.override(providers.Object((1, 2, 3, 4)))
|
|
||||||
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIs(provider.provides, provider_copy.provides)
|
|
||||||
self.assertIsInstance(provider, providers.Callable)
|
|
||||||
|
|
||||||
def test_deepcopy_from_memo(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
provider_copy_memo = providers.Callable(_example)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(
|
|
||||||
provider, memo={id(provider): provider_copy_memo})
|
|
||||||
|
|
||||||
self.assertIs(provider_copy, provider_copy_memo)
|
|
||||||
|
|
||||||
def test_deepcopy_args(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
dependent_provider1 = providers.Callable(list)
|
|
||||||
dependent_provider2 = providers.Callable(dict)
|
|
||||||
|
|
||||||
provider.add_args(dependent_provider1, dependent_provider2)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
dependent_provider_copy1 = provider_copy.args[0]
|
|
||||||
dependent_provider_copy2 = provider_copy.args[1]
|
|
||||||
|
|
||||||
self.assertNotEqual(provider.args, provider_copy.args)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider1.provides,
|
|
||||||
dependent_provider_copy1.provides)
|
|
||||||
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider2.provides,
|
|
||||||
dependent_provider_copy2.provides)
|
|
||||||
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
|
||||||
|
|
||||||
def test_deepcopy_kwargs(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
dependent_provider1 = providers.Callable(list)
|
|
||||||
dependent_provider2 = providers.Callable(dict)
|
|
||||||
|
|
||||||
provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
dependent_provider_copy1 = provider_copy.kwargs["a1"]
|
|
||||||
dependent_provider_copy2 = provider_copy.kwargs["a2"]
|
|
||||||
|
|
||||||
self.assertNotEqual(provider.kwargs, provider_copy.kwargs)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider1.provides,
|
|
||||||
dependent_provider_copy1.provides)
|
|
||||||
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider2.provides,
|
|
||||||
dependent_provider_copy2.provides)
|
|
||||||
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
|
||||||
|
|
||||||
def test_deepcopy_overridden(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
object_provider = providers.Object(object())
|
|
||||||
|
|
||||||
provider.override(object_provider)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
object_provider_copy = provider_copy.overridden[0]
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIs(provider.provides, provider_copy.provides)
|
|
||||||
self.assertIsInstance(provider, providers.Callable)
|
|
||||||
|
|
||||||
self.assertIsNot(object_provider, object_provider_copy)
|
|
||||||
self.assertIsInstance(object_provider_copy, providers.Object)
|
|
||||||
|
|
||||||
def test_deepcopy_with_sys_streams(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
provider.add_args(sys.stdin)
|
|
||||||
provider.add_kwargs(a2=sys.stdout)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIsInstance(provider_copy, providers.Callable)
|
|
||||||
self.assertIs(provider.args[0], sys.stdin)
|
|
||||||
self.assertIs(provider.kwargs["a2"], sys.stdout)
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
provider = providers.Callable(_example)
|
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Callable({0}) at {1}>".format(
|
|
||||||
repr(_example),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class DelegatedCallableTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_inheritance(self):
|
|
||||||
self.assertIsInstance(providers.DelegatedCallable(_example),
|
|
||||||
providers.Callable)
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(
|
|
||||||
providers.is_provider(providers.DelegatedCallable(_example)))
|
|
||||||
|
|
||||||
def test_is_delegated_provider(self):
|
|
||||||
provider = providers.DelegatedCallable(_example)
|
|
||||||
self.assertTrue(providers.is_delegated(provider))
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
provider = providers.DelegatedCallable(_example)
|
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"DelegatedCallable({0}) at {1}>".format(
|
|
||||||
repr(_example),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractCallableTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_inheritance(self):
|
|
||||||
self.assertIsInstance(providers.AbstractCallable(_example),
|
|
||||||
providers.Callable)
|
|
||||||
|
|
||||||
def test_call_overridden_by_callable(self):
|
|
||||||
def _abstract_example():
|
|
||||||
pass
|
|
||||||
|
|
||||||
provider = providers.AbstractCallable(_abstract_example)
|
|
||||||
provider.override(providers.Callable(_example))
|
|
||||||
|
|
||||||
self.assertTrue(provider(1, 2, 3, 4), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_overridden_by_delegated_callable(self):
|
|
||||||
def _abstract_example():
|
|
||||||
pass
|
|
||||||
|
|
||||||
provider = providers.AbstractCallable(_abstract_example)
|
|
||||||
provider.override(providers.DelegatedCallable(_example))
|
|
||||||
|
|
||||||
self.assertTrue(provider(1, 2, 3, 4), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_not_overridden(self):
|
|
||||||
provider = providers.AbstractCallable(_example)
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
provider(1, 2, 3, 4)
|
|
||||||
|
|
||||||
def test_override_by_not_callable(self):
|
|
||||||
provider = providers.AbstractCallable(_example)
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
provider.override(providers.Factory(object))
|
|
||||||
|
|
||||||
def test_provide_not_implemented(self):
|
|
||||||
provider = providers.AbstractCallable(_example)
|
|
||||||
|
|
||||||
with self.assertRaises(NotImplementedError):
|
|
||||||
provider._provide((1, 2, 3, 4), dict())
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
provider = providers.AbstractCallable(_example)
|
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"AbstractCallable({0}) at {1}>".format(
|
|
||||||
repr(_example),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class CallableDelegateTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.delegated = providers.Callable(_example)
|
|
||||||
self.delegate = providers.CallableDelegate(self.delegated)
|
|
||||||
|
|
||||||
def test_is_delegate(self):
|
|
||||||
self.assertIsInstance(self.delegate, providers.Delegate)
|
|
||||||
|
|
||||||
def test_init_with_not_callable(self):
|
|
||||||
self.assertRaises(errors.Error,
|
|
||||||
providers.CallableDelegate,
|
|
||||||
providers.Object(object()))
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,10 +1,9 @@
|
||||||
"""Dependency injector container provider unit tests."""
|
"""Container provider tests."""
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
from dependency_injector import containers, providers, errors
|
from dependency_injector import containers, providers, errors
|
||||||
|
from pytest import raises
|
||||||
|
|
||||||
|
|
||||||
TEST_VALUE_1 = "core_section_value1"
|
TEST_VALUE_1 = "core_section_value1"
|
||||||
|
@ -30,237 +29,238 @@ def _copied(value):
|
||||||
return copy.deepcopy(value)
|
return copy.deepcopy(value)
|
||||||
|
|
||||||
|
|
||||||
class TestCore(containers.DeclarativeContainer):
|
class Core(containers.DeclarativeContainer):
|
||||||
config = providers.Configuration("core")
|
config = providers.Configuration("core")
|
||||||
value_getter = providers.Callable(lambda _: _, config.section.value)
|
value_getter = providers.Callable(lambda _: _, config.section.value)
|
||||||
|
|
||||||
|
|
||||||
class TestApplication(containers.DeclarativeContainer):
|
class Application(containers.DeclarativeContainer):
|
||||||
config = providers.Configuration("config")
|
config = providers.Configuration("config")
|
||||||
core = providers.Container(TestCore, config=config.core)
|
core = providers.Container(Core, config=config.core)
|
||||||
dict_factory = providers.Factory(dict, value=core.value_getter)
|
dict_factory = providers.Factory(dict, value=core.value_getter)
|
||||||
|
|
||||||
|
|
||||||
class ContainerTests(unittest.TestCase):
|
def test():
|
||||||
|
application = Application(config=_copied(TEST_CONFIG_1))
|
||||||
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
||||||
|
|
||||||
def test(self):
|
|
||||||
application = TestApplication(config=_copied(TEST_CONFIG_1))
|
|
||||||
self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_1})
|
|
||||||
|
|
||||||
def test_double_override(self):
|
def test_double_override():
|
||||||
application = TestApplication()
|
application = Application()
|
||||||
application.config.override(_copied(TEST_CONFIG_1))
|
application.config.override(_copied(TEST_CONFIG_1))
|
||||||
application.config.override(_copied(TEST_CONFIG_2))
|
application.config.override(_copied(TEST_CONFIG_2))
|
||||||
self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_2})
|
assert application.dict_factory() == {"value": TEST_VALUE_2}
|
||||||
|
|
||||||
def test_override(self):
|
|
||||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
|
|
||||||
class D(containers.DeclarativeContainer):
|
|
||||||
foo = providers.Object("foo")
|
|
||||||
|
|
||||||
class A(containers.DeclarativeContainer):
|
def test_override():
|
||||||
d = providers.DependenciesContainer()
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
|
||||||
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
class D(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Object("foo")
|
||||||
|
|
||||||
class B(containers.DeclarativeContainer):
|
class A(containers.DeclarativeContainer):
|
||||||
d = providers.Container(D)
|
d = providers.DependenciesContainer()
|
||||||
|
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
||||||
|
|
||||||
a = providers.Container(A, d=d)
|
class B(containers.DeclarativeContainer):
|
||||||
|
d = providers.Container(D)
|
||||||
|
|
||||||
b = B(d=D())
|
a = providers.Container(A, d=d)
|
||||||
result = b.a().bar()
|
|
||||||
self.assertEqual(result, "foo++")
|
|
||||||
|
|
||||||
def test_override_not_root_provider(self):
|
b = B(d=D())
|
||||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/379
|
result = b.a().bar()
|
||||||
class NestedContainer(containers.DeclarativeContainer):
|
assert result == "foo++"
|
||||||
settings = providers.Configuration()
|
|
||||||
|
|
||||||
print_settings = providers.Callable(
|
|
||||||
lambda s: s,
|
|
||||||
settings,
|
|
||||||
)
|
|
||||||
|
|
||||||
class TestContainer(containers.DeclarativeContainer):
|
def test_override_not_root_provider():
|
||||||
settings = providers.Configuration()
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/379
|
||||||
|
class NestedContainer(containers.DeclarativeContainer):
|
||||||
|
settings = providers.Configuration()
|
||||||
|
|
||||||
root_container = providers.Container(
|
print_settings = providers.Callable(
|
||||||
|
lambda s: s,
|
||||||
|
settings,
|
||||||
|
)
|
||||||
|
|
||||||
|
class TestContainer(containers.DeclarativeContainer):
|
||||||
|
settings = providers.Configuration()
|
||||||
|
|
||||||
|
root_container = providers.Container(
|
||||||
|
NestedContainer,
|
||||||
|
settings=settings,
|
||||||
|
)
|
||||||
|
|
||||||
|
not_root_container = providers.Selector(
|
||||||
|
settings.container,
|
||||||
|
using_factory=providers.Factory(
|
||||||
|
NestedContainer,
|
||||||
|
settings=settings,
|
||||||
|
),
|
||||||
|
using_container=providers.Container(
|
||||||
NestedContainer,
|
NestedContainer,
|
||||||
settings=settings,
|
settings=settings,
|
||||||
)
|
)
|
||||||
|
|
||||||
not_root_container = providers.Selector(
|
|
||||||
settings.container,
|
|
||||||
using_factory=providers.Factory(
|
|
||||||
NestedContainer,
|
|
||||||
settings=settings,
|
|
||||||
),
|
|
||||||
using_container=providers.Container(
|
|
||||||
NestedContainer,
|
|
||||||
settings=settings,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
container_using_factory = TestContainer(settings=dict(
|
|
||||||
container="using_factory",
|
|
||||||
foo="bar"
|
|
||||||
))
|
|
||||||
self.assertEqual(
|
|
||||||
container_using_factory.root_container().print_settings(),
|
|
||||||
{"container": "using_factory", "foo": "bar"},
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
container_using_factory.not_root_container().print_settings(),
|
|
||||||
{"container": "using_factory", "foo": "bar"},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
container_using_factory = TestContainer(settings=dict(
|
||||||
|
container="using_factory",
|
||||||
|
foo="bar"
|
||||||
|
))
|
||||||
|
assert container_using_factory.root_container().print_settings() == {"container": "using_factory", "foo": "bar"}
|
||||||
|
assert container_using_factory.not_root_container().print_settings() == {"container": "using_factory", "foo": "bar"}
|
||||||
|
|
||||||
container_using_container = TestContainer(settings=dict(
|
container_using_container = TestContainer(settings=dict(
|
||||||
container="using_container",
|
container="using_container",
|
||||||
foo="bar"
|
foo="bar"
|
||||||
))
|
))
|
||||||
self.assertEqual(
|
assert container_using_container.root_container().print_settings() == {"container": "using_container", "foo": "bar"}
|
||||||
container_using_container.root_container().print_settings(),
|
assert container_using_container.not_root_container().print_settings() == {"container": "using_container", "foo": "bar"}
|
||||||
{"container": "using_container", "foo": "bar"},
|
|
||||||
)
|
|
||||||
self.assertEqual(
|
|
||||||
container_using_container.not_root_container().print_settings(),
|
|
||||||
{"container": "using_container", "foo": "bar"},
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_override_by_not_a_container(self):
|
|
||||||
provider = providers.Container(TestCore)
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
def test_override_by_not_a_container():
|
||||||
provider.override(providers.Object("foo"))
|
provider = providers.Container(Core)
|
||||||
|
|
||||||
def test_lazy_overriding(self):
|
with raises(errors.Error):
|
||||||
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
|
provider.override(providers.Object("foo"))
|
||||||
|
|
||||||
class D(containers.DeclarativeContainer):
|
|
||||||
foo = providers.Object("foo")
|
|
||||||
|
|
||||||
class A(containers.DeclarativeContainer):
|
def test_lazy_overriding():
|
||||||
d = providers.DependenciesContainer()
|
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
|
||||||
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
class D(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Object("foo")
|
||||||
|
|
||||||
class B(containers.DeclarativeContainer):
|
class A(containers.DeclarativeContainer):
|
||||||
d = providers.DependenciesContainer()
|
d = providers.DependenciesContainer()
|
||||||
|
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
||||||
|
|
||||||
a = providers.Container(A, d=d)
|
class B(containers.DeclarativeContainer):
|
||||||
|
d = providers.DependenciesContainer()
|
||||||
|
|
||||||
b = B(d=D())
|
a = providers.Container(A, d=d)
|
||||||
result = b.a().bar()
|
|
||||||
self.assertEqual(result, "foo++")
|
|
||||||
|
|
||||||
def test_lazy_overriding_deep(self):
|
b = B(d=D())
|
||||||
# Extended version of test_lazy_overriding()
|
result = b.a().bar()
|
||||||
|
assert result == "foo++"
|
||||||
|
|
||||||
class D(containers.DeclarativeContainer):
|
|
||||||
foo = providers.Object("foo")
|
|
||||||
|
|
||||||
class C(containers.DeclarativeContainer):
|
def test_lazy_overriding_deep():
|
||||||
d = providers.DependenciesContainer()
|
# Extended version of test_lazy_overriding()
|
||||||
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
class D(containers.DeclarativeContainer):
|
||||||
|
foo = providers.Object("foo")
|
||||||
|
|
||||||
class A(containers.DeclarativeContainer):
|
class C(containers.DeclarativeContainer):
|
||||||
d = providers.DependenciesContainer()
|
d = providers.DependenciesContainer()
|
||||||
c = providers.Container(C, d=d)
|
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
|
||||||
|
|
||||||
class B(containers.DeclarativeContainer):
|
class A(containers.DeclarativeContainer):
|
||||||
d = providers.DependenciesContainer()
|
d = providers.DependenciesContainer()
|
||||||
|
c = providers.Container(C, d=d)
|
||||||
|
|
||||||
a = providers.Container(A, d=d)
|
class B(containers.DeclarativeContainer):
|
||||||
|
d = providers.DependenciesContainer()
|
||||||
|
|
||||||
b = B(d=D())
|
a = providers.Container(A, d=d)
|
||||||
result = b.a().c().bar()
|
|
||||||
self.assertEqual(result, "foo++")
|
|
||||||
|
|
||||||
def test_reset_last_overriding(self):
|
b = B(d=D())
|
||||||
application = TestApplication(config=_copied(TEST_CONFIG_1))
|
result = b.a().c().bar()
|
||||||
application.core.override(TestCore(config=_copied(TEST_CONFIG_2["core"])))
|
assert result == "foo++"
|
||||||
|
|
||||||
application.core.reset_last_overriding()
|
|
||||||
|
|
||||||
self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_1})
|
def test_reset_last_overriding():
|
||||||
|
application = Application(config=_copied(TEST_CONFIG_1))
|
||||||
|
application.core.override(Core(config=_copied(TEST_CONFIG_2["core"])))
|
||||||
|
|
||||||
def test_reset_last_overriding_only_overridden(self):
|
application.core.reset_last_overriding()
|
||||||
application = TestApplication(config=_copied(TEST_CONFIG_1))
|
|
||||||
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
|
|
||||||
|
|
||||||
application.core.reset_last_overriding()
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
||||||
|
|
||||||
self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_1})
|
|
||||||
|
|
||||||
def test_override_context_manager(self):
|
def test_reset_last_overriding_only_overridden():
|
||||||
application = TestApplication(config=_copied(TEST_CONFIG_1))
|
application = Application(config=_copied(TEST_CONFIG_1))
|
||||||
overriding_core = TestCore(config=_copied(TEST_CONFIG_2["core"]))
|
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
|
||||||
|
|
||||||
with application.core.override(overriding_core) as context_core:
|
application.core.reset_last_overriding()
|
||||||
self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_2})
|
|
||||||
self.assertIs(context_core(), overriding_core)
|
|
||||||
|
|
||||||
self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_1})
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
||||||
|
|
||||||
def test_reset_override(self):
|
|
||||||
application = TestApplication(config=_copied(TEST_CONFIG_1))
|
|
||||||
application.core.override(TestCore(config=_copied(TEST_CONFIG_2["core"])))
|
|
||||||
|
|
||||||
application.core.reset_override()
|
def test_override_context_manager():
|
||||||
|
application = Application(config=_copied(TEST_CONFIG_1))
|
||||||
|
overriding_core = Core(config=_copied(TEST_CONFIG_2["core"]))
|
||||||
|
|
||||||
self.assertEqual(application.dict_factory(), {"value": None})
|
with application.core.override(overriding_core) as context_core:
|
||||||
|
assert application.dict_factory() == {"value": TEST_VALUE_2}
|
||||||
|
assert context_core() is overriding_core
|
||||||
|
|
||||||
def test_reset_override_only_overridden(self):
|
assert application.dict_factory() == {"value": TEST_VALUE_1}
|
||||||
application = TestApplication(config=_copied(TEST_CONFIG_1))
|
|
||||||
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
|
|
||||||
|
|
||||||
application.core.reset_override()
|
|
||||||
|
|
||||||
self.assertEqual(application.dict_factory(), {"value": None})
|
def test_reset_override():
|
||||||
|
application = Application(config=_copied(TEST_CONFIG_1))
|
||||||
|
application.core.override(Core(config=_copied(TEST_CONFIG_2["core"])))
|
||||||
|
|
||||||
def test_assign_parent(self):
|
application.core.reset_override()
|
||||||
parent = providers.DependenciesContainer()
|
|
||||||
provider = providers.Container(TestCore)
|
|
||||||
|
|
||||||
provider.assign_parent(parent)
|
assert application.dict_factory() == {"value": None}
|
||||||
|
|
||||||
self.assertIs(provider.parent, parent)
|
|
||||||
|
|
||||||
def test_parent_name(self):
|
def test_reset_override_only_overridden():
|
||||||
container = containers.DynamicContainer()
|
application = Application(config=_copied(TEST_CONFIG_1))
|
||||||
provider = providers.Container(TestCore)
|
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
|
||||||
container.name = provider
|
|
||||||
self.assertEqual(provider.parent_name, "name")
|
|
||||||
|
|
||||||
def test_parent_name_with_deep_parenting(self):
|
application.core.reset_override()
|
||||||
provider = providers.Container(TestCore)
|
|
||||||
container = providers.DependenciesContainer(name=provider)
|
|
||||||
_ = providers.DependenciesContainer(container=container)
|
|
||||||
self.assertEqual(provider.parent_name, "container.name")
|
|
||||||
|
|
||||||
def test_parent_name_is_none(self):
|
assert application.dict_factory() == {"value": None}
|
||||||
provider = providers.Container(TestCore)
|
|
||||||
self.assertIsNone(provider.parent_name)
|
|
||||||
|
|
||||||
def test_parent_deepcopy(self):
|
|
||||||
container = containers.DynamicContainer()
|
|
||||||
provider = providers.Container(TestCore)
|
|
||||||
container.name = provider
|
|
||||||
|
|
||||||
copied = providers.deepcopy(container)
|
def test_assign_parent():
|
||||||
|
parent = providers.DependenciesContainer()
|
||||||
|
provider = providers.Container(Core)
|
||||||
|
|
||||||
self.assertIs(container.name.parent, container)
|
provider.assign_parent(parent)
|
||||||
self.assertIs(copied.name.parent, copied)
|
|
||||||
|
|
||||||
self.assertIsNot(container, copied)
|
assert provider.parent is parent
|
||||||
self.assertIsNot(container.name, copied.name)
|
|
||||||
self.assertIsNot(container.name.parent, copied.name.parent)
|
|
||||||
|
|
||||||
def test_resolve_provider_name(self):
|
|
||||||
container = providers.Container(TestCore)
|
|
||||||
self.assertEqual(container.resolve_provider_name(container.value_getter), "value_getter")
|
|
||||||
|
|
||||||
def test_resolve_provider_name_no_provider(self):
|
def test_parent_name():
|
||||||
container = providers.Container(TestCore)
|
container = containers.DynamicContainer()
|
||||||
with self.assertRaises(errors.Error):
|
provider = providers.Container(Core)
|
||||||
container.resolve_provider_name(providers.Provider())
|
container.name = provider
|
||||||
|
assert provider.parent_name == "name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_with_deep_parenting():
|
||||||
|
provider = providers.Container(Core)
|
||||||
|
container = providers.DependenciesContainer(name=provider)
|
||||||
|
_ = providers.DependenciesContainer(container=container)
|
||||||
|
assert provider.parent_name == "container.name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_is_none():
|
||||||
|
provider = providers.Container(Core)
|
||||||
|
assert provider.parent_name is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_deepcopy():
|
||||||
|
container = containers.DynamicContainer()
|
||||||
|
provider = providers.Container(Core)
|
||||||
|
container.name = provider
|
||||||
|
|
||||||
|
copied = providers.deepcopy(container)
|
||||||
|
|
||||||
|
assert container.name.parent is container
|
||||||
|
assert copied.name.parent is copied
|
||||||
|
|
||||||
|
assert container is not copied
|
||||||
|
assert container.name is not copied.name
|
||||||
|
assert container.name.parent is not copied.name.parent
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name():
|
||||||
|
container = providers.Container(Core)
|
||||||
|
assert container.resolve_provider_name(container.value_getter) == "value_getter"
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name_no_provider():
|
||||||
|
container = providers.Container(Core)
|
||||||
|
with raises(errors.Error):
|
||||||
|
container.resolve_provider_name(providers.Provider())
|
||||||
|
|
|
@ -1,310 +0,0 @@
|
||||||
"""Dependency injector coroutine providers unit tests."""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import unittest
|
|
||||||
import warnings
|
|
||||||
|
|
||||||
from dependency_injector import (
|
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
async def _example(arg1, arg2, arg3, arg4):
|
|
||||||
future = asyncio.Future()
|
|
||||||
future.set_result(None)
|
|
||||||
await future
|
|
||||||
return arg1, arg2, arg3, arg4
|
|
||||||
|
|
||||||
|
|
||||||
def run(main):
|
|
||||||
loop = asyncio.get_event_loop()
|
|
||||||
return loop.run_until_complete(main)
|
|
||||||
|
|
||||||
|
|
||||||
class CoroutineTests(AsyncTestCase):
|
|
||||||
|
|
||||||
def test_init_with_coroutine(self):
|
|
||||||
self.assertTrue(providers.Coroutine(_example))
|
|
||||||
|
|
||||||
def test_init_with_not_coroutine(self):
|
|
||||||
self.assertRaises(errors.Error, providers.Coroutine, lambda: None)
|
|
||||||
|
|
||||||
def test_init_optional_provides(self):
|
|
||||||
provider = providers.Coroutine()
|
|
||||||
provider.set_provides(_example)
|
|
||||||
self.assertIs(provider.provides, _example)
|
|
||||||
self.assertEqual(run(provider(1, 2, 3, 4)), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_set_provides_returns_self(self):
|
|
||||||
provider = providers.Coroutine()
|
|
||||||
self.assertIs(provider.set_provides(_example), provider)
|
|
||||||
|
|
||||||
def test_call_with_positional_args(self):
|
|
||||||
provider = providers.Coroutine(_example, 1, 2, 3, 4)
|
|
||||||
self.assertTupleEqual(self._run(provider()), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_keyword_args(self):
|
|
||||||
provider = providers.Coroutine(_example,
|
|
||||||
arg1=1, arg2=2, arg3=3, arg4=4)
|
|
||||||
self.assertTupleEqual(self._run(provider()), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_positional_and_keyword_args(self):
|
|
||||||
provider = providers.Coroutine(_example,
|
|
||||||
1, 2,
|
|
||||||
arg3=3, arg4=4)
|
|
||||||
self.assertTupleEqual(run(provider()), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_context_args(self):
|
|
||||||
provider = providers.Coroutine(_example, 1, 2)
|
|
||||||
self.assertTupleEqual(self._run(provider(3, 4)), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_with_context_kwargs(self):
|
|
||||||
provider = providers.Coroutine(_example, arg1=1)
|
|
||||||
self.assertTupleEqual(
|
|
||||||
self._run(provider(arg2=2, arg3=3, arg4=4)),
|
|
||||||
(1, 2, 3, 4),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_call_with_context_args_and_kwargs(self):
|
|
||||||
provider = providers.Coroutine(_example, 1)
|
|
||||||
self.assertTupleEqual(
|
|
||||||
self._run(provider(2, arg3=3, arg4=4)),
|
|
||||||
(1, 2, 3, 4),
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_fluent_interface(self):
|
|
||||||
provider = providers.Coroutine(_example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.add_kwargs(arg3=3, arg4=4)
|
|
||||||
|
|
||||||
self.assertTupleEqual(self._run(provider()), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_set_args(self):
|
|
||||||
provider = providers.Coroutine(_example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.set_args(3, 4)
|
|
||||||
self.assertEqual(provider.args, (3, 4))
|
|
||||||
|
|
||||||
def test_set_kwargs(self):
|
|
||||||
provider = providers.Coroutine(_example) \
|
|
||||||
.add_kwargs(init_arg3=3, init_arg4=4) \
|
|
||||||
.set_kwargs(init_arg3=4, init_arg4=5)
|
|
||||||
self.assertEqual(provider.kwargs, dict(init_arg3=4, init_arg4=5))
|
|
||||||
|
|
||||||
def test_clear_args(self):
|
|
||||||
provider = providers.Coroutine(_example) \
|
|
||||||
.add_args(1, 2) \
|
|
||||||
.clear_args()
|
|
||||||
self.assertEqual(provider.args, tuple())
|
|
||||||
|
|
||||||
def test_clear_kwargs(self):
|
|
||||||
provider = providers.Coroutine(_example) \
|
|
||||||
.add_kwargs(init_arg3=3, init_arg4=4) \
|
|
||||||
.clear_kwargs()
|
|
||||||
self.assertEqual(provider.kwargs, dict())
|
|
||||||
|
|
||||||
def test_call_overridden(self):
|
|
||||||
provider = providers.Coroutine(_example)
|
|
||||||
|
|
||||||
provider.override(providers.Object((4, 3, 2, 1)))
|
|
||||||
provider.override(providers.Object((1, 2, 3, 4)))
|
|
||||||
|
|
||||||
self.assertTupleEqual(provider(), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_deepcopy(self):
|
|
||||||
provider = providers.Coroutine(_example)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIs(provider.provides, provider_copy.provides)
|
|
||||||
self.assertIsInstance(provider, providers.Coroutine)
|
|
||||||
|
|
||||||
def test_deepcopy_from_memo(self):
|
|
||||||
provider = providers.Coroutine(_example)
|
|
||||||
provider_copy_memo = providers.Coroutine(_example)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(
|
|
||||||
provider, memo={id(provider): provider_copy_memo})
|
|
||||||
|
|
||||||
self.assertIs(provider_copy, provider_copy_memo)
|
|
||||||
|
|
||||||
def test_deepcopy_args(self):
|
|
||||||
provider = providers.Coroutine(_example)
|
|
||||||
dependent_provider1 = providers.Callable(list)
|
|
||||||
dependent_provider2 = providers.Callable(dict)
|
|
||||||
|
|
||||||
provider.add_args(dependent_provider1, dependent_provider2)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
dependent_provider_copy1 = provider_copy.args[0]
|
|
||||||
dependent_provider_copy2 = provider_copy.args[1]
|
|
||||||
|
|
||||||
self.assertNotEqual(provider.args, provider_copy.args)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider1.provides,
|
|
||||||
dependent_provider_copy1.provides)
|
|
||||||
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider2.provides,
|
|
||||||
dependent_provider_copy2.provides)
|
|
||||||
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
|
||||||
|
|
||||||
def test_deepcopy_kwargs(self):
|
|
||||||
provider = providers.Coroutine(_example)
|
|
||||||
dependent_provider1 = providers.Callable(list)
|
|
||||||
dependent_provider2 = providers.Callable(dict)
|
|
||||||
|
|
||||||
provider.add_kwargs(a1=dependent_provider1, a2=dependent_provider2)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
dependent_provider_copy1 = provider_copy.kwargs["a1"]
|
|
||||||
dependent_provider_copy2 = provider_copy.kwargs["a2"]
|
|
||||||
|
|
||||||
self.assertNotEqual(provider.kwargs, provider_copy.kwargs)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider1.provides,
|
|
||||||
dependent_provider_copy1.provides)
|
|
||||||
self.assertIsNot(dependent_provider1, dependent_provider_copy1)
|
|
||||||
|
|
||||||
self.assertIs(dependent_provider2.provides,
|
|
||||||
dependent_provider_copy2.provides)
|
|
||||||
self.assertIsNot(dependent_provider2, dependent_provider_copy2)
|
|
||||||
|
|
||||||
def test_deepcopy_overridden(self):
|
|
||||||
provider = providers.Coroutine(_example)
|
|
||||||
object_provider = providers.Object(object())
|
|
||||||
|
|
||||||
provider.override(object_provider)
|
|
||||||
|
|
||||||
provider_copy = providers.deepcopy(provider)
|
|
||||||
object_provider_copy = provider_copy.overridden[0]
|
|
||||||
|
|
||||||
self.assertIsNot(provider, provider_copy)
|
|
||||||
self.assertIs(provider.provides, provider_copy.provides)
|
|
||||||
self.assertIsInstance(provider, providers.Callable)
|
|
||||||
|
|
||||||
self.assertIsNot(object_provider, object_provider_copy)
|
|
||||||
self.assertIsInstance(object_provider_copy, providers.Object)
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
provider = providers.Coroutine(_example)
|
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"Coroutine({0}) at {1}>".format(
|
|
||||||
repr(_example),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class DelegatedCoroutineTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def test_inheritance(self):
|
|
||||||
self.assertIsInstance(providers.DelegatedCoroutine(_example),
|
|
||||||
providers.Coroutine)
|
|
||||||
|
|
||||||
def test_is_provider(self):
|
|
||||||
self.assertTrue(
|
|
||||||
providers.is_provider(providers.DelegatedCoroutine(_example)))
|
|
||||||
|
|
||||||
def test_is_delegated_provider(self):
|
|
||||||
provider = providers.DelegatedCoroutine(_example)
|
|
||||||
self.assertTrue(providers.is_delegated(provider))
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
provider = providers.DelegatedCoroutine(_example)
|
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"DelegatedCoroutine({0}) at {1}>".format(
|
|
||||||
repr(_example),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class AbstractCoroutineTests(AsyncTestCase):
|
|
||||||
|
|
||||||
def test_inheritance(self):
|
|
||||||
self.assertIsInstance(providers.AbstractCoroutine(_example),
|
|
||||||
providers.Coroutine)
|
|
||||||
|
|
||||||
def test_call_overridden_by_coroutine(self):
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.simplefilter("ignore")
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def _abstract_example():
|
|
||||||
raise RuntimeError("Should not be raised")
|
|
||||||
|
|
||||||
provider = providers.AbstractCoroutine(_abstract_example)
|
|
||||||
provider.override(providers.Coroutine(_example))
|
|
||||||
|
|
||||||
self.assertTrue(self._run(provider(1, 2, 3, 4)), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_overridden_by_delegated_coroutine(self):
|
|
||||||
with warnings.catch_warnings():
|
|
||||||
warnings.simplefilter("ignore")
|
|
||||||
|
|
||||||
@asyncio.coroutine
|
|
||||||
def _abstract_example():
|
|
||||||
raise RuntimeError("Should not be raised")
|
|
||||||
|
|
||||||
provider = providers.AbstractCoroutine(_abstract_example)
|
|
||||||
provider.override(providers.DelegatedCoroutine(_example))
|
|
||||||
|
|
||||||
self.assertTrue(self._run(provider(1, 2, 3, 4)), (1, 2, 3, 4))
|
|
||||||
|
|
||||||
def test_call_not_overridden(self):
|
|
||||||
provider = providers.AbstractCoroutine(_example)
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
provider(1, 2, 3, 4)
|
|
||||||
|
|
||||||
def test_override_by_not_coroutine(self):
|
|
||||||
provider = providers.AbstractCoroutine(_example)
|
|
||||||
|
|
||||||
with self.assertRaises(errors.Error):
|
|
||||||
provider.override(providers.Factory(object))
|
|
||||||
|
|
||||||
def test_provide_not_implemented(self):
|
|
||||||
provider = providers.AbstractCoroutine(_example)
|
|
||||||
|
|
||||||
with self.assertRaises(NotImplementedError):
|
|
||||||
provider._provide((1, 2, 3, 4), dict())
|
|
||||||
|
|
||||||
def test_repr(self):
|
|
||||||
provider = providers.AbstractCoroutine(_example)
|
|
||||||
|
|
||||||
self.assertEqual(repr(provider),
|
|
||||||
"<dependency_injector.providers."
|
|
||||||
"AbstractCoroutine({0}) at {1}>".format(
|
|
||||||
repr(_example),
|
|
||||||
hex(id(provider))))
|
|
||||||
|
|
||||||
|
|
||||||
class CoroutineDelegateTests(unittest.TestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
self.delegated = providers.Coroutine(_example)
|
|
||||||
self.delegate = providers.CoroutineDelegate(self.delegated)
|
|
||||||
|
|
||||||
def test_is_delegate(self):
|
|
||||||
self.assertIsInstance(self.delegate, providers.Delegate)
|
|
||||||
|
|
||||||
def test_init_with_not_callable(self):
|
|
||||||
self.assertRaises(errors.Error,
|
|
||||||
providers.CoroutineDelegate,
|
|
||||||
providers.Object(object()))
|
|
49
tests/unit/providers/test_delegate_py2_py3.py
Normal file
49
tests/unit/providers/test_delegate_py2_py3.py
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
"""Delegate provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import providers, errors
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider():
|
||||||
|
return providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def delegate(provider):
|
||||||
|
return providers.Delegate(provider)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider(delegate):
|
||||||
|
assert providers.is_provider(delegate) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_optional_provides(provider):
|
||||||
|
delegate = providers.Delegate()
|
||||||
|
delegate.set_provides(provider)
|
||||||
|
assert delegate.provides is provider
|
||||||
|
assert delegate() is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_provides_returns_self(delegate, provider):
|
||||||
|
assert delegate.set_provides(provider) is delegate
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_provider():
|
||||||
|
with raises(errors.Error):
|
||||||
|
providers.Delegate(object())
|
||||||
|
|
||||||
|
|
||||||
|
def test_call(delegate, provider):
|
||||||
|
delegated1 = delegate()
|
||||||
|
delegated2 = delegate()
|
||||||
|
|
||||||
|
assert delegated1 is provider
|
||||||
|
assert delegated2 is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr(delegate, provider):
|
||||||
|
assert repr(delegate) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"Delegate({0}) at {1}>".format(repr(provider), hex(id(delegate)))
|
||||||
|
)
|
125
tests/unit/providers/test_dependencies_container_py2_py3.py
Normal file
125
tests/unit/providers/test_dependencies_container_py2_py3.py
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
"""DependencyContainer provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, errors
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
|
||||||
|
dependency = providers.Provider()
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider():
|
||||||
|
return providers.DependenciesContainer()
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def container():
|
||||||
|
return Container()
|
||||||
|
|
||||||
|
|
||||||
|
def test_getattr(provider):
|
||||||
|
has_dependency = hasattr(provider, "dependency")
|
||||||
|
dependency = provider.dependency
|
||||||
|
|
||||||
|
assert isinstance(dependency, providers.Dependency)
|
||||||
|
assert dependency is provider.dependency
|
||||||
|
assert has_dependency is True
|
||||||
|
assert dependency.last_overriding is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_getattr_with_container(provider, container):
|
||||||
|
provider.override(container)
|
||||||
|
|
||||||
|
dependency = provider.dependency
|
||||||
|
|
||||||
|
assert dependency.overridden == (container.dependency,)
|
||||||
|
assert dependency.last_overriding is container.dependency
|
||||||
|
|
||||||
|
|
||||||
|
def test_providers(provider):
|
||||||
|
dependency1 = provider.dependency1
|
||||||
|
dependency2 = provider.dependency2
|
||||||
|
assert provider.providers == {"dependency1": dependency1, "dependency2": dependency2}
|
||||||
|
|
||||||
|
|
||||||
|
def test_override(provider, container):
|
||||||
|
dependency = provider.dependency
|
||||||
|
provider.override(container)
|
||||||
|
|
||||||
|
assert dependency.overridden == (container.dependency,)
|
||||||
|
assert dependency.last_overriding is container.dependency
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_last_overriding(provider, container):
|
||||||
|
dependency = provider.dependency
|
||||||
|
provider.override(container)
|
||||||
|
provider.reset_last_overriding()
|
||||||
|
|
||||||
|
assert dependency.last_overriding is None
|
||||||
|
assert dependency.last_overriding is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_reset_override(provider, container):
|
||||||
|
dependency = provider.dependency
|
||||||
|
provider.override(container)
|
||||||
|
provider.reset_override()
|
||||||
|
|
||||||
|
assert dependency.overridden == tuple()
|
||||||
|
assert not dependency.overridden
|
||||||
|
|
||||||
|
|
||||||
|
def test_assign_parent(provider):
|
||||||
|
parent = providers.DependenciesContainer()
|
||||||
|
provider.assign_parent(parent)
|
||||||
|
assert provider.parent is parent
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name(provider):
|
||||||
|
container = containers.DynamicContainer()
|
||||||
|
container.name = provider
|
||||||
|
assert provider.parent_name == "name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_with_deep_parenting(provider):
|
||||||
|
container = providers.DependenciesContainer(name=provider)
|
||||||
|
_ = providers.DependenciesContainer(container=container)
|
||||||
|
assert provider.parent_name == "container.name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_is_none(provider):
|
||||||
|
assert provider.parent_name is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_deepcopy(provider, container):
|
||||||
|
container.name = provider
|
||||||
|
copied = providers.deepcopy(container)
|
||||||
|
|
||||||
|
assert container.name.parent is container
|
||||||
|
assert copied.name.parent is copied
|
||||||
|
|
||||||
|
assert container is not copied
|
||||||
|
assert container.name is not copied.name
|
||||||
|
assert container.name.parent is not copied.name.parent
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_set_on__getattr__(provider):
|
||||||
|
assert isinstance(provider.name, providers.Dependency)
|
||||||
|
assert provider.name.parent is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_set_on__init__():
|
||||||
|
provider = providers.Dependency()
|
||||||
|
container = providers.DependenciesContainer(name=provider)
|
||||||
|
assert container.name is provider
|
||||||
|
assert container.name.parent is container
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name(provider):
|
||||||
|
assert provider.resolve_provider_name(provider.name) == "name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_resolve_provider_name_no_provider(provider):
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider.resolve_provider_name(providers.Provider())
|
348
tests/unit/providers/test_dependency_py2_py3.py
Normal file
348
tests/unit/providers/test_dependency_py2_py3.py
Normal file
|
@ -0,0 +1,348 @@
|
||||||
|
"""Dependency provider tests."""
|
||||||
|
|
||||||
|
from dependency_injector import containers, providers, errors
|
||||||
|
from pytest import fixture, raises
|
||||||
|
|
||||||
|
|
||||||
|
@fixture
|
||||||
|
def provider():
|
||||||
|
return providers.Dependency(instance_of=list)
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_optional():
|
||||||
|
list_provider = providers.List(1, 2, 3)
|
||||||
|
provider = providers.Dependency()
|
||||||
|
provider.set_instance_of(list)
|
||||||
|
provider.set_default(list_provider)
|
||||||
|
|
||||||
|
assert provider.instance_of is list
|
||||||
|
assert provider.default is list_provider
|
||||||
|
assert provider() == [1, 2, 3]
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_instance_of_returns_self(provider):
|
||||||
|
assert provider.set_instance_of(list) is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_set_default_returns_self(provider):
|
||||||
|
assert provider.set_default(providers.Provider()) is provider
|
||||||
|
|
||||||
|
|
||||||
|
def test_init_with_not_class():
|
||||||
|
with raises(TypeError):
|
||||||
|
providers.Dependency(object())
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_abc():
|
||||||
|
try:
|
||||||
|
import collections.abc as collections_abc
|
||||||
|
except ImportError:
|
||||||
|
import collections as collections_abc
|
||||||
|
|
||||||
|
provider = providers.Dependency(collections_abc.Mapping)
|
||||||
|
provider.provided_by(providers.Factory(dict))
|
||||||
|
|
||||||
|
assert isinstance(provider(), collections_abc.Mapping)
|
||||||
|
assert isinstance(provider(), dict)
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_provider(provider):
|
||||||
|
assert providers.is_provider(provider) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_provided_instance_provider(provider):
|
||||||
|
assert isinstance(provider.provided, providers.ProvidedInstance)
|
||||||
|
|
||||||
|
|
||||||
|
def test_default():
|
||||||
|
provider = providers.Dependency(instance_of=dict, default={"foo": "bar"})
|
||||||
|
assert provider() == {"foo": "bar"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_attribute():
|
||||||
|
provider = providers.Dependency(instance_of=dict, default={"foo": "bar"})
|
||||||
|
assert provider.default() == {"foo": "bar"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_provider():
|
||||||
|
provider = providers.Dependency(instance_of=dict, default=providers.Factory(dict, foo="bar"))
|
||||||
|
assert provider.default() == {"foo": "bar"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_default_attribute_provider():
|
||||||
|
default = providers.Factory(dict, foo="bar")
|
||||||
|
provider = providers.Dependency(instance_of=dict, default=default)
|
||||||
|
|
||||||
|
assert provider.default() == {"foo": "bar"}
|
||||||
|
assert provider.default is default
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_defined(provider):
|
||||||
|
assert provider.is_defined is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_defined_when_overridden(provider):
|
||||||
|
provider.override("value")
|
||||||
|
assert provider.is_defined is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_is_defined_with_default():
|
||||||
|
provider = providers.Dependency(default="value")
|
||||||
|
assert provider.is_defined is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden(provider):
|
||||||
|
provider.provided_by(providers.Factory(list))
|
||||||
|
assert isinstance(provider(), list)
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_overridden_but_not_instance_of(provider):
|
||||||
|
provider.provided_by(providers.Factory(dict))
|
||||||
|
with raises(errors.Error):
|
||||||
|
provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_undefined(provider):
|
||||||
|
with raises(errors.Error, match="Dependency is not defined"):
|
||||||
|
provider()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_undefined_error_message_with_container_instance_parent():
|
||||||
|
class UserService:
|
||||||
|
def __init__(self, database):
|
||||||
|
self.database = database
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
database = providers.Dependency()
|
||||||
|
|
||||||
|
user_service = providers.Factory(
|
||||||
|
UserService,
|
||||||
|
database=database, # <---- missing dependency
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(errors.Error, match="Dependency \"Container.database\" is not defined"):
|
||||||
|
container.user_service()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_undefined_error_message_with_container_provider_parent_deep():
|
||||||
|
class Database:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class UserService:
|
||||||
|
def __init__(self, db):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
class Gateways(containers.DeclarativeContainer):
|
||||||
|
database_client = providers.Singleton(Database)
|
||||||
|
|
||||||
|
class Services(containers.DeclarativeContainer):
|
||||||
|
gateways = providers.DependenciesContainer()
|
||||||
|
|
||||||
|
user = providers.Factory(
|
||||||
|
UserService,
|
||||||
|
db=gateways.database_client,
|
||||||
|
)
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
gateways = providers.Container(Gateways)
|
||||||
|
|
||||||
|
services = providers.Container(
|
||||||
|
Services,
|
||||||
|
# gateways=gateways, # <---- missing dependency
|
||||||
|
)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
with raises(errors.Error, match="Dependency \"Container.services.gateways.database_client\" is not defined"):
|
||||||
|
container.services().user()
|
||||||
|
|
||||||
|
|
||||||
|
def test_call_undefined_error_message_with_dependenciescontainer_provider_parent():
|
||||||
|
class UserService:
|
||||||
|
def __init__(self, db):
|
||||||
|
self.db = db
|
||||||
|
|
||||||
|
class Services(containers.DeclarativeContainer):
|
||||||
|
gateways = providers.DependenciesContainer()
|
||||||
|
|
||||||
|
user = providers.Factory(
|
||||||
|
UserService,
|
||||||
|
db=gateways.database_client, # <---- missing dependency
|
||||||
|
)
|
||||||
|
|
||||||
|
services = Services()
|
||||||
|
|
||||||
|
with raises(errors.Error, match="Dependency \"Services.gateways.database_client\" is not defined"):
|
||||||
|
services.user()
|
||||||
|
|
||||||
|
|
||||||
|
def test_assign_parent(provider):
|
||||||
|
parent = providers.DependenciesContainer()
|
||||||
|
provider.assign_parent(parent)
|
||||||
|
assert provider.parent is parent
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name(provider):
|
||||||
|
container = containers.DynamicContainer()
|
||||||
|
container.name = provider
|
||||||
|
assert provider.parent_name == "name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_with_deep_parenting(provider):
|
||||||
|
container = providers.DependenciesContainer(name=provider)
|
||||||
|
_ = providers.DependenciesContainer(container=container)
|
||||||
|
assert provider.parent_name == "container.name"
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_name_is_none():
|
||||||
|
provider = providers.Dependency()
|
||||||
|
assert provider.parent_name is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_parent_deepcopy(provider):
|
||||||
|
container = containers.DynamicContainer()
|
||||||
|
container.name = provider
|
||||||
|
|
||||||
|
copied = providers.deepcopy(container)
|
||||||
|
|
||||||
|
assert container.name.parent is container
|
||||||
|
assert copied.name.parent is copied
|
||||||
|
|
||||||
|
assert container is not copied
|
||||||
|
assert container.name is not copied.name
|
||||||
|
assert container.name.parent is not copied.name.parent
|
||||||
|
|
||||||
|
|
||||||
|
def test_forward_attr_to_default():
|
||||||
|
default = providers.Configuration()
|
||||||
|
provider = providers.Dependency(default=default)
|
||||||
|
provider.from_dict({"foo": "bar"})
|
||||||
|
assert default() == {"foo": "bar"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_forward_attr_to_overriding(provider):
|
||||||
|
overriding = providers.Configuration()
|
||||||
|
provider.override(overriding)
|
||||||
|
provider.from_dict({"foo": "bar"})
|
||||||
|
assert overriding() == {"foo": "bar"}
|
||||||
|
|
||||||
|
|
||||||
|
def test_forward_attr_to_none(provider):
|
||||||
|
with raises(AttributeError):
|
||||||
|
provider.from_dict
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy(provider):
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert isinstance(provider, providers.Dependency)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_from_memo(provider):
|
||||||
|
provider_copy_memo = providers.Provider()
|
||||||
|
provider_copy = providers.deepcopy(provider, memo={id(provider): provider_copy_memo})
|
||||||
|
assert provider_copy is provider_copy_memo
|
||||||
|
|
||||||
|
|
||||||
|
def test_deepcopy_overridden(provider):
|
||||||
|
overriding_provider = providers.Provider()
|
||||||
|
|
||||||
|
provider.override(overriding_provider)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
overriding_provider_copy = provider_copy.overridden[0]
|
||||||
|
|
||||||
|
assert provider is not provider_copy
|
||||||
|
assert isinstance(provider, providers.Dependency)
|
||||||
|
|
||||||
|
assert overriding_provider is not overriding_provider_copy
|
||||||
|
assert isinstance(overriding_provider_copy, providers.Provider)
|
||||||
|
|
||||||
|
|
||||||
|
def test_deep_copy_default_object():
|
||||||
|
default = {"foo": "bar"}
|
||||||
|
provider = providers.Dependency(dict, default=default)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider_copy() is default
|
||||||
|
assert provider_copy.default() is default
|
||||||
|
|
||||||
|
|
||||||
|
def test_deep_copy_default_provider():
|
||||||
|
bar = object()
|
||||||
|
default = providers.Factory(dict, foo=providers.Object(bar))
|
||||||
|
provider = providers.Dependency(dict, default=default)
|
||||||
|
|
||||||
|
provider_copy = providers.deepcopy(provider)
|
||||||
|
|
||||||
|
assert provider_copy() == {"foo": bar}
|
||||||
|
assert provider_copy.default() == {"foo": bar}
|
||||||
|
assert provider_copy()["foo"] is bar
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_container_default_object():
|
||||||
|
default = {"foo": "bar"}
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
provider = providers.Dependency(dict, default=default)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.provider() is default
|
||||||
|
assert container.provider.default() is default
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_container_default_provider():
|
||||||
|
bar = object()
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
provider = providers.Dependency(dict, default=providers.Factory(dict, foo=providers.Object(bar)))
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert container.provider() == {"foo": bar}
|
||||||
|
assert container.provider.default() == {"foo": bar}
|
||||||
|
assert container.provider()["foo"] is bar
|
||||||
|
|
||||||
|
|
||||||
|
def test_with_container_default_provider_with_overriding():
|
||||||
|
bar = object()
|
||||||
|
baz = object()
|
||||||
|
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
provider = providers.Dependency(dict, default=providers.Factory(dict, foo=providers.Object(bar)))
|
||||||
|
|
||||||
|
container = Container(provider=providers.Factory(dict, foo=providers.Object(baz)))
|
||||||
|
|
||||||
|
assert container.provider() == {"foo": baz}
|
||||||
|
assert container.provider.default() == {"foo": bar}
|
||||||
|
assert container.provider()["foo"] is baz
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr(provider):
|
||||||
|
assert repr(provider) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"Dependency({0}) at {1}>".format(repr(list), hex(id(provider)))
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_repr_in_container():
|
||||||
|
class Container(containers.DeclarativeContainer):
|
||||||
|
dependency = providers.Dependency(instance_of=int)
|
||||||
|
|
||||||
|
container = Container()
|
||||||
|
|
||||||
|
assert repr(container.dependency) == (
|
||||||
|
"<dependency_injector.providers."
|
||||||
|
"Dependency({0}) at {1}, container name: \"Container.dependency\">".format(
|
||||||
|
repr(int),
|
||||||
|
hex(id(container.dependency)),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_external_dependency():
|
||||||
|
assert isinstance(providers.ExternalDependency(), providers.Dependency)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user