Artifact db78e75a08a93dec7db1ec1b80fd72442c47c4d91c85b96f567355e2ceaa06d2:
- File
internal/web/comment_test.go
— part of check-in
[51930149be]
at
2026-08-26 16:33:08
on branch trunk
— comments: render fossil links in the timeline, and three routes that were dropped
The timeline printed check-in comments as escaped text, so fossil's own bracket links showed as markup. commentHTML already existed and was wired to the check-in page only; the timeline now uses it for the lead line and each paragraph. Flat rows keep plain titles — theirs are drawn inside a link already, and an anchor cannot nest.
Surveying every link form fossil writes turned up three quarry HAS a page for and dropped anyway: /info, /artifact and /whatis (21 citations across the corpus) reach the same page a bare [hash] does, and /tktview reaches the ticket. A hex tail is required, so /info/2020-06-02T17:38z keeps its documented fate.
An unlabelled route printed its own path as the link text — markup leaking into prose, the one thing this renderer must not do. Those now read as prose.
/forumpost still aims at the forum index on purpose: measured against the fossil clone, 303 of 304 cited forum hashes are not present locally, so a deep link would 404. (user: dmestas, size: 2298) [annotate] [blame] [check-ins using] [more...]
package web import "testing" func TestCommentHTML(t *testing.T) { for in, want := range map[string]string{ "fix [0123abcdef] regression": `fix <a href="/r/tk/info/0123abcdef">0123abcdef</a> regression`, "see [0123abcdef|the fix]": `see <a href="/r/tk/info/0123abcdef">the fix</a>`, "per [https://x.test/a|docs]": `per <a href="https://x.test/a">docs</a>`, "read [Release Notes]": `read [Release Notes]`, "a <b> & [c|<d>]": `a <b> & [c|<d>]`, "case[0] in code": `case[0] in code`, "empty [] brackets": `empty [] brackets`, // An unlabelled fossil route must not print its own path as the // link text. quarry aims these at the forum INDEX on purpose: // measured against a fossil clone, 303 of 304 cited forum // hashes are not present locally, so a deep link would 404. "see [/forumpost/741c673e9e]": `see <a href="/r/tk/forum">forum post 741c673e9e</a>`, "ref [forum:/forumpost/9adfe7e46b|forum post 9adfe7e46b]": `ref <a href="/r/tk/forum">forum post 9adfe7e46b</a>`, // A label that WAS given always wins over the derived one. "see [/forumpost/741c673e9e|the report]": `see <a href="/r/tk/forum">the report</a>`, // The explicit spellings of an artifact citation reach the same // page a bare [hash] does; fossil's own comments use these. "per [/info/0123abcdef]": `per <a href="/r/tk/info/0123abcdef">0123abcdef</a>`, "per [/artifact/0123abcdef|art]": `per <a href="/r/tk/info/0123abcdef">art</a>`, "per [/whatis/0123abcdef|what]": `per <a href="/r/tk/info/0123abcdef">what</a>`, "see [/tktview/0123abcdef]": `see <a href="/r/tk/ticket/0123abcdef">ticket 0123abcdef</a>`, "see [/tktview?name=0123abcdef|t]": `see <a href="/r/tk/ticket/0123abcdef">t</a>`, // A timestamp names nothing quarry can resolve, so it keeps its // documented fate: the label, never the raw markup. "bug [/info/2020-06-02T17:38z|introduced then]": `bug introduced then`, // Routes quarry has no page for still degrade to their label. "see [/finfo?name=src/x.c|the file]": `see the file`, "see [/brlist|branches]": `see branches`, } { if got := string(commentHTML("tk", in)); got != want { t.Errorf("commentHTML(%q)\n got %s\n want %s", in, got, want) } } }