mirror of
https://github.com/kennethreitz/pipenv.git
synced 2026-06-05 14:50:16 +00:00
vendor: drop unused cerberus code
We don't need to ship tests and benchmarks to our users.
This commit is contained in:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -1,3 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
pass
|
||||
-543
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
-1975
File diff suppressed because it is too large
Load Diff
@@ -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"))
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user