Fix - fill inside loop (#273)

* simple iteration fill test case

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* a couple more tests

* distinguish between filled & default value

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: adriaan <lemontheme@gmail.com>
This commit is contained in:
VojtechPetru 2023-05-18 15:46:46 +02:00 committed by GitHub
parent 2d86f042da
commit 9fd53436d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 263 additions and 1 deletions

View file

@ -0,0 +1,7 @@
{% load component_tags %}
{% for object in objects %}
{% slot 'slot_inner' %}
{{ object }} default
{% endslot %}
{% endfor %}

View file

@ -1,6 +1,6 @@
import re import re
from textwrap import dedent from textwrap import dedent
from typing import Callable, Optional from typing import Callable, Iterable, Optional
from django.template import Context, Template, TemplateSyntaxError from django.template import Context, Template, TemplateSyntaxError
@ -1262,3 +1262,258 @@ class RegressionTests(SimpleTestCase):
</html> </html>
""" """
self.assertHTMLEqual(rendered, expected) self.assertHTMLEqual(rendered, expected)
class IterationFillTest(SimpleTestCase):
"""Tests a behaviour of {% fill .. %} tag which is inside a template {% for .. %} loop."""
class ComponentSimpleSlotInALoop(django_components.component.Component):
template_name = "template_with_slot_in_a_loop.html"
def get_context_data(self, objects: Iterable) -> dict:
return {
"objects": objects,
}
def setUp(self):
django_components.component.registry.clear()
def test_inner_slot_iteration_basic(self):
component.registry.register(
"slot_in_a_loop", self.ComponentSimpleSlotInALoop
)
template = Template(
"""
{% load component_tags %}
{% component_block "slot_in_a_loop" objects=objects %}
{% fill "slot_inner" %}
{{ object }}
{% endfill %}
{% endcomponent_block %}
"""
)
objects = ["OBJECT1", "OBJECT2"]
rendered = template.render(Context({"objects": objects}))
self.assertHTMLEqual(
rendered,
"""
OBJECT1
OBJECT2
""",
)
def test_inner_slot_iteration_with_variable_from_outer_scope(self):
component.registry.register(
"slot_in_a_loop", self.ComponentSimpleSlotInALoop
)
template = Template(
"""
{% load component_tags %}
{% component_block "slot_in_a_loop" objects=objects %}
{% fill "slot_inner" %}
{{ outer_scope_variable }}
{{ object }}
{% endfill %}
{% endcomponent_block %}
"""
)
objects = ["OBJECT1", "OBJECT2"]
rendered = template.render(
Context(
{
"objects": objects,
"outer_scope_variable": "OUTER_SCOPE_VARIABLE",
}
)
)
self.assertHTMLEqual(
rendered,
"""
OUTER_SCOPE_VARIABLE
OBJECT1
OUTER_SCOPE_VARIABLE
OBJECT2
""",
)
def test_inner_slot_iteration_nested(self):
component.registry.register(
"slot_in_a_loop", self.ComponentSimpleSlotInALoop
)
objects = [
{"inner": ["OBJECT1_ITER1", "OBJECT2_ITER1"]},
{"inner": ["OBJECT1_ITER2", "OBJECT2_ITER2"]},
]
template = Template(
"""
{% load component_tags %}
{% component_block "slot_in_a_loop" objects=objects %}
{% fill "slot_inner" %}
{% component_block "slot_in_a_loop" objects=object.inner %}
{% fill "slot_inner" %}
{{ object }}
{% endfill %}
{% endcomponent_block %}
{% endfill %}
{% endcomponent_block %}
"""
)
rendered = template.render(Context({"objects": objects}))
self.assertHTMLEqual(
rendered,
"""
OBJECT1_ITER1
OBJECT2_ITER1
OBJECT1_ITER2
OBJECT2_ITER2
""",
)
def test_inner_slot_iteration_nested_with_outer_scope_variable(self):
component.registry.register(
"slot_in_a_loop", self.ComponentSimpleSlotInALoop
)
objects = [
{"inner": ["OBJECT1_ITER1", "OBJECT2_ITER1"]},
{"inner": ["OBJECT1_ITER2", "OBJECT2_ITER2"]},
]
template = Template(
"""
{% load component_tags %}
{% component_block "slot_in_a_loop" objects=objects %}
{% fill "slot_inner" %}
{{ outer_scope_variable_1 }}
{% component_block "slot_in_a_loop" objects=object.inner %}
{% fill "slot_inner" %}
{{ outer_scope_variable_2 }}
{{ object }}
{% endfill %}
{% endcomponent_block %}
{% endfill %}
{% endcomponent_block %}
"""
)
rendered = template.render(
Context(
{
"objects": objects,
"outer_scope_variable_1": "OUTER_SCOPE_VARIABLE1",
"outer_scope_variable_2": "OUTER_SCOPE_VARIABLE2",
}
)
)
self.assertHTMLEqual(
rendered,
"""
OUTER_SCOPE_VARIABLE1
OUTER_SCOPE_VARIABLE2
OBJECT1_ITER1
OUTER_SCOPE_VARIABLE2
OBJECT2_ITER1
OUTER_SCOPE_VARIABLE1
OUTER_SCOPE_VARIABLE2
OBJECT1_ITER2
OUTER_SCOPE_VARIABLE2
OBJECT2_ITER2
""",
)
def test_inner_slot_iteration_nested_with_slot_default(self):
component.registry.register(
"slot_in_a_loop", self.ComponentSimpleSlotInALoop
)
objects = [
{"inner": ["OBJECT1_ITER1", "OBJECT2_ITER1"]},
{"inner": ["OBJECT1_ITER2", "OBJECT2_ITER2"]},
]
template = Template(
"""
{% load component_tags %}
{% component_block "slot_in_a_loop" objects=objects %}
{% fill "slot_inner" %}
{% component_block "slot_in_a_loop" objects=object.inner %}
{% fill "slot_inner" as "super_slot_inner" %}
{{ super_slot_inner.default }}
{% endfill %}
{% endcomponent_block %}
{% endfill %}
{% endcomponent_block %}
"""
)
rendered = template.render(Context({"objects": objects}))
self.assertHTMLEqual(
rendered,
"""
OBJECT1_ITER1 default
OBJECT2_ITER1 default
OBJECT1_ITER2 default
OBJECT2_ITER2 default
""",
)
def test_inner_slot_iteration_nested_with_slot_default_and_outer_scope_variable(
self,
):
component.registry.register(
"slot_in_a_loop", self.ComponentSimpleSlotInALoop
)
objects = [
{"inner": ["OBJECT1_ITER1", "OBJECT2_ITER1"]},
{"inner": ["OBJECT1_ITER2", "OBJECT2_ITER2"]},
]
template = Template(
"""
{% load component_tags %}
{% component_block "slot_in_a_loop" objects=objects %}
{% fill "slot_inner" %}
{{ outer_scope_variable_1 }}
{% component_block "slot_in_a_loop" objects=object.inner %}
{% fill "slot_inner" as "super_slot_inner" %}
{{ outer_scope_variable_2 }}
{{ super_slot_inner.default }}
{% endfill %}
{% endcomponent_block %}
{% endfill %}
{% endcomponent_block %}
"""
)
rendered = template.render(
Context(
{
"objects": objects,
"outer_scope_variable_1": "OUTER_SCOPE_VARIABLE1",
"outer_scope_variable_2": "OUTER_SCOPE_VARIABLE2",
}
)
)
self.assertHTMLEqual(
rendered,
"""
OUTER_SCOPE_VARIABLE1
OUTER_SCOPE_VARIABLE2
OBJECT1_ITER1 default
OUTER_SCOPE_VARIABLE2
OBJECT2_ITER1 default
OUTER_SCOPE_VARIABLE1
OUTER_SCOPE_VARIABLE2
OBJECT1_ITER2 default
OUTER_SCOPE_VARIABLE2
OBJECT2_ITER2 default
""",
)