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), "