Example #1
0
    def test_validation_errors(self):
        validator = dschema.Validator({
            'app_auth': {
                'id': dschema.prop(required=True),
                'token': dschema.prop(required=True),
                dschema.Required: True
            },
            'integer':
            dschema.prop(required=True, type=int)
        })

        data = {'app_auth': {'token': 'somerandomthing'}, 'integer': 1}

        with self.assertRaises(dschema.MissingKeyError):
            validator.validate(data)

        data = {'integer': 1}

        with self.assertRaises(dschema.MissingKeyError):
            validator.validate(data)

        data = {
            'app_auth': {
                'id': 12345,
                'token': 'somerandomthing'
            },
            'integer': 'notinteger'
        }

        with self.assertRaises(dschema.TypeValidationError):
            validator.validate(data)
Example #2
0
    def test_schema_errors(self):
        schema = {'bad': dschema.prop(required=True, default='cant-have-both')}

        with self.assertRaises(dschema.SchemaError):
            dschema.Validator(schema).validate({'bad': 'stuff'})

        schema = {'no_type_validator': dschema.prop(required=True, type='int')}

        with self.assertRaises(dschema.SchemaMissingTypeError):
            dschema.Validator(schema).validate({'no_type_validator': 1})
Example #3
0
    def test_prop(self):
        d = dschema.prop(default=2, dict=True, type=int, required=True)

        self.assertDictEqual(d, {
            '@default': 2,
            "@dict": True,
            "@type": int,
            "@required": True
        })

        with self.assertRaises(ValueError):
            dschema.prop(unknown_arg='BAD')
Example #4
0
    def test_required(self):
        validator = dschema.Validator({
            'test1': {
                'a': dschema.prop(required=True)
            },
            'test2': {
                'test3': {
                    dschema.Required: True,
                    'a': dschema.prop(default=1),
                    'b': dschema.prop(default=2)
                }
            },
            'test4': {
                'test5': {
                    dschema.Required: True,
                    'a': dschema.prop(required=True),
                    'b': dschema.prop(default=2)
                }
            }
        })

        # test2 is optional, test3 must exist if test2 exist though
        # shouldn't throw
        validator.validate({
            'test1': {
                'a': 1
            },
        })

        with self.assertRaises(dschema.ValidationError):
            # test.a must exist
            validator.validate({
                'test1': 1,
            })

        with self.assertRaises(dschema.ValidationError):
            # test2.test3 must exist
            validator.validate({'test1': {'a': 1}, 'test2': 1})

        # test2 is optional, test3 must exist if test2 exist though
        # shouldn't throw
        validator.validate({'test1': {'a': 1}, 'test2': {'test3': {'a': 1}}})

        with self.assertRaises(dschema.ValidationError):
            # test4.test5.a must exist
            validator.validate({'test1': {'a': 1}, 'test4': {'test5': None}})

        # test4.test5.a exists, shouldn't throw
        validator.validate({'test1': {'a': 1}, 'test4': {'test5': {'a': 1}}})
Example #5
0
    def test_dict(self):
        validator = dschema.Validator({
            'dict':
            dschema.Dict,
            'in_schema_not_dict':
            dschema.prop(default=dict())
        })

        # shouldn't throw
        result = validator.validate(
            {
                'dict': {
                    'a': 'b'
                },
                'not_dict': {
                    'c': 'd'
                },  # unhandled values should be namespacified when return_namespace=True,
                'in_schema_not_dict': {
                    'e': 'f'
                }
            },
            namespace=True,
            extra_keys=True)

        self.assertDictEqual(result.dict, {'a': 'b'})

        self.assertTrue(isinstance(result.not_dict, dschema.Namespace))

        self.assertEqual(result.not_dict.c, 'd')

        self.assertTrue(
            isinstance(result.in_schema_not_dict, dschema.Namespace))

        self.assertTrue(result.in_schema_not_dict.e, 'f')
