package doc
import (
"strings"
"testing"
)
func TestSplitLog(t *testing.T) {
body := strings.Join([]string{
"# Wiki Log",
"",
"## [2026-05-31] ingest | specification.website — modern web spec checklist",
"Single-page catalog. Pages created: [[specification-website-checklist]].",
"",
"## [2026-05-22] ingest | AgentMail — hosted inboxes",
"Service-side ingest, no source page.",
"",
"## [2026-05-22] lint | consistency pass",
"Second entry on the same date.",
"",
"## [2026-04-01] update | rewrote the storage cluster",
"```",
"## [2020-01-01] not-an-entry | inside a fence",
"```",
"Trailing prose after the fence.",
"",
}, "\n")
entries := SplitLog([]byte(body))
if len(entries) != 4 {
for _, e := range entries {
t.Logf(" %s %s | %s", e.ID, e.Action, e.Title)
}
t.Fatalf("got %d entries, want 4", len(entries))
}
t.Run("header fields are parsed", func(t *testing.T) {
e := entries[0]
if e.Date != "2026-05-31" || e.Action != "ingest" {
t.Errorf("date/action = %q/%q", e.Date, e.Action)
}
if e.Title != "specification.website — modern web spec checklist" {
t.Errorf("title = %q", e.Title)
}
if !strings.Contains(e.Body, "Pages created") {
t.Errorf("body lost: %q", e.Body)
}
if strings.Contains(e.Body, "## [") {
t.Errorf("body kept its own header line: %q", e.Body)
}
})
t.Run("the file title before the first entry is dropped", func(t *testing.T) {
for _, e := range entries {
if strings.Contains(e.Body, "# Wiki Log") {
t.Fatalf("preamble leaked into %s", e.ID)
}
}
})
t.Run("same-date entries get distinct ids", func(t *testing.T) {
if entries[1].ID != "log#2026-05-22-1" || entries[2].ID != "log#2026-05-22-2" {
t.Errorf("ids = %q, %q", entries[1].ID, entries[2].ID)
}
if entries[1].Anchor == entries[2].Anchor {
t.Errorf("same-date entries share an anchor: %q", entries[1].Anchor)
}
})
t.Run("a header inside a fence is not an entry", func(t *testing.T) {
last := entries[3]
if last.Date != "2026-04-01" {
t.Fatalf("last entry date = %q", last.Date)
}
if !strings.Contains(last.Body, "not-an-entry") {
t.Errorf("fenced text should stay in the body: %q", last.Body)
}
if !strings.Contains(last.Body, "Trailing prose") {
t.Errorf("content after the fence was dropped: %q", last.Body)
}
})
t.Run("search text carries the header fields", func(t *testing.T) {
st := entries[0].SearchText()
for _, want := range []string{"2026-05-31", "ingest", "specification.website"} {
if !strings.Contains(st, want) {
t.Errorf("search text missing %q: %q", want, st)
}
}
})
}
func TestSplitLogWithNoEntries(t *testing.T) {
// A page classified as a log that turns out not to follow the format keeps
// working as an ordinary page rather than vanishing from the index.
if got := SplitLog([]byte("# Notes\n\nJust prose, no dated headers.\n")); len(got) != 0 {
t.Fatalf("got %d entries, want none", len(got))
}
}