Kaku/kaku/render_test.go
2026-08-28 01:47:25 +02:00

212 lines
7.3 KiB
Go

package kaku
import "testing"
func TestRender(t *testing.T) {
tests := map[string]struct {
doc *Document
want string
}{
"heading with anchor": {
&Document{Children: []Node{
&Heading{Level: 2, Children: []Node{&Text{Value: "Hello World!"}}},
}},
`<h2 id="hello-world">Hello World!<a href="#hello-world" aria-label="Hello World! permalink" class="heading-anchor" title="Link to this heading">#</a></h2>`,
},
"paragraph + bold + em + strike + code": {
&Document{Children: []Node{
&Paragraph{Children: []Node{
&Bold{Children: []Node{&Text{Value: "bold"}}},
&Text{Value: " and "},
&Em{Children: []Node{&Text{Value: "emphasis"}}},
&Text{Value: " and "},
&Strike{Children: []Node{&Text{Value: "strike"}}},
&Text{Value: " and "},
&Code{Value: "<style>"},
}},
}},
"<p><strong>bold</strong> and <em>emphasis</em> and <del>strike</del> and <code>&lt;style&gt;</code></p>",
},
"hr": {
&Document{Children: []Node{&HR{}}},
"<hr>",
},
"escaping": {
&Document{Children: []Node{
&Paragraph{Children: []Node{&Text{Value: "<script>"}}},
}},
"<p>&lt;script&gt;</p>",
},
"codeBlock": {
&Document{Children: []Node{
&CodeBlock{Content: "<script>const hello = Hello</script>"},
}},
"<pre><code>&lt;script&gt;const hello = Hello&lt;/script&gt;</code></pre>",
},
"bullet list": {
&Document{Children: []Node{
&List{Kind: "ul", Items: []*ListItem{
{Children: []Node{&Text{Value: "AAA"}}},
{Children: []Node{&Text{Value: "BBB"}}},
{Children: []Node{&Text{Value: "CCC"}}},
}},
}},
"<ul><li>AAA</li><li>BBB</li><li>CCC</li></ul>",
},
"list with bold": {
&Document{Children: []Node{
&List{Kind: "ul", Items: []*ListItem{
{Children: []Node{
&Bold{Children: []Node{&Text{Value: "AAA"}}},
}},
{Children: []Node{&Text{Value: "BBB"}}},
}},
}},
"<ul><li><strong>AAA</strong></li><li>BBB</li></ul>",
},
"ordered list": {
&Document{Children: []Node{
&List{Kind: "ol", Items: []*ListItem{
{Children: []Node{&Text{Value: "Number 1"}}},
{Children: []Node{&Text{Value: "Number 2"}}},
{Children: []Node{&Text{Value: "Number 3"}}},
}},
}},
"<ol><li>Number 1</li><li>Number 2</li><li>Number 3</li></ol>",
},
"definition list": {
&Document{Children: []Node{
&DefList{Items: []*DefItem{
{
Term: []Node{&Text{Value: "Term 1"}},
Definition: []Node{&Text{Value: "definition 1"}},
},
{
Term: []Node{&Text{Value: "Term 2"}},
Definition: []Node{&Text{Value: "definition 2"}},
},
}},
}},
"<dl><dt>Term 1</dt><dd>definition 1</dd><dt>Term 2</dt><dd>definition 2</dd></dl>",
},
"quote full": {
&Document{Children: []Node{
&Quote{
Text: []Node{&Text{Value: "And even, quotes!"}},
Author: "Author",
Source: "Source of quote",
Link: "url_of_quote",
},
}},
`<figure><blockquote cite="url_of_quote">And even, quotes!</blockquote><figcaption>—Author, <a href="url_of_quote">Source of quote</a></figcaption></figure>`,
},
"link full": {
&Document{Children: []Node{
&Link{
URL: "https://git.merveilles.town/thomasorus/Kaku",
Text: []Node{&Text{Value: "Check this link to the repo!"}},
Label: "Link to Kaku's repo",
Title: "Hover title",
},
}},
`<a href="https://git.merveilles.town/thomasorus/Kaku" aria-label="Link to Kaku&#39;s repo" title="Hover title">Check this link to the repo!</a>`,
},
"link minimal": {
&Document{Children: []Node{
&Link{URL: "https://example.com", Text: []Node{&Text{Value: "Example"}}},
}},
`<a href="https://example.com">Example</a>`,
},
"image with alt": {
&Document{Children: []Node{
&Image{URL: "img_url", Alt: "the alternate text"},
}},
`<figure><img src="img_url" alt="the alternate text"><figcaption><small><a href="img_url">Full size</a></small></figcaption></figure>`,
},
"image with caption": {
&Document{Children: []Node{
&Image{
URL: "img_url",
Alt: "the alternate text",
Caption: []Node{&Text{Value: "the text under the image"}},
},
}},
`<figure><img src="img_url" alt="the alternate text"><figcaption>the text under the image | <small><a href="img_url">Full size</a></small></figcaption></figure>`,
},
"paragraph with inline link": {
&Document{Children: []Node{
&Paragraph{Children: []Node{
&Text{Value: "Check out "},
&Link{URL: "https://example.com", Text: []Node{&Text{Value: "Example"}}},
&Text{Value: " for more."},
}},
}},
`<p>Check out <a href="https://example.com">Example</a> for more.</p>`,
},
"paragraph with inline image": {
&Document{Children: []Node{
&Paragraph{Children: []Node{
&Text{Value: "Look: "},
&Image{URL: "img_url", Alt: "alt text"},
}},
}},
`<p>Look: <figure><img src="img_url" alt="alt text"><figcaption><small><a href="img_url">Full size</a></small></figcaption></figure></p>`,
},
"video autoplay/gif": {
&Document{Children: []Node{&Video{URL: "videoUrl", Autoplay: true}}},
`<figure><video autoplay="true" playsinline="true" loop="true" muted="true" preload="metadata" src="videoUrl" type="video/mp4"></video></figure>`,
},
"video with autoplay and figcaption": {
&Document{Children: []Node{
&Video{
URL: "aesthetics010.mp4",
Caption: []Node{&Text{Value: "Art by "}, &Link{URL: "https://twitter.com/lvl374", Text: []Node{&Text{Value: "lvl374"}}}},
Autoplay: true,
},
}},
`<figure><video autoplay="true" playsinline="true" loop="true" muted="true" preload="metadata" src="aesthetics010.mp4" type="video/mp4"></video><figcaption>Art by <a href="https://twitter.com/lvl374">lvl374</a></figcaption></figure>`,
},
"audio": {
&Document{Children: []Node{&Audio{URL: "audioUrl"}}},
`<audio controls="" preload="metadata" src="audioUrl" type="audio/mpeg"></audio>`,
},
"aside": {
&Document{Children: []Node{
&Aside{Children: []Node{&Text{Value: "A side note"}}},
}},
"<aside><p>Side note</p>A side note</aside>",
},
"details": {
&Document{Children: []Node{
&Details{
Summary: []Node{&Text{Value: "Click to expand"}},
Content: []Node{&Text{Value: "Hidden content here"}},
},
}},
"<details><summary>Click to expand</summary>Hidden content here</details>",
},
"todo list": {
&Document{Children: []Node{
&TodoList{Items: []*TodoItem{
{State: ' ', Children: []Node{&Text{Value: "Not started"}}},
{State: '@', Children: []Node{&Text{Value: "In progress"}}},
{State: '~', Children: []Node{&Text{Value: "Paused"}}},
{State: 'x', Children: []Node{&Text{Value: "Done"}}},
}},
}},
`<ul><li><code aria-hidden="true">[ ]</code><span class="visually-hidden">Opened task</span> Not started</li>` +
`<li><code aria-hidden="true">[@]</code><span class="visually-hidden">Ongoing task</span> In progress</li>` +
`<li><code aria-hidden="true">[~]</code><span class="visually-hidden">Paused or abandonned task</span> Paused</li>` +
`<li><code aria-hidden="true">[x]</code><span class="visually-hidden">Completed task</span> Done</li></ul>`,
},
}
for name, c := range tests {
t.Run(name, func(t *testing.T) {
got := c.doc.Render()
if string(got) != c.want {
t.Errorf("got:\n %s\nwant:\n %s", got, c.want)
}
})
}
}