A reply streams as text as before; once it ends, the server renders it with the model card's rules - raw HTML dropped, dangerous links emptied, images as links - and the page places that. Headings, lists, tables and code blocks read as they were written. Maths outside code is set aside before the markdown, so its underscores and asterisks are not taken for emphasis, and marked for the page to typeset. KaTeX no longer searches the reply for delimiters, which took "$5 and $10" for a formula. A reply that cannot be rendered stays plain text, with the old search. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
50 lines
1.6 KiB
Go
50 lines
1.6 KiB
Go
package web
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestAReplyIsMarkdownWithItsMathsLeftForKaTeX(t *testing.T) {
|
|
got := string(renderReply("Here is **bold** and `code`.\n\n" +
|
|
"The sum $a_1 * b_2$ and \\(x_i^2\\), then\n\n$$\\sum_{i=1}^n i$$\n\n" +
|
|
"```go\nfmt.Println(\"$5\")\n```\n\nIt costs $5 and $10."))
|
|
|
|
for _, want := range []string{
|
|
"<strong>bold</strong>", "<code>code</code>",
|
|
// Untouched by emphasis, and marked for KaTeX with its delimiters
|
|
// taken off.
|
|
`data-display="0" data-src="$a_1 * b_2$">a_1 * b_2</span>`,
|
|
`>x_i^2</span>`, `data-display="1" data-src="$$\sum_{i=1}^n i$$">\sum_{i=1}^n i</span>`,
|
|
`<pre><code class="language-go">`,
|
|
"It costs $5 and $10.",
|
|
} {
|
|
if !strings.Contains(got, want) {
|
|
t.Errorf("missing %q in %s", want, got)
|
|
}
|
|
}
|
|
if strings.Contains(got, "llmgwmath") {
|
|
t.Errorf("a placeholder was left behind: %s", got)
|
|
}
|
|
}
|
|
|
|
func TestAReplyCannotRunAnything(t *testing.T) {
|
|
got := string(renderReply("<script>alert(1)</script>\n\n[x](javascript:alert(1))\n\n" +
|
|
"$<img src=x onerror=alert(1)>$"))
|
|
for _, bad := range []string{"<script", "javascript:", "<img"} {
|
|
if strings.Contains(got, bad) {
|
|
t.Errorf("rendered %q: %s", bad, got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestMathsInCodeIsLeftAsCode(t *testing.T) {
|
|
got := string(renderReply("Use `$x$` literally.\n\n```sh\necho $HOME $PATH\n```\n\nBut $y_1$ is maths."))
|
|
if strings.Count(got, `class="math"`) != 1 || !strings.Contains(got, `data-src="$y_1$"`) {
|
|
t.Errorf("only the maths outside code should be marked: %s", got)
|
|
}
|
|
if !strings.Contains(got, "<code>$x$</code>") || !strings.Contains(got, "echo $HOME $PATH") {
|
|
t.Errorf("code should keep its dollars: %s", got)
|
|
}
|
|
}
|