diff --git a/jsonschema/_keywords.py b/jsonschema/_keywords.py index f33a1aa3..69d7580b 100644 --- a/jsonschema/_keywords.py +++ b/jsonschema/_keywords.py @@ -228,12 +228,14 @@ def format(validator, format, instance, schema): def minLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) < mL: - yield ValidationError(f"{instance!r} is too short") + message = "should be non-empty" if mL == 1 else "is too short" + yield ValidationError(f"{instance!r} {message}") def maxLength(validator, mL, instance, schema): if validator.is_type(instance, "string") and len(instance) > mL: - yield ValidationError(f"{instance!r} is too long") + message = "is expected to be empty" if mL == 0 else "is too long" + yield ValidationError(f"{instance!r} {message}") def dependentRequired(validator, dependentRequired, instance, schema): @@ -307,14 +309,22 @@ def required(validator, required, instance, schema): def minProperties(validator, mP, instance, schema): if validator.is_type(instance, "object") and len(instance) < mP: - yield ValidationError(f"{instance!r} does not have enough properties") + message = ( + "should be non-empty" if mP == 1 + else "does not have enough properties" + ) + yield ValidationError(f"{instance!r} {message}") def maxProperties(validator, mP, instance, schema): if not validator.is_type(instance, "object"): return if validator.is_type(instance, "object") and len(instance) > mP: - yield ValidationError(f"{instance!r} has too many properties") + message = ( + "is expected to be empty" if mP == 0 + else "has too many properties" + ) + yield ValidationError(f"{instance!r} {message}") def allOf(validator, allOf, instance, schema): diff --git a/jsonschema/tests/test_validators.py b/jsonschema/tests/test_validators.py index 52778bdf..28cc4027 100644 --- a/jsonschema/tests/test_validators.py +++ b/jsonschema/tests/test_validators.py @@ -517,6 +517,53 @@ def test_maxItems_0(self): message = self.message_for(instance=[1, 2, 3], schema={"maxItems": 0}) self.assertEqual(message, "[1, 2, 3] is expected to be empty") + def test_minLength(self): + message = self.message_for( + instance="", + schema={"minLength": 2}, + ) + self.assertEqual(message, "'' is too short") + + def test_maxLength(self): + message = self.message_for( + instance="abc", + schema={"maxLength": 2}, + ) + self.assertEqual(message, "'abc' is too long") + + def test_minLength_1(self): + message = self.message_for(instance="", schema={"minLength": 1}) + self.assertEqual(message, "'' should be non-empty") + + def test_maxLength_0(self): + message = self.message_for(instance="abc", schema={"maxLength": 0}) + self.assertEqual(message, "'abc' is expected to be empty") + + def test_minProperties(self): + message = self.message_for(instance={}, schema={"minProperties": 2}) + self.assertEqual(message, "{} does not have enough properties") + + def test_maxProperties(self): + message = self.message_for( + instance={"a": {}, "b": {}, "c": {}}, + schema={"maxProperties": 2}, + ) + self.assertEqual( + message, + "{'a': {}, 'b': {}, 'c': {}} has too many properties", + ) + + def test_minProperties_1(self): + message = self.message_for(instance={}, schema={"minProperties": 1}) + self.assertEqual(message, "{} should be non-empty") + + def test_maxProperties_0(self): + message = self.message_for( + instance={1: 2}, + schema={"maxProperties": 0}, + ) + self.assertEqual(message, "{1: 2} is expected to be empty") + def test_prefixItems_with_items(self): message = self.message_for( instance=[1, 2, "foo"], @@ -537,20 +584,6 @@ def test_prefixItems_with_multiple_extra_items(self): "Expected at most 2 items but found 2 extra: ['foo', 5]", ) - def test_minLength(self): - message = self.message_for( - instance="", - schema={"minLength": 2}, - ) - self.assertEqual(message, "'' is too short") - - def test_maxLength(self): - message = self.message_for( - instance="abc", - schema={"maxLength": 2}, - ) - self.assertEqual(message, "'abc' is too long") - def test_pattern(self): message = self.message_for( instance="bbb", @@ -646,20 +679,6 @@ def test_dependentRequired(self): ) self.assertEqual(message, "'bar' is a dependency of 'foo'") - def test_minProperties(self): - message = self.message_for(instance={}, schema={"minProperties": 2}) - self.assertEqual(message, "{} does not have enough properties") - - def test_maxProperties(self): - message = self.message_for( - instance={"a": {}, "b": {}, "c": {}}, - schema={"maxProperties": 2}, - ) - self.assertEqual( - message, - "{'a': {}, 'b': {}, 'c': {}} has too many properties", - ) - def test_oneOf_matches_none(self): message = self.message_for(instance={}, schema={"oneOf": [False]}) self.assertEqual(