Created
December 21, 2023 23:03
-
-
Save danott/d7743e012697fc85c8aacf150b8696a4 to your computer and use it in GitHub Desktop.
Embracing the grain of the web's <template> and <slot> tags for rendering declarative markup on the server.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class HtmlRenderingTest < Minitest::Test | |
CRUST = <<~HTML.strip | |
<!doctype html> | |
<html lang="en"> | |
<head> | |
<title><server-side-slot name="title"><%= title %></server-side-slot></title> | |
<server-side-slot name="head"></server-side-slot> | |
<% meta.each do |name, content| %> | |
<meta name="<%= name %>" content="<%= content %>"> | |
<% end %> | |
</head> | |
<time><%= date %></time> | |
<server-side-slot name="body">Fallback for body slot in crust.</server-side-slot> | |
</html> | |
HTML | |
MANTLE = <<~HTML.strip | |
<server-side-layout name="crust"> | |
<server-side-template slot="head"> | |
<server-side-slot name="head"></server-side-slot> | |
<link rel="mantle" href="https://www.example.com"> | |
</server-side-template> | |
<server-side-slot name="body">Fallback for body slot in mantle.</server-side-slot> | |
<p>Here is another random number: <%= Random.rand %></p> | |
</server-side-layout> | |
HTML | |
CORE = <<~HTML.strip | |
<server-side-layout name="mantle"> | |
<server-side-template slot="title">Inner Title</server-side-template> | |
<server-side-template slot="head"> | |
<link rel="inner" href="https://www.example.com"> | |
</server-side-template> | |
<h1>This is the title</h1> | |
<p>Here is a random number: <%= Random.rand %></p> | |
</server-side-layout> | |
HTML | |
DATA = { | |
"title" => "Default Title", | |
"date" => Date.new(2023, 1, 2), | |
"meta" => { | |
"hello" => "world", | |
"howdy" => "partner" | |
} | |
} | |
LAYOUTS = { "core" => CORE, "mantle" => MANTLE, "crust" => CRUST } | |
def test_rendering_three_layers_deep | |
rendered = HtmlRendering.new(DATA.merge("layout" => "core"), LAYOUTS).html | |
refute_includes rendered, "<title>Default Title</title>" | |
assert_includes rendered, "<title>Inner Title</title>" | |
assert_includes rendered, '<meta name="hello" content="world">' | |
assert_includes rendered, '<meta name="howdy" content="partner">' | |
assert_includes rendered, "Here is a random number:" | |
assert_includes rendered, "Here is another random number:" | |
refute_includes rendered, "Random.rand" | |
refute_includes rendered, "Fallback for body slot in mantle." | |
refute_includes rendered, "Fallback for body slot in crust." | |
end | |
def test_rendering_two_layers_deep | |
rendered = HtmlRendering.new(DATA.merge("layout" => "mantle"), LAYOUTS).html | |
assert_includes rendered, "<title>Default Title</title>" | |
assert_includes rendered, '<meta name="hello" content="world">' | |
assert_includes rendered, '<meta name="howdy" content="partner">' | |
refute_includes rendered, "Here is a random number:" | |
assert_includes rendered, "Here is another random number:" | |
refute_includes rendered, "Random.rand" | |
assert_includes rendered, "Fallback for body slot in mantle." | |
refute_includes rendered, "Fallback for body slot in crust." | |
end | |
def test_rendering_one_layer | |
rendered = HtmlRendering.new(DATA.merge("layout" => "crust"), LAYOUTS).html | |
assert_includes rendered, "<title>Default Title</title>" | |
assert_includes rendered, '<meta name="hello" content="world">' | |
assert_includes rendered, '<meta name="howdy" content="partner">' | |
refute_includes rendered, "Here is a random number:" | |
refute_includes rendered, "Here is another random number:" | |
refute_includes rendered, "Random.rand" | |
refute_includes rendered, "Fallback for body slot in mantle." | |
assert_includes rendered, "Fallback for body slot in crust." | |
end | |
def test_double_rendering_is_fine | |
instance = HtmlRendering.new(DATA.merge("layout" => "core"), LAYOUTS) | |
first_render = instance.html | |
second_render = instance.render.render.html | |
assert_equal first_render, second_render | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment