v0.6.0 43c5a7c

bidi_test.go RawHistoryFolder

1package bidi
2
3import (
4	"log"
5	"testing"
6)
7
8type runInformation struct {
9	str   string
10	dir   Direction
11	start int
12	end   int
13}
14
15func TestSimple(t *testing.T) {
16	str := "Hellö"
17	p := Paragraph{}
18	p.SetString(str)
19	order, err := p.Order()
20	if err != nil {
21		log.Fatal(err)
22	}
23	expectedRuns := []runInformation{
24		{"Hellö", LeftToRight, 0, 4},
25	}
26
27	if !p.IsLeftToRight() {
28		t.Error("p.IsLeftToRight() == false; want true")
29	}
30	if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
31		t.Errorf("order.NumRuns() = %d; want %d", nr, want)
32	}
33	for i, want := range expectedRuns {
34		r := order.Run(i)
35		if got := r.String(); got != want.str {
36			t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
37		}
38		if s, e := r.Pos(); s != want.start || e != want.end {
39			t.Errorf("Run(%d).start = %d, .end = %d; want start %d, end %d", i, s, e, want.start, want.end)
40		}
41		if d := r.Direction(); d != want.dir {
42			t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
43		}
44	}
45}
46
47func TestMixed(t *testing.T) {
48	str := `العاشر ليونيكود (Unicode Conference)، الذي سيعقد في 10-12 آذار 1997 مبدينة`
49	p := Paragraph{}
50	p.SetString(str)
51	order, err := p.Order()
52	if err != nil {
53		log.Fatal(err)
54	}
55	if p.IsLeftToRight() {
56		t.Error("p.IsLeftToRight() == true; want false")
57	}
58
59	expectedRuns := []runInformation{
60		{"العاشر ليونيكود (", RightToLeft, 0, 16},
61		{"Unicode Conference", LeftToRight, 17, 34},
62		{")، الذي سيعقد في ", RightToLeft, 35, 51},
63		{"10", LeftToRight, 52, 53},
64		{"-", RightToLeft, 54, 54},
65		{"12", LeftToRight, 55, 56},
66		{" آذار ", RightToLeft, 57, 62},
67		{"1997", LeftToRight, 63, 66},
68		{" مبدينة", RightToLeft, 67, 73},
69	}
70
71	if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
72		t.Errorf("order.NumRuns() = %d; want %d", nr, want)
73	}
74
75	for i, want := range expectedRuns {
76		r := order.Run(i)
77		if got := r.String(); got != want.str {
78			t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
79		}
80		if s, e := r.Pos(); s != want.start || e != want.end {
81			t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
82		}
83		if d := r.Direction(); d != want.dir {
84			t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
85		}
86	}
87}
88
89func TestExplicitIsolate(t *testing.T) {
90	// https://www.w3.org/International/articles/inline-bidi-markup/uba-basics.en#beyond
91	str := "The names of these states in Arabic are \u2067مصر\u2069, \u2067البحرين\u2069 and \u2067الكويت\u2069 respectively."
92	p := Paragraph{}
93	p.SetString(str)
94	order, err := p.Order()
95	if err != nil {
96		log.Fatal(err)
97	}
98	if !p.IsLeftToRight() {
99		t.Error("p.IsLeftToRight() == false; want true")
100	}
101
102	expectedRuns := []runInformation{
103		{"The names of these states in Arabic are \u2067", LeftToRight, 0, 40},
104		{"مصر", RightToLeft, 41, 43},
105		{"\u2069, \u2067", LeftToRight, 44, 47},
106		{"البحرين", RightToLeft, 48, 54},
107		{"\u2069 and \u2067", LeftToRight, 55, 61},
108		{"الكويت", RightToLeft, 62, 67},
109		{"\u2069 respectively.", LeftToRight, 68, 82},
110	}
111
112	if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
113		t.Errorf("order.NumRuns() = %d; want %d", nr, want)
114	}
115
116	for i, want := range expectedRuns {
117		r := order.Run(i)
118		if got := r.String(); got != want.str {
119			t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
120		}
121		if s, e := r.Pos(); s != want.start || e != want.end {
122			t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
123		}
124		if d := r.Direction(); d != want.dir {
125			t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
126		}
127	}
128}
129
130func TestWithoutExplicitIsolate(t *testing.T) {
131	str := "The names of these states in Arabic are مصر, البحرين and الكويت respectively."
132	p := Paragraph{}
133	p.SetString(str)
134	order, err := p.Order()
135	if err != nil {
136		log.Fatal(err)
137	}
138	if !p.IsLeftToRight() {
139		t.Error("p.IsLeftToRight() == false; want true")
140	}
141
142	expectedRuns := []runInformation{
143		{"The names of these states in Arabic are ", LeftToRight, 0, 39},
144		{"مصر, البحرين", RightToLeft, 40, 51},
145		{" and ", LeftToRight, 52, 56},
146		{"الكويت", RightToLeft, 57, 62},
147		{" respectively.", LeftToRight, 63, 76},
148	}
149
150	if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
151		t.Errorf("order.NumRuns() = %d; want %d", nr, want)
152	}
153
154	for i, want := range expectedRuns {
155		r := order.Run(i)
156		if got := r.String(); got != want.str {
157			t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
158		}
159		if s, e := r.Pos(); s != want.start || e != want.end {
160			t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
161		}
162		if d := r.Direction(); d != want.dir {
163			t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
164		}
165	}
166}
167
168func TestLongUTF8(t *testing.T) {
169	str := `𠀀`
170	p := Paragraph{}
171	p.SetString(str)
172	order, err := p.Order()
173	if err != nil {
174		log.Fatal(err)
175	}
176	if !p.IsLeftToRight() {
177		t.Error("p.IsLeftToRight() == false; want true")
178	}
179
180	expectedRuns := []runInformation{
181		{"𠀀", LeftToRight, 0, 0},
182	}
183
184	if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
185		t.Errorf("order.NumRuns() = %d; want %d", nr, want)
186	}
187
188	for i, want := range expectedRuns {
189		r := order.Run(i)
190		if got := r.String(); got != want.str {
191			t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
192		}
193		if s, e := r.Pos(); s != want.start || e != want.end {
194			t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
195		}
196		if d := r.Direction(); d != want.dir {
197			t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
198		}
199	}
200}
201
202func TestLLongUTF8(t *testing.T) {
203	strTester := []struct {
204		str string
205		l   int
206	}{
207		{"ö", 2},
208		{"ॡ", 3},
209		{`𠀀`, 4},
210	}
211	for _, st := range strTester {
212		str := st.str
213		want := st.l
214		if _, l := LookupString(str); l != want {
215			t.Errorf("LookupString(%q) length = %d; want %d", str, l, want)
216		}
217
218	}
219
220}
221
222func TestMixedSimple(t *testing.T) {
223	str := `Uا`
224	p := Paragraph{}
225	p.SetString(str)
226	order, err := p.Order()
227	if err != nil {
228		log.Fatal(err)
229	}
230	if !p.IsLeftToRight() {
231		t.Error("p.IsLeftToRight() == false; want true")
232	}
233
234	expectedRuns := []runInformation{
235		{"U", LeftToRight, 0, 0},
236		{"ا", RightToLeft, 1, 1},
237	}
238
239	if nr, want := order.NumRuns(), len(expectedRuns); nr != want {
240		t.Errorf("order.NumRuns() = %d; want %d", nr, want)
241	}
242
243	for i, want := range expectedRuns {
244		r := order.Run(i)
245		if got := r.String(); got != want.str {
246			t.Errorf("Run(%d) = %q; want %q", i, got, want.str)
247		}
248		if s, e := r.Pos(); s != want.start || e != want.end {
249			t.Errorf("Run(%d).start = %d, .end = %d; want start = %d, end = %d", i, s, e, want.start, want.end)
250		}
251		if d := r.Direction(); d != want.dir {
252			t.Errorf("Run(%d).Direction = %d; want %d", i, d, want.dir)
253		}
254	}
255}
256
257func TestDefaultDirection(t *testing.T) {
258	str := "+"
259	p := Paragraph{}
260	p.SetString(str, DefaultDirection(RightToLeft))
261	_, err := p.Order()
262	if err != nil {
263		t.Error(err)
264		t.Fail()
265	}
266	if want, dir := false, p.IsLeftToRight(); want != dir {
267		t.Errorf("p.IsLeftToRight() = %t; want %t", dir, want)
268	}
269	p.SetString(str, DefaultDirection(LeftToRight))
270	_, err = p.Order()
271	if err != nil {
272		t.Error(err)
273		t.Fail()
274	}
275	if want, dir := true, p.IsLeftToRight(); want != dir {
276		t.Errorf("p.IsLeftToRight() = %t; want %t", dir, want)
277	}
278
279}
280
281func TestEmpty(t *testing.T) {
282	p := Paragraph{}
283	p.SetBytes([]byte{})
284	o, err := p.Order()
285	if err != nil {
286		t.Error("p.Order() return err != nil; want err == nil")
287	}
288	if nr := o.NumRuns(); nr != 0 {
289		t.Errorf("o.NumRuns() = %d; want 0", nr)
290	}
291}
292
293func TestNewline(t *testing.T) {
294	str := "Hello\nworld"
295	p := Paragraph{}
296	n, err := p.SetString(str)
297	if err != nil {
298		t.Error(err)
299	}
300	// 6 is the length up to and including the \n
301	if want := 6; n != want {
302		t.Errorf("SetString(%q) = nil, %d; want nil, %d", str, n, want)
303	}
304}
305
306func TestDoubleSetString(t *testing.T) {
307	str := "العاشر ليونيكود (Unicode Conference)،"
308	p := Paragraph{}
309	_, err := p.SetString(str)
310	if err != nil {
311		t.Error(err)
312	}
313	_, err = p.SetString(str)
314	if err != nil {
315		t.Error(err)
316	}
317	_, err = p.Order()
318	if err != nil {
319		t.Error(err)
320	}
321}
322
323func TestReverseString(t *testing.T) {
324	input := "(Hello)"
325	want := "(olleH)"
326	if str := ReverseString(input); str != want {
327		t.Errorf("ReverseString(%s) = %q; want %q", input, str, want)
328	}
329}
330
331func TestAppendReverse(t *testing.T) {
332	testcase := []struct {
333		inString  string
334		outString string
335		want      string
336	}{
337		{"", "Hëllo", "Hëllo"},
338		{"nice (wörld)", "", "(dlröw) ecin"},
339		{"nice (wörld)", "Hëllo", "Hëllo(dlröw) ecin"},
340	}
341	for _, tc := range testcase {
342		if r := AppendReverse([]byte(tc.outString), []byte(tc.inString)); string(r) != tc.want {
343			t.Errorf("AppendReverse([]byte(%q), []byte(%q) = %q; want %q", tc.outString, tc.inString, string(r), tc.want)
344		}
345	}
346
347}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 1

Tags 12

↑↓ moveenter openesc close