Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fail-fast: false
matrix:
python_version:
- "3.11"
- "3.13"
steps:
- name: Checkout
uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
2 changes: 1 addition & 1 deletion airspeed/operators.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@


# This can be used by a function to bypass the silent behavior of a FormalReference.
# If a function returns this value instead of None, the origial text of the reference will be returned instead.
# If a function returns this value instead of None, the original text of the reference will be returned instead.
REPLACE_FORMAL_TEXT = "__FORMAL_REFERENCE__REPLACE_TEXT__"

# A dict that maps classes to dicts of additional methods.
Expand Down
70 changes: 22 additions & 48 deletions tests/test_templating.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,10 @@ def _run_test(template, context=None, snapshot_key=None, ignore_whitespaces=Fals

# construct response template with VTL template and input variables
variable_defs = " ".join(f"#set(${var} = $bodyJSON.{var})" for var in context)
response_template = textwrap.dedent(
"""
response_template = textwrap.dedent("""
#set($body = $context.requestOverride.path.body)
#set($bodyJSON = $util.parseJson($body)) %s
%s"""
).lstrip("\n")
%s""").lstrip("\n")
response_template = response_template % (variable_defs, template)

# create API Gateway API, method, integration response
Expand All @@ -76,14 +74,12 @@ def _run_test(template, context=None, snapshot_key=None, ignore_whitespaces=Fals
httpMethod="POST",
integrationHttpMethod="POST",
type="MOCK",
requestTemplates={
"application/json": """
requestTemplates={"application/json": """
#set($context.requestOverride.path.body = $input.body)
{
"statusCode": 200,
}
"""
},
"""},
)
aws_client.apigateway.put_integration_response(
restApiId=api_id,
Expand Down Expand Up @@ -427,8 +423,7 @@ def test_curly_end(self, test_render):

@pytest.mark.xfail(reason="Discrepancy with AWS - invalid escaping of \\$email")
def test_velocity_style_escaping(self, test_render): # example from Velocity docs
template = textwrap.dedent(
r"""
template = textwrap.dedent(r"""
#set( $email = "foo" )
$email
\$email
Expand All @@ -438,8 +433,7 @@ def test_velocity_style_escaping(self, test_render): # example from Velocity do
\#end
\# end
\#set( $email = "foo" )
"""
)
""")
test_render(template)

# def test_velocity_style_escaping_when_var_unset(self, test_render): # example from Velocity docs
Expand Down Expand Up @@ -569,20 +563,17 @@ def test_define_with_local_namespace(self, test_render):
)

def test_use_defined_func_multiple_times(self, test_render):
template = textwrap.dedent(
"""
template = textwrap.dedent("""
#define( $myfunc )$ctx#end
#set( $ctx = 'foo' )
$myfunc
#set( $ctx = 'bar' )
$myfunc
"""
)
""")
test_render(template)

def test_use_defined_func_create_json_loop(self, test_render):
template = textwrap.dedent(
"""
template = textwrap.dedent("""
#define( $loop ) {
#foreach($e in $map.keySet())
#set( $k = $e )
Expand All @@ -595,8 +586,7 @@ def test_use_defined_func_create_json_loop(self, test_render):
$loop
#set( $map = {'foo':'bar'} )
$loop
"""
)
""")
test_render(
template,
{"map": {"test": 123, "test2": "abc"}},
Expand Down Expand Up @@ -706,12 +696,10 @@ def test_parse_empty_dictionary(self, test_render):
test_render("#set($a = {})$a")

def test_if_whitespace_and_newlines_ignored(self, test_render):
template = textwrap.dedent(
"""
template = textwrap.dedent("""
#if(true)
hello##
#end"""
)
#end""")
test_render(template)

def test_expressions_with_numbers_with_fractions(self, test_render):
Expand Down Expand Up @@ -1234,10 +1222,8 @@ class Thing:
def func(self, arg):
return "y"

template = airspeed.Template(
"""$x.func("multi
line")"""
)
template = airspeed.Template("""$x.func("multi
line")""")
assert template.merge({"x": Thing()}) == "y"

def test_provides_helpful_error_location(self, test_render):
Expand Down Expand Up @@ -1266,15 +1252,11 @@ def test_template_cannot_modify_its_args(self, test_render):
assert ns["foo"] == 2

def test_doesnt_blow_stack(self, test_render):
template = airspeed.Template(
textwrap.dedent(
"""
template = airspeed.Template(textwrap.dedent("""
#foreach($i in [1..$end])
$assembly##
#end
"""
)
)
"""))
ns = {"end": 400}
template.merge(ns)

Expand All @@ -1284,17 +1266,13 @@ def test_formal_reference_test_bypass(self, test_render_locally):
)
assert test_render == "$bypass"

test_render_map = test_render_locally(
textwrap.dedent(
f"""
test_render_map = test_render_locally(textwrap.dedent(f"""
#set( $map = {{}})
#set($ignore = $map.put('bypass', "{airspeed.operators.REPLACE_FORMAL_TEXT}"))
#set($ignore = $map.put('no-bypass', "value"))
$map.bypass
$map.no-bypass
"""
)
)
"""))

assert test_render_map == "\n$map.bypass\nvalue\n"

Expand Down Expand Up @@ -1361,13 +1339,11 @@ def test_macros_expanded_in_double_quoted_strings(self, test_render_locally):
)

def test_macro_whitespace_and_newlines_ignored(self, test_render_locally):
template = textwrap.dedent(
"""
template = textwrap.dedent("""
#macro ( blah )
hello##
#end
#blah()"""
)
#blah()""")
test_render_locally(template)

def test_recursive_macro(self, test_render_locally):
Expand All @@ -1382,14 +1358,12 @@ def test_local_namespace_methods_are_not_available_in_context(

def test_evaluate_directive(self, test_render_locally):
# "#evaluate" not supported in AWS either, just like "#macro"
template = textwrap.dedent(
"""
template = textwrap.dedent("""
#set($source1 = "abc")
#set($select = "1")
#set($dynamicsource = "$source$select")
## $dynamicsource is now the string '$source1'
#evaluate($dynamicsource)"""
)
#evaluate($dynamicsource)""")
test_render_locally(template)

def test_return_macro(self, test_render_locally):
Expand Down