Example #6
0
    def test_type_validation(self):
        def type_test(param):
            def type_test2(p):
                self.assertEqual(p, param)
                return p

            return type_test2

        validator = dschema.Validator({
            'a': {
                'b': dschema.prop(type=int)
            },
            'c': {
                'd': 'int'
            },
            'e': 'test_validate',
            'f': type_test('test2'),
            'dict': dschema.Dict
        })

        validator.add_type('int', int)

        validator.add_type('test_validate', type_test('test1'))

        result = validator.validate({
            'a': {
                'b': 1
            },
            'c': {
                'd': 2
            },
            'e': 'test1',
            'f': 'test2',
            'dict': {
                'a': 'b'
            }
        })

        self.assertEqual(result['a']['b'], 1)
        self.assertEqual(result['c']['d'], 2)
        self.assertEqual(result['e'], 'test1')
        self.assertEqual(result['f'], 'test2')
Example #7
0
    def test_extraneous_values(self):
        validator = dschema.Validator({
            'namespace': {
                'nested': {
                    'a': dschema.prop(required=True),
                    dschema.Required: True
                },
                dschema.Required: True
            }
        })

        with self.assertRaises(dschema.ExtraKeysError):
            validator.validate({
                'namespace': {
                    'nested': {
                        'a': 1,
                        'b': 2  # not allowed
                    }
                }
            })

        with self.assertRaises(dschema.ExtraKeysError):
            validator.validate({
                'namespace': {
                    'nested': {
                        'a': 1
                    },
                    'b': 2  # not allowed
                }
            })

        with self.assertRaises(dschema.ExtraKeysError):
            validator.validate({
                'namespace': {
                    'nested': {
                        'a': 1
                    }
                },
                'b': 2  # not allowed
            })
Example #8
0
    def test_fill_defaults_algorithm(self):
        # test the defaults filler algorithm

        v = dschema.Validator({})

        schema = {
            'l': {
                '@dict': True,
                'm': dschema.prop(default={'test1': 1}, dict=True)
            },
            'a': {
                'b': dschema.prop(default={'test2': 2}, dict=True)
            }
        }

        r = v._fill_schema_defaults(schema, '.', True)

        self.assertTrue(hasattr(r, 'l'))

        self.assertDictEqual(r.l, {'m': {'test1': 1}})

        self.assertTrue(hasattr(r, 'a'))
        self.assertTrue(hasattr(r.a, 'b'))

        self.assertDictEqual(r.a.b, {'test2': 2})

        r = v._fill_schema_defaults(schema, '.', False)

        self.assertDictEqual(r, {
            'l': {
                'm': {
                    'test1': 1
                }
            },
            'a': {
                'b': {
                    'test2': 2
                }
            }
        })

        r = v._fill_schema_defaults({dschema.Default: 1}, '.', False)

        self.assertEqual(r, 1)

        r = v._fill_schema_defaults({dschema.Default: {'test': 1}}, '.', True)

        self.assertEqual(type(r), dschema.Namespace)
        self.assertTrue(hasattr(r, 'test'))
        self.assertEqual(r.test, 1)

        r = v._fill_schema_defaults(
            {
                dschema.Dict: True,
                dschema.Default: {
                    'test': 1
                }
            }, '.', True)

        self.assertEqual(type(r), dict)
        self.assertIn('test', r)
        self.assertEqual(r['test'], 1)

        r = v._fill_schema_defaults(
            {
                dschema.Dict: True,
                dschema.Default: {
                    'test': 1
                }
            }, '.', False)

        self.assertEqual(type(r), dict)
        self.assertIn('test', r)
        self.assertEqual(r['test'], 1)
