886 lines
26 KiB
Python
886 lines
26 KiB
Python
"""Unit tests for bison.bison"""
|
|
|
|
import os
|
|
|
|
import pytest
|
|
|
|
import bison
|
|
from bison import errors
|
|
from bison.bison import YAML
|
|
|
|
|
|
class TestBison:
|
|
"""Test for the `Bison` class."""
|
|
|
|
def test_simple_init(self):
|
|
"""Initialize a Bison object."""
|
|
b = bison.Bison()
|
|
|
|
assert b.scheme is None
|
|
assert b.config_name == 'config'
|
|
assert b.config_paths == []
|
|
assert b.config_file is None
|
|
assert b.env_prefix is None
|
|
assert b.auto_env is False
|
|
|
|
assert b._full_config is None
|
|
assert isinstance(b._default, bison.DotDict)
|
|
assert isinstance(b._config, bison.DotDict)
|
|
assert isinstance(b._environment, bison.DotDict)
|
|
assert isinstance(b._override, bison.DotDict)
|
|
|
|
assert len(b._default) == 0
|
|
assert len(b._config) == 0
|
|
assert len(b._environment) == 0
|
|
assert len(b._override) == 0
|
|
|
|
def test_config_property_empty(self):
|
|
"""Get the full configuration when nothing is set."""
|
|
b = bison.Bison()
|
|
|
|
assert b._full_config is None
|
|
c = b.config
|
|
assert isinstance(c, bison.DotDict)
|
|
assert len(c) == 0
|
|
assert b._full_config == c
|
|
|
|
@pytest.mark.parametrize(
|
|
'key,expected,config', [
|
|
('foo', None, None),
|
|
('foo', None, bison.DotDict()),
|
|
('foo', None, bison.DotDict({'foo': None})),
|
|
('foo', 'bar', bison.DotDict({'foo': 'bar'})),
|
|
('foo.bar', 'baz', bison.DotDict({'foo': {'bar': 'baz'}})),
|
|
('foo.bar.baz', 1, bison.DotDict({'foo': {'bar': {'baz': 1}}})),
|
|
]
|
|
)
|
|
def test_get(self, key, expected, config):
|
|
"""Get configuration values from Bison."""
|
|
b = bison.Bison()
|
|
b._full_config = config # for the test, set the config manually
|
|
|
|
value = b.get(key)
|
|
assert value == expected
|
|
|
|
@pytest.mark.parametrize(
|
|
'key,default,expected,config', [
|
|
('foo', 7, 7, None),
|
|
('foo', None, None, bison.DotDict()),
|
|
('foo', 'bar', 'bar', bison.DotDict()),
|
|
('foo', 'bar', None, bison.DotDict({'foo': None})),
|
|
('foo', 'bar', 'test', bison.DotDict({'foo': 'test'})),
|
|
('foo.bar', 7, 'baz', bison.DotDict({'foo': {'bar': 'baz'}})),
|
|
('foo.bar', 7, 7, bison.DotDict({'foo': {'something': 'else'}})),
|
|
]
|
|
)
|
|
def test_get_with_defaults(self, key, default, expected, config):
|
|
"""Get config values from Bison, using defaults if the key is not set."""
|
|
b = bison.Bison()
|
|
b._full_config = config # for the test, set the config manually
|
|
|
|
value = b.get(key, default=default)
|
|
assert value == expected
|
|
|
|
@pytest.mark.parametrize(
|
|
'key,expected,config', [
|
|
('foo', None, None),
|
|
('foo', None, bison.DotDict()),
|
|
('foo', None, bison.DotDict({'foo': None})),
|
|
('foo', 'bar', bison.DotDict({'foo': 'bar'})),
|
|
('foo.bar', 'baz', bison.DotDict({'foo': {'bar': 'baz'}})),
|
|
('foo.bar.baz', 1, bison.DotDict({'foo': {'bar': {'baz': 1}}})),
|
|
]
|
|
)
|
|
def test_get_subscriptable(self, key, expected, config):
|
|
"""Get config values from Bison via subscripting."""
|
|
b = bison.Bison()
|
|
b._full_config = config # for the test, set the config manually
|
|
|
|
value = b[key]
|
|
assert value == expected
|
|
|
|
@pytest.mark.parametrize(
|
|
'key,value', [
|
|
('foo', 'bar'),
|
|
('foo', 1),
|
|
('foo', False),
|
|
('foo', True),
|
|
('foo', None),
|
|
('foo.bar', 'baz'),
|
|
('foo.bar.baz', 1),
|
|
]
|
|
)
|
|
def test_set(self, key, value):
|
|
"""Set configuration overrides for a Bison instance."""
|
|
b = bison.Bison()
|
|
assert len(b._override) == 0
|
|
assert b.get(key) is None
|
|
|
|
b.set(key, value)
|
|
|
|
assert len(b._override) == 1
|
|
assert b.get(key) == value
|
|
|
|
def test_set_multiple_nested(self):
|
|
"""Set overrides for multiple nested values"""
|
|
b = bison.Bison()
|
|
assert len(b._override) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b.set('foo.bar.a', 'test')
|
|
|
|
assert b.config == {
|
|
'foo': {
|
|
'bar': {
|
|
'a': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
b.set('foo.bar.b', 'test')
|
|
|
|
assert b.config == {
|
|
'foo': {
|
|
'bar': {
|
|
'a': 'test',
|
|
'b': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
def test_set_multiple_nested_2(self):
|
|
"""Set overrides for multiple nested values when some already exist."""
|
|
b = bison.Bison()
|
|
assert len(b._override) == 0
|
|
assert len(b.config) == 0
|
|
|
|
# set the override config config to something to begin
|
|
b._override = bison.DotDict({
|
|
'foo': 'bar',
|
|
'bar': {
|
|
'bat': {
|
|
'a': 'test'
|
|
},
|
|
'bird': {
|
|
'b': 'test'
|
|
}
|
|
}
|
|
})
|
|
|
|
b.set('foo', 'baz')
|
|
assert b.config == {
|
|
'foo': 'baz',
|
|
'bar': {
|
|
'bat': {
|
|
'a': 'test'
|
|
},
|
|
'bird': {
|
|
'b': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
b.set('bar.bat.a', None)
|
|
assert b.config == {
|
|
'foo': 'baz',
|
|
'bar': {
|
|
'bat': {
|
|
'a': None
|
|
},
|
|
'bird': {
|
|
'b': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
b.set('bar.bird', 'warbler')
|
|
assert b.config == {
|
|
'foo': 'baz',
|
|
'bar': {
|
|
'bat': {
|
|
'a': None
|
|
},
|
|
'bird': 'warbler'
|
|
}
|
|
}
|
|
|
|
def test_set_multiple_nested_3(self):
|
|
"""Set overrides for multiple nested values when some already exist."""
|
|
b = bison.Bison()
|
|
assert len(b._override) == 0
|
|
assert len(b.config) == 0
|
|
|
|
# set a non override config config to something to begin
|
|
b._config = bison.DotDict({
|
|
'foo': 'bar',
|
|
'bar': {
|
|
'bat': {
|
|
'a': 'test'
|
|
},
|
|
'bird': {
|
|
'b': 'test'
|
|
}
|
|
}
|
|
})
|
|
|
|
b.set('foo', 'baz')
|
|
assert b.config == {
|
|
'foo': 'baz',
|
|
'bar': {
|
|
'bat': {
|
|
'a': 'test'
|
|
},
|
|
'bird': {
|
|
'b': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
b.set('bar.bat.a', None)
|
|
assert b.config == {
|
|
'foo': 'baz',
|
|
'bar': {
|
|
'bat': {
|
|
'a': None
|
|
},
|
|
'bird': {
|
|
'b': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
b.set('bar.bird', 'warbler')
|
|
assert b.config == {
|
|
'foo': 'baz',
|
|
'bar': {
|
|
'bat': {
|
|
'a': None
|
|
},
|
|
'bird': 'warbler'
|
|
}
|
|
}
|
|
|
|
@pytest.mark.parametrize(
|
|
'paths', [
|
|
(),
|
|
('path1',),
|
|
('path1', 'path2'),
|
|
('path1', 'path2', 'path3')
|
|
]
|
|
)
|
|
def test_add_config_paths(self, paths):
|
|
"""Add configuration paths to the Bison instance."""
|
|
b = bison.Bison()
|
|
assert len(b.config_paths) == 0
|
|
|
|
b.add_config_paths(*paths)
|
|
assert len(b.config_paths) == len(paths)
|
|
|
|
def test_validate_no_scheme(self):
|
|
"""Validate the Bison configuration when there is no Scheme to validate against."""
|
|
b = bison.Bison()
|
|
b.set('foo', 'bar')
|
|
b.validate()
|
|
|
|
def test_validate_ok(self):
|
|
"""Validate the Bison configuration successfully."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', field_type=str)
|
|
))
|
|
|
|
# add 'foo' to the config
|
|
b.set('foo', 'bar')
|
|
|
|
# validation should succeed -- the value of 'foo' is a string
|
|
b.validate()
|
|
|
|
def test_validate_fail(self):
|
|
"""Validate the Bison configuration unsuccessfully."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', field_type=str)
|
|
))
|
|
|
|
# add 'foo' to the config
|
|
b.set('foo', 1)
|
|
|
|
# validation should fail -- the value of 'foo' is not a string
|
|
with pytest.raises(errors.SchemeValidationError):
|
|
b.validate()
|
|
|
|
def test_find_config(self, yaml_config):
|
|
"""Find a config file when it does exist"""
|
|
b = bison.Bison()
|
|
b.config_name = 'config'
|
|
b.config_format = YAML
|
|
b.config_paths = ['.', yaml_config.dirname]
|
|
|
|
assert b.config_file is None
|
|
|
|
b._find_config()
|
|
|
|
assert b.config_file == os.path.join(yaml_config.dirname, yaml_config.basename)
|
|
|
|
def test_find_config_nonexistent(self):
|
|
"""Find a config file when it does not exist"""
|
|
b = bison.Bison()
|
|
b.config_name = 'config'
|
|
b.config_format = YAML
|
|
b.config_paths = ['.']
|
|
|
|
assert b.config_file is None
|
|
|
|
with pytest.raises(errors.BisonError):
|
|
b._find_config()
|
|
|
|
def test_parse_no_sources(self):
|
|
"""Parse when there are no sources to parse from."""
|
|
b = bison.Bison()
|
|
b.parse()
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_config_no_paths(self):
|
|
"""Parse the file config when no paths are specified"""
|
|
b = bison.Bison()
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b._parse_config()
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
def test_parse_config_ok(self, yaml_config):
|
|
"""Parse the file config successfully."""
|
|
b = bison.Bison()
|
|
b.add_config_paths(yaml_config.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b._parse_config()
|
|
|
|
assert b.config_file == os.path.join(yaml_config.dirname, yaml_config.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'bar': {
|
|
'baz': 1,
|
|
'test': 'value'
|
|
}
|
|
}
|
|
|
|
def test_parse_config_fail(self, bad_yaml_config):
|
|
"""Parse the file config unsuccessfully."""
|
|
b = bison.Bison()
|
|
b.add_config_paths(bad_yaml_config.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
with pytest.raises(errors.BisonError):
|
|
b._parse_config()
|
|
|
|
assert b.config_file == os.path.join(bad_yaml_config.dirname, bad_yaml_config.basename)
|
|
assert len(b._config) == 0
|
|
|
|
def test_parse_config_not_required_found(self, yaml_config):
|
|
"""Parse the file config when it isn't required."""
|
|
b = bison.Bison()
|
|
b.add_config_paths(yaml_config.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b._parse_config(requires_cfg=False)
|
|
|
|
assert b.config_file == os.path.join(yaml_config.dirname, yaml_config.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'bar': {
|
|
'baz': 1,
|
|
'test': 'value'
|
|
}
|
|
}
|
|
|
|
def test_parse_config_not_required_not_found(self):
|
|
"""Parse the file config when it isn't required."""
|
|
b = bison.Bison()
|
|
b.add_config_paths('.')
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b._parse_config(requires_cfg=False)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
def test_parse_defaults_no_scheme(self):
|
|
"""Parse the defaults when there is no Scheme."""
|
|
b = bison.Bison()
|
|
|
|
assert len(b._default) == 0
|
|
assert b._full_config is None
|
|
|
|
b._parse_default()
|
|
|
|
assert len(b._default) == 0
|
|
assert b._full_config is None
|
|
|
|
def test_parse_defaults_ok(self):
|
|
"""Parse the defaults successfully."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', default='bar')
|
|
))
|
|
|
|
assert len(b._default) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_default()
|
|
|
|
assert len(b._default) == 1
|
|
assert b.config == {'foo': 'bar'}
|
|
|
|
def test_parse_env_env_prefix(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison()
|
|
b.env_prefix = 'TEST_ENV_'
|
|
b.auto_env = True
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
# no scheme means nothing parsed.
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_env_env_prefix2(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison()
|
|
# here, do not include the trailing '_', this should be added
|
|
# on automatically if not there.
|
|
b.env_prefix = 'TEST_ENV'
|
|
b.auto_env = True
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
# no scheme means nothing parsed.
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_env_bind_env(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env='FOO')
|
|
))
|
|
b.env_prefix = 'TEST_ENV'
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
# we should get nothing back here -- env parsing will NOT
|
|
# use the env_prefix when bind_env is specified manually.
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_env_bind_env_no_prefix(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env='TEST_ENV_FOO')
|
|
))
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
assert len(b._environment) == 1
|
|
assert b.config == {
|
|
'foo': 'bar'
|
|
}
|
|
|
|
def test_parse_env_bind_env_auto(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
# this will autoenv to TEST_ENV_FOO, so we set to something
|
|
# different here to test that it a.) works, b.) overrides autoenv
|
|
bison.Option('foo', bind_env='TEST_OTHER_ENV_BAR'),
|
|
bison.DictOption('nested', scheme=bison.Scheme(
|
|
bison.DictOption('env', scheme=bison.Scheme(
|
|
bison.Option('key')
|
|
))
|
|
))
|
|
))
|
|
b.env_prefix = 'TEST_ENV'
|
|
b.auto_env = True
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
assert len(b._environment) == 2
|
|
assert b.config == {
|
|
'foo': 'baz',
|
|
'nested': {
|
|
'env': {
|
|
'key': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
def test_parse_env_bind_env_false(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=False)
|
|
))
|
|
b.env_prefix = 'TEST_ENV'
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
# we should get nothing back here -- nothing configured for
|
|
# env parsing
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_env_bind_env_false_no_prefix(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=False)
|
|
))
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
# we should get nothing back here -- nothing configured for
|
|
# env parsing
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_env_bind_env_false_auto(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=False)
|
|
))
|
|
b.env_prefix = 'TEST_ENV'
|
|
b.auto_env = True
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
# we should not get back the 'foo' key since its disabled,
|
|
# even with auto-env
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_env_bind_env_true(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True)
|
|
))
|
|
b.env_prefix = 'TEST_ENV'
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
assert len(b._environment) == 1
|
|
assert b.config == {
|
|
'foo': 'bar'
|
|
}
|
|
|
|
def test_parse_env_bind_env_true_no_prefix(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True)
|
|
))
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
# we should not get anything back since we don't have a 'FOO' env variable
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
def test_parse_env_bind_env_true_auto(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True),
|
|
bison.DictOption('nested', scheme=bison.Scheme(
|
|
bison.DictOption('env', scheme=bison.Scheme(
|
|
bison.Option('key')
|
|
))
|
|
))
|
|
))
|
|
b.env_prefix = 'TEST_ENV'
|
|
b.auto_env = True
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
assert len(b._environment) == 2
|
|
assert b.config == {
|
|
'foo': 'bar',
|
|
'nested': {
|
|
'env': {
|
|
'key': 'test'
|
|
}
|
|
}
|
|
}
|
|
|
|
def test_parse_env_int_value(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env='FOO_INT', field_type=int)
|
|
))
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
assert len(b._environment) == 1
|
|
assert b.config == {
|
|
'foo': 1,
|
|
}
|
|
|
|
def test_parse_env_bool_value(self, with_env):
|
|
"""Parse the environment variable configuration."""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env='FOO_BOOL', field_type=bool)
|
|
))
|
|
|
|
assert len(b._environment) == 0
|
|
assert len(b.config) == 0
|
|
|
|
b._parse_env()
|
|
|
|
assert len(b._environment) == 1
|
|
assert b.config == {
|
|
'foo': False,
|
|
}
|
|
|
|
def test_parse_validate_nested_optional(self, yaml_optional_nested):
|
|
"""Parse a config for a scheme with a non-required option with
|
|
required nested options where the non-required option is not set.
|
|
"""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True),
|
|
bison.DictOption('nested2', required=False, bind_env=True, scheme=bison.Scheme(
|
|
bison.Option('x', field_type=str),
|
|
bison.Option('y', field_type=str)
|
|
))
|
|
))
|
|
b.add_config_paths(yaml_optional_nested.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b.parse(requires_cfg=False)
|
|
|
|
assert b.config_file == os.path.join(yaml_optional_nested.dirname, yaml_optional_nested.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'nested1': {
|
|
'x': 'abc',
|
|
'y': 'def'
|
|
}
|
|
}
|
|
|
|
b.validate()
|
|
|
|
def test_parse_validate_nested_optional2(self, yaml_optional_nested):
|
|
"""Parse a config for a scheme with a non-required option with
|
|
required nested options where the non-required option is set.
|
|
"""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True),
|
|
bison.DictOption('nested1', required=False, bind_env=True, scheme=bison.Scheme(
|
|
bison.Option('x', field_type=str),
|
|
bison.Option('y', field_type=str)
|
|
))
|
|
))
|
|
b.add_config_paths(yaml_optional_nested.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b.parse(requires_cfg=False)
|
|
|
|
assert b.config_file == os.path.join(yaml_optional_nested.dirname, yaml_optional_nested.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'nested1': {
|
|
'x': 'abc',
|
|
'y': 'def'
|
|
}
|
|
}
|
|
|
|
b.validate()
|
|
|
|
def test_parse_validate_nested_optional3(self, yaml_optional_nested):
|
|
"""Parse a config for a scheme with a non-required option with
|
|
required nested options where the non-required option is not set,
|
|
and the required options have defaults.
|
|
"""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True),
|
|
bison.DictOption('nested2', required=False, bind_env=True, scheme=bison.Scheme(
|
|
bison.Option('x', default="abc", field_type=str),
|
|
bison.Option('y', default="def", field_type=str)
|
|
))
|
|
))
|
|
b.add_config_paths(yaml_optional_nested.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b.parse(requires_cfg=False)
|
|
|
|
assert b.config_file == os.path.join(yaml_optional_nested.dirname, yaml_optional_nested.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'nested1': {
|
|
'x': 'abc',
|
|
'y': 'def'
|
|
},
|
|
'nested2': { # defaults get picked up
|
|
'x': 'abc',
|
|
'y': 'def'
|
|
}
|
|
}
|
|
|
|
b.validate()
|
|
|
|
def test_parse_validate_nested_optional4(self, yaml_optional_nested):
|
|
"""Parse a config for a scheme with a non-required option with
|
|
required nested options where the non-required option is not set
|
|
and it has a default value.
|
|
"""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True),
|
|
bison.DictOption('nested2', required=False, default={}, bind_env=True, scheme=bison.Scheme(
|
|
bison.Option('x', field_type=str),
|
|
bison.Option('y', field_type=str)
|
|
))
|
|
))
|
|
b.add_config_paths(yaml_optional_nested.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b.parse(requires_cfg=False)
|
|
|
|
assert b.config_file == os.path.join(yaml_optional_nested.dirname, yaml_optional_nested.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'nested1': {
|
|
'x': 'abc',
|
|
'y': 'def'
|
|
},
|
|
'nested2': {} # default gets picked up
|
|
}
|
|
|
|
# validation should fail -- the default value gets added, but the required
|
|
# options are not set in the default
|
|
with pytest.raises(errors.SchemeValidationError):
|
|
b.validate()
|
|
|
|
def test_parse_validate_nested_optional5(self, yaml_optional_nested):
|
|
"""Parse a config for a scheme with a non-required option with
|
|
required nested options where the non-required option is not set
|
|
and it has a default value.
|
|
"""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True),
|
|
bison.DictOption('nested2', required=False, default={'x': 'ghi', 'y': 'jkl'}, bind_env=True, scheme=bison.Scheme(
|
|
bison.Option('x', field_type=str),
|
|
bison.Option('y', field_type=str)
|
|
))
|
|
))
|
|
b.add_config_paths(yaml_optional_nested.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b.parse(requires_cfg=False)
|
|
|
|
assert b.config_file == os.path.join(yaml_optional_nested.dirname, yaml_optional_nested.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'nested1': {
|
|
'x': 'abc',
|
|
'y': 'def'
|
|
},
|
|
'nested2': { # default gets picked up
|
|
'x': 'ghi',
|
|
'y': 'jkl'
|
|
}
|
|
}
|
|
|
|
b.validate()
|
|
|
|
def test_parse_validate_nested_optional6(self, yaml_optional_nested):
|
|
"""Parse a config for a scheme with a non-required option with
|
|
required nested options where the non-required option is not set
|
|
and it has a default value.
|
|
|
|
This test is the same as the one above, but the defaults are
|
|
specified differently.
|
|
"""
|
|
b = bison.Bison(scheme=bison.Scheme(
|
|
bison.Option('foo', bind_env=True),
|
|
bison.DictOption('nested2', required=False, default={}, bind_env=True, scheme=bison.Scheme(
|
|
bison.Option('x', default='ghi', field_type=str),
|
|
bison.Option('y', default='jkl', field_type=str)
|
|
))
|
|
))
|
|
b.add_config_paths(yaml_optional_nested.dirname)
|
|
|
|
assert b.config_file is None
|
|
assert len(b._config) == 0
|
|
|
|
b.parse(requires_cfg=False)
|
|
|
|
assert b.config_file == os.path.join(yaml_optional_nested.dirname, yaml_optional_nested.basename)
|
|
assert len(b._config) == 2
|
|
assert b.config == {
|
|
'foo': True,
|
|
'nested1': {
|
|
'x': 'abc',
|
|
'y': 'def'
|
|
},
|
|
'nested2': { # default gets picked up
|
|
'x': 'ghi',
|
|
'y': 'jkl'
|
|
}
|
|
}
|
|
|
|
b.validate()
|