Esempio n. 1
0
    def test_provider_decorator(self):  # type: () -> None
        with pytest.raises(TypeError):
            # noinspection PyTypeChecker
            ClassConfigurationSchema.provider(Boolean())  # type: ignore

        schema = Dictionary({})

        decorator = ClassConfigurationSchema.provider(schema)

        class IsAClass(object):
            pass

        def is_not_a_class():
            pass

        with pytest.raises(TypeError):
            decorator(is_not_a_class)  # type: ignore

        cls = decorator(IsAClass)
        assert cls is IsAClass
        assert getattr(cls, '_conformity_initialization_schema') is schema

        another_schema = Dictionary({})

        @ClassConfigurationSchema.provider(another_schema)
        class Sample(object):
            pass

        assert getattr(Sample,
                       '_conformity_initialization_schema') is another_schema
Esempio n. 2
0
    def test_schemaless(self):  # type: () -> None
        schema = ClassConfigurationSchema(base_class=BaseSomething)

        config = {
            'path': 'tests.test_fields_meta:SomethingWithJustKwargs'
        }  # type: dict
        value = schema.instantiate_from(config)
        assert config['object'] == SomethingWithJustKwargs
        assert isinstance(value, SomethingWithJustKwargs)
        assert value.kwargs == {}

        config = {
            'path': 'tests.test_fields_meta:SomethingWithJustKwargs',
            'kwargs': {
                'dog': 'Bree',
                'cute': True,
                'cat': b'Pumpkin'
            },
        }
        value = schema.instantiate_from(config)
        assert config['object'] == SomethingWithJustKwargs
        assert isinstance(value, SomethingWithJustKwargs)
        assert value.kwargs == {'dog': 'Bree', 'cute': True, 'cat': b'Pumpkin'}

        config = {
            'path': 'tests.test_fields_meta:SomethingWithJustKwargs',
            'kwargs': {
                b'Not unicode': False
            }
        }
        with pytest.raises(ValidationError) as error_context:
            schema.instantiate_from(config)
        assert error_context.value.args[0] == [
            Error('Not a unicode string',
                  code='INVALID',
                  pointer='kwargs.Not unicode')
            if six.PY2 else Error('Not a unicode string',
                                  code='INVALID',
                                  pointer='kwargs.{!r}'.format(b'Not unicode'))
        ]
        assert config['object'] == SomethingWithJustKwargs
Esempio n. 3
0
    def test_inline_definition_with_default_and_base_class(
            self):  # type: () -> None
        schema = ClassConfigurationSchema(
            base_class=BaseSomething,
            default_path='tests.test_fields_meta:SpecificSomething',
        )

        config = {}  # type: dict
        with pytest.raises(ValidationError) as error_context:
            schema.instantiate_from(config)
        assert sorted(error_context.value.args[0]) == [
            Error('Missing key: bar', code='MISSING', pointer='kwargs.bar'),
            Error('Missing key: foo', code='MISSING', pointer='kwargs.foo'),
        ]
        assert config['path'] == 'tests.test_fields_meta:SpecificSomething'
        assert config['object'] == SpecificSomething

        value = schema.instantiate_from(
            {'kwargs': {
                'foo': True,
                'bar': 'walk'
            }})
        assert isinstance(value, SpecificSomething)
        assert value.foo is True
        assert value.bar == 'walk'

        config = {'path': 'tests.test_fields_meta.AnotherSomething'}
        with pytest.raises(ValidationError) as error_context:
            schema.instantiate_from(config)
        assert error_context.value.args[0] == [
            Error('Missing key: baz', code='MISSING', pointer='kwargs.baz'),
        ]
        assert config['object'] == AnotherSomething

        config = {'path': 'tests.test_fields_meta.ExtendedAnotherSomething'}
        with pytest.raises(ValidationError) as error_context:
            schema.instantiate_from(config)
        assert error_context.value.args[0] == [
            Error('Missing key: baz', code='MISSING', pointer='kwargs.baz'),
        ]
        assert config['object'] == ExtendedAnotherSomething

        config = {'path': 'tests.test_fields_meta.OverridingAnotherSomething'}
        with pytest.raises(ValidationError) as error_context:
            schema.instantiate_from(config)
        assert error_context.value.args[0] == [
            Error('Missing key: no_baz',
                  code='MISSING',
                  pointer='kwargs.no_baz'),
        ]
        assert config['object'] == OverridingAnotherSomething

        config = {
            'path': 'tests.test_fields_meta.AnotherSomething',
            'kwargs': {
                'baz': None
            }
        }
        value = schema.instantiate_from(config)
        assert isinstance(value, AnotherSomething)
        assert value.baz is None
        assert value.qux == 'unset'
        assert config['object'] == AnotherSomething

        config = {
            'path': 'tests.test_fields_meta.AnotherSomething',
            'kwargs': {
                'baz': 'cool',
                'qux': False
            }
        }
        value = schema.instantiate_from(config)
        assert isinstance(value, AnotherSomething)
        assert value.baz == 'cool'
        assert value.qux is False
        assert config['object'] == AnotherSomething

        config = {
            'path': 'tests.test_fields_meta.ExtendedAnotherSomething',
            'kwargs': {
                'baz': 'cool',
                'qux': False
            }
        }
        value = schema.instantiate_from(config)
        assert isinstance(value, ExtendedAnotherSomething)
        assert value.baz == 'cool'
        assert value.qux is False
        assert config['object'] == ExtendedAnotherSomething

        config = {
            'path': 'tests.test_fields_meta.OverridingAnotherSomething',
            'kwargs': {
                'no_baz': 'very cool'
            }
        }
        value = schema.instantiate_from(config)
        assert isinstance(value, OverridingAnotherSomething)
        assert value.baz == 'very cool'
        assert value.qux == 'no_unset'
        assert config['object'] == OverridingAnotherSomething
