vendor: drop unused cerberus code

We don't need to ship tests and benchmarks to our users.
This commit is contained in:
Oz Tiram
2022-11-13 10:31:35 +01:00
parent 8699dc6277
commit 2cb30cead2
15 changed files with 3 additions and 3881 deletions
-4
View File
@@ -1,4 +0,0 @@
from pathlib import Path
DOCUMENTS_PATH = Path(__file__).parent / "documents"
@@ -1,212 +0,0 @@
"""
some notes regarding this test suite:
- results are only comparable using the semantically equal schema against and
identical set of documents in the same execution environment
- the module can be executed to generate a new set of test documents
- it is intended to detect *significant* changes in validation time
- benchmarks should run with as few other processes running on the system as
possible (e.g. an Alpine Linux on bare metal w/o a Desktop environment)
"""
import json
from collections import Counter
from pathlib import Path
from random import choice, randrange
from typing import Callable, List
from pytest import mark
from pipenv.vendor.cerberus import rules_set_registry, schema_registry, TypeDefinition, Validator
from pipenv.vendor.cerberus.benchmarks import DOCUMENTS_PATH
rules_set_registry.add("path_rules", {"coerce": Path, "type": "path"})
schema_registry.add(
"field_3_schema",
{
# an outer rule requires all fields' values to be a list
"field_31": {"contains": 0, "empty": False},
"field_32": {
"default": [None, None, None],
"items": [
{"type": "integer"},
{"type": "string"},
{"type": ["integer", "string"]},
],
"schema": {"nullable": True},
},
},
)
def schema_1_field_3_allow_unknown_check_with(field, value, error):
if len(value) > 9:
error(field, "Requires a smaller list.")
schema_1 = {
"field_1": {
"type": "dict",
"required": True,
"allow_unknown": True,
"keysrules": {"regex": r"field_1[12345]"},
"minlength": 3,
"maxlength": 5,
"schema": {
"field_11": {
"type": "integer",
"allowed": list(range(100)),
"dependencies": {"field_12": 0, "^field_1.field_13": 0},
},
"field_12": {
"type": "integer",
"default_setter": lambda _: 1,
"forbidden": (1,),
},
"field_13": {"type": "integer"},
"field_14": {"rename": "field_13"},
},
},
"field_2": {
"type": "dict",
"allow_unknown": False,
"schema": {
"field_21": {
"type": "integer",
"coerce": [str.strip, int],
"min": 9,
"max": 89,
"anyof": [{"dependencies": "field_22"}, {"dependencies": "field_23"}],
},
"field_22": {"excludes": "field_23", "nullable": True},
"field_23": {"nullable": True},
},
},
"field_3": {
"allow_unknown": {"check_with": schema_1_field_3_allow_unknown_check_with},
"valuesrules": {"type": "list"},
"require_all": True,
"schema": "field_3_schema",
},
"field_4": "path_rules",
}
def init_validator():
class TestValidator(Validator):
types_mapping = {
**Validator.types_mapping,
"path": TypeDefinition("path", (Path,), ()),
}
return TestValidator(schema_1, purge_unknown=True)
def load_documents():
with (DOCUMENTS_PATH / "overall_documents_1.json").open() as f:
documents = json.load(f)
return documents
def validate_documents(init_validator: Callable, documents: List[dict]):
doc_count = failed_count = 0
error_paths = Counter()
validator = init_validator()
def count_errors(errors):
if errors is None:
return
for error in errors:
if error.is_group_error:
count_errors(error.child_errors)
else:
error_paths[error.schema_path] += 1
for document in documents:
if validator.validated(document) is None:
failed_count += 1
count_errors(validator._errors)
doc_count += 1
print(
f"{failed_count} out of {doc_count} documents failed with "
f"{len(error_paths)} different error leafs."
)
print("Top 3 errors, excluding container errors:")
for path, count in error_paths.most_common(3):
print(f"{count}: {path}")
@mark.benchmark(group="overall-1")
def test_overall_performance_1(benchmark):
benchmark.pedantic(validate_documents, (init_validator, load_documents()), rounds=5)
#
def generate_sample_document_1() -> dict:
result = {}
for i in (1, 2, 3, 4, 5):
if randrange(100):
result[f"field_{i}"] = globals()[f"generate_document_1_field_{i}"]()
return result
def generate_document_1_field_1() -> dict:
result = {"field_11": randrange(100), "field_13": 0}
if randrange(100):
result["field_12"] = 0
if not randrange(100):
result["field_14"] = None
if randrange(100):
result["field_15"] = None
return result
def generate_document_1_field_2() -> dict:
x = "*" if not randrange(50) else " "
result = {"field_21": x + str(randrange(100)) + x}
if randrange(100):
result["field_22"] = None
if "field_22" in result and not randrange(100):
result["field_23"] = None
return result
def generate_document_1_field_3() -> dict:
result = {}
if randrange(100):
result["field_31"] = [randrange(2) for _ in range(randrange(20))]
else:
result["field_31"] = None
if randrange(100):
result["field_32"] = [
choice((0, 0, 0, 0, 0, 0, 0, 0, "", None)),
choice(("", "", "", "", "", "", "", "", 0, None)),
choice((0, 0, 0, 0, "", "", "", "", None)),
]
if not randrange(10):
result["3_unknown"] = [0] * (randrange(10) + 1)
return result
def generate_document_1_field_4():
return "/foo/bar" if randrange(100) else 0
def generate_document_1_field_5():
return None
def write_sample_documents():
with (DOCUMENTS_PATH / "overall_documents_1.json").open("wt") as f:
json.dump([generate_sample_document_1() for _ in range(10_000)], f)
if __name__ == "__main__":
write_sample_documents()
@@ -1,54 +0,0 @@
import json
from collections import Counter
from typing import Callable, List
from typing import Counter as CounterType
from pytest import mark
from pipenv.vendor.cerberus import Validator
from pipenv.vendor.cerberus.benchmarks.schemas.overalll_schema_2 import product_schema
from pipenv.vendor.cerberus.benchmarks import DOCUMENTS_PATH
def init_validator():
return Validator(product_schema, purge_unknown=True)
def load_documents():
with (DOCUMENTS_PATH / "overall_documents_2.json").open() as f:
documents = json.load(f)
return documents
def validate_documents(init_validator: Callable, documents: List[dict]) -> None:
doc_count = failed_count = 0
error_paths: CounterType[tuple] = Counter()
validator = init_validator()
def count_errors(errors):
if errors is None:
return
for error in errors:
if error.is_group_error:
count_errors(error.child_errors)
else:
error_paths[error.schema_path] += 1
for document in documents:
if validator.validated(document) is None:
failed_count += 1
count_errors(validator._errors)
doc_count += 1
print(
f"{failed_count} out of {doc_count} documents failed with "
f"{len(error_paths)} different error leafs."
)
print("Top 3 errors, excluding container errors:")
for path, count in error_paths.most_common(3):
print(f"{count}: {path}")
@mark.benchmark(group="overall-2")
def test_overall_performance_2(benchmark):
benchmark.pedantic(validate_documents, (init_validator, load_documents()), rounds=5)
-159
View File
@@ -1,159 +0,0 @@
# -*- coding: utf-8 -*-
import re
import pytest
from pipenv.vendor.cerberus import errors, Validator, SchemaError, DocumentError
from pipenv.vendor.cerberus.tests.conftest import sample_schema
def assert_exception(exception, document={}, schema=None, validator=None, msg=None):
"""
Tests whether a specific exception is raised. Optionally also tests whether the
exception message is as expected.
"""
if validator is None:
validator = Validator()
if msg is None:
with pytest.raises(exception):
validator(document, schema)
else:
with pytest.raises(exception, match=re.escape(msg)):
validator(document, schema)
def assert_schema_error(*args):
"""Tests whether a validation raises an exception due to a malformed schema."""
assert_exception(SchemaError, *args)
def assert_document_error(*args):
"""Tests whether a validation raises an exception due to a malformed document."""
assert_exception(DocumentError, *args)
def assert_fail(
document,
schema=None,
validator=None,
update=False,
error=None,
errors=None,
child_errors=None,
):
"""Tests whether a validation fails."""
if validator is None:
validator = Validator(sample_schema)
result = validator(document, schema, update)
assert isinstance(result, bool)
assert not result
actual_errors = validator._errors
assert not (error is not None and errors is not None)
assert not (errors is not None and child_errors is not None), (
'child_errors can only be tested in ' 'conjunction with the error parameter'
)
assert not (child_errors is not None and error is None)
if error is not None:
assert len(actual_errors) == 1
assert_has_error(actual_errors, *error)
if child_errors is not None:
assert len(actual_errors[0].child_errors) == len(child_errors)
assert_has_errors(actual_errors[0].child_errors, child_errors)
elif errors is not None:
assert len(actual_errors) == len(errors)
assert_has_errors(actual_errors, errors)
return actual_errors
def assert_success(document, schema=None, validator=None, update=False):
"""Tests whether a validation succeeds."""
if validator is None:
validator = Validator(sample_schema)
result = validator(document, schema, update)
assert isinstance(result, bool)
if not result:
raise AssertionError(validator.errors)
def assert_has_error(_errors, d_path, s_path, error_def, constraint, info=()):
if not isinstance(d_path, tuple):
d_path = (d_path,)
if not isinstance(info, tuple):
info = (info,)
assert isinstance(_errors, errors.ErrorList)
for i, error in enumerate(_errors):
assert isinstance(error, errors.ValidationError)
try:
assert error.document_path == d_path
assert error.schema_path == s_path
assert error.code == error_def.code
assert error.rule == error_def.rule
assert error.constraint == constraint
if not error.is_group_error:
assert error.info == info
except AssertionError:
pass
except Exception:
raise
else:
break
else:
raise AssertionError(
"""
Error with properties:
document_path={doc_path}
schema_path={schema_path}
code={code}
constraint={constraint}
info={info}
not found in errors:
{errors}
""".format(
doc_path=d_path,
schema_path=s_path,
code=hex(error.code),
info=info,
constraint=constraint,
errors=_errors,
)
)
return i
def assert_has_errors(_errors, _exp_errors):
assert isinstance(_exp_errors, list)
for error in _exp_errors:
assert isinstance(error, tuple)
assert_has_error(_errors, *error)
def assert_not_has_error(_errors, *args, **kwargs):
try:
assert_has_error(_errors, *args, **kwargs)
except AssertionError:
pass
except Exception as e:
raise e
else:
raise AssertionError('An unexpected error occurred.')
def assert_bad_type(field, data_type, value):
assert_fail(
{field: value}, error=(field, (field, 'type'), errors.BAD_TYPE, data_type)
)
def assert_normalized(document, expected, schema=None, validator=None):
if validator is None:
validator = Validator(sample_schema)
assert_success(document, schema, validator)
assert validator.document == expected
-81
View File
@@ -1,81 +0,0 @@
# -*- coding: utf-8 -*-
from copy import deepcopy
import pytest
from pipenv.vendor.cerberus import Validator
@pytest.fixture
def document():
return deepcopy(sample_document)
@pytest.fixture
def schema():
return deepcopy(sample_schema)
@pytest.fixture
def validator():
return Validator(sample_schema)
sample_schema = {
'a_string': {'type': 'string', 'minlength': 2, 'maxlength': 10},
'a_binary': {'type': 'binary', 'minlength': 2, 'maxlength': 10},
'a_nullable_integer': {'type': 'integer', 'nullable': True},
'an_integer': {'type': 'integer', 'min': 1, 'max': 100},
'a_restricted_integer': {'type': 'integer', 'allowed': [-1, 0, 1]},
'a_boolean': {'type': 'boolean', 'meta': 'can haz two distinct states'},
'a_datetime': {'type': 'datetime', 'meta': {'format': '%a, %d. %b %Y'}},
'a_float': {'type': 'float', 'min': 1, 'max': 100},
'a_number': {'type': 'number', 'min': 1, 'max': 100},
'a_set': {'type': 'set'},
'one_or_more_strings': {'type': ['string', 'list'], 'schema': {'type': 'string'}},
'a_regex_email': {
'type': 'string',
'regex': r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$',
},
'a_readonly_string': {'type': 'string', 'readonly': True},
'a_restricted_string': {'type': 'string', 'allowed': ['agent', 'client', 'vendor']},
'an_array': {'type': 'list', 'allowed': ['agent', 'client', 'vendor']},
'an_array_from_set': {
'type': 'list',
'allowed': set(['agent', 'client', 'vendor']),
},
'a_list_of_dicts': {
'type': 'list',
'schema': {
'type': 'dict',
'schema': {
'sku': {'type': 'string'},
'price': {'type': 'integer', 'required': True},
},
},
},
'a_list_of_values': {
'type': 'list',
'items': [{'type': 'string'}, {'type': 'integer'}],
},
'a_list_of_integers': {'type': 'list', 'schema': {'type': 'integer'}},
'a_dict': {
'type': 'dict',
'schema': {
'address': {'type': 'string'},
'city': {'type': 'string', 'required': True},
},
},
'a_dict_with_valuesrules': {'type': 'dict', 'valuesrules': {'type': 'integer'}},
'a_list_length': {
'type': 'list',
'schema': {'type': 'integer'},
'minlength': 2,
'maxlength': 5,
},
'a_nullable_field_without_type': {'nullable': True},
'a_not_nullable_field_without_type': {},
}
sample_document = {'name': 'john doe'}
-111
View File
@@ -1,111 +0,0 @@
# -*- coding: utf-8 -*-
from decimal import Decimal
from pipenv.patched.pip._vendor.pkg_resources import Distribution, DistributionNotFound
from pytest import mark
from pipenv.vendor.cerberus import TypeDefinition, Validator
from pipenv.vendor.cerberus.tests import assert_fail, assert_success
from pipenv.vendor.cerberus.utils import validator_factory
from pipenv.vendor.cerberus.validator import BareValidator
from pipenv.vendor.cerberus.platform import PYTHON_VERSION
if PYTHON_VERSION > 3 and PYTHON_VERSION < 3.4:
from imp import reload
elif PYTHON_VERSION >= 3.4:
from importlib import reload
else:
pass # Python 2.x
def test_pkgresources_version(monkeypatch):
def create_fake_distribution(name):
return Distribution(project_name="cerberus", version="1.2.3")
with monkeypatch.context() as m:
cerberus = __import__("cerberus")
m.setattr("pkg_resources.get_distribution", create_fake_distribution)
reload(cerberus)
assert cerberus.__version__ == "1.2.3"
def test_version_not_found(monkeypatch):
def raise_distribution_not_found(name):
raise DistributionNotFound("pkg_resources cannot get distribution")
with monkeypatch.context() as m:
cerberus = __import__("cerberus")
m.setattr("pkg_resources.get_distribution", raise_distribution_not_found)
reload(cerberus)
assert cerberus.__version__ == "unknown"
def test_clear_cache(validator):
assert len(validator._valid_schemas) > 0
validator.clear_caches()
assert len(validator._valid_schemas) == 0
def test_docstring(validator):
assert validator.__doc__
# Test that testing with the sample schema works as expected
# as there might be rules with side-effects in it
@mark.parametrize(
"test,document",
((assert_fail, {"an_integer": 60}), (assert_success, {"an_integer": 110})),
)
def test_that_test_fails(test, document):
try:
test(document)
except AssertionError:
pass
else:
raise AssertionError("test didn't fail")
def test_dynamic_types():
decimal_type = TypeDefinition("decimal", (Decimal,), ())
document = {"measurement": Decimal(0)}
schema = {"measurement": {"type": "decimal"}}
validator = Validator()
validator.types_mapping["decimal"] = decimal_type
assert_success(document, schema, validator)
class MyValidator(Validator):
types_mapping = Validator.types_mapping.copy()
types_mapping["decimal"] = decimal_type
validator = MyValidator()
assert_success(document, schema, validator)
def test_mro():
assert Validator.__mro__ == (Validator, BareValidator, object), Validator.__mro__
def test_mixin_init():
class Mixin(object):
def __init__(self, *args, **kwargs):
kwargs["test"] = True
super(Mixin, self).__init__(*args, **kwargs)
MyValidator = validator_factory("MyValidator", Mixin)
validator = MyValidator()
assert validator._config["test"]
def test_sub_init():
class MyValidator(Validator):
def __init__(self, *args, **kwargs):
kwargs["test"] = True
super(MyValidator, self).__init__(*args, **kwargs)
validator = MyValidator()
assert validator._config["test"]
-101
View File
@@ -1,101 +0,0 @@
# -*- coding: utf-8 -*-
from pytest import mark
import pipenv.vendor.cerberus as cerberus
from pipenv.vendor.cerberus.tests import assert_fail, assert_success
from pipenv.vendor.cerberus.tests.conftest import sample_schema
def test_contextual_data_preservation():
class InheritedValidator(cerberus.Validator):
def __init__(self, *args, **kwargs):
if 'working_dir' in kwargs:
self.working_dir = kwargs['working_dir']
super(InheritedValidator, self).__init__(*args, **kwargs)
def _validate_type_test(self, value):
if self.working_dir:
return True
assert 'test' in InheritedValidator.types
v = InheritedValidator(
{'test': {'type': 'list', 'schema': {'type': 'test'}}}, working_dir='/tmp'
)
assert_success({'test': ['foo']}, validator=v)
def test_docstring_parsing():
class CustomValidator(cerberus.Validator):
def _validate_foo(self, argument, field, value):
"""{'type': 'zap'}"""
pass
def _validate_bar(self, value):
"""
Test the barreness of a value.
The rule's arguments are validated against this schema:
{'type': 'boolean'}
"""
pass
assert 'foo' in CustomValidator.validation_rules
assert 'bar' in CustomValidator.validation_rules
# TODO remove 'validator' as rule parameter with the next major release
@mark.parametrize('rule', ('check_with', 'validator'))
def test_check_with_method(rule):
# https://github.com/pyeve/cerberus/issues/265
class MyValidator(cerberus.Validator):
def _check_with_oddity(self, field, value):
if not value & 1:
self._error(field, "Must be an odd number")
v = MyValidator(schema={'amount': {rule: 'oddity'}})
assert_success(document={'amount': 1}, validator=v)
assert_fail(
document={'amount': 2},
validator=v,
error=('amount', (), cerberus.errors.CUSTOM, None, ('Must be an odd number',)),
)
# TODO remove test with the next major release
@mark.parametrize('rule', ('check_with', 'validator'))
def test_validator_method(rule):
class MyValidator(cerberus.Validator):
def _validator_oddity(self, field, value):
if not value & 1:
self._error(field, "Must be an odd number")
v = MyValidator(schema={'amount': {rule: 'oddity'}})
assert_success(document={'amount': 1}, validator=v)
assert_fail(
document={'amount': 2},
validator=v,
error=('amount', (), cerberus.errors.CUSTOM, None, ('Must be an odd number',)),
)
def test_schema_validation_can_be_disabled_in_schema_setter():
class NonvalidatingValidator(cerberus.Validator):
"""
Skips schema validation to speed up initialization
"""
@cerberus.Validator.schema.setter
def schema(self, schema):
if schema is None:
self._schema = None
elif self.is_child:
self._schema = schema
elif isinstance(schema, cerberus.schema.DefinitionSchema):
self._schema = schema
else:
self._schema = cerberus.schema.UnvalidatedSchema(schema)
v = NonvalidatingValidator(schema=sample_schema)
assert v.validate(document={'an_integer': 1})
assert not v.validate(document={'an_integer': 'a'})
-365
View File
@@ -1,365 +0,0 @@
# -*- coding: utf-8 -*-
from pipenv.vendor.cerberus import Validator, errors
from pipenv.vendor.cerberus.tests import assert_fail
ValidationError = errors.ValidationError
def test__error_1():
v = Validator(schema={'foo': {'type': 'string'}})
v.document = {'foo': 42}
v._error('foo', errors.BAD_TYPE, 'string')
error = v._errors[0]
assert error.document_path == ('foo',)
assert error.schema_path == ('foo', 'type')
assert error.code == 0x24
assert error.rule == 'type'
assert error.constraint == 'string'
assert error.value == 42
assert error.info == ('string',)
assert not error.is_group_error
assert not error.is_logic_error
def test__error_2():
v = Validator(schema={'foo': {'keysrules': {'type': 'integer'}}})
v.document = {'foo': {'0': 'bar'}}
v._error('foo', errors.KEYSRULES, ())
error = v._errors[0]
assert error.document_path == ('foo',)
assert error.schema_path == ('foo', 'keysrules')
assert error.code == 0x83
assert error.rule == 'keysrules'
assert error.constraint == {'type': 'integer'}
assert error.value == {'0': 'bar'}
assert error.info == ((),)
assert error.is_group_error
assert not error.is_logic_error
def test__error_3():
valids = [
{'type': 'string', 'regex': '0x[0-9a-f]{2}'},
{'type': 'integer', 'min': 0, 'max': 255},
]
v = Validator(schema={'foo': {'oneof': valids}})
v.document = {'foo': '0x100'}
v._error('foo', errors.ONEOF, (), 0, 2)
error = v._errors[0]
assert error.document_path == ('foo',)
assert error.schema_path == ('foo', 'oneof')
assert error.code == 0x92
assert error.rule == 'oneof'
assert error.constraint == valids
assert error.value == '0x100'
assert error.info == ((), 0, 2)
assert error.is_group_error
assert error.is_logic_error
def test_error_tree_from_subschema(validator):
schema = {'foo': {'schema': {'bar': {'type': 'string'}}}}
document = {'foo': {'bar': 0}}
assert_fail(document, schema, validator=validator)
d_error_tree = validator.document_error_tree
s_error_tree = validator.schema_error_tree
assert 'foo' in d_error_tree
assert len(d_error_tree['foo'].errors) == 1, d_error_tree['foo']
assert d_error_tree['foo'].errors[0].code == errors.MAPPING_SCHEMA.code
assert 'bar' in d_error_tree['foo']
assert d_error_tree['foo']['bar'].errors[0].value == 0
assert d_error_tree.fetch_errors_from(('foo', 'bar'))[0].value == 0
assert 'foo' in s_error_tree
assert 'schema' in s_error_tree['foo']
assert 'bar' in s_error_tree['foo']['schema']
assert 'type' in s_error_tree['foo']['schema']['bar']
assert s_error_tree['foo']['schema']['bar']['type'].errors[0].value == 0
assert (
s_error_tree.fetch_errors_from(('foo', 'schema', 'bar', 'type'))[0].value == 0
)
def test_error_tree_from_anyof(validator):
schema = {'foo': {'anyof': [{'type': 'string'}, {'type': 'integer'}]}}
document = {'foo': []}
assert_fail(document, schema, validator=validator)
d_error_tree = validator.document_error_tree
s_error_tree = validator.schema_error_tree
assert 'foo' in d_error_tree
assert d_error_tree['foo'].errors[0].value == []
assert 'foo' in s_error_tree
assert 'anyof' in s_error_tree['foo']
assert 0 in s_error_tree['foo']['anyof']
assert 1 in s_error_tree['foo']['anyof']
assert 'type' in s_error_tree['foo']['anyof'][0]
assert s_error_tree['foo']['anyof'][0]['type'].errors[0].value == []
def test_nested_error_paths(validator):
# interpreters of the same version on some platforms showed different sort results
# over various runs:
def assert_has_all_errors(errors, *ref_errs):
for ref_err in ref_errs:
for error in errors:
if error == ref_err:
break
else:
raise AssertionError
schema = {
'a_dict': {
'keysrules': {'type': 'integer'},
'valuesrules': {'regex': '[a-z]*'},
},
'a_list': {'schema': {'type': 'string', 'oneof_regex': ['[a-z]*$', '[A-Z]*']}},
}
document = {
'a_dict': {0: 'abc', 'one': 'abc', 2: 'aBc', 'three': 'abC'},
'a_list': [0, 'abc', 'abC'],
}
assert_fail(document, schema, validator=validator)
det = validator.document_error_tree
set = validator.schema_error_tree
assert len(det.errors) == 0
assert len(set.errors) == 0
assert len(det['a_dict'].errors) == 2
assert len(set['a_dict'].errors) == 0
assert det['a_dict'][0] is None
assert len(det['a_dict']['one'].errors) == 1
assert len(det['a_dict'][2].errors) == 1
assert len(det['a_dict']['three'].errors) == 2
assert len(set['a_dict']['keysrules'].errors) == 1
assert len(set['a_dict']['valuesrules'].errors) == 1
assert len(set['a_dict']['keysrules']['type'].errors) == 2
assert len(set['a_dict']['valuesrules']['regex'].errors) == 2
ref_err1 = ValidationError(
('a_dict', 'one'),
('a_dict', 'keysrules', 'type'),
errors.BAD_TYPE.code,
'type',
'integer',
'one',
(),
)
ref_err2 = ValidationError(
('a_dict', 2),
('a_dict', 'valuesrules', 'regex'),
errors.REGEX_MISMATCH.code,
'regex',
'[a-z]*$',
'aBc',
(),
)
ref_err3 = ValidationError(
('a_dict', 'three'),
('a_dict', 'keysrules', 'type'),
errors.BAD_TYPE.code,
'type',
'integer',
'three',
(),
)
ref_err4 = ValidationError(
('a_dict', 'three'),
('a_dict', 'valuesrules', 'regex'),
errors.REGEX_MISMATCH.code,
'regex',
'[a-z]*$',
'abC',
(),
)
assert det['a_dict'][2].errors[0] == ref_err2
assert det['a_dict']['one'].errors[0] == ref_err1
assert_has_all_errors(det['a_dict']['three'].errors, ref_err3, ref_err4)
assert_has_all_errors(set['a_dict']['keysrules']['type'].errors, ref_err1, ref_err3)
assert_has_all_errors(
set['a_dict']['valuesrules']['regex'].errors, ref_err2, ref_err4
)
assert len(det['a_list'].errors) == 1
assert len(det['a_list'][0].errors) == 1
assert det['a_list'][1] is None
assert len(det['a_list'][2].errors) == 3
assert len(set['a_list'].errors) == 0
assert len(set['a_list']['schema'].errors) == 1
assert len(set['a_list']['schema']['type'].errors) == 1
assert len(set['a_list']['schema']['oneof'][0]['regex'].errors) == 1
assert len(set['a_list']['schema']['oneof'][1]['regex'].errors) == 1
ref_err5 = ValidationError(
('a_list', 0),
('a_list', 'schema', 'type'),
errors.BAD_TYPE.code,
'type',
'string',
0,
(),
)
ref_err6 = ValidationError(
('a_list', 2),
('a_list', 'schema', 'oneof'),
errors.ONEOF.code,
'oneof',
'irrelevant_at_this_point',
'abC',
(),
)
ref_err7 = ValidationError(
('a_list', 2),
('a_list', 'schema', 'oneof', 0, 'regex'),
errors.REGEX_MISMATCH.code,
'regex',
'[a-z]*$',
'abC',
(),
)
ref_err8 = ValidationError(
('a_list', 2),
('a_list', 'schema', 'oneof', 1, 'regex'),
errors.REGEX_MISMATCH.code,
'regex',
'[a-z]*$',
'abC',
(),
)
assert det['a_list'][0].errors[0] == ref_err5
assert_has_all_errors(det['a_list'][2].errors, ref_err6, ref_err7, ref_err8)
assert set['a_list']['schema']['oneof'].errors[0] == ref_err6
assert set['a_list']['schema']['oneof'][0]['regex'].errors[0] == ref_err7
assert set['a_list']['schema']['oneof'][1]['regex'].errors[0] == ref_err8
assert set['a_list']['schema']['type'].errors[0] == ref_err5
def test_path_resolution_for_registry_references():
class CustomValidator(Validator):
def _normalize_coerce_custom(self, value):
raise Exception("Failed coerce")
validator = CustomValidator()
validator.schema_registry.add(
"schema1", {"child": {"type": "boolean", "coerce": "custom"}}
)
validator.schema = {"parent": {"schema": "schema1"}}
validator.validate({"parent": {"child": "["}})
expected = {
'parent': [
{
'child': [
"must be of boolean type",
"field 'child' cannot be coerced: Failed coerce",
]
}
]
}
assert validator.errors == expected
def test_queries():
schema = {'foo': {'type': 'dict', 'schema': {'bar': {'type': 'number'}}}}
document = {'foo': {'bar': 'zero'}}
validator = Validator(schema)
validator(document)
assert 'foo' in validator.document_error_tree
assert 'bar' in validator.document_error_tree['foo']
assert 'foo' in validator.schema_error_tree
assert 'schema' in validator.schema_error_tree['foo']
assert errors.MAPPING_SCHEMA in validator.document_error_tree['foo'].errors
assert errors.MAPPING_SCHEMA in validator.document_error_tree['foo']
assert errors.BAD_TYPE in validator.document_error_tree['foo']['bar']
assert errors.MAPPING_SCHEMA in validator.schema_error_tree['foo']['schema']
assert (
errors.BAD_TYPE in validator.schema_error_tree['foo']['schema']['bar']['type']
)
assert (
validator.document_error_tree['foo'][errors.MAPPING_SCHEMA].child_errors[0].code
== errors.BAD_TYPE.code
)
def test_basic_error_handler():
handler = errors.BasicErrorHandler()
_errors, ref = [], {}
_errors.append(ValidationError(['foo'], ['foo'], 0x63, 'readonly', True, None, ()))
ref.update({'foo': [handler.messages[0x63]]})
assert handler(_errors) == ref
_errors.append(ValidationError(['bar'], ['foo'], 0x42, 'min', 1, 2, ()))
ref.update({'bar': [handler.messages[0x42].format(constraint=1)]})
assert handler(_errors) == ref
_errors.append(
ValidationError(
['zap', 'foo'], ['zap', 'schema', 'foo'], 0x24, 'type', 'string', True, ()
)
)
ref.update({'zap': [{'foo': [handler.messages[0x24].format(constraint='string')]}]})
assert handler(_errors) == ref
_errors.append(
ValidationError(
['zap', 'foo'],
['zap', 'schema', 'foo'],
0x41,
'regex',
'^p[äe]ng$',
'boom',
(),
)
)
ref['zap'][0]['foo'].append(handler.messages[0x41].format(constraint='^p[äe]ng$'))
assert handler(_errors) == ref
def test_basic_error_of_errors(validator):
schema = {'foo': {'oneof': [{'type': 'integer'}, {'type': 'string'}]}}
document = {'foo': 23.42}
error = ('foo', ('foo', 'oneof'), errors.ONEOF, schema['foo']['oneof'], ())
child_errors = [
(error[0], error[1] + (0, 'type'), errors.BAD_TYPE, 'integer'),
(error[0], error[1] + (1, 'type'), errors.BAD_TYPE, 'string'),
]
assert_fail(
document, schema, validator=validator, error=error, child_errors=child_errors
)
assert validator.errors == {
'foo': [
errors.BasicErrorHandler.messages[0x92],
{
'oneof definition 0': ['must be of integer type'],
'oneof definition 1': ['must be of string type'],
},
]
}
def test_wrong_amount_of_items(validator):
# https://github.com/pyeve/cerberus/issues/505
validator.schema = {
'test_list': {
'type': 'list',
'required': True,
'items': [{'type': 'string'}, {'type': 'string'}],
}
}
validator({'test_list': ['test']})
assert validator.errors == {'test_list': ["length of list should be 2, it is 1"]}
-3
View File
@@ -1,3 +0,0 @@
# -*- coding: utf-8 -*-
pass
-543
View File
@@ -1,543 +0,0 @@
# -*- coding: utf-8 -*-
from copy import deepcopy
from tempfile import NamedTemporaryFile
from pytest import mark
from pipenv.vendor.cerberus import Validator, errors
from pipenv.vendor.cerberus.tests import (
assert_fail,
assert_has_error,
assert_normalized,
assert_success,
)
def must_not_be_called(*args, **kwargs):
raise RuntimeError('This shall not be called.')
def test_coerce():
schema = {'amount': {'coerce': int}}
document = {'amount': '1'}
expected = {'amount': 1}
assert_normalized(document, expected, schema)
def test_coerce_in_dictschema():
schema = {'thing': {'type': 'dict', 'schema': {'amount': {'coerce': int}}}}
document = {'thing': {'amount': '2'}}
expected = {'thing': {'amount': 2}}
assert_normalized(document, expected, schema)
def test_coerce_in_listschema():
schema = {'things': {'type': 'list', 'schema': {'coerce': int}}}
document = {'things': ['1', '2', '3']}
expected = {'things': [1, 2, 3]}
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)
validator = Validator(schema)
document['things'].append(3)
assert not validator(document)
assert validator.document['things'] == document['things']
def test_coerce_in_dictschema_in_listschema():
item_schema = {'type': 'dict', 'schema': {'amount': {'coerce': int}}}
schema = {'things': {'type': 'list', 'schema': item_schema}}
document = {'things': [{'amount': '2'}]}
expected = {'things': [{'amount': 2}]}
assert_normalized(document, expected, schema)
def test_coerce_not_destructive():
schema = {'amount': {'coerce': int}}
v = Validator(schema)
doc = {'amount': '1'}
v.validate(doc)
assert v.document is not doc
def test_coerce_catches_ValueError():
schema = {'amount': {'coerce': int}}
_errors = assert_fail({'amount': 'not_a_number'}, schema)
_errors[0].info = () # ignore exception message here
assert_has_error(
_errors, 'amount', ('amount', 'coerce'), 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)
_errors[0].info = () # ignore exception message here
assert_has_error(
_errors, 'name', ('name', 'coerce'), 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'}}
expected = {'foo': {'bar': 0}}
assert_normalized(document, expected, schema)
def test_custom_coerce_and_rename():
class MyNormalizer(Validator):
def __init__(self, multiplier, *args, **kwargs):
super(MyNormalizer, self).__init__(*args, **kwargs)
self.multiplier = multiplier
def _normalize_coerce_multiply(self, value):
return value * self.multiplier
v = MyNormalizer(2, {'foo': {'coerce': 'multiply'}})
assert v.normalized({'foo': 2})['foo'] == 4
v = MyNormalizer(3, allow_unknown={'rename_handler': 'multiply'})
assert v.normalized({3: None}) == {9: None}
def test_coerce_chain():
drop_prefix = lambda x: x[2:] # noqa: E731
upper = lambda x: x.upper() # noqa: E731
schema = {'foo': {'coerce': [hex, drop_prefix, upper]}}
assert_normalized({'foo': 15}, {'foo': 'F'}, schema)
def test_coerce_chain_aborts(validator):
def dont_do_me(value):
raise AssertionError('The coercion chain did not abort after an ' 'error.')
schema = {'foo': {'coerce': [hex, dont_do_me]}}
validator({'foo': '0'}, schema)
assert errors.COERCION_FAILED in validator._errors
def test_coerce_non_digit_in_sequence(validator):
# https://github.com/pyeve/cerberus/issues/211
schema = {'data': {'type': 'list', 'schema': {'type': 'integer', 'coerce': int}}}
document = {'data': ['q']}
assert validator.validated(document, schema) is None
assert (
validator.validated(document, schema, always_return_document=True) == document
) # noqa: W503
def test_nullables_dont_fail_coerce():
schema = {'foo': {'coerce': int, 'nullable': True, 'type': 'integer'}}
document = {'foo': None}
assert_normalized(document, document, schema)
def test_nullables_fail_coerce_on_non_null_values(validator):
def failing_coercion(value):
raise Exception("expected to fail")
schema = {'foo': {'coerce': failing_coercion, 'nullable': True, 'type': 'integer'}}
document = {'foo': None}
assert_normalized(document, document, schema)
validator({'foo': 2}, schema)
assert errors.COERCION_FAILED in validator._errors
def test_normalized():
schema = {'amount': {'coerce': int}}
document = {'amount': '2'}
expected = {'amount': 2}
assert_normalized(document, expected, schema)
def test_rename(validator):
schema = {'foo': {'rename': 'bar'}}
document = {'foo': 0}
expected = {'bar': 0}
# We cannot use assertNormalized here since there is bug where
# Cerberus says that the renamed field is an unknown field:
# {'bar': 'unknown field'}
validator(document, schema, False)
assert validator.document == expected
def test_rename_handler():
validator = Validator(allow_unknown={'rename_handler': int})
schema = {}
document = {'0': 'foo'}
expected = {0: 'foo'}
assert_normalized(document, expected, schema, validator)
def test_purge_unknown():
validator = Validator(purge_unknown=True)
schema = {'foo': {'type': 'string'}}
document = {'bar': 'foo'}
expected = {}
assert_normalized(document, expected, schema, validator)
def test_purge_unknown_in_subschema():
schema = {
'foo': {
'type': 'dict',
'schema': {'foo': {'type': 'string'}},
'purge_unknown': True,
}
}
document = {'foo': {'bar': ''}}
expected = {'foo': {}}
assert_normalized(document, expected, schema)
def test_issue_147_complex():
schema = {'revision': {'coerce': int}}
document = {'revision': '5', 'file': NamedTemporaryFile(mode='w+')}
document['file'].write(r'foobar')
document['file'].seek(0)
normalized = Validator(schema, allow_unknown=True).normalized(document)
assert normalized['revision'] == 5
assert normalized['file'].read() == 'foobar'
document['file'].close()
normalized['file'].close()
def test_issue_147_nested_dict():
schema = {'thing': {'type': 'dict', 'schema': {'amount': {'coerce': int}}}}
ref_obj = '2'
document = {'thing': {'amount': ref_obj}}
normalized = Validator(schema).normalized(document)
assert document is not normalized
assert normalized['thing']['amount'] == 2
assert ref_obj == '2'
assert document['thing']['amount'] is ref_obj
def test_coerce_in_valuesrules():
# https://github.com/pyeve/cerberus/issues/155
schema = {
'thing': {'type': 'dict', 'valuesrules': {'coerce': int, 'type': 'integer'}}
}
document = {'thing': {'amount': '2'}}
expected = {'thing': {'amount': 2}}
assert_normalized(document, expected, schema)
def test_coerce_in_keysrules():
# https://github.com/pyeve/cerberus/issues/155
schema = {
'thing': {'type': 'dict', 'keysrules': {'coerce': int, 'type': 'integer'}}
}
document = {'thing': {'5': 'foo'}}
expected = {'thing': {5: 'foo'}}
assert_normalized(document, expected, schema)
def test_coercion_of_sequence_items(validator):
# https://github.com/pyeve/cerberus/issues/161
schema = {'a_list': {'type': 'list', 'schema': {'type': 'float', 'coerce': float}}}
document = {'a_list': [3, 4, 5]}
expected = {'a_list': [3.0, 4.0, 5.0]}
assert_normalized(document, expected, schema, validator)
for x in validator.document['a_list']:
assert isinstance(x, float)
@mark.parametrize(
'default', ({'default': 'bar_value'}, {'default_setter': lambda doc: 'bar_value'})
)
def test_default_missing(default):
bar_schema = {'type': 'string'}
bar_schema.update(default)
schema = {'foo': {'type': 'string'}, 'bar': bar_schema}
document = {'foo': 'foo_value'}
expected = {'foo': 'foo_value', 'bar': 'bar_value'}
assert_normalized(document, expected, schema)
@mark.parametrize(
'default', ({'default': 'bar_value'}, {'default_setter': must_not_be_called})
)
def test_default_existent(default):
bar_schema = {'type': 'string'}
bar_schema.update(default)
schema = {'foo': {'type': 'string'}, 'bar': bar_schema}
document = {'foo': 'foo_value', 'bar': 'non_default'}
assert_normalized(document, document.copy(), schema)
@mark.parametrize(
'default', ({'default': 'bar_value'}, {'default_setter': must_not_be_called})
)
def test_default_none_nullable(default):
bar_schema = {'type': 'string', 'nullable': True}
bar_schema.update(default)
schema = {'foo': {'type': 'string'}, 'bar': bar_schema}
document = {'foo': 'foo_value', 'bar': None}
assert_normalized(document, document.copy(), schema)
@mark.parametrize(
'default', ({'default': 'bar_value'}, {'default_setter': lambda doc: 'bar_value'})
)
def test_default_none_nonnullable(default):
bar_schema = {'type': 'string', 'nullable': False}
bar_schema.update(default)
schema = {'foo': {'type': 'string'}, 'bar': bar_schema}
document = {'foo': 'foo_value', 'bar': None}
expected = {'foo': 'foo_value', 'bar': 'bar_value'}
assert_normalized(document, expected, schema)
def test_default_none_default_value():
schema = {
'foo': {'type': 'string'},
'bar': {'type': 'string', 'nullable': True, 'default': None},
}
document = {'foo': 'foo_value'}
expected = {'foo': 'foo_value', 'bar': None}
assert_normalized(document, expected, schema)
@mark.parametrize(
'default', ({'default': 'bar_value'}, {'default_setter': lambda doc: 'bar_value'})
)
def test_default_missing_in_subschema(default):
bar_schema = {'type': 'string'}
bar_schema.update(default)
schema = {
'thing': {
'type': 'dict',
'schema': {'foo': {'type': 'string'}, 'bar': bar_schema},
}
}
document = {'thing': {'foo': 'foo_value'}}
expected = {'thing': {'foo': 'foo_value', 'bar': 'bar_value'}}
assert_normalized(document, expected, schema)
def test_depending_default_setters():
schema = {
'a': {'type': 'integer'},
'b': {'type': 'integer', 'default_setter': lambda d: d['a'] + 1},
'c': {'type': 'integer', 'default_setter': lambda d: d['b'] * 2},
'd': {'type': 'integer', 'default_setter': lambda d: d['b'] + d['c']},
}
document = {'a': 1}
expected = {'a': 1, 'b': 2, 'c': 4, 'd': 6}
assert_normalized(document, expected, schema)
def test_circular_depending_default_setters(validator):
schema = {
'a': {'type': 'integer', 'default_setter': lambda d: d['b'] + 1},
'b': {'type': 'integer', 'default_setter': lambda d: d['a'] + 1},
}
validator({}, schema)
assert errors.SETTING_DEFAULT_FAILED in validator._errors
def test_issue_250():
# https://github.com/pyeve/cerberus/issues/250
schema = {
'list': {
'type': 'list',
'schema': {
'type': 'dict',
'allow_unknown': True,
'schema': {'a': {'type': 'string'}},
},
}
}
document = {'list': {'is_a': 'mapping'}}
assert_fail(
document,
schema,
error=('list', ('list', 'type'), errors.BAD_TYPE, schema['list']['type']),
)
def test_issue_250_no_type_pass_on_list():
# https://github.com/pyeve/cerberus/issues/250
schema = {
'list': {
'schema': {
'allow_unknown': True,
'type': 'dict',
'schema': {'a': {'type': 'string'}},
}
}
}
document = {'list': [{'a': 'known', 'b': 'unknown'}]}
assert_normalized(document, document, schema)
def test_issue_250_no_type_fail_on_dict():
# https://github.com/pyeve/cerberus/issues/250
schema = {
'list': {'schema': {'allow_unknown': True, 'schema': {'a': {'type': 'string'}}}}
}
document = {'list': {'a': {'a': 'known'}}}
assert_fail(
document,
schema,
error=(
'list',
('list', 'schema'),
errors.BAD_TYPE_FOR_SCHEMA,
schema['list']['schema'],
),
)
def test_issue_250_no_type_fail_pass_on_other():
# https://github.com/pyeve/cerberus/issues/250
schema = {
'list': {'schema': {'allow_unknown': True, 'schema': {'a': {'type': 'string'}}}}
}
document = {'list': 1}
assert_normalized(document, document, schema)
def test_allow_unknown_with_of_rules():
# https://github.com/pyeve/cerberus/issues/251
schema = {
'test': {
'oneof': [
{
'type': 'dict',
'allow_unknown': True,
'schema': {'known': {'type': 'string'}},
},
{'type': 'dict', 'schema': {'known': {'type': 'string'}}},
]
}
}
# check regression and that allow unknown does not cause any different
# than expected behaviour for one-of.
document = {'test': {'known': 's'}}
assert_fail(
document,
schema,
error=('test', ('test', 'oneof'), errors.ONEOF, schema['test']['oneof']),
)
# check that allow_unknown is actually applied
document = {'test': {'known': 's', 'unknown': 'asd'}}
assert_success(document, schema)
def test_271_normalising_tuples():
# https://github.com/pyeve/cerberus/issues/271
schema = {
'my_field': {'type': 'list', 'schema': {'type': ('string', 'number', 'dict')}}
}
document = {'my_field': ('foo', 'bar', 42, 'albert', 'kandinsky', {'items': 23})}
assert_success(document, schema)
normalized = Validator(schema).normalized(document)
assert normalized['my_field'] == (
'foo',
'bar',
42,
'albert',
'kandinsky',
{'items': 23},
)
def test_allow_unknown_wo_schema():
# https://github.com/pyeve/cerberus/issues/302
v = Validator({'a': {'type': 'dict', 'allow_unknown': True}})
v({'a': {}})
def test_allow_unknown_with_purge_unknown():
validator = Validator(purge_unknown=True)
schema = {'foo': {'type': 'dict', 'allow_unknown': True}}
document = {'foo': {'bar': True}, 'bar': 'foo'}
expected = {'foo': {'bar': True}}
assert_normalized(document, expected, schema, validator)
def test_allow_unknown_with_purge_unknown_subdocument():
validator = Validator(purge_unknown=True)
schema = {
'foo': {
'type': 'dict',
'schema': {'bar': {'type': 'string'}},
'allow_unknown': True,
}
}
document = {'foo': {'bar': 'baz', 'corge': False}, 'thud': 'xyzzy'}
expected = {'foo': {'bar': 'baz', 'corge': False}}
assert_normalized(document, expected, schema, validator)
def test_purge_readonly():
schema = {
'description': {'type': 'string', 'maxlength': 500},
'last_updated': {'readonly': True},
}
validator = Validator(schema=schema, purge_readonly=True)
document = {'description': 'it is a thing'}
expected = deepcopy(document)
document['last_updated'] = 'future'
assert_normalized(document, expected, validator=validator)
def test_defaults_in_allow_unknown_schema():
schema = {'meta': {'type': 'dict'}, 'version': {'type': 'string'}}
allow_unknown = {
'type': 'dict',
'schema': {
'cfg_path': {'type': 'string', 'default': 'cfg.yaml'},
'package': {'type': 'string'},
},
}
validator = Validator(schema=schema, allow_unknown=allow_unknown)
document = {'version': '1.2.3', 'plugin_foo': {'package': 'foo'}}
expected = {
'version': '1.2.3',
'plugin_foo': {'package': 'foo', 'cfg_path': 'cfg.yaml'},
}
assert_normalized(document, expected, schema, validator)
-84
View File
@@ -1,84 +0,0 @@
# -*- coding: utf-8 -*-
from pipenv.vendor.cerberus import schema_registry, rules_set_registry, Validator
from pipenv.vendor.cerberus.tests import (
assert_fail,
assert_normalized,
assert_schema_error,
assert_success,
)
def test_schema_registry_simple():
schema_registry.add('foo', {'bar': {'type': 'string'}})
schema = {'a': {'schema': 'foo'}, 'b': {'schema': 'foo'}}
document = {'a': {'bar': 'a'}, 'b': {'bar': 'b'}}
assert_success(document, schema)
def test_top_level_reference():
schema_registry.add('peng', {'foo': {'type': 'integer'}})
document = {'foo': 42}
assert_success(document, 'peng')
def test_rules_set_simple():
rules_set_registry.add('foo', {'type': 'integer'})
assert_success({'bar': 1}, {'bar': 'foo'})
assert_fail({'bar': 'one'}, {'bar': 'foo'})
def test_allow_unknown_as_reference():
rules_set_registry.add('foo', {'type': 'number'})
v = Validator(allow_unknown='foo')
assert_success({0: 1}, {}, v)
assert_fail({0: 'one'}, {}, v)
def test_recursion():
rules_set_registry.add('self', {'type': 'dict', 'allow_unknown': 'self'})
v = Validator(allow_unknown='self')
assert_success({0: {1: {2: {}}}}, {}, v)
def test_references_remain_unresolved(validator):
rules_set_registry.extend(
(('boolean', {'type': 'boolean'}), ('booleans', {'valuesrules': 'boolean'}))
)
validator.schema = {'foo': 'booleans'}
assert 'booleans' == validator.schema['foo']
assert 'boolean' == rules_set_registry._storage['booleans']['valuesrules']
def test_rules_registry_with_anyof_type():
rules_set_registry.add('string_or_integer', {'anyof_type': ['string', 'integer']})
schema = {'soi': 'string_or_integer'}
assert_success({'soi': 'hello'}, schema)
def test_schema_registry_with_anyof_type():
schema_registry.add('soi_id', {'id': {'anyof_type': ['string', 'integer']}})
schema = {'soi': {'schema': 'soi_id'}}
assert_success({'soi': {'id': 'hello'}}, schema)
def test_normalization_with_rules_set():
# https://github.com/pyeve/cerberus/issues/283
rules_set_registry.add('foo', {'default': 42})
assert_normalized({}, {'bar': 42}, {'bar': 'foo'})
rules_set_registry.add('foo', {'default_setter': lambda _: 42})
assert_normalized({}, {'bar': 42}, {'bar': 'foo'})
rules_set_registry.add('foo', {'type': 'integer', 'nullable': True})
assert_success({'bar': None}, {'bar': 'foo'})
def test_rules_set_with_dict_field():
document = {'a_dict': {'foo': 1}}
schema = {'a_dict': {'type': 'dict', 'schema': {'foo': 'rule'}}}
# the schema's not yet added to the valid ones, so test the faulty first
rules_set_registry.add('rule', {'tüpe': 'integer'})
assert_schema_error(document, schema)
rules_set_registry.add('rule', {'type': 'integer'})
assert_success(document, schema)
-178
View File
@@ -1,178 +0,0 @@
# -*- coding: utf-8 -*-
import re
import pytest
from pipenv.vendor.cerberus import Validator, errors, SchemaError
from pipenv.vendor.cerberus.schema import UnvalidatedSchema
from pipenv.vendor.cerberus.tests import assert_schema_error
def test_empty_schema():
validator = Validator()
with pytest.raises(SchemaError, match=errors.SCHEMA_ERROR_MISSING):
validator({}, schema=None)
def test_bad_schema_type(validator):
schema = "this string should really be dict"
msg = errors.SCHEMA_ERROR_DEFINITION_TYPE.format(schema)
with pytest.raises(SchemaError, match=msg):
validator.schema = schema
def test_bad_schema_type_field(validator):
field = 'foo'
schema = {field: {'schema': {'bar': {'type': 'strong'}}}}
with pytest.raises(SchemaError):
validator.schema = schema
def test_unknown_rule(validator):
msg = "{'foo': [{'unknown': ['unknown rule']}]}"
with pytest.raises(SchemaError, match=re.escape(msg)):
validator.schema = {'foo': {'unknown': 'rule'}}
def test_unknown_type(validator):
msg = str({'foo': [{'type': ['Unsupported types: unknown']}]})
with pytest.raises(SchemaError, match=re.escape(msg)):
validator.schema = {'foo': {'type': 'unknown'}}
def test_bad_schema_definition(validator):
field = 'name'
msg = str({field: ['must be of dict type']})
with pytest.raises(SchemaError, match=re.escape(msg)):
validator.schema = {field: 'this should really be a dict'}
def test_bad_of_rules():
schema = {'foo': {'anyof': {'type': 'string'}}}
assert_schema_error({}, schema)
def test_normalization_rules_are_invalid_in_of_rules():
schema = {0: {'anyof': [{'coerce': lambda x: x}]}}
assert_schema_error({}, schema)
def test_anyof_allof_schema_validate():
# make sure schema with 'anyof' and 'allof' constraints are checked
# correctly
schema = {
'doc': {'type': 'dict', 'anyof': [{'schema': [{'param': {'type': 'number'}}]}]}
}
assert_schema_error({'doc': 'this is my document'}, schema)
schema = {
'doc': {'type': 'dict', 'allof': [{'schema': [{'param': {'type': 'number'}}]}]}
}
assert_schema_error({'doc': 'this is my document'}, schema)
def test_repr():
v = Validator({'foo': {'type': 'string'}})
assert repr(v.schema) == "{'foo': {'type': 'string'}}"
def test_validated_schema_cache():
v = Validator({'foozifix': {'coerce': int}})
cache_size = len(v._valid_schemas)
v = Validator({'foozifix': {'type': 'integer'}})
cache_size += 1
assert len(v._valid_schemas) == cache_size
v = Validator({'foozifix': {'coerce': int}})
assert len(v._valid_schemas) == cache_size
max_cache_size = 163
assert cache_size <= max_cache_size, (
"There's an unexpected high amount (%s) of cached valid "
"definition schemas. Unless you added further tests, "
"there are good chances that something is wrong. "
"If you added tests with new schemas, you can try to "
"adjust the variable `max_cache_size` according to "
"the added schemas." % cache_size
)
def test_expansion_in_nested_schema():
schema = {'detroit': {'schema': {'anyof_regex': ['^Aladdin', 'Sane$']}}}
v = Validator(schema)
assert v.schema['detroit']['schema'] == {
'anyof': [{'regex': '^Aladdin'}, {'regex': 'Sane$'}]
}
def test_unvalidated_schema_can_be_copied():
schema = UnvalidatedSchema()
schema_copy = schema.copy()
assert schema_copy == schema
# TODO remove with next major release
def test_deprecated_rule_names_in_valueschema():
def check_with(field, value, error):
pass
schema = {
"field_1": {
"type": "dict",
"valueschema": {
"type": "dict",
"keyschema": {"type": "string"},
"valueschema": {"type": "string"},
},
},
"field_2": {
"type": "list",
"items": [
{"keyschema": {}},
{"validator": check_with},
{"valueschema": {}},
],
},
}
validator = Validator(schema)
assert validator.schema == {
"field_1": {
"type": "dict",
"valuesrules": {
"type": "dict",
"keysrules": {"type": "string"},
"valuesrules": {"type": "string"},
},
},
"field_2": {
"type": "list",
"items": [
{"keysrules": {}},
{"check_with": check_with},
{"valuesrules": {}},
],
},
}
def test_anyof_check_with():
def foo(field, value, error):
pass
def bar(field, value, error):
pass
schema = {'field': {'anyof_check_with': [foo, bar]}}
validator = Validator(schema)
assert validator.schema == {
'field': {'anyof': [{'check_with': foo}, {'check_with': bar}]}
}
def test_rulename_space_is_normalized():
Validator(schema={"field": {"default setter": lambda x: x, "type": "string"}})
-11
View File
@@ -1,11 +0,0 @@
from pipenv.vendor.cerberus.utils import compare_paths_lt
def test_compare_paths():
lesser = ('a_dict', 'keysrules')
greater = ('a_dict', 'valuesrules')
assert compare_paths_lt(lesser, greater)
lesser += ('type',)
greater += ('regex',)
assert compare_paths_lt(lesser, greater)
File diff suppressed because it is too large Load Diff
+3
View File
@@ -315,6 +315,9 @@ def post_install_cleanup(ctx, vendor_dir):
drop_dir(vendor_dir / "bin")
drop_dir(vendor_dir / "tests")
drop_dir(vendor_dir / "shutil_backports")
drop_dir(vendor_dir / "cerberus" / "tests")
drop_dir(vendor_dir / "cerberus" / "benchmarks")
remove_all(vendor_dir.glob("toml.py"))