v0.6.1 aa12db3

conformance_test.go RawHistoryFolder

1package bidi
2
3import (
4	"bufio"
5	"fmt"
6	"os"
7	"reflect"
8	"strconv"
9	"strings"
10	"testing"
11)
12
13// nefergui: verify pinned Unicode 17 BidiCharacterTest paragraph level, L1
14// character levels and L2 visual order against the full upstream corpus.
15func TestBidiCharacterConformance(t *testing.T) {
16	f, err := os.Open("testdata/BidiCharacterTest.txt")
17	if err != nil {
18		t.Fatal(err)
19	}
20	defer f.Close()
21	scan := bufio.NewScanner(f)
22	scan.Buffer(make([]byte, 4096), 2<<20)
23	lineNo, failures, cases := 0, 0, 0
24	for scan.Scan() {
25		lineNo++
26		s := strings.TrimSpace(scan.Text())
27		if s == "" || s[0] == '#' {
28			continue
29		}
30		parts := strings.Split(s, ";")
31		if len(parts) != 5 {
32			t.Fatalf("line %d: fields %d", lineNo, len(parts))
33		}
34		text := make([]rune, 0)
35		for _, hex := range strings.Fields(parts[0]) {
36			n, e := strconv.ParseUint(hex, 16, 32)
37			if e != nil {
38				t.Fatal(e)
39			}
40			text = append(text, rune(n))
41		}
42		mode, e := strconv.Atoi(parts[1])
43		if e != nil || mode < 0 || mode > 2 {
44			t.Fatalf("line %d: base %q", lineNo, parts[1])
45		}
46		base := Auto
47		if mode == 0 {
48			base = LTR
49		} else if mode == 1 {
50			base = RTL
51		}
52		breaks := []int{len(text)}
53		levels, para, e := Resolve(text, base, breaks)
54		if e != nil {
55			t.Fatalf("line %d: %v", lineNo, e)
56		}
57		expectedPara, e := strconv.Atoi(parts[2])
58		if e != nil {
59			t.Fatal(e)
60		}
61		var expectedLevels []uint8
62		for _, token := range strings.Fields(parts[3]) {
63			if token == "x" {
64				expectedLevels = append(expectedLevels, 255)
65				continue
66			}
67			n, e := strconv.Atoi(token)
68			if e != nil {
69				t.Fatal(e)
70			}
71			expectedLevels = append(expectedLevels, uint8(n))
72		}
73		order, e := Reorder(text, levels, breaks)
74		if e != nil {
75			t.Fatal(e)
76		}
77		var expectedOrder []int
78		for _, token := range strings.Fields(parts[4]) {
79			n, e := strconv.Atoi(token)
80			if e != nil {
81				t.Fatal(e)
82			}
83			expectedOrder = append(expectedOrder, n)
84		}
85		if len(expectedOrder) == 0 {
86			expectedOrder = []int{}
87		}
88		if len(order) != 1 {
89			t.Fatal("missing line")
90		}
91		if int(para) != expectedPara || len(levels) != len(expectedLevels) || !reflect.DeepEqual(order[0], expectedOrder) || !matchLevels(text, levels, expectedLevels) {
92			failures++
93			if failures <= 10 {
94				t.Errorf("line %d: para %d/%d levels %v/%v order %v/%v", lineNo, para, expectedPara, levels, expectedLevels, order[0], expectedOrder)
95			}
96		}
97		cases++
98	}
99	if err := scan.Err(); err != nil {
100		t.Fatal(err)
101	}
102	if failures > 0 {
103		t.Fatalf("%d/%d conformance failures", failures, cases)
104	}
105	t.Logf("%d Unicode 17 BidiCharacterTest cases", cases)
106}
107func matchLevels(text []rune, got, want []uint8) bool {
108	if len(got) != len(want) {
109		return false
110	}
111	for i, n := range want {
112		if n == 255 {
113			p, _ := LookupRune(text[i])
114			if !isRemovedByX9(p.Class()) {
115				panic(fmt.Sprintf("non-X9 x at %d", i))
116			}
117			continue
118		}
119		if got[i] != n {
120			return false
121		}
122	}
123	return true
124}

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