Esempio n. 4
0
    def test_inline_definition_no_default_or_base_class(
            self):  # type: () -> None
        schema = ClassConfigurationSchema()

        assert schema.errors('Not a dict') == [
            Error('Not a mapping (dictionary)')
        ]
        assert schema.errors({
            'foo': 'bar',
            'baz': 'qux',
            'path': 'unprocessed',
            'kwargs': {},
            'object': Foo
        }) == [Error('Extra keys present: baz, foo', code='UNKNOWN')]
        assert schema.errors({}) == [
            Error('Missing key (and no default specified): path',
                  code='MISSING',
                  pointer='path'),
        ]
        assert schema.errors({'path': 'foo.bar:Hello'}) == [
            Error(
                'ImportError: No module named foo.bar'
                if six.PY2 else "ImportError: No module named 'foo'",
                pointer='path',
            )
        ]
        assert schema.errors({'path': 'tests.test_fields_meta.Foo'}) == [
            Error(
                "Neither class 'tests.test_fields_meta.Foo' nor one of its superclasses was decorated with "
                "@ClassConfigurationSchema.provider",
                pointer='path',
            )
        ]
        assert schema.errors({
            'path': 'tests.test_fields_meta:InvalidProvider'
        }) == [
            Error(
                "Class 'tests.test_fields_meta:InvalidProvider' attribute '_conformity_initialization_schema' should be a "
                "Dictionary or SchemalessDictionary Conformity field or one of their subclasses",
                pointer='path',
            )
        ]

        config = {
            'path': 'tests.test_fields_meta:BasicProvider'
        }  # type: Dict[HashableType, AnyType]
        assert sorted(schema.errors(config)) == [
            Error('Missing key: bar', code='MISSING', pointer='kwargs.bar'),
            Error('Missing key: foo', code='MISSING', pointer='kwargs.foo'),
        ]
        assert config['object'] == BasicProvider

        with pytest.raises(ValidationError) as error_context:
            # noinspection PyTypeChecker
            schema.instantiate_from('Not a dict')  # type: ignore
        assert error_context.value.args[0] == [
            Error('Not a mutable mapping (dictionary)')
        ]

        config = {'path': 'tests.test_fields_meta:BasicProvider'}
        with pytest.raises(ValidationError) as error_context:
            schema.instantiate_from(config)
        assert sorted(error_context.value.args[0]) == [
            Error('Missing key: bar', code='MISSING', pointer='kwargs.bar'),
            Error('Missing key: foo', code='MISSING', pointer='kwargs.foo'),
        ]
        assert config['object'] == BasicProvider

        config = {
            'path': 'tests.test_fields_meta:BasicProvider',
            'kwargs': {
                'foo': 'Fine',
                'bar': 'Bad'
            }
        }
        assert schema.errors(config) == [
            Error('Not a boolean', pointer='kwargs.bar')
        ]
        assert config['object'] == BasicProvider

        config = {
            'path': 'tests.test_fields_meta:BasicProvider',
            'kwargs': {
                'foo': 'Fine',
                'bar': 'Bad'
            }
        }
        with pytest.raises(ValidationError) as error_context:
            schema.instantiate_from(config)
        assert error_context.value.args[0] == [
            Error('Not a boolean', pointer='kwargs.bar')
        ]
        assert config['object'] == BasicProvider

        config = {
            'path': 'tests.test_fields_meta:BasicProvider',
            'kwargs': {
                'foo': 'Fine',
                'bar': True
            }
        }
        assert schema.errors(config) == []
        assert config['object'] == BasicProvider

        config = {
            'path': 'tests.test_fields_meta:BasicProvider',
            'kwargs': {
                'foo': 'Fine',
                'bar': True
            }
        }
        value = schema.instantiate_from(config)
        assert isinstance(value, BasicProvider)
        assert value.foo == 'Fine'
        assert value.bar is True
        assert config['object'] == BasicProvider

        schema = ClassConfigurationSchema()
        with pytest.raises(ValidationError):
            schema.initiate_cache_for('foo.bar:Hello')
        schema.initiate_cache_for('tests.test_fields_meta.BasicProvider')
        schema.initiate_cache_for('tests.test_fields_meta:BasicProvider')
        assert schema.introspect() == {
            'type': 'class_config_dictionary',
            'base_class': 'object',
            'switch_field': 'path',
            'switch_field_schema': TypePath(base_classes=object).introspect(),
            'kwargs_field': 'kwargs',
            'kwargs_contents_map': {
                'tests.test_fields_meta.BasicProvider':
                Dictionary({
                    'foo': UnicodeString(),
                    'bar': Boolean()
                }, ).introspect(),
                'tests.test_fields_meta:BasicProvider':
                Dictionary({
                    'foo': UnicodeString(),
                    'bar': Boolean()
                }, ).introspect(),
            },
        }

        schema = ClassConfigurationSchema(add_class_object_to_dict=False)
        config = {
            'path': 'tests.test_fields_meta:BasicProvider',
            'kwargs': {
                'foo': 'Fine',
                'bar': True
            }
        }
        value = schema.instantiate_from(config)
        assert isinstance(value, BasicProvider)
        assert value.foo == 'Fine'
        assert value.bar is True
        assert 'object' not in config