Example #9
0
    def test_application_of_schema_to_defaults(self):
        v = dschema.Validator(
            schema={
                "node": {
                    dschema.Default: {
                        "node2": {
                            "a": 1
                        }
                    },
                    "node2": {
                        "a": dschema.prop(required=True, type=lambda x: x + 1)
                    }
                }
            })

        r = v.validate({"node": None}, namespace=True)

        self.assertEqual(r.node.node2.a, 2)

        v.schema = {
            "node": {
                dschema.Default: {
                    "a": 1
                },
                "a": dschema.prop(required=True, type=lambda x: x + 1)
            }
        }

        r = v.validate({}, namespace=True)

        self.assertEqual(r.node.a, 2)

        v.schema = {
            "node": {
                dschema.Default: {
                    "node2": {
                        "a": 1
                    }
                },
                "node2": {
                    "a": dschema.prop(required=True, type=lambda x: x + 1)
                }
            }
        }

        r = v.validate({})

        self.assertEqual(r['node']['node2']['a'], 2)

        v.schema = {
            "node": {
                dschema.Default: {
                    "a": 1
                },
                "a": dschema.prop(required=True, type=lambda x: x + 1)
            }
        }

        r = v.validate({"node": None})

        self.assertEqual(r['node']['a'], 2)

        v.schema = {"a": dschema.prop(default='notint', type=int)}

        with self.assertRaises(dschema.SchemaDefaultError) as err:
            v.validate({})

        self.assertTrue(
            isinstance(err.exception.validation_error,
                       dschema.TypeValidationError))

        v.schema = {
            "a": {
                dschema.Default: {
                    "b": None
                },
                "b": {
                    dschema.Default: None,
                    "c": dschema.prop(required=True, type=int)
                }
            }
        }

        with self.assertRaises(dschema.SchemaDefaultError) as err:
            v.validate({})

        self.assertTrue(
            isinstance(err.exception.validation_error,
                       dschema.MissingKeyError))

        v.schema = {
            'a': {
                'b': {
                    'c': dschema.prop(default='d', type=lambda x: x + 'd')
                },
            }
        }

        r = v.validate({}, namespace=True)

        self.assertEqual(r.a.b.c, 'dd')

        v.schema = {
            'a': {
                'b': {
                    'c': dschema.prop(default='d', type=lambda x: x + 'd')
                },
            }
        }

        r = v.validate({})

        self.assertEqual(r['a']['b']['c'], 'dd')

        v.schema = {
            'a': {
                'b': {
                    'c': dschema.prop(default='notint', type=int)
                },
            }
        }

        with self.assertRaises(dschema.SchemaDefaultError) as err:
            v.validate({}, namespace=True)

        self.assertTrue(
            isinstance(err.exception.validation_error,
                       dschema.TypeValidationError))

        with self.assertRaises(dschema.SchemaDefaultError) as err:
            v.validate({})

        self.assertTrue(
            isinstance(err.exception.validation_error,
                       dschema.TypeValidationError))

        v.schema = {
            'a': {
                'b': {
                    'c': {
                        dschema.Default: {
                            'd': 4
                        },
                        "d": dschema.prop(default=3)
                    }
                },
            }
        }

        r = v.validate({}, namespace=True)

        self.assertTrue(r.a.b.c.d, 4)

        v.schema = {
            'a': {
                'b': {
                    'c': {
                        dschema.Default: {
                            'd': 4
                        },
                        "d": dschema.prop(default=3)
                    }
                },
            }
        }

        r = v.validate({})

        self.assertTrue(r['a']['b']['c']['d'], 4)

        v.schema = {
            'a': {
                'b': {
                    'c': {
                        dschema.Default: {
                            'd': 'notint'
                        },
                        "d": dschema.prop(type=int)
                    }
                },
            }
        }

        with self.assertRaises(dschema.SchemaDefaultError) as err:
            v.validate({}, namespace=True)

        self.assertTrue(
            isinstance(err.exception.validation_error,
                       dschema.TypeValidationError))

        with self.assertRaises(dschema.SchemaDefaultError) as err:
            v.validate({})

        self.assertTrue(
            isinstance(err.exception.validation_error,
                       dschema.TypeValidationError))
