From c0c7686926f5f997ef38c817600523c934d05c44 Mon Sep 17 00:00:00 2001 From: t Date: Fri, 31 Jul 2026 16:40:49 -0600 Subject: Add recursive Markdown rendering templates --- main_test.go | 328 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 326 insertions(+), 2 deletions(-) (limited to 'main_test.go') diff --git a/main_test.go b/main_test.go index f6c943e..cf292a6 100644 --- a/main_test.go +++ b/main_test.go @@ -1,14 +1,19 @@ package main import ( + "bytes" "encoding/json" "encoding/xml" + "errors" "html/template" + "io" "os" "path/filepath" "strings" "testing" "time" + + "golang.org/x/net/html" ) func writeTestFile(t *testing.T, root, name, contents string) { @@ -81,8 +86,17 @@ First paragraph with [local](other.md#part), [web](https://example.com/a.md), an page = src.page } } - if page == nil || page.Meta["summary"] != "hello" || len(page.Sections) != 5 { - t.Fatalf("unexpected page model: %#v", page) + if page == nil || page.Meta["summary"] != "hello" || len(page.Sections) != 0 || page.markdownAST == nil { + t.Fatalf("unexpected discovery model: %#v", page) + } + if err := s.loadTemplates(); err != nil { + t.Fatal(err) + } + if err := s.prepareMarkdown(); err != nil { + t.Fatal(err) + } + if len(page.Sections) != 5 { + t.Fatalf("prepared sections = %d, want 5", len(page.Sections)) } } @@ -440,3 +454,313 @@ func TestUnchangedOutputsKeepMtime(t *testing.T) { t.Error("changed output mtime not updated") } } + +func TestMarkdownNoOverrideMatchesGoldmark(t *testing.T) { + root := t.TempDir() + writeTestFile(t, root, "layouts.tmpl", `{{define "page"}}{{joinSections .Sections}}{{end}}`) + markdown := "# Heading\n\nParagraph with **strong**, ~~strike~~, and [link](#heading).\n\n| A | B |\n| - | - |\n| 1 | 2 |\n\n\n" + writeTestFile(t, root, "page.md", markdown) + if err := build(root); err != nil { + t.Fatal(err) + } + got, err := os.ReadFile(filepath.Join(root, "page.html")) + if err != nil { + t.Fatal(err) + } + var want bytes.Buffer + if err := newMarkdown().Convert([]byte(markdown), &want); err != nil { + t.Fatal(err) + } + if !bytes.Equal(got, want.Bytes()) { + t.Fatalf("no-override output changed:\n got: %s\nwant: %s", got, want.Bytes()) + } +} + +func TestMarkdownCoreOverrideContract(t *testing.T) { + root := t.TempDir() + writeTestFile(t, root, "layouts.tmpl", `{{define "page"}}{{joinSections .Sections}}{{end}} +{{define "markdown/heading1"}}

{{.Content}}

{{end}} +{{define "markdown/paragraph"}}

{{.Content}}

{{end}} +{{define "markdown/blockquote"}}{{.Content}}{{end}} +{{define "markdown/code_block"}}{{.Content}}{{end}} +{{define "markdown/fenced_code_block"}}{{if .HighlightedContent}}{{.HighlightedContent}}{{else}}{{.Content}}{{end}}{{end}} +{{define "markdown/ordered_list"}}
    {{.Content}}
{{end}} +{{define "markdown/unordered_list"}}{{end}} +{{define "markdown/list_item"}}
  • {{.Content}}
  • {{end}} +{{define "markdown/emphasis"}}{{.Content}}{{end}} +{{define "markdown/strong"}}{{.Content}}{{end}} +{{define "markdown/code_span"}}{{.Content}}{{end}} +{{define "markdown/link"}}{{.Content}}{{end}} +{{define "markdown/autolink"}}{{.Content}}{{end}} +{{define "markdown/email_autolink"}}{{.Content}}{{end}} +{{define "markdown/image"}}{{.Alt}}{{end}}`) + writeTestFile(t, root, "target.md", "# Target\n") + markdown := "# Root Heading\n\n## Default *heading*\n\nParagraph *em **deep*** ` a b ` [local](target.md \"Title\") [unsafe](javascript:alert(1)).\n\n ![A **very** & black](cat.jpg \"Mochi\")\n\n> quoted **strong**\n\n \n\n" + + "```go extra\nx := \"\"\n```\n\n```unknown\n\n```\n\n```\n\n```\n\n" + + "1. one\n1. two\n\n### split one\n\n3. three\n3. four\n\n### split two\n\n5. five\n99. six\n\n### split three\n\n- tight\n 1. nested\n\n### split four\n\n- loose\n\n- list\n" + writeTestFile(t, root, "page.md", markdown) + if err := build(root); err != nil { + t.Fatal(err) + } + raw, err := os.ReadFile(filepath.Join(root, "page.html")) + if err != nil { + t.Fatal(err) + } + got := string(raw) + for _, want := range []string{ + `

    Root Heading

    `, + `

    Default heading

    `, + `

    Paragraph em deep a b`, + `local`, + `unsafe`, + `https://example.com/a`, + `person@example.com`, + `A very & black`, + `

    quoted strong

    `, + `<script>indented</script>`, + ``, + `<a>`, + `<b>`, + `
      `, + `
        `, + `
          `, + `
          • tight`, + `
            1. nested`, + `
              • loose

                `, + } { + if !strings.Contains(got, want) { + t.Errorf("output missing %q:\n%s", want, got) + } + } + if strings.Contains(got, "