"""
Here we check that the logic around dependency rendering outputs correct HTML.
During actual rendering, the HTML is then picked up by the JS-side dependency manager.
"""
import re
from django.template import Template
from django_components import Component, registry, types
from .django_test_setup import setup_test_config
from .testutils import BaseTestCase, create_and_process_template_response
setup_test_config({"autodiscover": False})
def to_spaces(s: str):
return re.compile(r"\s+").sub(" ", s)
class SimpleComponent(Component):
template: types.django_html = """
Variable: {{ variable }}
"""
def get_context_data(self, variable, variable2="default"):
return {
"variable": variable,
"variable2": variable2,
}
class Media:
css = "style.css"
js = "script.js"
class SimpleComponentNested(Component):
template: types.django_html = """
{% load component_tags %}
{% component "inner" variable=variable / %}
{% slot "default" default / %}
"""
css: types.css = """
.my-class {
color: red;
}
"""
js: types.js = """
console.log("Hello");
"""
def get_context_data(self, variable):
return {}
class Media:
css = ["style.css", "style2.css"]
js = "script2.js"
class OtherComponent(Component):
template: types.django_html = """
XYZ: {{ variable }}
"""
css: types.css = """
.xyz {
color: red;
}
"""
js: types.js = """
console.log("xyz");
"""
def get_context_data(self, variable):
return {}
class Media:
css = "xyz1.css"
js = "xyz1.js"
class SimpleComponentWithSharedDependency(Component):
template: types.django_html = """
Variable: {{ variable }}
"""
def get_context_data(self, variable, variable2="default"):
return {}
class Media:
css = ["style.css", "style2.css"]
js = ["script.js", "script2.js"]
class MultistyleComponent(Component):
template: types.django_html = """
Variable: {{ variable }}
"""
class Media:
css = ["style.css", "style2.css"]
js = ["script.js", "script2.js"]
class DependencyRenderingTests(BaseTestCase):
def test_no_dependencies_when_no_components_used(self):
registry.register(name="test", component=SimpleComponent)
template_str: types.django_html = """
{% load component_tags %}
{% component_js_dependencies %}
{% component_css_dependencies %}
"""
template = Template(template_str)
rendered = create_and_process_template_response(template)
# Dependency manager script
self.assertInHTML('', rendered, count=1)
self.assertEqual(rendered.count("', rendered, count=1)
self.assertEqual(rendered.count("', rendered, count=1)
self.assertEqual(rendered.count(' '), 1) # Media.css
self.assertEqual(rendered.count(" ', rendered, count=1)
self.assertEqual(rendered.count(' '), 1) # Media.css
self.assertEqual(rendered.count(" ', rendered, count=0)
self.assertEqual(rendered.count(" '), 1) # Media.css
def test_single_component_js_dependencies(self):
registry.register(name="test", component=SimpleComponent)
template_str: types.django_html = """
{% load component_tags %}{% component_js_dependencies %}
{% component 'test' variable='foo' %}{% endcomponent %}
"""
template = Template(template_str)
rendered = create_and_process_template_response(template)
# Dependency manager script
self.assertInHTML('', rendered, count=1)
# CSS NOT included
self.assertEqual(rendered.count(" ', rendered, count=1)
self.assertEqual(rendered.count(" '), 1) # Media.css
self.assertEqual(rendered.count(' '), 1)
self.assertEqual(rendered.count("const loadedJsScripts = [];"), 1)
self.assertEqual(
rendered.count("const loadedCssScripts = ["style.css", "style2.css"];"), 1
)
self.assertEqual(
rendered.count(
r"const toLoadJsScripts = [Components.unescapeJs(\`<script src="script.js"></script>\`), Components.unescapeJs(\`<script src="script2.js"></script>\`)];"
),
1,
)
self.assertEqual(
rendered.count(
r"const toLoadCssScripts = [Components.unescapeJs(\`<link href="style.css" media="all" rel="stylesheet">\`), Components.unescapeJs(\`<link href="style2.css" media="all" rel="stylesheet">\`)];"
),
1,
)
def test_no_dependencies_with_multiple_unused_components(self):
registry.register(name="inner", component=SimpleComponent)
registry.register(name="outer", component=SimpleComponentNested)
template_str: types.django_html = """
{% load component_tags %}
{% component_js_dependencies %}
{% component_css_dependencies %}
"""
template = Template(template_str)
rendered = create_and_process_template_response(template)
# Dependency manager script
self.assertInHTML('', rendered, count=1)
self.assertEqual(rendered.count("', rendered, count=1)
self.assertEqual(rendered.count("