126 lines
4.9 KiB
Go
126 lines
4.9 KiB
Go
// Cthulhu screen reader.
|
|
// Copyright (c) 2026 Storm Dragon
|
|
// Authors: Storm Dragon, Angus Kola
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify it
|
|
// under the terms of the GNU General Public License as published by the Free
|
|
// Software Foundation, either version 3 of the License, or (at your option)
|
|
// any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
|
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
// more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along with
|
|
// this program. If not, see <https://www.gnu.org/licenses/gpl-3.0.html>.
|
|
|
|
package presentation
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.stormux.org/storm/cthulhu/internal/atspi"
|
|
)
|
|
|
|
func TestEventTextAppliesPrintableKeyEchoSettings(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
payload string
|
|
update func(*Options)
|
|
want string
|
|
}{
|
|
{name: "alphabetic enabled", payload: "a", want: "a"},
|
|
{name: "alphabetic disabled", payload: "a", update: func(options *Options) { options.EnableAlphabeticKeys = false }},
|
|
{name: "numeric disabled", payload: "7", update: func(options *Options) { options.EnableNumericKeys = false }},
|
|
{name: "punctuation disabled", payload: "!", update: func(options *Options) { options.EnablePunctuationKeys = false }},
|
|
{name: "symbol uses punctuation setting", payload: "€", update: func(options *Options) { options.EnablePunctuationKeys = false }},
|
|
{name: "space enabled", payload: " ", want: "space"},
|
|
{name: "space disabled", payload: " ", update: func(options *Options) { options.EnableSpace = false }},
|
|
{name: "diacritical enabled", payload: "́", update: func(options *Options) { options.EnableDiacriticalKeys = true }, want: "́"},
|
|
{name: "character echo overrides category", payload: "a", update: func(options *Options) {
|
|
options.EnableAlphabeticKeys = false
|
|
options.EnableEchoByCharacter = true
|
|
}, want: "a"},
|
|
{name: "key echo disables character echo", payload: "a", update: func(options *Options) {
|
|
options.EnableKeyEcho = false
|
|
options.EnableEchoByCharacter = true
|
|
}},
|
|
{name: "multi-character insertion is not a key echo", payload: "pasted text", update: func(options *Options) {
|
|
options.EnableKeyEcho = false
|
|
}, want: "pasted text"},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.name, func(t *testing.T) {
|
|
options := DefaultOptions()
|
|
if test.update != nil {
|
|
test.update(&options)
|
|
}
|
|
event := atspi.NewEventWithPayload(
|
|
atspi.TextInsertedEvent,
|
|
atspi.NewSnapshot("/accessible/editor", "", "text", "", ""),
|
|
test.payload,
|
|
)
|
|
if got := EventTextWithOptions(event, options); got != test.want {
|
|
t.Fatalf("EventTextWithOptions() = %q, want %q", got, test.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestSentenceEchoStopsAtPreviousLine(t *testing.T) {
|
|
options := DefaultOptions()
|
|
options.EnableEchoBySentence = true
|
|
for _, context := range []string{"First line\nSecond line. ", "First line\rSecond line. "} {
|
|
event := atspi.NewEvent(atspi.TextInsertedEvent, atspi.Snapshot{TextBeforeCaret: context})
|
|
event.Payload = " "
|
|
if got := TypingEchoText(event, "", options); got != "Second line." {
|
|
t.Fatalf("sentence echo = %q, want only the current sentence", got)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTypingEchoTextAppliesWordAndSentenceSettings(t *testing.T) {
|
|
options := DefaultOptions()
|
|
options.EnableEchoByWord = true
|
|
snapshot := atspi.NewSnapshot("/accessible/editor", "", "text", "", "hello ")
|
|
snapshot.Editable = true
|
|
snapshot.TextBeforeCaret = "hello "
|
|
event := atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, " ")
|
|
if got := TypingEchoText(event, "", options); got != "hello" {
|
|
t.Fatalf("word echo = %q, want hello", got)
|
|
}
|
|
|
|
snapshot.TextBeforeCaret = "hello,"
|
|
event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, ",")
|
|
if got := TypingEchoText(event, "", options); got != "hello" {
|
|
t.Fatalf("punctuation word echo = %q, want hello", got)
|
|
}
|
|
|
|
snapshot.TextBeforeCaret = "hello "
|
|
event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, " ")
|
|
if got := TypingEchoText(event, "", options); got != "space" {
|
|
t.Fatalf("repeated delimiter echo = %q, want space", got)
|
|
}
|
|
|
|
options.EnableEchoBySentence = true
|
|
snapshot.TextBeforeCaret = "First. Second. "
|
|
event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, " ")
|
|
if got := TypingEchoText(event, "", options); got != "Second." {
|
|
t.Fatalf("sentence echo = %q, want Second.", got)
|
|
}
|
|
|
|
snapshot.TextBeforeCaret = ""
|
|
snapshot.Text = ""
|
|
event = atspi.NewEventWithPayload(atspi.TextInsertedEvent, snapshot, "\n")
|
|
if got := TypingEchoText(event, "Line without punctuation", options); got != "Line without punctuation" {
|
|
t.Fatalf("newline sentence echo = %q", got)
|
|
}
|
|
|
|
options.EnableKeyEcho = false
|
|
if got := TypingEchoText(event, "Line without punctuation", options); got != "" {
|
|
t.Fatalf("disabled key echo sentence = %q", got)
|
|
}
|
|
}
|