Skip to content

Commit

Permalink
update error messagings from json schema
Browse files Browse the repository at this point in the history
  • Loading branch information
kddejong committed Oct 28, 2024
1 parent 8164ed9 commit 6563c29
Show file tree
Hide file tree
Showing 17 changed files with 48 additions and 63 deletions.
24 changes: 16 additions & 8 deletions src/cfnlint/jsonschema/_keywords.py
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,9 @@ def maxItems(
validator: Validator, mI: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult: # pylint: disable=arguments-renamed
if validator.is_type(instance, "array") and len(instance) > mI:
yield ValidationError(f"{instance!r} is too long ({mI})")
yield ValidationError(
f"expected maximum item count: {mI}, found: {len(instance)}"
)


def maxLength(
Expand All @@ -333,7 +335,7 @@ def maxLength(
return

if len(instance) > mL:
yield ValidationError(f"{instance!r} is longer than {mL}")
yield ValidationError(f"expected maximum length: {mL}, found: {len(instance)}")


def maxProperties(
Expand All @@ -342,7 +344,9 @@ def maxProperties(
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")
yield ValidationError(
f"expected maximum property count: {mP}, found: {len(instance)}"
)


def maximum(
Expand All @@ -366,7 +370,9 @@ def minItems(
validator: Validator, mI: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if validator.is_type(instance, "array") and len(instance) < mI:
yield ValidationError(f"{instance!r} is too short ({mI})")
yield ValidationError(
f"expected minimum item count: {mI}, found: {len(instance)}"
)


def minLength(
Expand All @@ -376,14 +382,16 @@ def minLength(
return

if len(instance) < mL:
yield ValidationError(f"{instance!r} is shorter than {mL}")
yield ValidationError(f"expected minimum length: {mL}, found: {len(instance)}")


def minProperties(
validator: Validator, mP: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if validator.is_type(instance, "object") and len(instance) < mP:
yield ValidationError(f"{instance!r} does not have enough properties")
yield ValidationError(
f"expected minimum property count: {mP}, found: {len(instance)}"
)


def minimum(
Expand Down Expand Up @@ -590,14 +598,14 @@ def uniqueItems(
validator: Validator, uI: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if uI and validator.is_type(instance, "array") and not uniq(instance):
yield ValidationError(f"{instance!r} has non-unique elements")
yield ValidationError("array items are not unique")


def uniqueKeys(
validator: Validator, uKs: Any, instance: Any, schema: dict[str, Any]
) -> ValidationResult:
if uKs and validator.is_type(instance, "array") and not uniq_keys(instance, uKs):
yield ValidationError(f"{instance!r} has non-unique elements for keys {uKs!r}")
yield ValidationError(f"array items are not unique for keys {uKs!r}")


def type(
Expand Down
2 changes: 1 addition & 1 deletion src/cfnlint/rules/functions/_BaseFn.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def resolve(
all_errs = []
for value, v, resolve_err in validator.resolve_value(instance):
if resolve_err:
yield resolve_err
yield from self.fix_errors(iter([resolve_err]))
continue
errs = list(
self.fix_errors(
Expand Down
18 changes: 3 additions & 15 deletions test/integration/jsonschema/test_validator_cfn.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,7 @@ def test_unique_items(self):
schema_patches=schema_patch,
expected_errs=[
ValidationError(
message=(
"[{'Key': 'Name', 'Value': 'Value'}, "
"{'Key': 'Name', 'Value': 'Value'}] has "
"non-unique elements"
),
message=("array items are not unique"),
path=deque(["Tags"]),
validator="uniqueItems",
validator_value=True,
Expand All @@ -220,11 +216,7 @@ def test_unique_items(self):
schema_patches=schema_patch,
expected_errs=[
ValidationError(
message=(
"[{'Key': 'Name', 'Value': 'Value'}, "
"{'Key': 'Name', 'Value': 'Value'}] has "
"non-unique elements"
),
message=("array items are not unique"),
path=deque(["Tags"]),
validator="uniqueItems",
validator_value=True,
Expand Down Expand Up @@ -289,11 +281,7 @@ def test_unique_items(self):
schema_patches=schema_patch,
expected_errs=[
ValidationError(
message=(
"[{'Key': 'Name', 'Value': 'Value'}, "
"{'Key': 'Name', 'Value': 'Value'}] has "
"non-unique elements"
),
message=("array items are not unique"),
path=deque(["Tags"]),
validator="uniqueItems",
validator_value=True,
Expand Down
21 changes: 8 additions & 13 deletions test/unit/module/jsonschema/test_validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ def test_validator(name, schema, instance, expected, validator):
[],
[
ValidationError(
"[] is too short (2)",
"expected minimum item count: 2, found: 0",
)
],
),
Expand All @@ -552,11 +552,7 @@ def test_validator(name, schema, instance, expected, validator):
"maxItems",
{"maxItems": 0},
["foo"],
[
ValidationError(
"['foo'] is too long (0)",
)
],
[ValidationError("expected maximum item count: 0, found: 1")],
),
(
"valid minLength",
Expand All @@ -576,7 +572,7 @@ def test_validator(name, schema, instance, expected, validator):
"",
[
ValidationError(
"'' is shorter than 2",
"expected minimum length: 2, found: 0",
)
],
),
Expand All @@ -598,7 +594,7 @@ def test_validator(name, schema, instance, expected, validator):
"foo",
[
ValidationError(
"'foo' is longer than 0",
"expected maximum length: 0, found: 3",
)
],
),
Expand Down Expand Up @@ -768,7 +764,7 @@ def test_validator(name, schema, instance, expected, validator):
{},
[
ValidationError(
"{} does not have enough properties",
"expected minimum property count: 1, found: 0",
)
],
),
Expand All @@ -790,7 +786,7 @@ def test_validator(name, schema, instance, expected, validator):
{"foo": {}, "bar": {}},
[
ValidationError(
"{'foo': {}, 'bar': {}} has too many properties",
"expected maximum property count: 1, found: 2",
)
],
),
Expand Down Expand Up @@ -943,7 +939,7 @@ def test_validator(name, schema, instance, expected, validator):
[1, 2, "1"],
[
ValidationError(
"[1, 2, '1'] has non-unique elements",
"array items are not unique",
)
],
),
Expand Down Expand Up @@ -1035,8 +1031,7 @@ def test_validator(name, schema, instance, expected, validator):
],
[
ValidationError(
"[{'Name': 'foo'}, {'Name': 'foo'}] has non-unique "
"elements for keys ['Name']",
"array items are not unique " "for keys ['Name']",
)
],
),
Expand Down
7 changes: 2 additions & 5 deletions test/unit/rules/functions/test_dynamic_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ def context(cfn):
},
[
ValidationError(
"['resolve', 'ssm'] is too short (3)",
"expected minimum item count: 3, found: 2",
validator="minItems",
rule=DynamicReference(),
)
Expand Down Expand Up @@ -182,10 +182,7 @@ def context(cfn):
},
[
ValidationError(
"['resolve', 'secretsmanager', 'arn', 'aws', "
"'secretsmanager', 'us-east-1', '012345678901', "
"'secret', 'my-secret', 'SecretString', "
"'', '', '', ''] is too long (13)",
"expected maximum item count: 13, found: 14",
validator="maxItems",
rule=DynamicReference(),
)
Expand Down
3 changes: 2 additions & 1 deletion test/unit/rules/functions/test_find_in_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def context(cfn):
None,
[
ValidationError(
"['foo', 'bar', 'key', 'key2'] is too long (3)",
"expected maximum item count: 3, found: 4",
path=deque(["Fn::FindInMap"]),
schema_path=deque(["maxItems"]),
validator="fn_findinmap",
Expand Down Expand Up @@ -164,6 +164,7 @@ def context(cfn):
"'C' is not one of ['B'] for mapping 'A'",
path=deque(["Fn::FindInMap", 1]),
schema_path=deque([]),
validator="fn_findinmap",
),
],
),
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/functions/test_if.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def validator(cfn, context):
{"type": "string"},
[
ValidationError(
"['IsUsEast1', 'foo', 'bar', 'key'] is too long (3)",
"expected maximum item count: 3, found: 4",
path=deque(["Fn::If"]),
schema_path=deque(["maxItems"]),
validator="fn_if",
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/functions/test_sub.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ def context(cfn):
{"type": "string"},
[
ValidationError(
"['${foo}', {'foo': 'bar'}, {}] is too long (2)",
"expected maximum item count: 2, found: 3",
path=deque(["Fn::Sub"]),
schema_path=deque(["maxItems"]),
validator="fn_sub",
Expand Down
4 changes: 2 additions & 2 deletions test/unit/rules/functions/test_tojsonstring.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def context(cfn):
{"transforms": Transforms(["AWS::LanguageExtensions"])},
[
ValidationError(
"{} does not have enough properties",
"expected minimum property count: 1, found: 0",
path=deque(["Fn::ToJsonString"]),
schema_path=deque(["minProperties"]),
validator="fn_tojsonstring",
Expand All @@ -93,7 +93,7 @@ def context(cfn):
{"transforms": Transforms(["AWS::LanguageExtensions"])},
[
ValidationError(
"[] is too short (1)",
"expected minimum item count: 1, found: 0",
path=deque(["Fn::ToJsonString"]),
schema_path=deque(["minItems"]),
validator="fn_tojsonstring",
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/mappings/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def rule():
{"a" * 256: {"Key": {"Value": "Foo"}}},
[
ValidationError(
f"{'a'*256!r} is longer than 255",
"expected maximum length: 255, found: 256",
validator="maxLength",
schema_path=deque(["propertyNames", "maxLength"]),
rule=None, # empty because we didn't load child rules
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/outputs/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ def context(cfn):
},
[
ValidationError(
f"{'a'*256!r} is longer than 255",
"expected maximum length: 255, found: 256",
validator="maxLength",
schema_path=deque(["propertyNames", "maxLength"]),
rule=None, # none becuase we don't load child rule
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/parameters/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ def context(cfn):
},
[
ValidationError(
f"{'a'*256!r} is longer than 255",
"expected maximum length: 255, found: 256",
validator="maxLength",
schema_path=deque(["propertyNames", "maxLength"]),
rule=None, # none becuase we don't load child rule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def template():
{"HealthCheckGracePeriodSeconds": "Foo", "LoadBalancers": []},
[
ValidationError(
"[] is too short (1)",
"expected minimum item count: 1, found: 0",
rule=ServiceHealthCheckGracePeriodSeconds(),
path=deque(["LoadBalancers"]),
validator="minItems",
Expand Down Expand Up @@ -80,7 +80,7 @@ def template():
},
[
ValidationError(
"[] is too short (1)",
"expected minimum item count: 1, found: 0",
rule=ServiceHealthCheckGracePeriodSeconds(),
path=deque(["LoadBalancers"]),
validator="minItems",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def rule():
{"Subnets": ["SubnetA"]},
[
ValidationError(
("['SubnetA'] is too short (2)"),
"expected minimum item count: 2, found: 1",
rule=LoadBalancerApplicationSubnets(),
path=deque(["Subnets"]),
validator="minItems",
Expand All @@ -55,7 +55,7 @@ def rule():
},
[
ValidationError(
("['SubnetA'] is too short (2)"),
"expected minimum item count: 2, found: 1",
rule=LoadBalancerApplicationSubnets(),
path=deque(["Subnets"]),
validator="minItems",
Expand Down
10 changes: 3 additions & 7 deletions test/unit/rules/resources/properties/test_tagging.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,7 @@ def rule():
{"taggable": True},
[
ValidationError(
(
"[{'Key': 'Foo', 'Value': 'Bar'}, "
"{'Key': 'Foo', 'Value': 'Bar'}] "
"has non-unique elements for keys ['Key']"
),
("array items are not unique for keys ['Key']"),
path=deque(["Tags"]),
schema_path=deque(["properties", "Tags", "uniqueKeys"]),
validator="tagging",
Expand All @@ -59,7 +55,7 @@ def rule():
{"taggable": True},
[
ValidationError(
f"{'a'*257!r} is longer than 256",
"expected maximum length: 256, found: 257",
path=deque(["Tags", 0, "Value"]),
schema_path=deque(
[
Expand All @@ -83,7 +79,7 @@ def rule():
{"taggable": True},
[
ValidationError(
f"{'a'*257!r} is longer than 256",
"expected maximum length: 256, found: 257",
path=deque(["Tags", "Foo"]),
schema_path=deque(
[
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/resources/route53/test_recordsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ def rule():
),
),
ValidationError(
"['cname1.example.com', 'foo√bar'] is too long (1)",
"expected maximum item count: 1, found: 2",
rule=RecordSet(),
path=deque(["ResourceRecords"]),
validator="maxItems",
Expand Down
2 changes: 1 addition & 1 deletion test/unit/rules/templates/test_limitsize_description.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def rule():
None,
[
ValidationError(
("'FooBar' is longer than 3"),
("expected maximum length: 3, found: 6"),
)
],
),
Expand Down

0 comments on commit 6563c29

Please sign in to comment.