diff --git a/cqlengine/columns.py b/cqlengine/columns.py index df01bef7..2f6ee4f4 100644 --- a/cqlengine/columns.py +++ b/cqlengine/columns.py @@ -146,6 +146,23 @@ class Ascii(Column): class Text(Column): db_type = 'text' + def __init__(self, *args, **kwargs): + self.min_length = kwargs.pop('min_length', 1 if kwargs.get('required', True) else None) + self.max_length = kwargs.pop('max_length', None) + super(Text, self).__init__(*args, **kwargs) + + def validate(self, value): + value = super(Text, self).validate(value) + if not isinstance(value, (basestring, bytearray)) and value is not None: + raise ValidationError('{} is not a string'.format(type(value))) + if self.max_length: + if len(value) > self.max_length: + raise ValidationError('{} is longer than {} characters'.format(self.column_name, self.max_length)) + if self.min_length: + if len(value) < self.min_length: + raise ValidationError('{} is shorter than {} characters'.format(self.column_name, self.min_length)) + return value + class Integer(Column): db_type = 'int' diff --git a/cqlengine/tests/columns/test_validation.py b/cqlengine/tests/columns/test_validation.py index 00a4097b..4921b672 100644 --- a/cqlengine/tests/columns/test_validation.py +++ b/cqlengine/tests/columns/test_validation.py @@ -1,6 +1,7 @@ #tests the behavior of the column classes from datetime import datetime from decimal import Decimal as D +from cqlengine import ValidationError from cqlengine.tests.base import BaseCassEngTestCase @@ -94,6 +95,48 @@ class TestInteger(BaseCassEngTestCase): it = self.IntegerTest() it.validate() +class TestText(BaseCassEngTestCase): + + def test_min_length(self): + #min len defaults to 1 + col = Text() + + with self.assertRaises(ValidationError): + col.validate('') + + col.validate('b') + + #test not required defaults to 0 + Text(required=False).validate('') + + #test arbitrary lengths + Text(min_length=0).validate('') + Text(min_length=5).validate('blake') + Text(min_length=5).validate('blaketastic') + with self.assertRaises(ValidationError): + Text(min_length=6).validate('blake') + + def test_max_length(self): + + Text(max_length=5).validate('blake') + with self.assertRaises(ValidationError): + Text(max_length=5).validate('blaketastic') + + def test_type_checking(self): + Text().validate('string') + Text().validate(u'unicode') + Text().validate(bytearray('bytearray')) + + with self.assertRaises(ValidationError): + Text().validate(None) + + with self.assertRaises(ValidationError): + Text().validate(5) + + with self.assertRaises(ValidationError): + Text().validate(True) + +