Skip to content

Commit

Permalink
Makes coerce working within items rule
Browse files Browse the repository at this point in the history
  • Loading branch information
oev81 committed Feb 24, 2018
1 parent b8b26f9 commit b1475fd
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 4 deletions.
29 changes: 29 additions & 0 deletions cerberus/tests/test_normalization.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,15 @@ def test_coerce_in_listschema():
assert_normalized(document, expected, schema)


def test_coerce_in_listitems():
schema = {'things': {'type': 'list',
'items': [{'coerce': int},
{'coerce': str}]}}
document = {'things': ['1', 2]}
expected = {'things': [1, '2']}
assert_normalized(document, expected, schema)


def test_coerce_in_dictschema_in_listschema():
item_schema = {'type': 'dict', 'schema': {'amount': {'coerce': int}}}
schema = {'things': {'type': 'list', 'schema': item_schema}}
Expand All @@ -56,6 +65,16 @@ def test_coerce_catches_ValueError():
errors.COERCION_FAILED, int)


def test_coerce_in_listitems_catches_ValueError():
schema = {'things': {'type': 'list',
'items': [{'coerce': int}, {'coerce': str}]}}
document = {'things': ['not_a_number', 2]}
_errors = assert_fail(document, schema)
_errors[0].info = () # ignore exception message here
assert_has_error(_errors, ('things', 0), ('things', 'items', 'coerce'),
errors.COERCION_FAILED, int)


def test_coerce_catches_TypeError():
schema = {'name': {'coerce': str.lower}}
_errors = assert_fail({'name': 1234}, schema)
Expand All @@ -64,6 +83,16 @@ def test_coerce_catches_TypeError():
errors.COERCION_FAILED, str.lower)


def test_coerce_in_listitems_catches_TypeError():
schema = {'things': {'type': 'list',
'items': [{'coerce': int}, {'coerce': str.lower}]}}
document = {'things': ['1', 2]}
_errors = assert_fail(document, schema)
_errors[0].info = () # ignore exception message here
assert_has_error(_errors, ('things', 1), ('things', 'items', 'coerce'),
errors.COERCION_FAILED, str.lower)


def test_coerce_unknown():
schema = {'foo': {'schema': {}, 'allow_unknown': {'coerce': int}}}
document = {'foo': {'bar': '0'}}
Expand Down
2 changes: 1 addition & 1 deletion cerberus/tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def test_validated_schema_cache():
v = Validator({'foozifix': {'coerce': int}})
assert len(v._valid_schemas) == cache_size

max_cache_size = 145
max_cache_size = 149
assert cache_size <= max_cache_size, \
"There's an unexpected high amount (%s) of cached valid " \
"definition schemas. Unless you added further tests, " \
Expand Down
21 changes: 18 additions & 3 deletions cerberus/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -682,9 +682,11 @@ def __normalize_containers(self, mapping, schema):
pass
elif isinstance(mapping[field], _str_type):
continue
elif isinstance(mapping[field], Sequence) and \
'schema' in schema[field]:
self.__normalize_sequence(field, mapping, schema)
elif isinstance(mapping[field], Sequence):
if 'schema' in schema[field]:
self.__normalize_sequence(field, mapping, schema)
elif 'items' in schema[field]:
self.__normalize_items(field, mapping, schema)

def __normalize_mapping_per_keyschema(self, field, mapping, property_rules):
schema = dict(((k, property_rules) for k in mapping[field]))
Expand Down Expand Up @@ -747,6 +749,19 @@ def __normalize_sequence(self, field, mapping, schema):
self._drop_nodes_from_errorpaths(validator._errors, [], [2])
self._error(validator._errors)

def __normalize_items(self, field, mapping, schema):
schema = dict(((k, v) for k, v in enumerate(schema[field]['items'])))
document = dict((k, v) for k, v in enumerate(mapping[field]))
validator = self._get_child_validator(
document_crumb=field, schema_crumb=(field, 'items'),
schema=schema)
value_type = type(mapping[field])
result = validator.normalized(document, always_return_document=True)
mapping[field] = value_type(result.values())
if validator._errors:
self._drop_nodes_from_errorpaths(validator._errors, [], [2])
self._error(validator._errors)

@staticmethod
def _normalize_purge_unknown(mapping, schema):
""" {'type': 'boolean'} """
Expand Down

0 comments on commit b1475fd

Please sign in to comment.