2020-01-09 21:16:40 +00:00
|
|
|
|
package formatter
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"testing"
|
|
|
|
|
|
2022-01-17 20:45:40 +00:00
|
|
|
|
"github.com/zelenin/go-tdlib/client"
|
2020-01-09 21:16:40 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func TestNoFormatting(t *testing.T) {
|
|
|
|
|
markup := Format("abc\ndef", []*client.TextEntity{}, EntityToMarkdown)
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToMarkdown)
|
|
|
|
|
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/",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToMarkdown)
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToMarkdown)
|
2022-03-11 17:01:38 +00:00
|
|
|
|
if markup != "```\n**👙**🐧\n```_🐖_" {
|
2020-01-09 21:16:40 +00:00
|
|
|
|
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 2–0: %#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)
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-10 16:25:45 +00:00
|
|
|
|
|
|
|
|
|
func TestNoFormattingXEP0393(t *testing.T) {
|
|
|
|
|
markup := Format("abc\ndef", []*client.TextEntity{}, EntityToXEP0393)
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
|
|
|
|
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/",
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
2022-03-11 17:01:38 +00:00
|
|
|
|
if markup != "```\n*👙*🐧\n```_🐖_" {
|
2022-03-10 16:25:45 +00:00
|
|
|
|
t.Errorf("Wrong adjacent&nested formatting: %v", markup)
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-11 16:12:36 +00:00
|
|
|
|
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
|
|
|
|
if markup != "a*b*_*cd*e_" {
|
|
|
|
|
t.Errorf("Wrong intersecting formatting: %v", markup)
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-11 17:01:38 +00:00
|
|
|
|
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
|
|
|
|
if markup != "Is `Gajim` a thing?\n\n```\necho 'Hello'\necho 'world'\n```\n\nhruck(" {
|
|
|
|
|
t.Errorf("Wrong intersecting formatting: %v", markup)
|
|
|
|
|
}
|
|
|
|
|
}
|
2022-03-11 17:54:03 +00:00
|
|
|
|
|
|
|
|
|
func TestFormattingMarkdownStrikethrough(t *testing.T) {
|
|
|
|
|
markup := Format("Everyone dislikes cake.", []*client.TextEntity{
|
|
|
|
|
&client.TextEntity{
|
|
|
|
|
Offset: 9,
|
|
|
|
|
Length: 3,
|
|
|
|
|
Type: &client.TextEntityTypeStrikethrough{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToMarkdown)
|
|
|
|
|
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{},
|
|
|
|
|
},
|
|
|
|
|
}, EntityToXEP0393)
|
|
|
|
|
if markup != "Everyone ~dis~likes cake." {
|
|
|
|
|
t.Errorf("Wrong strikethrough formatting: %v", markup)
|
|
|
|
|
}
|
|
|
|
|
}
|