python-dependency-injector/tests/unit/providers/test_container_py2_py3.py
2021-10-18 14:56:37 -04:00

267 lines
7.7 KiB
Python

"""Container provider tests."""
import copy
from dependency_injector import containers, providers, errors
from pytest import raises
TEST_VALUE_1 = "core_section_value1"
TEST_CONFIG_1 = {
"core": {
"section": {
"value": TEST_VALUE_1,
},
},
}
TEST_VALUE_2 = "core_section_value2"
TEST_CONFIG_2 = {
"core": {
"section": {
"value": TEST_VALUE_2,
},
},
}
def _copied(value):
return copy.deepcopy(value)
class Core(containers.DeclarativeContainer):
config = providers.Configuration("core")
value_getter = providers.Callable(lambda _: _, config.section.value)
class Application(containers.DeclarativeContainer):
config = providers.Configuration("config")
core = providers.Container(Core, config=config.core)
dict_factory = providers.Factory(dict, value=core.value_getter)
def test():
application = Application(config=_copied(TEST_CONFIG_1))
assert application.dict_factory() == {"value": TEST_VALUE_1}
def test_double_override():
application = Application()
application.config.override(_copied(TEST_CONFIG_1))
application.config.override(_copied(TEST_CONFIG_2))
assert application.dict_factory() == {"value": TEST_VALUE_2}
def test_override():
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
class D(containers.DeclarativeContainer):
foo = providers.Object("foo")
class A(containers.DeclarativeContainer):
d = providers.DependenciesContainer()
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
class B(containers.DeclarativeContainer):
d = providers.Container(D)
a = providers.Container(A, d=d)
b = B(d=D())
result = b.a().bar()
assert result == "foo++"
def test_override_not_root_provider():
# See: https://github.com/ets-labs/python-dependency-injector/issues/379
class NestedContainer(containers.DeclarativeContainer):
settings = providers.Configuration()
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,
settings=settings,
)
)
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",
foo="bar"
))
assert container_using_container.root_container().print_settings() == {"container": "using_container", "foo": "bar"}
assert container_using_container.not_root_container().print_settings() == {"container": "using_container", "foo": "bar"}
def test_override_by_not_a_container():
provider = providers.Container(Core)
with raises(errors.Error):
provider.override(providers.Object("foo"))
def test_lazy_overriding():
# See: https://github.com/ets-labs/python-dependency-injector/issues/354
class D(containers.DeclarativeContainer):
foo = providers.Object("foo")
class A(containers.DeclarativeContainer):
d = providers.DependenciesContainer()
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
class B(containers.DeclarativeContainer):
d = providers.DependenciesContainer()
a = providers.Container(A, d=d)
b = B(d=D())
result = b.a().bar()
assert result == "foo++"
def test_lazy_overriding_deep():
# Extended version of test_lazy_overriding()
class D(containers.DeclarativeContainer):
foo = providers.Object("foo")
class C(containers.DeclarativeContainer):
d = providers.DependenciesContainer()
bar = providers.Callable(lambda f: f + "++", d.foo.provided)
class A(containers.DeclarativeContainer):
d = providers.DependenciesContainer()
c = providers.Container(C, d=d)
class B(containers.DeclarativeContainer):
d = providers.DependenciesContainer()
a = providers.Container(A, d=d)
b = B(d=D())
result = b.a().c().bar()
assert result == "foo++"
def test_reset_last_overriding():
application = Application(config=_copied(TEST_CONFIG_1))
application.core.override(Core(config=_copied(TEST_CONFIG_2["core"])))
application.core.reset_last_overriding()
assert application.dict_factory() == {"value": TEST_VALUE_1}
def test_reset_last_overriding_only_overridden():
application = Application(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}
def test_override_context_manager():
application = Application(config=_copied(TEST_CONFIG_1))
overriding_core = Core(config=_copied(TEST_CONFIG_2["core"]))
with application.core.override(overriding_core) as context_core:
assert application.dict_factory() == {"value": TEST_VALUE_2}
assert context_core() is overriding_core
assert application.dict_factory() == {"value": TEST_VALUE_1}
def test_reset_override():
application = Application(config=_copied(TEST_CONFIG_1))
application.core.override(Core(config=_copied(TEST_CONFIG_2["core"])))
application.core.reset_override()
assert application.dict_factory() == {"value": None}
def test_reset_override_only_overridden():
application = Application(config=_copied(TEST_CONFIG_1))
application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
application.core.reset_override()
assert application.dict_factory() == {"value": None}
def test_assign_parent():
parent = providers.DependenciesContainer()
provider = providers.Container(Core)
provider.assign_parent(parent)
assert provider.parent is parent
def test_parent_name():
container = containers.DynamicContainer()
provider = providers.Container(Core)
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())