示例#1
0
    def test_init_simple(self):
        """Initialize a DictOption."""
        opt = scheme.DictOption('test-opt', None)

        assert opt.name == 'test-opt'
        assert type(opt.default) == scheme.NoDefault
        assert opt.scheme is None
        assert opt.bind_env is False
示例#2
0
    def test_init_full(self):
        """Initialize a DictOption."""
        opt = scheme.DictOption(
            name='test-opt',
            scheme=scheme.Scheme(),
            default='foo',
            bind_env=True
        )

        assert opt.name == 'test-opt'
        assert type(opt.default) != scheme.NoDefault
        assert opt.default == 'foo'
        assert isinstance(opt.scheme, scheme.Scheme)
        assert opt.bind_env is True
示例#3
0
class TestScheme:
    """Tests for the `Scheme` class."""

    def test_empty_init(self):
        """Initialize a Scheme with no arguments."""
        sch = scheme.Scheme()

        assert len(sch.args) == 0
        assert sch._flat is None

    def test_single_arg_init(self):
        """Initialize a Scheme with one argument."""
        sch = scheme.Scheme(
            'item'
        )

        assert len(sch.args) == 1
        assert sch._flat is None

    def test_multi_arg_init(self):
        """Initialize a Scheme with multiple arguments."""
        sch = scheme.Scheme(
            'item-1',
            'item-2',
            'item-3'
        )

        assert len(sch.args) == 3
        assert sch._flat is None

    @pytest.mark.parametrize(
        'args,expected', [
            (
                # args
                (scheme.Option('foo', default='bar'),),
                # expected
                {'foo': 'bar'}
            ),
            (
                # args
                (
                    scheme.Option('foo'),
                    scheme.Option('bar', default='baz'),
                    scheme.ListOption('list', default=['a', 'b'])
                ),
                # expected
                {
                    'bar': 'baz',
                    'list': ['a', 'b']
                }
            ),
            (
                # args
                (
                    scheme.Option('foo', default='bar'),
                    scheme.DictOption('bar', scheme=None)
                ),
                # expected
                {
                    'foo': 'bar'
                }
            ),
            (
                # args
                (
                    scheme.DictOption('foo', scheme=scheme.Scheme(), default={}),
                    scheme.DictOption('bar', scheme=scheme.Scheme(
                        scheme.Option('test', default=True),
                        scheme.Option('data', default=None),
                        scheme.Option('value', default=20),
                        scheme.Option('float', default=10.1010),
                        scheme.Option('no_default'),
                        scheme.DictOption('dct', scheme=scheme.Scheme(
                            scheme.Option('nested', default='here')
                        ))
                    ))
                ),
                # expected
                {
                    'foo': {},
                    'bar': {
                        'test': True,
                        'data': None,
                        'value': 20,
                        'float': 10.1010,
                        'dct': {
                            'nested': 'here'
                        }
                    }
                }
            ),
        ]
    )
    def test_build_defaults(self, args, expected):
        """Build a defaults dict from a Scheme."""
        sch = scheme.Scheme(*args)
        defaults = sch.build_defaults()

        assert defaults == expected

    @pytest.mark.parametrize(
        'args', [
            ('a', 'b'),  # not an instance of _BaseOpt
        ]
    )
    def test_build_defaults_failure(self, args):
        """Build a defaults dict from a Scheme with bad data."""
        sch = scheme.Scheme(*args)
        with pytest.raises(errors.InvalidSchemeError):
            sch.build_defaults()

    @pytest.mark.parametrize(
        'args,expected', [
            (
                (scheme.Option('foo'),),
                ['foo']
            ),
            (
                (scheme.Option('foo'), scheme.Option('bar')),
                ['foo', 'bar']
            ),
            (
                (scheme.Option('foo'), scheme.DictOption('bar', scheme=None)),
                ['foo', 'bar']
            ),
            (
                (
                    scheme.Option('foo'),
                    scheme.DictOption('bar', scheme=scheme.Scheme(
                        scheme.Option('test'),
                        scheme.DictOption('dct', scheme=scheme.Scheme(
                            scheme.Option('nested')
                        )),
                        scheme.ListOption('list')
                    ))
                ),
                ['foo', 'bar', 'bar.test', 'bar.dct', 'bar.list', 'bar.dct.nested']
            )
        ]
    )
    def test_flatten(self, args, expected):
        """Flatten a Scheme."""
        sch = scheme.Scheme(*args)
        flattened = sch.flatten()

        assert len(flattened) == len(expected)
        for key in expected:
            assert key in flattened

    @pytest.mark.parametrize(
        'args,value', [
            (
                # option exists in config
                (scheme.Option('foo', default='bar', field_type=str),),
                {'foo': 'baz'}
            ),
            (
                # option does not exist in config and has default, but is not required
                (scheme.Option('foo', default='bar', required=False, field_type=str),),
                {}
            ),
            (
                # multiple args
                (
                    scheme.Option('foo', field_type=str),
                    scheme.Option('bar', field_type=int),
                    scheme.Option('baz', choices=['test'])
                ),
                {'foo': 'a', 'bar': 1, 'baz': 'test'}
            ),
            (
                # optional parent option not specified, required child option
                # not specified
                (
                    scheme.DictOption('foo', required=False, scheme=scheme.Scheme(
                        scheme.Option('bar', field_type=str),
                        scheme.Option('baz', field_type=str),
                    )),
                ),
                {}
            )
        ]
    )
    def test_validate_ok(self, args, value):
        """Validate a Scheme successfully."""
        sch = scheme.Scheme(*args)
        sch.validate(value)

    @pytest.mark.parametrize(
        'args,value', [
            (
                # option does not exist in config, no default
                (scheme.Option('foo', field_type=str),),
                {}
            ),
            (
                # option exists in config, fails validation
                (scheme.Option('foo', default='bar', field_type=str),),
                {'foo': 1}
            ),
            (
                # multiple args, one fails validation
                (
                    scheme.Option('foo', field_type=str),
                    scheme.Option('bar', field_type=int),
                    scheme.Option('baz', choices=['test'])
                ),
                {'foo': 'a', 'bar': 1, 'baz': 'something'}
            ),
            (
                # optional parent option specified, required child option
                # not specified
                (
                    scheme.DictOption('foo', required=True, scheme=scheme.Scheme(
                        scheme.Option('bar', field_type=str),
                        scheme.Option('baz', field_type=str),
                    )),
                ),
                {'foo': {'baz': 2}}
            )
        ]
    )
    def test_validate_failure(self, args, value):
        """Validate a Scheme unsuccessfully."""
        sch = scheme.Scheme(*args)
        with pytest.raises(errors.SchemeValidationError):
            sch.validate(value)

    @pytest.mark.parametrize(
        'value', [
            'foo',
            1,
            1.23,
            ['a', 'b', 'c'],
            {'a', 'b', 'c'},
            ('a', 'b', 'c'),
            None,
            False,
            True
        ]
    )
    def test_validate_failure_bad_config(self, value):
        """Validate a Scheme where the given config is not a dict."""
        sch = scheme.Scheme()
        with pytest.raises(errors.SchemeValidationError):
            sch.validate(value)

    @pytest.mark.parametrize(
        'args,value', [
            (
                    # option does not exist in config, has default, not required
                    (scheme.Option('foo', default='bar'),),
                    {}
            ),
            (
                    # option does not exist in config, has default, not required
                    (
                            scheme.DictOption('foo', scheme=scheme.Scheme(
                                scheme.Option('bar', default=1),
                                scheme.Option('baz'),
                            )),
                    ),
                    {'foo': {'baz': 2}}
            ),
            (
                    # option does not exist in config, has default, not required
                    (
                            scheme.ListOption('foo', member_scheme=scheme.Scheme(
                                scheme.Option('bar', default=1),
                                scheme.Option('baz'),
                            )),
                    ),
                    {'foo': [{'baz': 2}, {'bar': 3, 'baz': 2}]}
            ),
        ]
    )
    def test_validate_has_default(self, args, value):
        """Validate a Scheme where a default value is set, and the required field
        may or may not be set.

        If a default value is provided, it should be assumed to not be required.
        """
        sch = scheme.Scheme(*args)
        sch.validate(value)
