FILE / ScuroNeko/Laniakea

tgrich/ast_test.go

Исходный файл и его история в репозитории.
FILE dev
Files
ScuroNeko f03a081ed6
Golang lint / lint (pull_request) Successful in 1m20s
Golang lint / lint (push) Successful in 4m8s
(new): rich message support
(fix): runtime reliability
(tests): regression coverage
(doc): v1.1 release notes
2026-08-12 16:34:44 +03:00

113 lines
2.9 KiB
Go

package tgrich
import (
"errors"
"testing"
"time"
"git.scuroneko.dev/scuroneko/laniakea/tgapi"
)
func TestRenderText(t *testing.T) {
tests := []struct {
name string
text tgapi.RichText
want string
}{
{"plain", Text("<text&>"), "&lt;text&amp;&gt;"},
{"array", Concat(Bold(Text("bold")), Text(" plain")), "<b>bold</b> plain"},
{"spoiler", Spoiler(Text("secret")), "<tg-spoiler>secret</tg-spoiler>"},
{"date time", DateTimeWithFormat(Text("tomorrow"), time.Unix(1, 0), `w"DT`), `<tg-time unix="1" format="w&quot;DT">tomorrow</tg-time>`},
{"custom emoji", Emoji("🙂", `id"`), `<tg-emoji emoji-id="id&quot;">🙂</tg-emoji>`},
{"formula", MathExpression("x < y"), "<tg-math>x &lt; y</tg-math>"},
{"automatic entity", Hashtag(Text("#go"), "go"), "#go"},
{"reference", Reference(Text("note"), "note-1"), `<tg-reference name="note-1">note</tg-reference>`},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := renderText(tt.text, 0)
if err != nil {
t.Fatal(err)
}
if got != tt.want {
t.Fatalf("renderText() = %q, want %q", got, tt.want)
}
})
}
}
func TestRenderTextRejectsUnknownWrapper(t *testing.T) {
_, err := renderText(tgapi.RichTextWrap{Tag: "unknown", Text: Text("text")}, 0)
if !errors.Is(err, ErrRichUnknownTag) {
t.Fatalf("renderText() error = %v, want %v", err, ErrRichUnknownTag)
}
}
func TestRenderTextNestingLimit(t *testing.T) {
for _, tt := range []struct {
name string
depth int
want error
}{
{"maximum", maxRichDepth, nil},
{"too deep", maxRichDepth + 1, ErrRichNestingTooDeep},
} {
t.Run(tt.name, func(t *testing.T) {
text := tgapi.RichText(Text("text"))
for range tt.depth {
text = Bold(text)
}
_, err := renderText(text, 0)
if !errors.Is(err, tt.want) {
t.Fatalf("renderText() error = %v, want %v", err, tt.want)
}
})
}
}
func TestRenderBlockNestingLimit(t *testing.T) {
for _, tt := range []struct {
name string
depth int
want error
}{
{"maximum", maxRichDepth, nil},
{"too deep", maxRichDepth + 1, ErrRichNestingTooDeep},
} {
t.Run(tt.name, func(t *testing.T) {
var block tgapi.InputRichBlock = P(Text("text"))
for range tt.depth - 1 {
block = Details(Text("summary"), block)
}
_, err := renderBlockHTML(block, 0)
if !errors.Is(err, tt.want) {
t.Fatalf("renderBlockHTML() error = %v, want %v", err, tt.want)
}
})
}
}
func TestRenderCombinedNestingLimit(t *testing.T) {
for _, tt := range []struct {
name string
textDepth int
want error
}{
{"maximum", maxRichDepth - 1, nil},
{"too deep", maxRichDepth, ErrRichNestingTooDeep},
} {
t.Run(tt.name, func(t *testing.T) {
text := tgapi.RichText(Text("text"))
for range tt.textDepth {
text = Bold(text)
}
_, err := renderBlockHTML(P(text), 0)
if !errors.Is(err, tt.want) {
t.Fatalf("renderBlockHTML() error = %v, want %v", err, tt.want)
}
})
}
}