blob: 88572f5654170c3f61a54f44f756694047f8262c [file] [log] [blame]
package bidi
import (
"log"
"testing"
)
type runInformation struct {
str string
dir Direction
start int
end int
}
func TestSimple(t *testing.T) {
str := "Hellö"
p := Paragraph{}
p.SetString(str)
order, err := p.Order()
if err != nil {
log.Fatal(err)
}
expectedRuns := []runInformation{
{"Hellö", LeftToRight, 0, 4},
}
if !p.IsLeftToRight() {
t.Error("p.IsLeftToRight() == false; want true")
}
if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
t.Errorf("order.NumRuns() = %d; want %d", nr, want)
}
for i, want := range expectedRuns {
r := order.Run(i)
if got := r.String(); got != want.str {
t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
}
if s, e := r.Pos(); s != want.start || e != want.end {
t.Errorf("Run(%d).start = %d, .end = %d; want start %d, end %d", i, s, e, want.start, want.end)
}
if d := r.Direction(); d != want.dir {
t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
}
}
}
func TestMixed(t *testing.T) {
str := `العاشر ليونيكود (Unicode Conference)، الذي سيعقد في 10-12 آذار 1997 مبدينة`
p := Paragraph{}
p.SetString(str)
order, err := p.Order()
if err != nil {
log.Fatal(err)
}
if p.IsLeftToRight() {
t.Error("p.IsLeftToRight() == true; want false")
}
expectedRuns := []runInformation{
{"العاشر ليونيكود (", RightToLeft, 0, 16},
{"Unicode Conference", LeftToRight, 17, 34},
{")، الذي سيعقد في ", RightToLeft, 35, 51},
{"10", LeftToRight, 52, 53},
{"-", RightToLeft, 54, 54},
{"12", LeftToRight, 55, 56},
{" آذار ", RightToLeft, 57, 62},
{"1997", LeftToRight, 63, 66},
{" مبدينة", RightToLeft, 67, 73},
}
if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
t.Errorf("order.NumRuns() = %d; want %d", nr, want)
}
for i, want := range expectedRuns {
r := order.Run(i)
if got := r.String(); got != want.str {
t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
}
if s, e := r.Pos(); s != want.start || e != want.end {
t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
}
if d := r.Direction(); d != want.dir {
t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
}
}
}
func TestExplicitIsolate(t *testing.T) {
// https://www.w3.org/International/articles/inline-bidi-markup/uba-basics.en#beyond
str := "The names of these states in Arabic are \u2067مصر\u2069, \u2067البحرين\u2069 and \u2067الكويت\u2069 respectively."
p := Paragraph{}
p.SetString(str)
order, err := p.Order()
if err != nil {
log.Fatal(err)
}
if !p.IsLeftToRight() {
t.Error("p.IsLeftToRight() == false; want true")
}
expectedRuns := []runInformation{
{"The names of these states in Arabic are \u2067", LeftToRight, 0, 40},
{"مصر", RightToLeft, 41, 43},
{"\u2069, \u2067", LeftToRight, 44, 47},
{"البحرين", RightToLeft, 48, 54},
{"\u2069 and \u2067", LeftToRight, 55, 61},
{"الكويت", RightToLeft, 62, 67},
{"\u2069 respectively.", LeftToRight, 68, 82},
}
if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
t.Errorf("order.NumRuns() = %d; want %d", nr, want)
}
for i, want := range expectedRuns {
r := order.Run(i)
if got := r.String(); got != want.str {
t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
}
if s, e := r.Pos(); s != want.start || e != want.end {
t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
}
if d := r.Direction(); d != want.dir {
t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
}
}
}
func TestWithoutExplicitIsolate(t *testing.T) {
str := "The names of these states in Arabic are مصر, البحرين and الكويت respectively."
p := Paragraph{}
p.SetString(str)
order, err := p.Order()
if err != nil {
log.Fatal(err)
}
if !p.IsLeftToRight() {
t.Error("p.IsLeftToRight() == false; want true")
}
expectedRuns := []runInformation{
{"The names of these states in Arabic are ", LeftToRight, 0, 39},
{"مصر, البحرين", RightToLeft, 40, 51},
{" and ", LeftToRight, 52, 56},
{"الكويت", RightToLeft, 57, 62},
{" respectively.", LeftToRight, 63, 76},
}
if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
t.Errorf("order.NumRuns() = %d; want %d", nr, want)
}
for i, want := range expectedRuns {
r := order.Run(i)
if got := r.String(); got != want.str {
t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
}
if s, e := r.Pos(); s != want.start || e != want.end {
t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
}
if d := r.Direction(); d != want.dir {
t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
}
}
}
func TestLongUTF8(t *testing.T) {
str := `𠀀`
p := Paragraph{}
p.SetString(str)
order, err := p.Order()
if err != nil {
log.Fatal(err)
}
if !p.IsLeftToRight() {
t.Error("p.IsLeftToRight() == false; want true")
}
expectedRuns := []runInformation{
{"𠀀", LeftToRight, 0, 0},
}
if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
t.Errorf("order.NumRuns() = %d; want %d", nr, want)
}
for i, want := range expectedRuns {
r := order.Run(i)
if got := r.String(); got != want.str {
t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
}
if s, e := r.Pos(); s != want.start || e != want.end {
t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
}
if d := r.Direction(); d != want.dir {
t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
}
}
}
func TestLLongUTF8(t *testing.T) {
strTester := []struct {
str string
l int
}{
{"ö", 2},
{"ॡ", 3},
{`𠀀`, 4},
}
for _, st := range strTester {
str := st.str
want := st.l
if _, l := LookupString(str); l != want {
t.Errorf("LookupString(%q) length = %d; want %d", str, l, want)
}
}
}
func TestMixedSimple(t *testing.T) {
str := `Uا`
p := Paragraph{}
p.SetString(str)
order, err := p.Order()
if err != nil {
log.Fatal(err)
}
if !p.IsLeftToRight() {
t.Error("p.IsLeftToRight() == false; want true")
}
expectedRuns := []runInformation{
{"U", LeftToRight, 0, 0},
{"ا", RightToLeft, 1, 1},
}
if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
t.Errorf("order.NumRuns() = %d; want %d", nr, want)
}
for i, want := range expectedRuns {
r := order.Run(i)
if got := r.String(); got != want.str {
t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
}
if s, e := r.Pos(); s != want.start || e != want.end {
t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
}
if d := r.Direction(); d != want.dir {
t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
}
}
}
func TestDefaultDirection(t *testing.T) {
str := "+"
p := Paragraph{}
p.SetString(str, DefaultDirection(RightToLeft))
_, err := p.Order()
if err != nil {
t.Error(err)
t.Fail()
}
if want, dir := false, p.IsLeftToRight(); want != dir {
t.Errorf("p.IsLeftToRight() = %t; want %t", dir, want)
}
p.SetString(str, DefaultDirection(LeftToRight))
_, err = p.Order()
if err != nil {
t.Error(err)
t.Fail()
}
if want, dir := true, p.IsLeftToRight(); want != dir {
t.Errorf("p.IsLeftToRight() = %t; want %t", dir, want)
}
}
func TestEmpty(t *testing.T) {
p := Paragraph{}
p.SetBytes([]byte{})
o, err := p.Order()
if err != nil {
t.Error("p.Order() return err != nil; want err == nil")
}
if nr := o.NumRuns(); nr != 0 {
t.Errorf("o.NumRuns() = %d; want 0", nr)
}
}
func TestNewline(t *testing.T) {
str := "Hello\nworld"
p := Paragraph{}
n, err := p.SetString(str)
if err != nil {
t.Error(err)
}
// 6 is the length up to and including the \n
if want := 6; n != want {
t.Errorf("SetString(%q) = nil, %d; want nil, %d", str, n, want)
}
}
func TestDoubleSetString(t *testing.T) {
str := "العاشر ليونيكود (Unicode Conference)،"
p := Paragraph{}
_, err := p.SetString(str)
if err != nil {
t.Error(err)
}
_, err = p.SetString(str)
if err != nil {
t.Error(err)
}
_, err = p.Order()
if err != nil {
t.Error(err)
}
}
func TestReverseString(t *testing.T) {
input := "(Hello)"
want := "(olleH)"
if str := ReverseString(input); str != want {
t.Errorf("ReverseString(%s) = %q; want %q", input, str, want)
}
}
func TestAppendReverse(t *testing.T) {
testcase := []struct {
inString string
outString string
want string
}{
{"", "Hëllo", "Hëllo"},
{"nice (wörld)", "", "(dlröw) ecin"},
{"nice (wörld)", "Hëllo", "Hëllo(dlröw) ecin"},
}
for _, tc := range testcase {
if r := AppendReverse([]byte(tc.outString), []byte(tc.inString)); string(r) != tc.want {
t.Errorf("AppendReverse([]byte(%q), []byte(%q) = %q; want %q", tc.outString, tc.inString, string(r), tc.want)
}
}
}