Example #10
0
    def test_default_values(self):
        validator = dschema.Validator({
            'a': {
                'b': {
                    'c': dschema.prop(default='d')
                },
            },
            'e': {
                'f': {
                    '@default': 'g'
                }
            },
            'h': {
                '@default': 'i'
            },
            'j':
            dschema.prop(default={'test': 1}, dict=True),
            'l': {
                'm': dschema.prop(default={'test2': 2}, dict=True)
            },
            'o': {
                'p': {
                    'q': dschema.prop(default={'test3': 3})
                },
            },
            'r': {
                's': {
                    dschema.Default: {
                        't': 'u'
                    },
                    dschema.Dict: True,
                    't': 'a'
                }
            }
        })

        result = validator.validate({}, namespace=True)

        self.assertTrue(hasattr(result, 'a'))

        self.assertTrue(hasattr(result.a, 'b'))

        self.assertTrue(hasattr(result.a.b, 'c'))

        self.assertEqual(result.a.b.c, 'd')

        self.assertTrue(hasattr(result, 'e'))

        self.assertTrue(hasattr(result.e, 'f'))

        self.assertEqual(result.e.f, 'g')

        self.assertEqual('i', result.h)

        self.assertTrue(hasattr(result, 'h'))

        self.assertTrue(hasattr(result, 'j'))

        self.assertTrue(hasattr(result, 'l'))

        self.assertTrue(hasattr(result.l, 'm'))

        self.assertDictEqual({'test': 1}, result.j)

        self.assertDictEqual({'test2': 2}, result.l.m)

        self.assertTrue(hasattr(result, 'o'))

        self.assertTrue(hasattr(result.o, 'p'))

        self.assertTrue(hasattr(result.o.p, 'q'))

        self.assertTrue(hasattr(result.o.p.q, 'test3'))

        self.assertEqual(result.o.p.q.test3, 3)

        self.assertTrue(hasattr(result, 'r'))

        self.assertTrue(hasattr(result.r, 's'))

        self.assertDictEqual(result.r.s, {'t': 'u'})

        result = validator.validate({'r': {'s': {'t': 'a'}}}, namespace=True)

        self.assertTrue(hasattr(result, 'r'))

        self.assertTrue(hasattr(result.r, 's'))

        self.assertDictEqual(result.r.s, {'t': 'a'})

        #

        result = validator.validate({'h': None})

        self.assertIn('a', result)

        self.assertIn('b', result['a'])

        self.assertIn('c', result['a']['b'])

        self.assertEqual('d', result['a']['b']['c'])

        self.assertIn('e', result)

        self.assertIn('f', result['e'])

        self.assertEqual('g', result['e']['f'])

        self.assertEqual('i', result['h'])

        self.assertDictEqual({'test': 1}, result['j'])

        self.assertDictEqual({'test2': 2}, result['l']['m'])

        self.assertIn('r', result)

        self.assertIn('s', result['r'])

        self.assertIn('t', result['r']['s'])

        self.assertDictEqual(result['r']['s'], {'t': 'u'})

        result = validator.validate({'r': {'s': {'t': 'a'}}})

        self.assertIn('r', result)

        self.assertIn('s', result['r'])

        self.assertIn('t', result['r']['s'])

        self.assertDictEqual(result['r']['s'], {'t': 'a'})
Example #11
0
import dschema

# specifying a required property as
# having a default value.

schema = {'bad': dschema.prop(required=True, default='cant-have-both')}

try:
    dschema.Validator(schema).validate({'bad': 'stuff'})
except dschema.SchemaError as e:

    # Message about 'required' and 'default' being mutually exclusive
    print(e)

# Not providing a validation handler
# for a type specified as a string

schema = {'no_type_validator': dschema.prop(required=True, type='int')}

try:
    validator = dschema.Validator(schema)

    # Validator.add_type must be used to add
    # something that handles 'int' ...

    # validator.add_type('int', int)

    validator.validate({'no_type_validator': 1})

except dschema.SchemaMissingTypeError as e:
Example #12
0
def phone_type(number):
    # Exceptions are validation errors
    # Very similar design to the "argparse" module
    return phonenumbers.parse(number)


