{#- Python assertion template
Context variables:
- assertion_type: assertion type ("equals", "contains", etc.)
- field_access: Python expression for the field
- field_access_arg: `field_access` with one redundant enclosing `(...)` pair dropped, for use
in call-argument position (hasattr's/len's/_alef_e2e_text's sole argument). Optional --
falls back to `field_access` when the caller doesn't set it.
- field_is_optional: bool
- expected_val: Python-formatted value string (or empty string)
- has_expected_val: bool
- op: "is" or "==" for equality
- is_string_val: bool
- values_list: array of Python-formatted strings
- n: number (as u64) or 0
- cmp_expr: comparison expression for enum/array
- cmp_expr_any: comparison for any containment
- call_expr: method call expression
- check: method_result check type
- check_val: check value (or empty)
- has_check_val: bool
- check_n: number for check (or 0)
- is_boolean_val: bool
- bool_is_true: bool
- bool_val_str: "True" or "False"
#}
{% if assertion_type == "equals" %}
{% if is_string_val %}
{% if is_enum %}
assert _alef_e2e_text({{ field_access_arg | default(field_access) }}).lower() {{ op }} {{ expected_val }}.lower()
{% else %}
assert {{ field_access }} {{ op }} {{ expected_val }}
{% endif %}
{% else %}
assert {{ field_access }} {{ op }} {{ expected_val }}
{% endif %}
{% elif assertion_type == "contains" %}
{% if field_is_optional %}
assert {{ field_access }} is not None
{% endif %}
assert {{ cmp_expr }}
{% elif assertion_type == "contains_all" %}
{% for val in values_list %}
{% if field_is_optional %}
assert {{ field_access }} is not None
{% endif %}
assert {{ val }}
{% endfor %}
{% elif assertion_type == "not_contains" %}
{% if field_is_optional %}
assert {{ field_access }} is None or {{ negated_cmp_expr }}
{% else %}
assert {{ negated_cmp_expr }}
{% endif %}
{% elif assertion_type == "not_empty" %}
{# Bare truthiness would reject a legitimate 0/0.0/False. Only sized values carry an emptiness notion; #}
{# everything else just has to be present. `field_access_arg` is `field_access` with any redundant #}
{# enclosing parens dropped -- safe only in call-argument position (hasattr's/len's sole argument), #}
{# NOT before `is not None`, where the parens are load-bearing. Falls back to `field_access` when the #}
{# caller didn't precompute it, so a direct-template caller that only sets `field_access` still works. #}
assert {{ field_access }} is not None and (not hasattr({{ field_access_arg | default(field_access) }}, "__len__") or len({{ field_access_arg | default(field_access) }}) > 0)
{% elif assertion_type == "is_empty" %}
assert not {{ field_access }}
{% elif assertion_type == "contains_any" %}
{% if field_is_optional %}
assert {{ field_access }} is not None
{% endif %}
assert {{ cmp_expr_any }}
{% elif assertion_type == "greater_than" %}
assert {{ field_access }} > {{ expected_val }}
{% elif assertion_type == "less_than" %}
assert {{ field_access }} < {{ expected_val }}
{% elif assertion_type == "greater_than_or_equal" or assertion_type == "min" %}
assert {{ field_access }} >= {{ expected_val }}
{% elif assertion_type == "less_than_or_equal" or assertion_type == "max" %}
assert {{ field_access }} <= {{ expected_val }}
{% elif assertion_type == "starts_with" %}
assert {{ field_access }}.startswith({{ expected_val }})
{% elif assertion_type == "ends_with" %}
assert {{ field_access }}.endswith({{ expected_val }})
{% elif assertion_type == "min_length" %}
assert len({{ field_access_arg | default(field_access) }}) >= {{ n }}
{% elif assertion_type == "max_length" %}
assert len({{ field_access_arg | default(field_access) }}) <= {{ n }}
{% elif assertion_type == "count_min" %}
assert len({{ field_access_arg | default(field_access) }}) >= {{ n }}
{% elif assertion_type == "count_equals" %}
assert len({{ field_access_arg | default(field_access) }}) == {{ n }}
{% elif assertion_type == "is_true" %}
{% if field_is_optional %}
{# `is_true` on an Optional field means "present" -- `is True` fails for any non-bool #}
{# value (a struct, a string, a list), which is the wrong check for `Option<T>` where T #}
{# is not bool. `is not None` is the interpretation that holds for any T. #}
assert {{ field_access }} is not None
{% else %}
assert {{ field_access }} is True
{% endif %}
{% elif assertion_type == "is_false" %}
{% if field_is_optional %}
assert {{ field_access }} is None
{% else %}
assert not {{ field_access }}
{% endif %}
{% elif assertion_type == "method_result" %}
{% if check == "equals" %}
{% if is_boolean_val %}
assert {{ call_expr }} is {{ bool_val_str }}
{% else %}
assert {{ call_expr }} == {{ check_val }}
{% endif %}
{% elif check == "is_true" %}
assert {{ call_expr }}
{% elif check == "is_false" %}
assert not {{ call_expr }}
{% elif check == "greater_than_or_equal" %}
assert {{ call_expr }} >= {{ check_n }}
{% elif check == "count_min" %}
assert len({{ call_expr }}) >= {{ check_n }}
{% elif check == "contains" %}
assert {{ check_val }} in {{ call_expr }}
{% elif check == "is_error" %}
with pytest.raises(Exception): # noqa: B017
{{ call_expr }}
{% endif %}
{% elif assertion_type == "matches_regex" %}
assert re.search({{ expected_val }}, {{ field_access }}) is not None
{% endif %}