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
import json
import logging
import random
import re
import jinja2
from jinja2 import contextfilter
from jinja2.sandbox import ImmutableSandboxedEnvironment
from homeassistant.const import (
@ -418,6 +420,16 @@ def forgiving_float(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):
"""The Home Assistant template environment."""
@ -435,6 +447,7 @@ ENV.filters['timestamp_utc'] = timestamp_utc
ENV.filters['is_defined'] = fail_when_undefined
ENV.filters['max'] = max
ENV.filters['min'] = min
ENV.filters['random'] = random_every_time
ENV.globals['float'] = forgiving_float
ENV.globals['now'] = dt_util.now
ENV.globals['utcnow'] = dt_util.utcnow

View File

@ -1,6 +1,7 @@
"""Test Home Assistant template helper methods."""
from datetime import datetime
import unittest
import random
from unittest.mock import patch
from homeassistant.components import group
@ -232,6 +233,15 @@ class TestHelpersTemplate(unittest.TestCase):
self.assertEqual("1706951424.0",
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):
"""Test passing variables as keywords."""
self.assertEqual(