django-cotton/django_cotton/tests/test_attributes.py
Will Abbott f1638be9c4 wip
2024-09-07 17:36:14 +01:00

485 lines
16 KiB
Python

from django_cotton.tests.utils import CottonInlineTestCase
from django_cotton.tests.utils import get_compiled
class AttributeHandlingTests(CottonInlineTestCase):
def test_dynamic_attributes_on_components(self):
self.create_template(
"eval_attributes_on_component_view.html",
"""
<c-dynamic-attributes-component
:none="None"
:number="1"
:boolean_true="True"
:boolean_false="False"
:dict="{'key': 'value'}"
:list="[1, 2, 3]"
:listdict="[{'key': 'value'}]"
:variable="variable"
:template_string_lit="{'dummy': {{ dummy }}}"
/>
""",
"view/",
context={"variable": 111, "dummy": 222},
)
self.create_template(
"cotton/dynamic_attributes_component.html",
"""
{% if none is None %}
<p>none is None</p>
{% endif %}
{% if number == 1 %}
<p>number is 1</p>
{% endif %}
{% if boolean_true is True %}
<p>boolean_true is True</p>
{% endif %}
{% if boolean_false is False %}
<p>boolean_false is False</p>
{% endif %}
{% if dict.key == 'value' %}
<p>dict.key is 'value'</p>
{% endif %}
{% if list.0 == 1 %}
<p>list.0 is 1</p>
{% endif %}
{% if listdict.0.key == 'value' %}
<p>listdict.0.key is 'value'</p>
{% endif %}
{% if variable == 111 %}
<p>variable is 111</p>
{% endif %}
{% if template_string_lit.dummy == 222 %}
<p>template_string_lit.dummy is 222</p>
{% endif %}
""",
)
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "none is None")
self.assertContains(response, "number is 1")
self.assertContains(response, "boolean_true is True")
self.assertContains(response, "boolean_false is False")
self.assertContains(response, "list.0 is 1")
self.assertContains(response, "dict.key is 'value'")
self.assertContains(response, "listdict.0.key is 'value'")
self.assertContains(response, "variable is 111")
self.assertContains(response, "template_string_lit.dummy is 222")
def test_dynamic_attributes_in_cvars(self):
self.create_template(
"eval_attributes_in_cvars_view.html",
"""
<c-dynamic-attributes-cvars />
""",
"view/",
)
self.create_template(
"cotton/dynamic_attributes_cvars.html",
"""
<c-vars
:none="None"
:number="1"
:boolean_true="True"
:boolean_false="False"
:dict="{'key': 'value'}"
:list="[1, 2, 3]"
:listdict="[{'key': 'value'}]"
:variable="111"
/>
{% if none is None %}
<p>none is None</p>
{% endif %}
{% if number == 1 %}
<p>number is 1</p>
{% endif %}
{% if boolean_true is True %}
<p>boolean_true is True</p>
{% endif %}
{% if boolean_false is False %}
<p>boolean_false is False</p>
{% endif %}
{% if dict.key == 'value' %}
<p>dict.key is 'value'</p>
{% endif %}
{% if list.0 == 1 %}
<p>list.0 is 1</p>
{% endif %}
{% if listdict.0.key == 'value' %}
<p>listdict.0.key is 'value'</p>
{% endif %}
{% if variable == 111 %}
<p>variable is 111</p>
{% endif %}
""",
)
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "none is None")
self.assertContains(response, "number is 1")
self.assertContains(response, "boolean_true is True")
self.assertContains(response, "boolean_false is False")
self.assertContains(response, "list.0 is 1")
self.assertContains(response, "dict.key is 'value'")
self.assertContains(response, "listdict.0.key is 'value'")
self.assertContains(response, "variable is 111")
def test_we_can_govern_whole_attributes_in_html_elements(self):
self.create_template(
"cotton/attribute_govern.html",
"""
<div {% if something %} class="first" {% else %} class="second" {% endif %}><div>
""",
)
self.create_template(
"attribute_govern_view.html",
"""
<c-attribute-govern :something="False" />
""",
"view/",
)
# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, 'class="second"')
self.assertNotContains(response, 'class="first"')
def test_attribute_names_on_component_containing_hyphens_are_converted_to_underscores(
self,
):
self.create_template(
"cotton/hyphens.html",
"""
<div x-data="{{ x_data }}" x-init="{{ x_init }}"></div>
""",
)
self.create_template(
"hyphens_view.html",
"""
<c-hyphens x-data="{}" x-init="do_something()" />
""",
"view/",
)
# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, 'x-data="{}" x-init="do_something()"')
def test_attribute_names_on_cvars_containing_hyphens_are_converted_to_underscores(
self,
):
self.create_template(
"cotton/cvar_hyphens.html",
"""
<c-vars x-data="{}" x-init="do_something()" />
<div x-data="{{ x_data }}" x-init="{{ x_init }}"></div>
""",
)
self.create_template(
"cvar_hyphens_view.html",
"""
<c-cvar-hyphens />
""",
"view/",
)
# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, 'x-data="{}" x-init="do_something()"')
def test_equals_in_attribute_values(self):
self.create_template(
"cotton/equals.html",
"""
<div {{ attrs }}><div>
""",
)
self.create_template(
"equals_view.html",
"""
<c-equals
@click="this=test"
/>
""",
"view/",
)
# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, '@click="this=test"')
def test_spaces_are_maintained_around_expressions_inside_attributes(self):
self.create_template(
"maintain_spaces_in_attributes_view.html",
"""
<div some_attribute_{{ id }}_something="true"></div>
""",
"view/",
)
# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "some_attribute__something")
def test_boolean_attributes(self):
self.create_template(
"cotton/boolean_attribute.html",
"""
{% if is_something is True %}
It's True
{% endif %}
""",
)
self.create_template(
"boolean_attribute_view.html",
"""
<c-boolean-attribute is_something />
""",
"view/",
)
# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "It's True")
def test_attributes_without_colons_are_not_evaluated(self):
self.create_template(
"cotton/static_attrs.html",
"""
{% if something == "1,234" %}
All good
{% endif %}
{% if something == "(1, 234)" %}
"1,234" was evaluated as a tuple
{% endif %}
""",
)
self.create_template(
"static_attrs_view.html",
"""
<c-static-attrs something="{{ something }}" />
""",
"view/",
context={"something": "1,234"},
)
# Override URLconf
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "All good")
def test_unprocessable_dynamic_attributes_fallback_to_cvars_defaults(self):
self.create_template(
"cotton/unprocessable_dynamic_attribute.html",
"""
<c-vars color="gray" />
{{ color }}
""",
)
self.create_template(
"unprocessable_dynamic_attribute_view.html",
"""
<c-unprocessable-dynamic-attribute :color="button.color" />
""",
"view/",
context={},
)
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertTrue("gray" in response.content.decode())
def test_attribute_merging(self):
self.create_template(
"cotton/merges_attributes.html",
"""
<div {{ attrs_dict|merge:'class:form-group another-class-with:colon' }}></div>
""",
)
self.create_template(
"attribute_merging_view.html",
"""
<c-merges-attributes class="extra-class" silica:model="test" another="test">ss</c-merges-attributes>
""",
"view/",
)
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, 'class="form-group another-class-with:colon extra-class"')
def test_attributes_can_contain_django_native_tags(self):
self.create_template(
"native_tags_in_attributes_view.html",
"""
<c-native-tags-in-attributes
attr1="Hello {{ name }}"
attr2="{{ test|default:"none" }}"
attr3="{% if 1 == 1 %}cowabonga!{% endif %}"
>
<c-slot name="named">test</c-slot>
</c-native-tags-in-attributes>
""",
"view/",
context={"name": "Will", "test": "world"},
)
self.create_template(
"cotton/native_tags_in_attributes.html",
"""
Attribute 1 says: '{{ attr1 }}'
Attribute 2 says: '{{ attr2 }}'
Attribute 3 says: '{{ attr3 }}'
attrs tag is: '{{ attrs }}'
""",
)
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "Attribute 1 says: 'Hello Will'")
self.assertContains(response, "Attribute 2 says: 'world'")
self.assertContains(response, "Attribute 3 says: 'cowabonga!'")
self.assertContains(
response,
"""attrs tag is: 'attr1="Hello Will" attr2="world" attr3="cowabonga!"'""",
)
def test_strings_with_spaces_can_be_passed(self):
self.create_template(
"string_with_spaces_view.html",
"""
<c-string-test var1="string with space" attr1="I have spaces">
<c-slot name="named_slot">
named_slot with spaces
</c-slot>
</c-string-test>
""",
"view/",
)
self.create_template(
"cotton/string_test.html",
"""
<c-vars var1 default_var="default var" />
slot: '{{ slot }}'
attr1: '{{ attr1 }}'
attr2: '{{ attr2 }}'
var1: '{{ var1 }}'
default_var: '{{ default_var }}'
named_slot: '{{ named_slot }}'
attrs: '{{ attrs }}'
""",
)
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "attr1: 'I have spaces'")
self.assertContains(response, "var1: 'string with space'")
self.assertContains(response, "default_var: 'default var'")
self.assertContains(response, "named_slot: '")
self.assertContains(response, "named_slot with spaces")
self.assertContains(response, """attrs: 'attr1="I have spaces"'""")
def test_attrs_do_not_contain_cvars(self):
self.create_template(
"cvars_test_view.html",
"""
<c-cvars-test-component var1="im a var" attr1="im an attr">
default slot
</c-cvars-test-component>
""",
"view/",
)
self.create_template(
"cotton/cvars_test_component.html",
"""
<c-vars var1="sds" prop_with_default="1" />
<div>
{{ testy }}
<p>var1: '{{ var1 }}'</p>
<p>attr1: '{{ attr1 }}'</p>
<p>empty_var: '{{ empty_var }}'</p>
<p>var_with_default: '{{ var_with_default }}'</p>
<p>slot: '{{ slot }}'</p>
<p>named_slot: '{{ named_slot }}'</p>
<p>attrs: '{{ attrs }}'</p>
</div>
""",
)
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(response, "attr1: 'im an attr'")
self.assertContains(response, "var1: 'im a var'")
self.assertContains(response, """attrs: 'attr1="im an attr"'""")
def test_attribute_passing(self):
self.create_template(
"attribute_passing_view.html",
"""
<c-attribute-passing attribute_1="hello" and-another="woo1" thirdForLuck="yes" />
""",
"view/",
)
self.create_template("cotton/attribute_passing.html", """<div {{ attrs }}></div>""")
with self.settings(ROOT_URLCONF=self.url_conf()):
response = self.client.get("/view/")
self.assertContains(
response, '<div attribute_1="hello" and-another="woo1" thirdforluck="yes">'
)
def test_loader_preserves_duplicate_attributes(self):
compiled = get_compiled("""<a href="#" class="test" class="test2">hello</a>""")
self.assertEquals(
compiled,
"""<a href="#" class="test" class="test2">hello</a>""",
)