introduce PropertyValidator (wrapper)
This commit is contained in:
parent
40e531c0da
commit
ad0a5c27db
@ -24,7 +24,6 @@ class Subscription(object):
|
|||||||
class PropertyManager(ABC):
|
class PropertyManager(ABC):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.subscribers = []
|
self.subscribers = []
|
||||||
self.validators = {}
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def __getitem__(self, item):
|
def __getitem__(self, item):
|
||||||
@ -83,9 +82,6 @@ class PropertyManager(ABC):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.exception(e)
|
logger.exception(e)
|
||||||
|
|
||||||
def setValidator(self, name, validator):
|
|
||||||
self.validators[name] = Validator.of(validator)
|
|
||||||
|
|
||||||
|
|
||||||
class PropertyLayer(PropertyManager):
|
class PropertyLayer(PropertyManager):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -153,6 +149,49 @@ class PropertyFilter(PropertyManager):
|
|||||||
return [k for k in self.pm.keys() if k in self.props]
|
return [k for k in self.pm.keys() if k in self.props]
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyValidationError(Exception):
|
||||||
|
def __init__(self, key, value):
|
||||||
|
super().__init__('Invalid value for property "{key}": "{value}"'.format(key=key, value=str(value)))
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyValidator(PropertyManager):
|
||||||
|
def __init__(self, pm: PropertyManager, validators=None):
|
||||||
|
self.pm = pm
|
||||||
|
if validators is None:
|
||||||
|
self.validators = {}
|
||||||
|
else:
|
||||||
|
self.validators = {k: Validator.of(v) for k, v in validators.items()}
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
def validate(self, key, value):
|
||||||
|
if key not in self.validators:
|
||||||
|
return
|
||||||
|
if not self.validators[key].isValid(value):
|
||||||
|
raise PropertyValidationError(key, value)
|
||||||
|
|
||||||
|
def setValidator(self, key, validator):
|
||||||
|
self.validators[key] = Validator.of(validator)
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
return self.pm.__getitem__(item)
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self.validate(key, value)
|
||||||
|
return self.pm.__setitem__(key, value)
|
||||||
|
|
||||||
|
def __contains__(self, item):
|
||||||
|
return self.pm.__contains__(item)
|
||||||
|
|
||||||
|
def __dict__(self):
|
||||||
|
return self.pm.__dict__()
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
return self.pm.__delitem__(key)
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
return self.pm.keys()
|
||||||
|
|
||||||
|
|
||||||
class PropertyStack(PropertyManager):
|
class PropertyStack(PropertyManager):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
37
test/property/test_property_validator.py
Normal file
37
test/property/test_property_validator.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from unittest import TestCase
|
||||||
|
from owrx.property import PropertyLayer, PropertyValidator, PropertyValidationError
|
||||||
|
from owrx.property.validators import NumberValidator, StringValidator
|
||||||
|
|
||||||
|
|
||||||
|
class PropertyValidatorTest(TestCase):
|
||||||
|
def testPassesUnvalidated(self):
|
||||||
|
pm = PropertyLayer()
|
||||||
|
pv = PropertyValidator(pm)
|
||||||
|
pv["testkey"] = "testvalue"
|
||||||
|
self.assertEqual(pv["testkey"], "testvalue")
|
||||||
|
self.assertEqual(pm["testkey"], "testvalue")
|
||||||
|
|
||||||
|
def testPassesValidValue(self):
|
||||||
|
pv = PropertyValidator(PropertyLayer(), {"testkey": NumberValidator()})
|
||||||
|
pv["testkey"] = 42
|
||||||
|
self.assertEqual(pv["testkey"], 42)
|
||||||
|
|
||||||
|
def testThrowsErrorOnInvalidValue(self):
|
||||||
|
pv = PropertyValidator(PropertyLayer(), {"testkey": NumberValidator()})
|
||||||
|
with self.assertRaises(PropertyValidationError):
|
||||||
|
pv["testkey"] = "text"
|
||||||
|
|
||||||
|
def testSetValidator(self):
|
||||||
|
pv = PropertyValidator(PropertyLayer())
|
||||||
|
pv.setValidator("testkey", NumberValidator())
|
||||||
|
with self.assertRaises(PropertyValidationError):
|
||||||
|
pv["testkey"] = "text"
|
||||||
|
|
||||||
|
def testUpdateValidator(self):
|
||||||
|
pv = PropertyValidator(PropertyLayer(), {"testkey": StringValidator()})
|
||||||
|
# this should pass
|
||||||
|
pv["testkey"] = "text"
|
||||||
|
pv.setValidator("testkey", NumberValidator())
|
||||||
|
# this should raise
|
||||||
|
with self.assertRaises(PropertyValidationError):
|
||||||
|
pv["testkey"] = "text"
|
Loading…
Reference in New Issue
Block a user