Create cloned template for rendering so test instrumentation works.

Co-authored-by: rbeard0330 <@dul2k3BKW6m>
This commit is contained in:
rbeard0330 2021-01-31 17:18:04 -05:00 committed by GitHub
parent 8c784f3a4c
commit 1ea86fc50d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 5 deletions

View file

@ -1,4 +1,5 @@
import warnings
from copy import copy
from itertools import chain
from django.conf import settings
@ -73,12 +74,17 @@ class Component(with_metaclass(MediaDefiningClass)):
del slots_filled[unexpected_slot]
combined_slots = dict(slots_in_template, **slots_filled)
if combined_slots:
# Replace slot nodes with their nodelists, then combine into a single, flat nodelist
node_iterator = ([node] if not is_slot_node(node) else combined_slots[node.name]
for node in template.template.nodelist)
flattened_nodelist = NodeList(chain.from_iterable(node_iterator))
return flattened_nodelist.render(context)
template = copy(template.template)
template.nodelist = NodeList(chain.from_iterable(node_iterator))
else:
template = template.template
return template.render(context)
class Media:
css = {}

View file

@ -366,3 +366,49 @@ class MultiComponentTests(SimpleTestCase):
second_slot = self.wrap_with_slot_tags(second_slot_content)
rendered = self.make_template('', second_slot).render(Context({}))
self.assertHTMLEqual(rendered, self.expected_result('', second_slot_content))
class TemplateInstrumentationTest(SimpleTestCase):
@classmethod
def setUpClass(cls):
"""Emulate Django test instrumentation for TestCase (see setup_test_environment)"""
from django.test.utils import instrumented_test_render
cls.saved_render_method = Template._render
Template._render = instrumented_test_render
@classmethod
def tearDownClass(cls):
Template._render = cls.saved_render_method
def setUp(self):
component.registry.clear()
component.registry.register('test_component', SlottedComponent)
component.registry.register('inner_component', SimpleComponent)
def templates_used_to_render(self, subject_template, render_context=None):
"""Emulate django.test.client.Client (see request method)."""
from django.test.signals import template_rendered
templates_used = []
def receive_template_signal(sender, template, context, **_kwargs):
templates_used.append(template.name)
template_rendered.connect(receive_template_signal, dispatch_uid='test_method')
subject_template.render(render_context or Context({}))
template_rendered.disconnect(dispatch_uid='test_method')
return templates_used
def test_template_shown_as_used(self):
template = Template("{% load component_tags %}{% component 'test_component' %}", name='root')
templates_used = self.templates_used_to_render(template)
self.assertIn('slotted_template.html', templates_used)
def test_nested_component_templates_all_shown_as_used(self):
template = Template("{% load component_tags %}{% component_block 'test_component' %}"
"{% slot \"header\" %}{% component 'inner_component' variable='foo' %}{% endslot %}"
"{% endcomponent_block %}", name='root')
templates_used = self.templates_used_to_render(template)
self.assertIn('slotted_template.html', templates_used)
self.assertIn('simple_template.html', templates_used)