def ssn_type(ssn):
    if re.match('^\d{3}-?\d{2}-?\d{4}$', ssn):
        return ssn
    else:
        raise ValueError('"{}" is not a valid SSN.')


schema = {
    'person': {
        'first_name': dschema.prop(required=True),
        'last_name': dschema.prop(required=True),
        'phone': dschema.prop(required=True, type=phone_type),
        'ssn': dschema.prop(required=True, type='ssn_type'),
        dschema.Required: True
        # "person" namespace is required, you must specify
        # even if "person" itself contains required properties
    },

    # Allow a raw dictionary value to pass through
    'other_info': dschema.prop(default=dict(), dict=True),

    # default to False if not present
    'subscribed': dschema.prop(default=False, type=bool)
}
Example #13
0
    def __init__(self, path: str):
        self.config_path = path

        def regex_type(value):
            return re.compile(value)

        def workers_type(value):
            try:
                value = int(value)
            except Exception:
                raise ValueError('Must be an integer value.')

            if value < 1:
                raise ValueError('Count must be at least 1.')

            return value

        self._validator = dschema.Validator({
            'api_key': {
                'id': dschema.prop(required=True, type=int),
                'hash': dschema.prop(required=True),
                dschema.Required: True
            },
            'session_path': dschema.prop(default='tgminer'),
            'data_dir': dschema.prop(default='data'),
            'chat_stdout': dschema.prop(default=False, type=bool),
            'timestamp_format': dschema.prop(default='({:%Y/%m/%d - %I:%M:%S %p})'),

            'group_filters': {
                'title': dschema.prop(default='.*', type=regex_type),
                'title_slug': dschema.prop(default='.*', type=regex_type),
                'id': dschema.prop(default='.*', type=regex_type),

                'username': dschema.prop(default='.*', type=regex_type),
                'user_alias': dschema.prop(default='.*', type=regex_type),
                'user_id': dschema.prop(default='.*', type=regex_type)
            },

            'direct_chat_filters': {
                'username': dschema.prop(default='.*', type=regex_type),
                'alias': dschema.prop(default='.*', type=regex_type),
                'id': dschema.prop(default='.*', type=regex_type)
            },

            'user_filters': {
                'username': dschema.prop(default='.*', type=regex_type),
                'alias': dschema.prop(default='.*', type=regex_type),
                'id': dschema.prop(default='.*', type=regex_type)
            },

            'download_photos': dschema.prop(default=True, type=bool),

            'download_documents': dschema.prop(default=True, type=bool),

            'download_stickers': dschema.prop(default=True, type=bool),

            'download_animations': dschema.prop(default=True, type=bool),

            'download_videos': dschema.prop(default=True, type=bool),

            'download_video_notes': dschema.prop(default=True, type=bool),

            'download_voice': dschema.prop(default=True, type=bool),

            'download_audio': dschema.prop(default=True, type=bool),

            'write_raw_logs': dschema.prop(default=True, type=bool),

            'docname_filter': dschema.prop(default='.*', type=regex_type),

            'log_direct_chats': dschema.prop(default=True, type=bool),
            'log_group_chats': dschema.prop(default=True, type=bool),

            'download_workers': dschema.prop(default=4, type=workers_type),
            'updates_workers': dschema.prop(default=1, type=workers_type),
            'log_update_threads': dschema.prop(default=False, type=bool)
        })

        self._config = None

        self.load()
import dschema

validator = dschema.Validator({
    'app_auth': {
        'id': dschema.prop(required=True),
        'token': dschema.prop(required=True),
        dschema.Required: True
        # You must specify a namespace as required
        # if you want it to be required, even if it
        # contains required properties
    },
    'integer': dschema.prop(required=True, type=int)
})

# Handling of missing required values
# ===================================

data = {
    'app_auth': {
        'token': 'somerandomthing',
    },
    'integer': 1
}

try:
    validator.validate(data)
except dschema.MissingKeyError as e:
    # message about 'app_auth.id' being required but missing...
    print(e)

data = {'integer': 1}