from contextvars import ContextVar
from textwrap import dedent
from minihtml import (
Component,
Element,
Slots,
component,
component_scripts,
component_styles,
template,
text,
)
from minihtml.tags import body, div, head, html, main, script, style, title
def test_template_renders_as_html_with_doctype_and_trailing_newline():
@template()
def my_template(message: str) -> Element:
return div(message)
assert my_template("hello").render() == dedent("""\
hello
""")
def test_template_can_disable_doctype():
@template()
def my_template(message: str) -> Element:
return div(message)
assert my_template("hello").render(doctype=False) == "hello
\n"
def test_template_with_layout_component():
@component(slots=["title", "content"], default="content")
def my_layout(slots: Slots) -> Element:
with html as elem:
with head, title:
slots.slot("title")
with body:
with div["#content"]:
slots.slot()
return elem
@template(layout=my_layout)
def my_template(layout: Component, message: str) -> None:
with layout.slot("title"):
text("my title")
div(message)
assert my_template("hello").render() == dedent("""\
my title
""")
# Test that layout is not cached
assert my_template("goodbye").render() == dedent("""\
my title
""")
def test_template_collects_and_deduplicates_component_styles_and_scripts():
@component(
style=style(".my-component { background: #ccc }"),
script=[
script("// 1st script goes here"),
script("// 2nd script goes here"),
],
)
def my_component(slots: Slots) -> Element:
return div["my-component"]
@component(
style=style("main { background: #eee }"),
script=script("// layout script goes here"),
)
def my_layout(slots: Slots) -> Element:
with html as elem:
with head:
component_styles()
with body:
with main:
slots.slot()
component_scripts()
return elem
@template(layout=my_layout)
def my_template(layout: Component) -> None:
my_component()
my_component()
assert my_template().render() == dedent("""\
""")
def test_passing_component_styles_and_scripts_as_arguments():
@component(
style=style(".my-component { background: #ccc }"),
script=[
script("// 1st script goes here"),
script("// 2nd script goes here"),
],
)
def my_component(slots: Slots) -> Element:
return div["my-component"]
@template()
def my_template() -> Element:
return html(
head(
component_styles(),
),
body(
my_component(),
my_component(),
component_scripts(),
),
)
assert my_template().render() == dedent("""\
""")
name_context = ContextVar[str]("name")
def test_template_is_rendered_lazily():
@template()
def my_template() -> Element:
return div(name_context.get())
t = my_template()
name_context.set("fred")
assert t.render(doctype=False) == "fred
\n"
name_context.set("barney")
assert t.render(doctype=False) == "barney
\n"