示例#4
0
 def test_validate_with_scheme(self):
     """Validate a DictOption with a scheme"""
     opt = scheme.DictOption('test-opt', scheme.Scheme(
         scheme.Option('foo', field_type=str)
     ))
     opt.validate('foo', {'foo': 'bar'})
示例#5
0
 def test_validate_no_scheme(self):
     """Validate a DictOption with no scheme"""
     opt = scheme.DictOption('test-opt', None)
     opt.validate('foo', {'foo': 'bar'})
示例#6
0
 def test_validate_bad_data(self, value):
     """Validate a DictOption where the given value is not a dict"""
     opt = scheme.DictOption('test-opt', scheme.Scheme())
     with pytest.raises(errors.SchemeValidationError):
         opt.validate('foo', value)
示例#7
0
class TestDictOption:
    """Tests for the `DictOption` class."""

    def test_init_simple(self):
        """Initialize a DictOption."""
        opt = scheme.DictOption('test-opt', None)

        assert opt.name == 'test-opt'
        assert type(opt.default) == scheme.NoDefault
        assert opt.scheme is None
        assert opt.bind_env is False

    def test_init_full(self):
        """Initialize a DictOption."""
        opt = scheme.DictOption(
            name='test-opt',
            scheme=scheme.Scheme(),
            default='foo',
            bind_env=True
        )

        assert opt.name == 'test-opt'
        assert type(opt.default) != scheme.NoDefault
        assert opt.default == 'foo'
        assert isinstance(opt.scheme, scheme.Scheme)
        assert opt.bind_env is True

    @pytest.mark.parametrize(
        'value', [
            'foo',
            1,
            1.234,
            False,
            True,
            None,
            [1, 2, 3],
            ['a', 'b', 'c'],
            [{'a': 1}, {'b': 2}],
            ('foo', 'bar'),
            {1, 2, 3}
        ]
    )
    def test_validate_bad_data(self, value):
        """Validate a DictOption where the given value is not a dict"""
        opt = scheme.DictOption('test-opt', scheme.Scheme())
        with pytest.raises(errors.SchemeValidationError):
            opt.validate('foo', value)

    def test_validate_no_scheme(self):
        """Validate a DictOption with no scheme"""
        opt = scheme.DictOption('test-opt', None)
        opt.validate('foo', {'foo': 'bar'})

    def test_validate_with_scheme(self):
        """Validate a DictOption with a scheme"""
        opt = scheme.DictOption('test-opt', scheme.Scheme(
            scheme.Option('foo', field_type=str)
        ))
        opt.validate('foo', {'foo': 'bar'})

    @pytest.mark.parametrize(
        'option,prefix,auto_env', [
            (scheme.DictOption('foo', scheme=None, bind_env=False), None, False),
            (scheme.DictOption('foo', scheme=None, bind_env=False), None, True),
            (scheme.DictOption('foo', scheme=None, bind_env=False), 'TEST_ENV', False),
            (scheme.DictOption('foo', scheme=None, bind_env=False), 'TEST_ENV', True),

            (scheme.DictOption('foo', scheme=None, bind_env=True), None, False),
            (scheme.DictOption('foo', scheme=None, bind_env=True), None, True),
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'TEST_ENV', False),
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'TEST_ENV', True),
        ]
    )
    def test_parse_env_none(self, option, prefix, auto_env):
        """Parse environment variables for the DictOption. All of theses tests
        should result in None being returned because no environment variables
        are actually set.
        """
        actual = option.parse_env(prefix=prefix, auto_env=auto_env)
        assert actual is None

    @pytest.mark.parametrize(
        'option,key,prefix,auto_env,expected', [
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'foo', 'TEST_ENV_', False, None),
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'foo', 'TEST_ENV_', True, None),
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'nested', 'TEST_ENV_', False, {'env': {'key': 'test'}}),
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'nested', 'TEST_ENV_', True, {'env': {'key': 'test'}}),
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'nested.env', 'TEST_ENV_', False, {'key': 'test'}),
            (scheme.DictOption('foo', scheme=None, bind_env=True), 'nested.env', 'TEST_ENV_', True, {'key': 'test'}),
        ]
    )
    def test_parse_env_ok(self, option, key, prefix, auto_env, expected, with_env):
        """Parse environment variables for the DictOption."""
        actual = option.parse_env(key=key, prefix=prefix, auto_env=auto_env)
        assert actual == expected