Skip to content

Commit

Permalink
Merge 1ec97a0 into e2b5b6f
Browse files Browse the repository at this point in the history
  • Loading branch information
hagenrd committed May 22, 2019
2 parents e2b5b6f + 1ec97a0 commit 16e3407
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 5 deletions.
6 changes: 3 additions & 3 deletions CHANGES.rst
Expand Up @@ -3,11 +3,11 @@
=========


1.12.1 (unreleased)
1.13.0(unreleased)
===================

- Nothing changed yet.

- Add ``StrippedValidTextLine`` field to strip leading/trailing
whitespace from values.

1.12.0 (2018-10-10)
===================
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Expand Up @@ -2,7 +2,7 @@
import codecs
from setuptools import setup, find_packages

version = '1.12.1.dev0'
version = '1.13.0.dev0'

entry_points = {
}
Expand Down
24 changes: 24 additions & 0 deletions src/nti/schema/field.py
Expand Up @@ -74,6 +74,7 @@
from nti.schema.interfaces import BeforeTextLineAssignedEvent
from nti.schema.interfaces import IFromObject
from nti.schema.interfaces import IListOrTuple
from nti.schema.interfaces import InvalidValue
from nti.schema.interfaces import IVariant
from nti.schema.interfaces import VariantValidationError

Expand Down Expand Up @@ -113,6 +114,7 @@
'Real',
'Set',
'Sequence',
'StrippedValidTextLine',
'Text',
'TextLine',
'Timedelta',
Expand Down Expand Up @@ -628,6 +630,28 @@ def validate(self, value):
def fromBytes(self, value):
return self.fromUnicode(value.decode('utf-8'))

_is_stripped = r"\S.*\S$" # non space at beginning and end
_is_stripped = re.compile(_is_stripped).match

class StrippedValidTextLine(DecodingValidTextLine):
"""
A text line that strips whitespace from incoming values.
.. versionadded:: 1.13.0
"""

def fromUnicode(self, value):
v = value.strip() if value else value
result = super(StrippedValidTextLine, self).fromUnicode(v)
return result

def _validate(self, value):
super(StrippedValidTextLine, self)._validate(value)
if not value or _is_stripped(value):
return

raise InvalidValue(value).with_field_and_value(self, value)

class ValidRegularExpression(ValidTextLine):

def __init__(self, pattern, flags=(re.U|re.I|re.M), *args, **kwargs):
Expand Down
22 changes: 21 additions & 1 deletion src/nti/schema/tests/test_field.py
Expand Up @@ -12,11 +12,13 @@
import unittest
import warnings


from zope.component import eventtesting

from zope.interface.common import interfaces as cmn_interfaces
from zope.schema import Dict

from zope.schema.fieldproperty import FieldProperty

from zope.schema.interfaces import ValidationError
from zope.schema.interfaces import InvalidURI
from zope.schema.interfaces import SchemaNotProvided
Expand All @@ -36,6 +38,7 @@
from nti.schema.field import Number
from nti.schema.field import Object
from nti.schema.field import ObjectLen
from nti.schema.field import StrippedValidTextLine
from nti.schema.field import TupleFromObject
from nti.schema.field import UniqueIterable
from nti.schema.field import ValidDatetime
Expand All @@ -44,6 +47,7 @@
from nti.schema.field import ValidTextLine as TextLine
from nti.schema.interfaces import IBeforeDictAssignedEvent
from nti.schema.interfaces import IBeforeSequenceAssignedEvent
from nti.schema.interfaces import InvalidValue
from nti.schema.interfaces import IVariant
from nti.schema.interfaces import IFromObject
from nti.schema.interfaces import VariantValidationError
Expand All @@ -63,6 +67,7 @@
from hamcrest import calling
from hamcrest import contains
from hamcrest import contains_string
from hamcrest import equal_to
from hamcrest import has_length
from hamcrest import has_property
from hamcrest import is_
Expand Down Expand Up @@ -572,6 +577,21 @@ class Thing(object):
field.set(thing, 'abc')
assert_that(thing, has_property('foo', 'abc'))

class TestStrippedValidTextLine(unittest.TestCase):

def test_stripped(self):
field = StrippedValidTextLine(__name__='foo')

class Thing(object):
foo = FieldProperty(field)

assert_that(field.fromUnicode(u' abc '), equal_to(u'abc'))
assert_that(field.fromBytes(b' abc '), equal_to(u'abc'))
assert_that(calling(setattr).with_args(Thing(), 'foo', u' abc '), raises(InvalidValue))

# Check valid case
Thing().foo = u'abc'

class TestDecodingValidTextLine(unittest.TestCase):

def test_decode(self):
Expand Down

0 comments on commit 16e3407

Please sign in to comment.