mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			267 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
		
			8.9 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
"""Dependency injector container provider unit tests."""
 | 
						|
 | 
						|
import copy
 | 
						|
 | 
						|
import unittest
 | 
						|
 | 
						|
from dependency_injector import containers, providers, errors
 | 
						|
 | 
						|
 | 
						|
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 TestCore(containers.DeclarativeContainer):
 | 
						|
    config = providers.Configuration("core")
 | 
						|
    value_getter = providers.Callable(lambda _: _, config.section.value)
 | 
						|
 | 
						|
 | 
						|
class TestApplication(containers.DeclarativeContainer):
 | 
						|
    config = providers.Configuration("config")
 | 
						|
    core = providers.Container(TestCore, config=config.core)
 | 
						|
    dict_factory = providers.Factory(dict, value=core.value_getter)
 | 
						|
 | 
						|
 | 
						|
class ContainerTests(unittest.TestCase):
 | 
						|
 | 
						|
    def test(self):
 | 
						|
        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
						|
        self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_1})
 | 
						|
 | 
						|
    def test_double_override(self):
 | 
						|
        application = TestApplication()
 | 
						|
        application.config.override(_copied(TEST_CONFIG_1))
 | 
						|
        application.config.override(_copied(TEST_CONFIG_2))
 | 
						|
        self.assertEqual(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):
 | 
						|
            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()
 | 
						|
        self.assertEqual(result, "foo++")
 | 
						|
 | 
						|
    def test_override_not_root_provider(self):
 | 
						|
        # 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"
 | 
						|
        ))
 | 
						|
        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_container = TestContainer(settings=dict(
 | 
						|
            container="using_container",
 | 
						|
            foo="bar"
 | 
						|
        ))
 | 
						|
        self.assertEqual(
 | 
						|
            container_using_container.root_container().print_settings(),
 | 
						|
            {"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):
 | 
						|
            provider.override(providers.Object("foo"))
 | 
						|
 | 
						|
    def test_lazy_overriding(self):
 | 
						|
        # 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()
 | 
						|
        self.assertEqual(result, "foo++")
 | 
						|
 | 
						|
    def test_lazy_overriding_deep(self):
 | 
						|
        # 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()
 | 
						|
        self.assertEqual(result, "foo++")
 | 
						|
 | 
						|
    def test_reset_last_overriding(self):
 | 
						|
        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
						|
        application.core.override(TestCore(config=_copied(TEST_CONFIG_2["core"])))
 | 
						|
 | 
						|
        application.core.reset_last_overriding()
 | 
						|
 | 
						|
        self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_1})
 | 
						|
 | 
						|
    def test_reset_last_overriding_only_overridden(self):
 | 
						|
        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
						|
        application.core.override(providers.DependenciesContainer(config=_copied(TEST_CONFIG_2["core"])))
 | 
						|
 | 
						|
        application.core.reset_last_overriding()
 | 
						|
 | 
						|
        self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_1})
 | 
						|
 | 
						|
    def test_override_context_manager(self):
 | 
						|
        application = TestApplication(config=_copied(TEST_CONFIG_1))
 | 
						|
        overriding_core = TestCore(config=_copied(TEST_CONFIG_2["core"]))
 | 
						|
 | 
						|
        with application.core.override(overriding_core) as context_core:
 | 
						|
            self.assertEqual(application.dict_factory(), {"value": TEST_VALUE_2})
 | 
						|
            self.assertIs(context_core(), overriding_core)
 | 
						|
 | 
						|
        self.assertEqual(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()
 | 
						|
 | 
						|
        self.assertEqual(application.dict_factory(), {"value": None})
 | 
						|
 | 
						|
    def test_reset_override_only_overridden(self):
 | 
						|
        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_assign_parent(self):
 | 
						|
        parent = providers.DependenciesContainer()
 | 
						|
        provider = providers.Container(TestCore)
 | 
						|
 | 
						|
        provider.assign_parent(parent)
 | 
						|
 | 
						|
        self.assertIs(provider.parent, parent)
 | 
						|
 | 
						|
    def test_parent_name(self):
 | 
						|
        container = containers.DynamicContainer()
 | 
						|
        provider = providers.Container(TestCore)
 | 
						|
        container.name = provider
 | 
						|
        self.assertEqual(provider.parent_name, "name")
 | 
						|
 | 
						|
    def test_parent_name_with_deep_parenting(self):
 | 
						|
        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):
 | 
						|
        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)
 | 
						|
 | 
						|
        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_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):
 | 
						|
        container = providers.Container(TestCore)
 | 
						|
        with self.assertRaises(errors.Error):
 | 
						|
            container.resolve_provider_name(providers.Provider())
 |