Files

120 lines
3.6 KiB
Go

package atspi
import (
"context"
"errors"
"strings"
"testing"
"unicode/utf8"
)
func TestBrailleCaptureKeepsTruncatedUnicodeOrigin(t *testing.T) {
raw := strings.Repeat("猫", 2000) + " é"
var snapshot Snapshot
captureBrailleLine(&snapshot, raw, raw[:len(raw)-len("é")], 19)
removed := utf8.RuneCountInString(raw) - utf8.RuneCountInString(snapshot.BrailleLine)
if snapshot.BrailleLineStart != 19+removed || snapshot.BrailleCaret != 2021 || !strings.HasSuffix(snapshot.BrailleLine, " é") {
t.Fatalf("origin=%d caret=%d", snapshot.BrailleLineStart, snapshot.BrailleCaret)
}
}
func TestBrailleRouteRejectsChangedLineAndFocus(t *testing.T) {
s := NewSnapshot("/entry", "Message", "entry", "", "é猫")
s.BusName, s.TextCaretKnown = ":1.42", true
s.StatesKnown, s.Focused = true, true
captureBrailleLine(&s, "é猫", "é", 12)
route := BrailleRoute{Focus: s.ID(), Line: "é猫", Start: 12, Offset: 14}
if !validBrailleRoute(s, route) {
t.Fatal("valid EOL route rejected")
}
for _, change := range []func(*Snapshot){
func(s *Snapshot) { s.BusName = ":1.43" },
func(s *Snapshot) { s.Path = "/other" },
func(s *Snapshot) { s.BrailleLine = "ab" },
func(s *Snapshot) { s.BrailleLineStart++ },
func(s *Snapshot) { s.Defunct = true },
func(s *Snapshot) { s.Focused = false },
func(s *Snapshot) { s.StatesKnown = false },
func(s *Snapshot) { s.Role = "password text" },
func(s *Snapshot) { s.TextCaretKnown = false },
} {
changed := s
change(&changed)
if validBrailleRoute(changed, route) {
t.Fatalf("accepted stale/protected route %+v", changed)
}
}
for _, offset := range []int{-1, 11, 15} {
route.Offset = offset
if validBrailleRoute(s, route) {
t.Fatalf("accepted offset %d", offset)
}
}
}
func assertNativeBrailleRouting(t *testing.T, ctx context.Context, adapter *Adapter) {
t.Helper()
wait := func(name string, offset int) Snapshot {
t.Helper()
for {
select {
case e := <-adapter.Events():
if e.Source.Name != name {
continue
}
if offset < 0 && (e.Type == FocusEvent || e.Type == FocusedStateEvent && e.Detail1 == 1) {
return e.Source
}
if offset >= 0 && e.Type == CaretEvent && e.Source.BrailleCaret == offset {
return e.Source
}
case <-ctx.Done():
t.Fatalf("missing native braille event for %s offset %d", name, offset)
}
}
}
pressTreeProbeKey(t, "F6")
s := wait("Caret review probe", -1)
if !s.TextCaretKnown || s.BrailleLine != "Caret 猫 text" {
t.Fatalf("native braille snapshot %+v", s)
}
route := BrailleRoute{Focus: s.ID(), Line: s.BrailleLine, Start: s.BrailleLineStart}
for _, offset := range []int{1, 6, 7, 12, 6} {
route.Offset = offset
if err := adapter.RouteBraille(ctx, route); err != nil {
t.Fatalf("route offset %d: %v", offset, err)
}
wait("Caret review probe", offset)
}
waitLine := func(line string) {
t.Helper()
for {
select {
case event := <-adapter.Events():
if event.Source.ID() == s.ID() && event.Source.BrailleLine == line {
return
}
case <-ctx.Done():
t.Fatal("edited braille line was not captured")
}
}
}
pressTreeProbeKey(t, "z")
waitLine("Caret z猫 text")
if err := adapter.RouteBraille(ctx, route); !errors.Is(err, ErrStaleObject) {
t.Fatalf("stale text route: %v", err)
}
pressTreeProbeKey(t, "BackSpace")
waitLine("Caret 猫 text")
pressTreeProbeKey(t, "F7")
secret := wait("Protected text probe", -1)
if secret.TextCaretKnown || secret.BrailleLine != "" {
t.Fatal("captured protected braille text")
}
if err := adapter.RouteBraille(ctx, route); !errors.Is(err, ErrStaleObject) {
t.Fatalf("old focus route: %v", err)
}
pressTreeProbeKey(t, "F8")
wait("Numeric value probe", -1)
}