Prevent the random template filter from caching its output. Fixes #5678 (#7716)

This commit is contained in:
Anton Sarukhanov 2017-05-23 10:32:06 -07:00 committed by Paulus Schoutsen
parent 228fb8c072
commit f3dabe21ab
2 changed files with 23 additions and 0 deletions

View File

@ -2,9 +2,11 @@
from datetime import datetime from datetime import datetime
import json import json
import logging import logging
import random
import re import re
import jinja2 import jinja2
from jinja2 import contextfilter
from jinja2.sandbox import ImmutableSandboxedEnvironment from jinja2.sandbox import ImmutableSandboxedEnvironment
from homeassistant.const import ( from homeassistant.const import (
@ -418,6 +420,16 @@ def forgiving_float(value):
return value return value
@contextfilter
def random_every_time(context, values):
"""Choose a random value.
Unlike Jinja's random filter,
this is context-dependent to avoid caching the chosen value.
"""
return random.choice(values)
class TemplateEnvironment(ImmutableSandboxedEnvironment): class TemplateEnvironment(ImmutableSandboxedEnvironment):
"""The Home Assistant template environment.""" """The Home Assistant template environment."""
@ -435,6 +447,7 @@ ENV.filters['timestamp_utc'] = timestamp_utc
ENV.filters['is_defined'] = fail_when_undefined ENV.filters['is_defined'] = fail_when_undefined
ENV.filters['max'] = max ENV.filters['max'] = max
ENV.filters['min'] = min ENV.filters['min'] = min
ENV.filters['random'] = random_every_time
ENV.globals['float'] = forgiving_float ENV.globals['float'] = forgiving_float
ENV.globals['now'] = dt_util.now ENV.globals['now'] = dt_util.now
ENV.globals['utcnow'] = dt_util.utcnow ENV.globals['utcnow'] = dt_util.utcnow

View File

@ -1,6 +1,7 @@
"""Test Home Assistant template helper methods.""" """Test Home Assistant template helper methods."""
from datetime import datetime from datetime import datetime
import unittest import unittest
import random
from unittest.mock import patch from unittest.mock import patch
from homeassistant.components import group from homeassistant.components import group
@ -232,6 +233,15 @@ class TestHelpersTemplate(unittest.TestCase):
self.assertEqual("1706951424.0", self.assertEqual("1706951424.0",
template.Template(tpl, self.hass).render()) template.Template(tpl, self.hass).render())
@patch.object(random, 'choice')
def test_random_every_time(self, test_choice):
"""Ensure the random filter runs every time, not just once."""
tpl = template.Template('{{ [1,2] | random }}', self.hass)
test_choice.return_value = 'foo'
self.assertEqual('foo', tpl.render())
test_choice.return_value = 'bar'
self.assertEqual('bar', tpl.render())
def test_passing_vars_as_keywords(self): def test_passing_vars_as_keywords(self):
"""Test passing variables as keywords.""" """Test passing variables as keywords."""
self.assertEqual( self.assertEqual(