Skip to content

Commit

Permalink
Add basic validators
Browse files Browse the repository at this point in the history
  • Loading branch information
ziima committed Sep 14, 2018
1 parent b53ebb0 commit f872d45
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 1 deletion.
7 changes: 6 additions & 1 deletion src/appsettings/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,15 @@
NestedSetting, ObjectSetting, ObjectTypeChecker, PositiveFloatSetting,
PositiveIntegerSetting, SetSetting, Setting, SetTypeChecker, StringSetting,
StringTypeChecker, TupleSetting, TupleTypeChecker, TypeChecker)
from .validators import (
DictValuesTypeValidator, TypeValidator, ValuesTypeValidator)

__all__ = (
'BooleanSetting',
'BooleanTypeChecker',
'DictSetting',
'DictTypeChecker',
'DictValuesTypeValidator',
'FloatSetting',
'FloatTypeChecker',
'IntegerSetting',
Expand All @@ -40,7 +43,9 @@
'StringTypeChecker',
'TupleSetting',
'TupleTypeChecker',
'TypeChecker'
'TypeChecker',
'TypeValidator',
'ValuesTypeValidator',
)


Expand Down
52 changes: 52 additions & 0 deletions src/appsettings/validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"""Basic set of setting validators."""
from django.core.exceptions import ValidationError


class TypeValidator(object):
"""Validator which checks type of the value."""

message = 'Value %(value)s is not of type %(type)s.'

def __init__(self, value_type, message=None):
self.value_type = value_type
if message:
self.message = message

def __call__(self, value):
if not isinstance(value, self.value_type):
params = {'value': value, 'type': self.value_type.__name__}
raise ValidationError(self.message, params=params)


class ValuesTypeValidator(object):
"""Validator which checks types of iterable values."""

message = 'Element %(value)s is not of type %(type)s.'

def __init__(self, value_type, message=None):
self.value_type = value_type
if message:
self.message = message

def __call__(self, value):
for element in value:
if not isinstance(element, self.value_type):
params = {'value': element, 'type': self.value_type.__name__}
raise ValidationError(self.message, params=params)


class DictValuesTypeValidator(object):
"""Validator which checks types of dict values."""

message = "Item %(key)s's value %(value)s is not of type %(type)s."

def __init__(self, value_type, message=None):
self.value_type = value_type
if message:
self.message = message

def __call__(self, value):
for key, element in value.items():
if not isinstance(element, self.value_type):
params = {'key': key, 'value': element, 'type': self.value_type.__name__}
raise ValidationError(self.message, params=params)
43 changes: 43 additions & 0 deletions tests/test_validators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"""Test settings validators."""
from django.core.exceptions import ValidationError
from django.test import SimpleTestCase

from appsettings import (
DictValuesTypeValidator, TypeValidator, ValuesTypeValidator)


class TypeValidatorTestCase(SimpleTestCase):
"""Test TypeValidator."""

def test_valid(self):
TypeValidator(int)(42)
TypeValidator(float)(4.5)
TypeValidator(list)([])

def test_invalid(self):
with self.assertRaisesMessage(ValidationError, "Value None is not of type int."):
TypeValidator(int)(None)


class ValuesTypeValidatorTestCase(SimpleTestCase):
"""Test ValuesTypeValidator."""

def test_valid(self):
ValuesTypeValidator(int)([42, 14, 1676])
ValuesTypeValidator(int)({42, 14, 1676})
ValuesTypeValidator(int)((42, 14, 1676))

def test_invalid(self):
with self.assertRaisesMessage(ValidationError, "Element None is not of type int."):
ValuesTypeValidator(int)([42, None, 1676])


class DictValuesTypeValidatorTestCase(SimpleTestCase):
"""Test DictValuesTypeValidator."""

def test_valid(self):
DictValuesTypeValidator(int)({'a': 42, 'b': 1676})

def test_invalid(self):
with self.assertRaisesMessage(ValidationError, "Item b's value None is not of type int."):
DictValuesTypeValidator(int)({'a': 42, 'b': None})

0 comments on commit f872d45

Please sign in to comment.