Add landing page for kjol, documentation

This commit is contained in:
2026-07-13 16:51:21 -04:00
parent 5230bd6702
commit fec8ef4a3e
54 changed files with 3529 additions and 547 deletions

99
go/webui/code_test.go Normal file
View File

@@ -0,0 +1,99 @@
package webui
import (
"strings"
"testing"
)
// The highlighter emits HTML, and its input is Go source — which is full of <, > and &.
// Anything that reaches the page unescaped is markup injection into your own docs page:
// a snippet containing `<div>` would render a div.
func TestHighlightGoEscapes(t *testing.T) {
got := HighlightGo(`s := "<div class=\"x\">" // a & b`)
if strings.Contains(got, "<div") {
t.Errorf("a `<div>` in the SOURCE reached the output as markup:\n%s", got)
}
if !strings.Contains(got, "&lt;div") {
t.Errorf("the angle bracket was not escaped:\n%s", got)
}
if !strings.Contains(got, "&amp;") {
t.Errorf("the ampersand was not escaped:\n%s", got)
}
}
func TestHighlightGoClassifies(t *testing.T) {
got := HighlightGo("func main() { x := 42 // note\n}")
for _, want := range []struct{ what, class, text string }{
{"keyword", goKeywordClass, "func"},
{"call", goFuncClass, "main"},
{"number", goNumberClass, "42"},
{"comment", goCommentClass, "// note"},
} {
if !strings.Contains(got, `<span class="`+want.class+`">`+want.text+`</span>`) {
t.Errorf("%s %q was not highlighted:\n%s", want.what, want.text, got)
}
}
}
// The //gowasm: directives are the most important line in half these snippets. They are
// comments, and must survive as such.
func TestHighlightGoKeepsDirectives(t *testing.T) {
got := HighlightGo("//gowasm:page / static layout=public\nfunc HomePage() {}")
if !strings.Contains(got, `<span class="`+goCommentClass+`">//gowasm:page / static layout=public</span>`) {
t.Errorf("the directive was not kept whole as a comment:\n%s", got)
}
}
// A lexer that can hang or eat the rest of the file on malformed input would take the
// whole page down with it. Unterminated literals stop; they do not run away.
func TestHighlightGoSurvivesMalformedInput(t *testing.T) {
for _, src := range []string{
`x := "unterminated`,
"y := `unterminated raw",
"/* unterminated block",
`z := '`,
"",
} {
got := HighlightGo(src)
// The text must all still be there — mangling is not an acceptable failure mode
// either. Compare on the visible characters, ignoring the spans.
if plain := stripTags(got); plain != src {
t.Errorf("input %q came out as %q", src, plain)
}
}
}
// Nothing is dropped: every byte of the source is still on the page, in order.
func TestHighlightGoIsLossless(t *testing.T) {
src := "package app\n\nimport \"strings\"\n\nfunc f(n int) string {\n\treturn strings.Repeat(\"x\", n) // pad\n}\n"
if plain := stripTags(HighlightGo(src)); plain != src {
t.Errorf("the highlighter changed the source.\n got: %q\nwant: %q", plain, src)
}
}
// stripTags removes the spans and unescapes, recovering the original source.
func stripTags(s string) string {
var b strings.Builder
for i := 0; i < len(s); {
if s[i] == '<' {
j := strings.IndexByte(s[i:], '>')
if j < 0 {
break
}
i += j + 1
continue
}
b.WriteByte(s[i])
i++
}
out := b.String()
// Reverse html.EscapeString, innermost last.
out = strings.ReplaceAll(out, "&lt;", "<")
out = strings.ReplaceAll(out, "&gt;", ">")
out = strings.ReplaceAll(out, "&#34;", `"`)
out = strings.ReplaceAll(out, "&#39;", "'")
out = strings.ReplaceAll(out, "&amp;", "&")
return out
}