mirror of
https://github.com/ets-labs/python-dependency-injector.git
synced 2025-07-04 12:23:14 +03:00
Migrate configuration tests
This commit is contained in:
parent
98cb4ab244
commit
fe149c27a2
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"
|
344
tests/unit/providers/configuration/test_config_py2_py3.py
Normal file
344
tests/unit/providers/configuration/test_config_py2_py3.py
Normal file
|
@ -0,0 +1,344 @@
|
|||
"""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")
|
||||
|
||||
|
||||
# TODO: do we really need to skip it?
|
||||
# @unittest.skipIf(sys.version_info[:2] == (2, 7), "Python 2.7 does not support this assert")
|
||||
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
|
||||
|
||||
|
||||
# TODO: do we really need to skip it?
|
||||
# @unittest.skipIf(sys.version_info[:2] == (2, 7), "Python 2.7 does not support this assert")
|
||||
@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()
|
||||
|
||||
|
||||
# TODO: do we really need to skip it?
|
||||
# @unittest.skipIf(sys.version_info[:2] == (2, 7), "Python 2.7 does not support this assert")
|
||||
@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"
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import asyncio
|
||||
import inspect
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
from dependency_injector import containers, providers, resources
|
||||
|
@ -33,6 +34,7 @@ async def test_init_async_function():
|
|||
|
||||
|
||||
@mark.asyncio
|
||||
@mark.skipif(sys.version_info < (3, 6), reason="requires Python 3.6+")
|
||||
async def test_init_async_generator():
|
||||
resource = object()
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user