diff options
author | Julian Berman <Julian@GrayVines.com> | 2021-08-25 10:33:10 +0100 |
---|---|---|
committer | Julian Berman <Julian@GrayVines.com> | 2021-08-25 10:33:10 +0100 |
commit | ebebf529e984599b411d3632385f72ec4197502a (patch) | |
tree | 5ff39fe4f3806236ecc5e71ef5406da759d3ec77 | |
parent | 3992d99a74099c99cc02338ecffa5647d0a2bdc4 (diff) | |
download | jsonschema-ebebf529e984599b411d3632385f72ec4197502a.tar.gz |
Properly set the failing validator for min/maxContains.
Also check that only one error is raised for maxContains,
which is the case right now due to short circuiting as
soon as we see too many matches.
-rw-r--r-- | jsonschema/_validators.py | 4 | ||||
-rw-r--r-- | jsonschema/tests/test_validators.py | 88 |
2 files changed, 92 insertions, 0 deletions
diff --git a/jsonschema/_validators.py b/jsonschema/_validators.py index 0cfc8c0..c6d0e9a 100644 --- a/jsonschema/_validators.py +++ b/jsonschema/_validators.py @@ -118,6 +118,8 @@ def contains(validator, contains, instance, schema): yield ValidationError( "Too many items match the given schema " f"(expected at most {max_contains})", + validator="maxContains", + validator_value=max_contains, ) return @@ -131,6 +133,8 @@ def contains(validator, contains, instance, schema): yield ValidationError( "Too few items match the given schema (expected at least " f"{min_contains} but only {matches} matched)", + validator="minContains", + validator_value=min_contains, ) diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 91d3819..12276e6 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -1221,6 +1221,94 @@ class TestValidationErrorDetails(TestCase): ), ) + def test_contains_too_many(self): + """ + `contains` + `maxContains` produces only one error, even if there are + many more incorrectly matching elements. + """ + schema = {"contains": {"type": "string"}, "maxContains": 2} + validator = validators.Draft202012Validator(schema) + error, = validator.iter_errors(["foo", 2, "bar", 4, "baz", "quux"]) + self.assertEqual( + ( + error.message, + error.validator, + error.validator_value, + error.instance, + error.absolute_path, + error.schema, + error.schema_path, + error.json_path, + ), + ( + "Too many items match the given schema (expected at most 2)", + "maxContains", + 2, + ["foo", 2, "bar", 4, "baz", "quux"], + deque([]), + {"contains": {"type": "string"}, "maxContains": 2}, + deque(["contains"]), + "$", + ), + ) + + def test_contains_too_few(self): + schema = {"contains": {"type": "string"}, "minContains": 2} + validator = validators.Draft202012Validator(schema) + error, = validator.iter_errors(["foo", 2, 4]) + self.assertEqual( + ( + error.message, + error.validator, + error.validator_value, + error.instance, + error.absolute_path, + error.schema, + error.schema_path, + error.json_path, + ), + ( + ( + "Too few items match the given schema " + "(expected at least 2 but only 1 matched)" + ), + "minContains", + 2, + ["foo", 2, 4], + deque([]), + {"contains": {"type": "string"}, "minContains": 2}, + deque(["contains"]), + "$", + ), + ) + + def test_contains_none(self): + schema = {"contains": {"type": "string"}, "minContains": 2} + validator = validators.Draft202012Validator(schema) + error, = validator.iter_errors([2, 4]) + self.assertEqual( + ( + error.message, + error.validator, + error.validator_value, + error.instance, + error.absolute_path, + error.schema, + error.schema_path, + error.json_path, + ), + ( + "[2, 4] does not contain items matching the given schema", + "contains", + {"type": "string"}, + [2, 4], + deque([]), + {"contains": {"type": "string"}, "minContains": 2}, + deque(["contains"]), + "$", + ), + ) + class MetaSchemaTestsMixin(object): # TODO: These all belong upstream |