Skip to content

Commit

Permalink
Allow Fn::Length in Fn::Select (#3633)
Browse files Browse the repository at this point in the history
  • Loading branch information
kddejong authored Aug 28, 2024
1 parent 754f132 commit 1a1447b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
7 changes: 6 additions & 1 deletion src/cfnlint/rules/functions/Select.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def __init__(self) -> None:
self.fn_select = self.validate

def schema(self, validator: Validator, instance: Any) -> dict[str, Any]:
return {
schema = {
"type": "array",
"maxItems": 2,
"minItems": 2,
Expand Down Expand Up @@ -63,3 +63,8 @@ def schema(self, validator: Validator, instance: Any) -> dict[str, Any]:
},
],
}

if validator.context.transforms.has_language_extensions_transform():
schema["fn_items"][0]["functions"].append("Fn::Length") # type: ignore

return schema
6 changes: 3 additions & 3 deletions test/unit/rules/functions/test_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,12 @@ def template():
],
),
(
"Invalid Fn::Select using an invalid function for index",
{"Fn::Select": [{"Fn::GetAtt": "MyResource"}, ["bar"]]},
"Invalid Fn::Length using an invalid function for index",
{"Fn::Select": [{"Fn::Length": [1, 2]}, ["bar"]]},
{"type": "string"},
[
ValidationError(
"{'Fn::GetAtt': 'MyResource'} is not of type 'integer'",
"{'Fn::Length': [1, 2]} is not of type 'integer'",
path=deque(["Fn::Select", 0]),
schema_path=deque(["fn_items", "type"]),
validator="fn_select",
Expand Down
53 changes: 53 additions & 0 deletions test/unit/rules/functions/test_select_language_extension.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
"""
Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
SPDX-License-Identifier: MIT-0
"""

from collections import deque

import pytest

from cfnlint.jsonschema import ValidationError
from cfnlint.rules.functions.Select import Select
from cfnlint.rules.functions.SelectResolved import SelectResolved


@pytest.fixture(scope="module")
def rule():
rule = Select()
rule.child_rules["W1035"] = SelectResolved()
yield rule


@pytest.fixture
def template():
return {"Transform": "AWS::LanguageExtensions"}


@pytest.mark.parametrize(
"name,instance,schema,expected",
[
(
"Invalid Fn::Select using an invalid function for index",
{"Fn::Select": [{"Fn::GetAtt": "MyResource"}, ["bar"]]},
{"type": "string"},
[
ValidationError(
"{'Fn::GetAtt': 'MyResource'} is not of type 'integer'",
path=deque(["Fn::Select", 0]),
schema_path=deque(["fn_items", "type"]),
validator="fn_select",
),
],
),
(
"Valid Fn::Length with language extension",
{"Fn::Select": [{"Fn::Length": [1, 2]}, ["A", "B", "C"]]},
{"type": "string"},
[],
),
],
)
def test_validate(name, instance, schema, expected, rule, validator):
errs = list(rule.fn_select(validator, schema, instance, {}))
assert errs == expected, f"Test {name!r} got {errs!r}"

0 comments on commit 1a1447b

Please sign in to comment.