Add opt-in Tentacle protocol 1.1, explicit remote grants, lifecycle IPC and expiring core leases in both SDKs. Revoke access before update preparation, including failed updates. Add transient secret entries, shared Braille cell export and isolated Xorg recovery experiments with focused tests and documented limitations. Production consent, desktop services and live interoperability remain pending.
117 lines
4.2 KiB
Go
117 lines
4.2 KiB
Go
//go:build brlapi && cgo
|
|
|
|
package braille
|
|
|
|
import (
|
|
"bytes"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
// These feasibility checks use real liblouis translation and the helper's
|
|
// viewport, but never construct or open a BrlAPI backend. The two viewports
|
|
// model independently owned local and remote sessions, not a session API.
|
|
func TestVirtualBrailleIndependentWidthsAndRouting(t *testing.T) {
|
|
frame := Frame{ID: 11, Text: "the cat", Cursor: -1, Contract: true,
|
|
Table: "en-us-g2.ctb", WordWrap: true, Dots: []byte{0, 0x40, 0, 0, 0, 0, 0}}
|
|
local, remote := viewport{width: 8}, viewport{width: 4}
|
|
for _, v := range []*viewport{&local, &remote} {
|
|
if err := v.setFrame(frame); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
localCells, err := local.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(localCells, []byte{0x6e, 0, 9, 1, 0x1e, 0, 0, 0}) {
|
|
t.Fatalf("local=%x error=%v", localCells, err)
|
|
}
|
|
remoteCells, err := remote.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(remoteCells, []byte{0x6e, 0, 0, 0}) {
|
|
t.Fatalf("wrapped remote=%x error=%v", remoteCells, err)
|
|
}
|
|
if route, ok := remote.route(RouteBase + 1); !ok || route != (RoutingEvent{ID: 11, Offset: 3}) {
|
|
t.Fatalf("contracted route=%+v ok=%v", route, ok)
|
|
}
|
|
if _, ok := remote.route(RouteBase + 2); ok {
|
|
t.Fatal("wrapped padding routed into hidden text")
|
|
}
|
|
if !remote.pan(PanRight) {
|
|
t.Fatal("remote did not pan")
|
|
}
|
|
panned, err := remote.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(panned, []byte{9, 1, 0x1e, 0}) {
|
|
t.Fatalf("panned=%x error=%v", panned, err)
|
|
}
|
|
if route, ok := remote.route(RouteBase); !ok || route != (RoutingEvent{ID: 11, Offset: 4}) {
|
|
t.Fatalf("panned route=%+v ok=%v", route, ok)
|
|
}
|
|
if !remote.pan(PanLeft) {
|
|
t.Fatal("remote did not pan back")
|
|
}
|
|
restored, err := remote.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(restored, remoteCells) {
|
|
t.Fatalf("restored=%x error=%v", restored, err)
|
|
}
|
|
// A new width gets fresh state. No physical geometry is changed and no
|
|
// old pan offset or routing map is carried across the replacement.
|
|
remote = viewport{width: 2}
|
|
frame.ID = 12
|
|
if err := remote.setFrame(frame); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if route, ok := remote.route(RouteBase); !ok || route.ID != 12 {
|
|
t.Fatal("replacement retained an old frame identity")
|
|
}
|
|
unchanged, err := local.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(unchanged, localCells) || local.offset != 0 || local.width != 8 || local.id != 11 {
|
|
t.Fatal("remote pan/resize altered local viewport")
|
|
}
|
|
}
|
|
|
|
func TestVirtualBrailleCursorUsesTranslatedPosition(t *testing.T) {
|
|
v := viewport{width: 4}
|
|
if err := v.setFrame(Frame{Text: "the cat", Cursor: 4, Contract: true, Table: "en-us-g2.ctb"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cells, err := v.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(cells, []byte{0x2e, 0, 0xc9, 1}) {
|
|
t.Fatalf("translated cursor=%x error=%v", cells, err)
|
|
}
|
|
if !v.pan(PanRight) {
|
|
t.Fatal("did not pan past cursor")
|
|
}
|
|
cells, err = v.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(cells, []byte{0x1e, 0, 0, 0}) {
|
|
t.Fatalf("hidden cursor=%x error=%v", cells, err)
|
|
}
|
|
if err := v.setFrame(Frame{ID: 14, Text: "the cat", Cursor: 7, Contract: true, Table: "en-us-g2.ctb"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cells, err = v.rawCells(0xc0)
|
|
if err != nil || !bytes.Equal(cells, []byte{0x1e, 0xc0, 0, 0}) {
|
|
t.Fatalf("end cursor=%x error=%v", cells, err)
|
|
}
|
|
if route, ok := v.route(RouteBase + 1); !ok || route != (RoutingEvent{ID: 14, Offset: 7}) {
|
|
t.Fatalf("end route=%+v ok=%v", route, ok)
|
|
}
|
|
}
|
|
|
|
func TestVirtualBrailleExplicitComputerTableAndFailure(t *testing.T) {
|
|
v := viewport{width: 4}
|
|
// Contract selects the helper's liblouis path; the table determines whether
|
|
// it contracts. A future virtual-helper API must resolve this distinction.
|
|
if err := v.setFrame(Frame{ID: 15, Text: "cat", Cursor: -1, Contract: true, Table: "en-us-comp8.ctb"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cells, err := v.rawCells(0)
|
|
if err != nil || !bytes.Equal(cells, []byte{9, 1, 0x1e, 0}) {
|
|
t.Fatalf("computer table=%x error=%v", cells, err)
|
|
}
|
|
before := v
|
|
if err := v.setFrame(Frame{Text: "cat", Cursor: -1, Contract: true, Table: "missing-remote-test-table.ctb"}); err == nil {
|
|
t.Fatal("missing table accepted")
|
|
}
|
|
if !reflect.DeepEqual(v, before) {
|
|
t.Fatal("failed translation replaced a valid viewport")
|
|
}
|
|
}
|