Eshu
view release on metacpan or search on metacpan
t/0244-realworld-html.t view on Meta::CPAN
END
is(h($code), $code, 'HTML: modal dialog');
}
# 8. responsive image with srcset
{
my $code = <<'END';
<picture>
<source media="(min-width: 1024px)" srcset="/img/hero-lg.webp">
<source media="(min-width: 640px)" srcset="/img/hero-md.webp">
<img src="/img/hero-sm.jpg" alt="Hero image" loading="lazy" width="800" height="400">
</picture>
END
is(h($code), $code, 'HTML: responsive picture element');
}
# 9. video embed
{
my $code = <<'END';
<figure>
<video controls width="720" preload="metadata">
<source src="/video/demo.mp4" type="video/mp4">
<source src="/video/demo.webm" type="video/webm">
<track src="/captions/demo.vtt" kind="captions" srclang="en" label="English">
Your browser does not support the video element.
</video>
<figcaption>Demo video â click to play</figcaption>
</figure>
END
is(h($code), $code, 'HTML: video with tracks');
}
# 10. details/summary
{
my $code = <<'END';
<details>
<summary>Click to expand</summary>
<div class="details-content">
<p>Hidden content revealed on click.</p>
<ul>
<li>Item one</li>
<li>Item two</li>
</ul>
</div>
</details>
END
is(h($code), $code, 'HTML: details/summary accordion');
}
# 11. search form
{
my $code = <<'END';
<form role="search" action="/search" method="get">
<div class="search-box">
<input type="search" name="q" placeholder="Search..." aria-label="Search">
<button type="submit" aria-label="Submit search">
<svg aria-hidden="true"><use href="#icon-search"/></svg>
</button>
</div>
<fieldset>
<legend>Filter by type</legend>
<label><input type="radio" name="type" value="all" checked> All</label>
<label><input type="radio" name="type" value="docs"> Docs</label>
<label><input type="radio" name="type" value="blog"> Blog</label>
</fieldset>
</form>
END
is(h($code), $code, 'HTML: search form with filters');
}
# 12. breadcrumb nav
{
my $code = <<'END';
<nav aria-label="Breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="/">Home</a>
</li>
<li class="breadcrumb-item">
<a href="/products">Products</a>
</li>
<li class="breadcrumb-item" aria-current="page">Widget Pro</li>
</ol>
</nav>
END
is(h($code), $code, 'HTML: breadcrumb navigation');
}
# 13. pagination
{
my $code = <<'END';
<nav aria-label="Pagination">
<ul class="pagination">
<li class="page-item disabled">
<a class="page-link" href="#" aria-label="Previous">«</a>
</li>
<li class="page-item active" aria-current="page">
<a class="page-link" href="/page/1">1</a>
</li>
<li class="page-item">
<a class="page-link" href="/page/2">2</a>
</li>
<li class="page-item">
<a class="page-link" href="/page/3">3</a>
</li>
<li class="page-item">
<a class="page-link" href="/page/2" aria-label="Next">»</a>
</li>
</ul>
</nav>
END
is(h($code), $code, 'HTML: pagination');
}
# 14. tabs widget
{
my $code = <<'END';
<div class="tabs" role="tablist">
<button role="tab" aria-selected="true" aria-controls="panel-1" id="tab-1">Overview</button>
<button role="tab" aria-selected="false" aria-controls="panel-2" id="tab-2">Details</button>
<button role="tab" aria-selected="false" aria-controls="panel-3" id="tab-3">Reviews</button>
t/0244-realworld-html.t view on Meta::CPAN
<p>A question and answer section.</p>
</details>
<details>
<summary>How does it work?</summary>
<p>Click to expand for more info.</p>
</details>
</section>
END
my $exp = <<'END';
<section>
<h2>FAQ</h2>
<details>
<summary>What is this?</summary>
<p>A question and answer section.</p>
</details>
<details>
<summary>How does it work?</summary>
<p>Click to expand for more info.</p>
</details>
</section>
END
is(h($in), $exp, 'HTML: unindented FAQ section normalised');
}
# 30
{
my $in = <<'END';
<form>
<label for="name">Name</label>
<input type="text" id="name" name="name">
<label for="msg">Message</label>
<textarea id="msg" name="message" rows="5"></textarea>
<button type="submit">Send</button>
</form>
END
my $exp = <<'END';
<form>
<label for="name">Name</label>
<input type="text" id="name" name="name">
<label for="msg">Message</label>
<textarea id="msg" name="message" rows="5"></textarea>
<button type="submit">Send</button>
</form>
END
is(h($in), $exp, 'HTML: unindented contact form normalised');
}
# ââ idempotency tests ââââââââââââââââââââââââââââââââââââââââââââââ
for my $snippet (
"<html>\n<head>\n<title>T</title>\n<link rel=\"stylesheet\" href=\"a.css\">\n</head>\n<body>\n<div id=\"app\">\n<header>\n<nav>\n<a href=\"/\">Home</a>\n</nav>\n</header>\n<main>\n<p>Content</p>\n</main>\n</div>\n</body>\n</html>\n",
"<div class=\"dropdown\">\n<button>Menu</button>\n<ul>\n<li><a href=\"/a\">A</a></li>\n<li>\n<a href=\"/b\">B</a>\n<ul>\n<li><a href=\"/b1\">B1</a></li>\n<li><a href=\"/b2\">B2</a></li>\n</ul>\n</li>\n</ul>\n</div>\n",
"<article>\n<header>\n<h1>Title</h1>\n<p>By <a href=\"/a\">Author</a></p>\n</header>\n<section>\n<h2>S1</h2>\n<p>Text</p>\n</section>\n<section>\n<h2>S2</h2>\n<p>Text</p>\n</section>\n<footer>\n<p>Tags</p>\n</footer>\n</article>\n",
"<div class=\"wizard\">\n<nav>\n<button data-step=\"1\">Step 1</button>\n<button data-step=\"2\">Step 2</button>\n<button data-step=\"3\">Step 3</button>\n</nav>\n<div data-panel=\"1\">\n<h2>Info</h2>\n<input type=\"text\" name=\"name\">\n</div>\n<d...
"<main>\n<h1>Dashboard</h1>\n<div class=\"stats\">\n<div class=\"stat-card\">\n<h2>Users</h2>\n<p class=\"number\">1,234</p>\n</div>\n<div class=\"stat-card\">\n<h2>Revenue</h2>\n<p class=\"number\">\$56,789</p>\n</div>\n</div>\n</main>\n",
"<header role=\"banner\">\n<a href=\"/\" class=\"logo\">\n<img src=\"/logo.svg\" alt=\"Site Logo\" width=\"120\" height=\"40\">\n</a>\n<nav aria-label=\"Main\">\n<ul>\n<li><a href=\"/features\" aria-current=\"page\">Features</a></li>\n<li><a href=\"...
"<ol class=\"steps\">\n<li>\n<h3>Install</h3>\n<code>npm install widget</code>\n</li>\n<li>\n<h3>Import</h3>\n<code>import Widget from 'widget'</code>\n</li>\n<li>\n<h3>Use</h3>\n<code><Widget /></code>\n</li>\n</ol>\n",
"<div class=\"accordion\">\n<div class=\"accordion-item\">\n<button class=\"accordion-header\">Section 1</button>\n<div class=\"accordion-body\">\n<p>Content 1</p>\n</div>\n</div>\n<div class=\"accordion-item\">\n<button class=\"accordion-header\">S...
"<aside class=\"sidebar\">\n<section>\n<h2>Recent</h2>\n<ul>\n<li><a href=\"/p/1\">Post 1</a></li>\n<li><a href=\"/p/2\">Post 2</a></li>\n<li><a href=\"/p/3\">Post 3</a></li>\n</ul>\n</section>\n<section>\n<h2>Popular</h2>\n<ul>\n<li><a href=\"/p/a\...
"<div class=\"toast\" role=\"alert\" aria-live=\"assertive\">\n<div class=\"toast-header\">\n<strong>Notification</strong>\n<button type=\"button\" class=\"close\" aria-label=\"Close\">X</button>\n</div>\n<div class=\"toast-body\">\nYour file has be...
"<form class=\"settings\">\n<fieldset>\n<legend>Notifications</legend>\n<label><input type=\"checkbox\" name=\"email\" checked> Email</label>\n<label><input type=\"checkbox\" name=\"sms\"> SMS</label>\n<label><input type=\"checkbox\" name=\"push\" c...
"<div class=\"chat\">\n<div class=\"messages\">\n<div class=\"message sent\">\n<p>Hello!</p>\n<time>10:00</time>\n</div>\n<div class=\"message received\">\n<p>Hi there!</p>\n<time>10:01</time>\n</div>\n</div>\n<form class=\"compose\">\n<input type=\...
"<div class=\"kanban\">\n<div class=\"column\" data-status=\"todo\">\n<h2>To Do</h2>\n<div class=\"card\" draggable=\"true\">Task A</div>\n<div class=\"card\" draggable=\"true\">Task B</div>\n</div>\n<div class=\"column\" data-status=\"doing\">\n<h2...
"<iframe\n src=\"https://www.youtube.com/embed/abc123\"\n title=\"Video\"\n frameborder=\"0\"\n allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope\"\n allowfullscreen>\n</iframe>\n",
"<figure class=\"code-example\">\n<pre><code class=\"language-js\">const x = 1;</code></pre>\n<figcaption>Example JavaScript</figcaption>\n</figure>\n",
) {
my $once = h($snippet);
is(h($once), $once, 'HTML: snippet idempotent');
}
done_testing;
( run in 0.583 second using v1.01-cache-2.11-cpan-364913b4093 )