Artifact e6b6490a00e9525f6bf4d5ea1b0a8b40a7a2b13ae9e61a265e53c6a5cd9c1d4a:
- File
internal/index/counts_test.go
— part of check-in
[3a330c9560]
at
2026-08-17 18:49:56
on branch trunk
— web: repository nav shows counts and current section
Counts tell a reader where a store's content is — pikchr is 245 forum threads and one ticket, tk is 5,809 tickets and one post. The index memoizes them per fold; on tk they cost ~110ms cold and 3ms after.
Also: the current section is marked, empty sections are dimmed but stay linked, the repository outranks the forge name in the header, and timestamps render relative with the exact value in the title. (user: dmestas, size: 2826) [annotate] [blame] [check-ins using]
package index import ( "testing" "craftdesign.group/quarry/internal/artifact" ) func wikiEdit(hash, title, date string) Parsed { return Parsed{Hash: hash, Art: &artifact.Artifact{ Type: artifact.Wiki, Date: date, User: "dan", WikiTitle: title, Body: []byte("body"), }} } // Counts is memoized because it is read on every page render, which // makes staleness the thing to prove. A nav that says "wiki 3" after a // fourth page is saved is a small lie, and small lies about counts are // how a reader learns not to trust the rest of the page. func TestCountsRefreshAfterAFold(t *testing.T) { ix := openIndex(t) got, err := ix.Counts() if err != nil { t.Fatal(err) } if got.WikiPages != 0 { t.Fatalf("empty index reports %d wiki pages", got.WikiPages) } if err := ix.FoldNow([]Parsed{ wikiEdit("w1", "Home", "2026-01-01T00:00:00"), wikiEdit("w2", "Install", "2026-01-02T00:00:00"), }); err != nil { t.Fatal(err) } got, err = ix.Counts() if err != nil { t.Fatal(err) } if got.WikiPages != 2 { t.Fatalf("after fold: %d wiki pages, want 2 — the memo went stale", got.WikiPages) } // A second edit to an EXISTING page must not raise the page count: // the nav links to a list of pages, so it has to count pages. if err := ix.FoldNow([]Parsed{ wikiEdit("w3", "Home", "2026-01-03T00:00:00"), }); err != nil { t.Fatal(err) } got, _ = ix.Counts() if got.WikiPages != 2 { t.Fatalf("re-editing a page changed the count to %d, want 2", got.WikiPages) } // Reset is the reindex path; the memo must not survive it. if err := ix.Reset(); err != nil { t.Fatal(err) } got, err = ix.Counts() if err != nil { t.Fatal(err) } if got.WikiPages != 0 { t.Fatalf("after Reset: %d wiki pages, want 0 — the memo survived a reindex", got.WikiPages) } } // The forum count is THREADS, not posts, because that is what the forum // page lists. Counting posts would send a reader to a page showing // fewer rows than the nav promised. func TestForumCountIsThreadsNotPosts(t *testing.T) { ix := openIndex(t) root := "f1" if err := ix.FoldNow([]Parsed{ {Hash: root, Art: &artifact.Artifact{ Type: artifact.Forum, Date: "2026-01-01T00:00:00", User: "dan", ThreadTitle: "A thread", Body: []byte("hi"), }}, {Hash: "f2", Art: &artifact.Artifact{ Type: artifact.Forum, Date: "2026-01-02T00:00:00", User: "dan", InReplyTo: root, ThreadRoot: root, Body: []byte("reply"), }}, {Hash: "f3", Art: &artifact.Artifact{ Type: artifact.Forum, Date: "2026-01-03T00:00:00", User: "dan", InReplyTo: root, ThreadRoot: root, Body: []byte("reply"), }}, }); err != nil { t.Fatal(err) } got, err := ix.Counts() if err != nil { t.Fatal(err) } if got.ForumThreads != 1 { t.Fatalf("ForumThreads = %d for one thread with two replies, want 1", got.ForumThreads) } }