From e15292daa04110f59dcb7515221e22d576437bb2 Mon Sep 17 00:00:00 2001 From: Preston Timmons Date: Sat, 21 Feb 2015 13:19:08 -0600 Subject: [PATCH] [1.8.x] Moved ifchanged tests into syntax_tests/test_if_changed.py. Backport of 3d8fee605184d8ffa47a32546298b52b52d7a087 from master --- .../syntax_tests/test_if_changed.py | 35 +++++++++++++++++++ tests/template_tests/tests.py | 28 --------------- 2 files changed, 35 insertions(+), 28 deletions(-) diff --git a/tests/template_tests/syntax_tests/test_if_changed.py b/tests/template_tests/syntax_tests/test_if_changed.py index 0d94365733..33e66880dd 100644 --- a/tests/template_tests/syntax_tests/test_if_changed.py +++ b/tests/template_tests/syntax_tests/test_if_changed.py @@ -1,3 +1,4 @@ +from django.template import Context, Template from django.test import SimpleTestCase from ..utils import setup @@ -152,3 +153,37 @@ class IfChangedTagTests(SimpleTestCase): """ output = self.engine.render_to_string('ifchanged-filter-ws', {'num': (1, 2, 3)}) self.assertEqual(output, '..1..2..3') + + +class IfChangedTests(SimpleTestCase): + + def test_ifchanged_concurrency(self): + """ + #15849 -- ifchanged should be thread-safe. + """ + template = Template('[0{% for x in foo %},{% with var=get_value %}{% ifchanged %}{{ var }}{% endifchanged %}{% endwith %}{% endfor %}]') + + # Using generator to mimic concurrency. + # The generator is not passed to the 'for' loop, because it does a list(values) + # instead, call gen.next() in the template to control the generator. + def gen(): + yield 1 + yield 2 + # Simulate that another thread is now rendering. + # When the IfChangeNode stores state at 'self' it stays at '3' and skip the last yielded value below. + iter2 = iter([1, 2, 3]) + output2 = template.render(Context({'foo': range(3), 'get_value': lambda: next(iter2)})) + self.assertEqual(output2, '[0,1,2,3]', 'Expected [0,1,2,3] in second parallel template, got {}'.format(output2)) + yield 3 + + gen1 = gen() + output1 = template.render(Context({'foo': range(3), 'get_value': lambda: next(gen1)})) + self.assertEqual(output1, '[0,1,2,3]', 'Expected [0,1,2,3] in first template, got {}'.format(output1)) + + def test_ifchanged_render_once(self): + """ + #19890. The content of ifchanged template tag was rendered twice. + """ + template = Template('{% ifchanged %}{% cycle "1st time" "2nd time" %}{% endifchanged %}') + output = template.render(Context({})) + self.assertEqual(output, '1st time') diff --git a/tests/template_tests/tests.py b/tests/template_tests/tests.py index c62d8a3147..74fa1e22fc 100644 --- a/tests/template_tests/tests.py +++ b/tests/template_tests/tests.py @@ -82,34 +82,6 @@ class TemplateRegressionTests(SimpleTestCase): except TemplateSyntaxError as e: self.assertEqual(e.args[0], "Invalid block tag: 'endblock', expected 'elif', 'else' or 'endif'") - def test_ifchanged_concurrency(self): - # Tests for #15849 - template = Template('[0{% for x in foo %},{% with var=get_value %}{% ifchanged %}{{ var }}{% endifchanged %}{% endwith %}{% endfor %}]') - - # Using generator to mimic concurrency. - # The generator is not passed to the 'for' loop, because it does a list(values) - # instead, call gen.next() in the template to control the generator. - def gen(): - yield 1 - yield 2 - # Simulate that another thread is now rendering. - # When the IfChangeNode stores state at 'self' it stays at '3' and skip the last yielded value below. - iter2 = iter([1, 2, 3]) - output2 = template.render(Context({'foo': range(3), 'get_value': lambda: next(iter2)})) - self.assertEqual(output2, '[0,1,2,3]', 'Expected [0,1,2,3] in second parallel template, got {}'.format(output2)) - yield 3 - - gen1 = gen() - output1 = template.render(Context({'foo': range(3), 'get_value': lambda: next(gen1)})) - self.assertEqual(output1, '[0,1,2,3]', 'Expected [0,1,2,3] in first template, got {}'.format(output1)) - - def test_ifchanged_render_once(self): - """ Test for ticket #19890. The content of ifchanged template tag was - rendered twice.""" - template = Template('{% ifchanged %}{% cycle "1st time" "2nd time" %}{% endifchanged %}') - output = template.render(Context({})) - self.assertEqual(output, '1st time') - def test_super_errors(self): """ Test behavior of the raise errors into included blocks.