Warn if template functions fail and no default is specified (#56453)
Co-authored-by: Martin Hjelmare <marhje52@gmail.com> Co-authored-by: Paulus Schoutsen <balloob@gmail.com>
This commit is contained in:
parent
ae00c221e0
commit
ef13e473cf
2 changed files with 280 additions and 64 deletions
|
@ -38,6 +38,12 @@ def _set_up_units(hass):
|
|||
)
|
||||
|
||||
|
||||
def render(hass, template_str, variables=None):
|
||||
"""Create render info from template."""
|
||||
tmp = template.Template(template_str, hass)
|
||||
return tmp.async_render(variables)
|
||||
|
||||
|
||||
def render_to_info(hass, template_str, variables=None):
|
||||
"""Create render info from template."""
|
||||
tmp = template.Template(template_str, hass)
|
||||
|
@ -196,8 +202,8 @@ def test_iterating_domain_states(hass):
|
|||
)
|
||||
|
||||
|
||||
def test_float(hass):
|
||||
"""Test float."""
|
||||
def test_float_function(hass):
|
||||
"""Test float function."""
|
||||
hass.states.async_set("sensor.temperature", "12")
|
||||
|
||||
assert (
|
||||
|
@ -219,6 +225,20 @@ def test_float(hass):
|
|||
== "forgiving"
|
||||
)
|
||||
|
||||
assert render(hass, "{{ float('bad', 1) }}") == 1
|
||||
assert render(hass, "{{ float('bad', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_float_filter(hass):
|
||||
"""Test float filter."""
|
||||
hass.states.async_set("sensor.temperature", "12")
|
||||
|
||||
assert render(hass, "{{ states.sensor.temperature.state | float }}") == 12.0
|
||||
assert render(hass, "{{ states.sensor.temperature.state | float > 11 }}") is True
|
||||
assert render(hass, "{{ 'bad' | float }}") == 0
|
||||
assert render(hass, "{{ 'bad' | float(1) }}") == 1
|
||||
assert render(hass, "{{ 'bad' | float(default=1) }}") == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"value, expected",
|
||||
|
@ -295,8 +315,8 @@ def test_rounding_value(hass):
|
|||
)
|
||||
|
||||
|
||||
def test_rounding_value_get_original_value_on_error(hass):
|
||||
"""Test rounding value get original value on error."""
|
||||
def test_rounding_value_on_error(hass):
|
||||
"""Test rounding value handling of error."""
|
||||
assert template.Template("{{ None | round }}", hass).async_render() is None
|
||||
|
||||
assert (
|
||||
|
@ -304,6 +324,9 @@ def test_rounding_value_get_original_value_on_error(hass):
|
|||
== "no_number"
|
||||
)
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | round(default=1) }}") == 1
|
||||
|
||||
|
||||
def test_multiply(hass):
|
||||
"""Test multiply."""
|
||||
|
@ -317,6 +340,10 @@ def test_multiply(hass):
|
|||
== out
|
||||
)
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | multiply(10, 1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | multiply(10, default=1) }}") == 1
|
||||
|
||||
|
||||
def test_logarithm(hass):
|
||||
"""Test logarithm."""
|
||||
|
@ -343,6 +370,12 @@ def test_logarithm(hass):
|
|||
== expected
|
||||
)
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | log(10, 1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | log(10, default=1) }}") == 1
|
||||
assert render(hass, "{{ log('no_number', 10, 1) }}") == 1
|
||||
assert render(hass, "{{ log('no_number', 10, default=1) }}") == 1
|
||||
|
||||
|
||||
def test_sine(hass):
|
||||
"""Test sine."""
|
||||
|
@ -360,6 +393,13 @@ def test_sine(hass):
|
|||
template.Template("{{ %s | sin | round(3) }}" % value, hass).async_render()
|
||||
== expected
|
||||
)
|
||||
assert render(hass, f"{{{{ sin({value}) | round(3) }}}}") == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | sin(1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | sin(default=1) }}") == 1
|
||||
assert render(hass, "{{ sin('no_number', 1) }}") == 1
|
||||
assert render(hass, "{{ sin('no_number', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_cos(hass):
|
||||
|
@ -378,6 +418,13 @@ def test_cos(hass):
|
|||
template.Template("{{ %s | cos | round(3) }}" % value, hass).async_render()
|
||||
== expected
|
||||
)
|
||||
assert render(hass, f"{{{{ cos({value}) | round(3) }}}}") == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | sin(1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | sin(default=1) }}") == 1
|
||||
assert render(hass, "{{ sin('no_number', 1) }}") == 1
|
||||
assert render(hass, "{{ sin('no_number', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_tan(hass):
|
||||
|
@ -396,6 +443,13 @@ def test_tan(hass):
|
|||
template.Template("{{ %s | tan | round(3) }}" % value, hass).async_render()
|
||||
== expected
|
||||
)
|
||||
assert render(hass, f"{{{{ tan({value}) | round(3) }}}}") == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | tan(1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | tan(default=1) }}") == 1
|
||||
assert render(hass, "{{ tan('no_number', 1) }}") == 1
|
||||
assert render(hass, "{{ tan('no_number', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_sqrt(hass):
|
||||
|
@ -414,6 +468,13 @@ def test_sqrt(hass):
|
|||
template.Template("{{ %s | sqrt | round(3) }}" % value, hass).async_render()
|
||||
== expected
|
||||
)
|
||||
assert render(hass, f"{{{{ sqrt({value}) | round(3) }}}}") == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | sqrt(1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | sqrt(default=1) }}") == 1
|
||||
assert render(hass, "{{ sqrt('no_number', 1) }}") == 1
|
||||
assert render(hass, "{{ sqrt('no_number', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_arc_sine(hass):
|
||||
|
@ -434,6 +495,13 @@ def test_arc_sine(hass):
|
|||
template.Template("{{ %s | asin | round(3) }}" % value, hass).async_render()
|
||||
== expected
|
||||
)
|
||||
assert render(hass, f"{{{{ asin({value}) | round(3) }}}}") == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | asin(1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | asin(default=1) }}") == 1
|
||||
assert render(hass, "{{ asin('no_number', 1) }}") == 1
|
||||
assert render(hass, "{{ asin('no_number', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_arc_cos(hass):
|
||||
|
@ -454,6 +522,13 @@ def test_arc_cos(hass):
|
|||
template.Template("{{ %s | acos | round(3) }}" % value, hass).async_render()
|
||||
== expected
|
||||
)
|
||||
assert render(hass, f"{{{{ acos({value}) | round(3) }}}}") == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | acos(1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | acos(default=1) }}") == 1
|
||||
assert render(hass, "{{ acos('no_number', 1) }}") == 1
|
||||
assert render(hass, "{{ acos('no_number', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_arc_tan(hass):
|
||||
|
@ -476,6 +551,13 @@ def test_arc_tan(hass):
|
|||
template.Template("{{ %s | atan | round(3) }}" % value, hass).async_render()
|
||||
== expected
|
||||
)
|
||||
assert render(hass, f"{{{{ atan({value}) | round(3) }}}}") == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'no_number' | atan(1) }}") == 1
|
||||
assert render(hass, "{{ 'no_number' | atan(default=1) }}") == 1
|
||||
assert render(hass, "{{ atan('no_number', 1) }}") == 1
|
||||
assert render(hass, "{{ atan('no_number', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_arc_tan2(hass):
|
||||
|
@ -510,6 +592,12 @@ def test_arc_tan2(hass):
|
|||
== expected
|
||||
)
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ ('duck', 'goose') | atan2(1) }}") == 1
|
||||
assert render(hass, "{{ ('duck', 'goose') | atan2(default=1) }}") == 1
|
||||
assert render(hass, "{{ atan2('duck', 'goose', 1) }}") == 1
|
||||
assert render(hass, "{{ atan2('duck', 'goose', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_strptime(hass):
|
||||
"""Test the parse timestamp method."""
|
||||
|
@ -532,6 +620,10 @@ def test_strptime(hass):
|
|||
|
||||
assert template.Template(temp, hass).async_render() == expected
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ strptime('invalid', '%Y', 1) }}") == 1
|
||||
assert render(hass, "{{ strptime('invalid', '%Y', default=1) }}") == 1
|
||||
|
||||
|
||||
def test_timestamp_custom(hass):
|
||||
"""Test the timestamps to custom filter."""
|
||||
|
@ -554,6 +646,10 @@ def test_timestamp_custom(hass):
|
|||
|
||||
assert template.Template(f"{{{{ {inp} | {fil} }}}}", hass).async_render() == out
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ None | timestamp_custom('invalid', True, 1) }}") == 1
|
||||
assert render(hass, "{{ None | timestamp_custom(default=1) }}") == 1
|
||||
|
||||
|
||||
def test_timestamp_local(hass):
|
||||
"""Test the timestamps to local filter."""
|
||||
|
@ -565,6 +661,10 @@ def test_timestamp_local(hass):
|
|||
== out
|
||||
)
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ None | timestamp_local(1) }}") == 1
|
||||
assert render(hass, "{{ None | timestamp_local(default=1) }}") == 1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"input",
|
||||
|
@ -702,6 +802,10 @@ def test_timestamp_utc(hass):
|
|||
== out
|
||||
)
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ None | timestamp_utc(1) }}") == 1
|
||||
assert render(hass, "{{ None | timestamp_utc(default=1) }}") == 1
|
||||
|
||||
|
||||
def test_as_timestamp(hass):
|
||||
"""Test the as_timestamp function."""
|
||||
|
@ -720,6 +824,12 @@ def test_as_timestamp(hass):
|
|||
)
|
||||
assert template.Template(tpl, hass).async_render() == 1706951424.0
|
||||
|
||||
# Test handling of default return value
|
||||
assert render(hass, "{{ 'invalid' | as_timestamp(1) }}") == 1
|
||||
assert render(hass, "{{ 'invalid' | as_timestamp(default=1) }}") == 1
|
||||
assert render(hass, "{{ as_timestamp('invalid', 1) }}") == 1
|
||||
assert render(hass, "{{ as_timestamp('invalid', default=1) }}") == 1
|
||||
|
||||
|
||||
@patch.object(random, "choice")
|
||||
def test_random_every_time(test_choice, hass):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue