(new): rich message support
(fix): runtime reliability (tests): regression coverage (doc): v1.1 release notes
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
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&>"), "<text&>"},
|
||||
{"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"DT">tomorrow</tg-time>`},
|
||||
{"custom emoji", Emoji("🙂", `id"`), `<tg-emoji emoji-id="id"">🙂</tg-emoji>`},
|
||||
{"formula", MathExpression("x < y"), "<tg-math>x < 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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user