telegabber/telegram/formatter/formatter_test.go

583 lines
14 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package formatter
import (
"testing"
"github.com/zelenin/go-tdlib/client"
)
func TestNoFormatting(t *testing.T) {
markup := Format("abc\ndef", []*client.TextEntity{}, MarkupModeMarkdown)
if markup != "abc\ndef" {
t.Errorf("No formatting expected, but: %v", markup)
}
}
func TestFormattingSimple(t *testing.T) {
markup := Format("👙🐧🐖", []*client.TextEntity{
&client.TextEntity{
Offset: 2,
Length: 4,
Type: &client.TextEntityTypeBold{},
},
}, MarkupModeMarkdown)
if markup != "👙**🐧🐖**" {
t.Errorf("Wrong simple formatting: %v", markup)
}
}
func TestFormattingAdjacent(t *testing.T) {
markup := Format("a👙🐧🐖", []*client.TextEntity{
&client.TextEntity{
Offset: 3,
Length: 2,
Type: &client.TextEntityTypeItalic{},
},
&client.TextEntity{
Offset: 5,
Length: 2,
Type: &client.TextEntityTypeTextUrl{
Url: "https://narayana.im/",
},
},
}, MarkupModeMarkdown)
if markup != "a👙_🐧_[🐖](https://narayana.im/)" {
t.Errorf("Wrong adjacent formatting: %v", markup)
}
}
func TestFormattingAdjacentAndNested(t *testing.T) {
markup := Format("👙🐧🐖", []*client.TextEntity{
&client.TextEntity{
Offset: 0,
Length: 4,
Type: &client.TextEntityTypePre{},
},
&client.TextEntity{
Offset: 0,
Length: 2,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 4,
Length: 2,
Type: &client.TextEntityTypeItalic{},
},
}, MarkupModeMarkdown)
if markup != "```\n**👙**🐧\n```_🐖_" {
t.Errorf("Wrong adjacent&nested formatting: %v", markup)
}
}
func TestRebalanceTwoZero(t *testing.T) {
s1 := insertionStack{
&insertion{Offset: 7},
&insertion{Offset: 8},
}
s2 := insertionStack{}
s1, s2 = s1.rebalance(s2, 7)
if !(len(s1) == 2 && len(s2) == 0 && s1[0].Offset == 7 && s1[1].Offset == 8) {
t.Errorf("Wrong rebalance 20: %#v %#v", s1, s2)
}
}
func TestRebalanceNeeded(t *testing.T) {
s1 := insertionStack{
&insertion{Offset: 7},
&insertion{Offset: 8},
}
s2 := insertionStack{
&insertion{Offset: 10},
&insertion{Offset: 9},
}
s1, s2 = s1.rebalance(s2, 9)
if !(len(s1) == 3 && len(s2) == 1 &&
s1[0].Offset == 7 && s1[1].Offset == 8 && s1[2].Offset == 9 &&
s2[0].Offset == 10) {
t.Errorf("Wrong rebalance when needed: %#v %#v", s1, s2)
}
}
func TestRebalanceNotNeeded(t *testing.T) {
s1 := insertionStack{
&insertion{Offset: 7},
&insertion{Offset: 8},
}
s2 := insertionStack{
&insertion{Offset: 10},
&insertion{Offset: 9},
}
s1, s2 = s1.rebalance(s2, 8)
if !(len(s1) == 2 && len(s2) == 2 &&
s1[0].Offset == 7 && s1[1].Offset == 8 &&
s2[0].Offset == 10 && s2[1].Offset == 9) {
t.Errorf("Wrong rebalance when not needed: %#v %#v", s1, s2)
}
}
func TestRebalanceLate(t *testing.T) {
s1 := insertionStack{
&insertion{Offset: 7},
&insertion{Offset: 8},
}
s2 := insertionStack{
&insertion{Offset: 10},
&insertion{Offset: 9},
}
s1, s2 = s1.rebalance(s2, 10)
if !(len(s1) == 4 && len(s2) == 0 &&
s1[0].Offset == 7 && s1[1].Offset == 8 &&
s1[2].Offset == 9 && s1[3].Offset == 10) {
t.Errorf("Wrong rebalance when late: %#v %#v", s1, s2)
}
}
func TestIteratorEmpty(t *testing.T) {
s := insertionStack{}
g := s.NewIterator()
v := g()
if v != nil {
t.Errorf("Empty iterator should return nil but returned %#v", v)
}
}
func TestIterator(t *testing.T) {
s := insertionStack{
&insertion{Offset: 7},
&insertion{Offset: 8},
}
g := s.NewIterator()
v := g()
if v == nil || v.Offset != 7 {
t.Errorf("Wrong insertion instead of 7: %#v", v)
}
v = g()
if v == nil || v.Offset != 8 {
t.Errorf("Wrong insertion instead of 8: %#v", v)
}
v = g()
if v != nil {
t.Errorf("nil should be returned after end, %#v instead", v)
}
v = g()
if v != nil {
t.Errorf("Further attempts should return nil too, %#v instead", v)
}
}
func TestSortEntities(t *testing.T) {
entities := []*client.TextEntity{
&client.TextEntity{
Offset: 3,
Length: 2,
},
&client.TextEntity{
Offset: 5,
Length: 2,
},
&client.TextEntity{
Offset: 7,
Length: 2,
},
&client.TextEntity{
Offset: 6,
Length: 1,
},
&client.TextEntity{
Offset: 5,
Length: 1,
},
}
entities = SortEntities(entities)
if !(len(entities) == 5 &&
entities[0].Offset == 3 && entities[0].Length == 2 &&
entities[1].Offset == 5 && entities[1].Length == 2 &&
entities[2].Offset == 5 && entities[2].Length == 1 &&
entities[3].Offset == 6 && entities[3].Length == 1 &&
entities[4].Offset == 7 && entities[4].Length == 2) {
t.Errorf("Wrong sorting order: %#v", entities)
}
}
func TestSortEmpty(t *testing.T) {
entities := []*client.TextEntity{}
entities = SortEntities(entities)
if len(entities) != 0 {
t.Errorf("Empty entities set sorting error: %#v", entities)
}
}
func TestNoFormattingXEP0393(t *testing.T) {
markup := Format("abc\ndef", []*client.TextEntity{}, MarkupModeXEP0393)
if markup != "abc\ndef" {
t.Errorf("No formatting expected, but: %v", markup)
}
}
func TestFormattingXEP0393Simple(t *testing.T) {
markup := Format("👙🐧🐖", []*client.TextEntity{
&client.TextEntity{
Offset: 2,
Length: 4,
Type: &client.TextEntityTypeBold{},
},
}, MarkupModeXEP0393)
if markup != "👙*🐧🐖*" {
t.Errorf("Wrong simple formatting: %v", markup)
}
}
func TestFormattingXEP0393Adjacent(t *testing.T) {
markup := Format("a👙🐧🐖", []*client.TextEntity{
&client.TextEntity{
Offset: 3,
Length: 2,
Type: &client.TextEntityTypeItalic{},
},
&client.TextEntity{
Offset: 5,
Length: 2,
Type: &client.TextEntityTypeTextUrl{
Url: "https://narayana.im/",
},
},
}, MarkupModeXEP0393)
if markup != "a👙_🐧_🐖 <https://narayana.im/>" {
t.Errorf("Wrong adjacent formatting: %v", markup)
}
}
func TestFormattingXEP0393AdjacentAndNested(t *testing.T) {
markup := Format("👙🐧🐖", []*client.TextEntity{
&client.TextEntity{
Offset: 0,
Length: 4,
Type: &client.TextEntityTypePre{},
},
&client.TextEntity{
Offset: 0,
Length: 2,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 4,
Length: 2,
Type: &client.TextEntityTypeItalic{},
},
}, MarkupModeXEP0393)
if markup != "```\n*👙*🐧\n```_🐖_" {
t.Errorf("Wrong adjacent&nested formatting: %v", markup)
}
}
func TestFormattingXEP0393AdjacentItalicBoldItalic(t *testing.T) {
markup := Format("раса двуногих крысолюдей, которую так редко замечают, что многие отрицают само их существование", []*client.TextEntity{
&client.TextEntity{
Offset: 0,
Length: 26,
Type: &client.TextEntityTypeItalic{},
},
&client.TextEntity{
Offset: 26,
Length: 69,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 26,
Length: 69,
Type: &client.TextEntityTypeItalic{},
},
}, MarkupModeXEP0393)
if markup != "_раса двуногих крысолюдей, *которую так редко замечают, что многие отрицают само их существование*_" {
t.Errorf("Wrong adjacent italic/bold-italic formatting: %v", markup)
}
}
func TestFormattingXEP0393MultipleAdjacent(t *testing.T) {
markup := Format("abcde", []*client.TextEntity{
&client.TextEntity{
Offset: 1,
Length: 1,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 2,
Length: 1,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 3,
Length: 1,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 4,
Length: 1,
Type: &client.TextEntityTypeItalic{},
},
}, MarkupModeXEP0393)
if markup != "a*bcd*_e_" {
t.Errorf("Wrong multiple adjacent formatting: %v", markup)
}
}
func TestFormattingXEP0393Intersecting(t *testing.T) {
markup := Format("abcde", []*client.TextEntity{
&client.TextEntity{
Offset: 1,
Length: 1,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 2,
Length: 3,
Type: &client.TextEntityTypeItalic{},
},
&client.TextEntity{
Offset: 2,
Length: 1,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 3,
Length: 1,
Type: &client.TextEntityTypeBold{},
},
}, MarkupModeXEP0393)
if markup != "a*b*_*cd*e_" {
t.Errorf("Wrong intersecting formatting: %v", markup)
}
}
func TestFormattingXEP0393InlineCode(t *testing.T) {
markup := Format("Is Gajim a thing?\n\necho 'Hello'\necho 'world'\n\nhruck(", []*client.TextEntity{
&client.TextEntity{
Offset: 3,
Length: 5,
Type: &client.TextEntityTypeCode{},
},
&client.TextEntity{
Offset: 19,
Length: 25,
Type: &client.TextEntityTypePre{},
},
}, MarkupModeXEP0393)
if markup != "Is `Gajim` a thing?\n\n```\necho 'Hello'\necho 'world'\n```\n\nhruck(" {
t.Errorf("Wrong intersecting formatting: %v", markup)
}
}
func TestFormattingMarkdownStrikethrough(t *testing.T) {
markup := Format("Everyone dislikes cake.", []*client.TextEntity{
&client.TextEntity{
Offset: 9,
Length: 3,
Type: &client.TextEntityTypeStrikethrough{},
},
}, MarkupModeMarkdown)
if markup != "Everyone ~~dis~~likes cake." {
t.Errorf("Wrong strikethrough formatting: %v", markup)
}
}
func TestFormattingXEP0393Strikethrough(t *testing.T) {
markup := Format("Everyone dislikes cake.", []*client.TextEntity{
&client.TextEntity{
Offset: 9,
Length: 3,
Type: &client.TextEntityTypeStrikethrough{},
},
}, MarkupModeXEP0393)
if markup != "Everyone ~dis~likes cake." {
t.Errorf("Wrong strikethrough formatting: %v", markup)
}
}
func TestClaspLeft(t *testing.T) {
text := textToDoubledRunes("a b c")
entities := []*client.TextEntity{
&client.TextEntity{
Offset: 1,
Length: 2,
},
}
entities = ClaspDirectives(text, entities)
if !(len(entities) == 1 &&
entities[0].Offset == 2 && entities[0].Length == 1) {
t.Errorf("Wrong claspleft: %#v", entities)
}
}
func TestClaspBoth(t *testing.T) {
text := textToDoubledRunes("a b c")
entities := []*client.TextEntity{
&client.TextEntity{
Offset: 1,
Length: 3,
},
}
entities = ClaspDirectives(text, entities)
if !(len(entities) == 1 &&
entities[0].Offset == 2 && entities[0].Length == 1) {
t.Errorf("Wrong claspboth: %#v", entities)
}
}
func TestClaspNotNeeded(t *testing.T) {
text := textToDoubledRunes(" abc ")
entities := []*client.TextEntity{
&client.TextEntity{
Offset: 1,
Length: 3,
},
}
entities = ClaspDirectives(text, entities)
if !(len(entities) == 1 &&
entities[0].Offset == 1 && entities[0].Length == 3) {
t.Errorf("Wrong claspnotneeded: %#v", entities)
}
}
func TestClaspNested(t *testing.T) {
text := textToDoubledRunes("a b c")
entities := []*client.TextEntity{
&client.TextEntity{
Offset: 1,
Length: 3,
},
&client.TextEntity{
Offset: 2,
Length: 2,
},
}
entities = ClaspDirectives(text, entities)
if !(len(entities) == 2 &&
entities[0].Offset == 2 && entities[0].Length == 1 &&
entities[1].Offset == 2 && entities[1].Length == 1) {
t.Errorf("Wrong claspnested: %#v", entities)
}
}
func TestClaspEmoji(t *testing.T) {
text := textToDoubledRunes("a 🐖 c")
entities := []*client.TextEntity{
&client.TextEntity{
Offset: 1,
Length: 4,
},
}
entities = ClaspDirectives(text, entities)
if !(len(entities) == 1 &&
entities[0].Offset == 2 && entities[0].Length == 2) {
t.Errorf("Wrong claspemoji: %#v", entities)
}
}
func TestNoNewlineBlockquoteXEP0393(t *testing.T) {
markup := Format("yes it can i think", []*client.TextEntity{
&client.TextEntity{
Offset: 4,
Length: 6,
Type: &client.TextEntityTypeBlockQuote{},
},
}, MarkupModeXEP0393)
if markup != "yes \n> it can\n i think" {
t.Errorf("Wrong blockquote formatting: %v", markup)
}
}
func TestNoNewlineBlockquoteMarkdown(t *testing.T) {
markup := Format("yes it can i think", []*client.TextEntity{
&client.TextEntity{
Offset: 4,
Length: 6,
Type: &client.TextEntityTypeBlockQuote{},
},
}, MarkupModeMarkdown)
if markup != "yes \n> it can\n\n i think" {
t.Errorf("Wrong blockquote formatting: %v", markup)
}
}
func TestMultilineBlockquoteXEP0393(t *testing.T) {
markup := Format("hruck\npuck\n\nshuck\ntext", []*client.TextEntity{
&client.TextEntity{
Offset: 0,
Length: 17,
Type: &client.TextEntityTypeBlockQuote{},
},
}, MarkupModeXEP0393)
if markup != "> hruck\n> puck\n> \n> shuck\ntext" {
t.Errorf("Wrong blockquote formatting: %v", markup)
}
}
func TestMultilineBlockquoteMarkdown(t *testing.T) {
markup := Format("hruck\npuck\n\nshuck\ntext", []*client.TextEntity{
&client.TextEntity{
Offset: 0,
Length: 17,
Type: &client.TextEntityTypeBlockQuote{},
},
}, MarkupModeMarkdown)
if markup != "> hruck\npuck\n\n> shuck\n\ntext" {
t.Errorf("Wrong blockquote formatting: %v", markup)
}
}
func TestMixedBlockquoteXEP0393(t *testing.T) {
markup := Format("hruck\npuck\nshuck\ntext", []*client.TextEntity{
&client.TextEntity{
Offset: 0,
Length: 16,
Type: &client.TextEntityTypeBlockQuote{},
},
&client.TextEntity{
Offset: 0,
Length: 16,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 0,
Length: 10,
Type: &client.TextEntityTypeItalic{},
},
&client.TextEntity{
Offset: 7,
Length: 2,
Type: &client.TextEntityTypeStrikethrough{},
},
}, MarkupModeXEP0393)
if markup != "> *_hruck\n> p~uc~k_\n> shuck*\ntext" {
t.Errorf("Wrong blockquote formatting: %v", markup)
}
}
func TestMixedBlockquoteMarkdown(t *testing.T) {
markup := Format("hruck\npuck\nshuck\ntext", []*client.TextEntity{
&client.TextEntity{
Offset: 0,
Length: 16,
Type: &client.TextEntityTypeBlockQuote{},
},
&client.TextEntity{
Offset: 0,
Length: 16,
Type: &client.TextEntityTypeBold{},
},
&client.TextEntity{
Offset: 0,
Length: 10,
Type: &client.TextEntityTypeItalic{},
},
&client.TextEntity{
Offset: 7,
Length: 2,
Type: &client.TextEntityTypeStrikethrough{},
},
}, MarkupModeMarkdown)
if markup != "> **_hruck\np~~uc~~k_\nshuck**\n\ntext" {
t.Errorf("Wrong blockquote formatting: %v", markup)
}
}