package renderkit
import (
stdhtml "html"
"regexp"
"strings"
"testing"
)
var tagRe = regexp.MustCompile(`<[^>]*>`)
// visibleText strips the span markup and unescapes, i.e. what the user
// sees and what the copy button copies.
func visibleText(s string) string { return stdhtml.UnescapeString(tagRe.ReplaceAllString(s, "")) }
func TestHighlightPreservesText(t *testing.T) {
samples := map[string]string{
"go": "package main\n\n// hi\nfunc main() {\n\tx := \"a\" + `raw\nline`\n\tif x != nil { return 42 }\n}\n",
"py": "def f(x):\n \"\"\"doc\"\"\"\n return x # c\n",
"bash": "echo \"$HOME\" ${A} | grep 'x' # note\nfoo#bar $#\n",
"json": "{\"a\": [1, 2.5, true, null], \"b\": \"x\"}",
"sql": "SELECT count(*) FROM t WHERE a = 'x' -- c\n",
"rust": "fn f<'a>(x: &'a str) -> u32 { 1 }\n",
"diff": "@@ -1 +1 @@\n-old\n+new\n ctx\n",
}
for lang, src := range samples {
out := highlight(lang, stdhtml.EscapeString(src))
if got := visibleText(out); got != src {
t.Errorf("%s: text changed\nwant %q\ngot %q", lang, src, got)
}
if !strings.Contains(out, "\" } // done"))
for _, want := range []string{
`func`,
`main`,
`return`,
`"a<b>"`,
`// done`,
} {
if !strings.Contains(out, want) {
t.Errorf("missing %s in %s", want, out)
}
}
if !strings.Contains(highlight("json", `"k": 1`), `tok-key`) {
t.Error("json key not detected")
}
if !strings.Contains(highlight("sql", "select 1"), `select`) {
t.Error("sql keywords should be case-insensitive")
}
}
func TestHighlightNeverInjectsMarkup(t *testing.T) {
evil := "x := \"\" //
"
out := highlight("go", stdhtml.EscapeString(evil))
if strings.Contains(out, "