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
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
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
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