| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- package main
- import (
- "strings"
- "testing"
- "time"
- )
- func TestParsePost(t *testing.T) {
- mod := time.Date(2026, 3, 4, 15, 30, 0, 0, time.UTC)
- tests := []struct {
- name, file, src string
- slug, title string
- date string
- summary string
- draft bool
- wantErr string
- }{
- {
- name: "full front matter",
- file: "2026-01-01-first.md",
- src: "---\ntitle: \"Front title\"\ndate: 2026-02-02\nsummary: Short.\ndraft: false\n---\nBody\n",
- slug: "first", title: "Front title", date: "2026-02-02", summary: "Short.",
- },
- {
- name: "title from heading, date from filename",
- file: "2026-01-01-first.md",
- src: "\n# Heading title\n\nBody\n",
- slug: "first", title: "Heading title", date: "2026-01-01",
- },
- {
- name: "plain filename falls back to slug and mtime",
- file: "about.md",
- src: "Just text.\n",
- slug: "about", title: "about", date: "2026-03-04",
- },
- {
- name: "CRLF line endings",
- file: "crlf.md",
- src: "---\r\ntitle: Windows\r\ndate: 2026-05-05\r\n---\r\nBody\r\n",
- slug: "crlf", title: "Windows", date: "2026-05-05",
- },
- {
- name: "draft",
- file: "2026-01-01-wip.md",
- src: "---\ndraft: true\n---\n# WIP\n",
- slug: "wip", title: "WIP", date: "2026-01-01", draft: true,
- },
- {name: "unterminated front matter", file: "a.md", src: "---\ntitle: x\n", wantErr: "closing ---"},
- {name: "bad front matter line", file: "a.md", src: "---\nnot a pair\n---\n", wantErr: "expected key: value"},
- {name: "bad date", file: "a.md", src: "---\ndate: yesterday\n---\n", wantErr: "not YYYY-MM-DD"},
- {name: "bad draft", file: "a.md", src: "---\ndraft: maybe\n---\n", wantErr: "not true or false"},
- {name: "bad filename", file: "Hello World.md", src: "x", wantErr: "filename must be"},
- {name: "bad filename date", file: "2026-13-01-x.md", src: "x", wantErr: "bad date"},
- }
- md := newMarkdown()
- for _, tt := range tests {
- t.Run(tt.name, func(t *testing.T) {
- p, err := parsePost(md, tt.file, []byte(tt.src), mod)
- if tt.wantErr != "" {
- if err == nil || !strings.Contains(err.Error(), tt.wantErr) {
- t.Fatalf("err = %v, want containing %q", err, tt.wantErr)
- }
- return
- }
- if err != nil {
- t.Fatal(err)
- }
- if p.Slug != tt.slug || p.Title != tt.title || p.Summary != tt.summary || p.Draft != tt.draft {
- t.Errorf("got slug=%q title=%q summary=%q draft=%v", p.Slug, p.Title, p.Summary, p.Draft)
- }
- if got := p.Date.Format(time.DateOnly); got != tt.date {
- t.Errorf("date = %s, want %s", got, tt.date)
- }
- })
- }
- }
- func TestHeadingTitleRemovedFromBody(t *testing.T) {
- p, err := parsePost(newMarkdown(), "x.md", []byte("# Title\n\nBody text\n"), time.Now())
- if err != nil {
- t.Fatal(err)
- }
- if strings.Contains(string(p.HTML), "<h1") {
- t.Errorf("heading used as title should not be repeated in body: %s", p.HTML)
- }
- }
- func TestMarkdownRendering(t *testing.T) {
- src := "| a | b |\n|---|---|\n| 1 | 2 |\n\n~~old~~ https://example.com\n\n<script>alert(1)</script>\n"
- p, err := parsePost(newMarkdown(), "x.md", []byte(src), time.Now())
- if err != nil {
- t.Fatal(err)
- }
- html := string(p.HTML)
- for _, want := range []string{"<table>", "<del>old</del>", `<a href="https://example.com">`} {
- if !strings.Contains(html, want) {
- t.Errorf("missing %q in %s", want, html)
- }
- }
- if strings.Contains(html, "<script") {
- t.Errorf("raw HTML was rendered: %s", html)
- }
- }
|