Cthulhu is no longer a fork. Now it is a screen reader written in Golang.
This commit is contained in:
1 parent
a998fe67de
commit
069fc674dc
708 files changed
+112482
-532
No files matched your search
@@ -0,0 +1,125 @@
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user