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,111 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package presentation
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"git.stormux.org/storm/cthulhu/internal/atspi"
|
||||
"git.stormux.org/storm/cthulhu/internal/config"
|
||||
)
|
||||
|
||||
func TestReadingPreferencesChangeControlOutput(t *testing.T) {
|
||||
reading := config.DefaultSettings().Reading
|
||||
options := DefaultOptions()
|
||||
options.Reading = &reading
|
||||
snapshot := atspi.Snapshot{Name: "Save", Role: "button", Description: "Save document", Mnemonic: "s", PositionInSet: 2, SetSize: 3}
|
||||
reading.EnableMnemonicSpeaking, reading.EnablePositionSpeaking, reading.EnableTutorialMessages = true, true, true
|
||||
text := FocusTextWithOptions(snapshot, options)
|
||||
want := "Save, button, Save document, 2 of 3, s, Press Space to activate."
|
||||
if text != want {
|
||||
t.Fatalf("enabled extras = %q, want %q", text, want)
|
||||
}
|
||||
reading.EnableMnemonicSpeaking, reading.EnablePositionSpeaking, reading.EnableTutorialMessages = false, false, false
|
||||
if got := FocusTextWithOptions(snapshot, options); got != "Save, button, Save document" {
|
||||
t.Fatalf("disabled extras: %q", got)
|
||||
}
|
||||
reading.EnablePauseBreaks = false
|
||||
if got := FocusTextWithOptions(snapshot, options); got != "Save button Save document" {
|
||||
t.Fatalf("pause breaks survived: %q", got)
|
||||
}
|
||||
reading.OnlySpeakDisplayedText = true
|
||||
if got := FocusTextWithOptions(snapshot, options); got != "Save" {
|
||||
t.Fatalf("displayed text: %q", got)
|
||||
}
|
||||
if got := EventTextWithOptions(atspi.NewEvent("object:state-changed:checked", atspi.Snapshot{Role: "check box", Checked: true}), options); got != "" {
|
||||
t.Fatalf("state speech survived displayed-only: %q", got)
|
||||
}
|
||||
reading.OnlySpeakDisplayedText = false
|
||||
line := atspi.DocumentLine{Contents: []atspi.DocumentContent{{Text: "word", Snapshot: atspi.Snapshot{Role: "text", Misspelled: true}}}}
|
||||
if got := DocumentLineTextWithOptions(line, options); got != "word misspelled" {
|
||||
t.Fatalf("misspelling: %q", got)
|
||||
}
|
||||
reading.SpeakMisspelledIndicator = false
|
||||
if got := DocumentLineTextWithOptions(line, options); got != "word" {
|
||||
t.Fatalf("disabled misspelling: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocumentAndSpreadsheetFullRowsUseIndependentFlags(t *testing.T) {
|
||||
reading := config.DefaultSettings().Reading
|
||||
options := DefaultOptions()
|
||||
options.Reading = &reading
|
||||
cell := atspi.Snapshot{Role: "table cell", Name: "Cell one", TableRowText: "Cell one, Cell two"}
|
||||
if got := FocusTextWithOptions(cell, options); got != cell.TableRowText {
|
||||
t.Fatalf("document row = %q", got)
|
||||
}
|
||||
reading.ReadFullRowInDocumentTable = false
|
||||
if got := FocusTextWithOptions(cell, options); got != cell.Name {
|
||||
t.Fatalf("document cell = %q", got)
|
||||
}
|
||||
cell.Spreadsheet = true
|
||||
reading.ReadFullRowInDocumentTable = true
|
||||
if got := FocusTextWithOptions(cell, options); got != cell.Name {
|
||||
t.Fatalf("document flag affected spreadsheet: %q", got)
|
||||
}
|
||||
reading.ReadFullRowInSpreadSheet = true
|
||||
if got := FocusTextWithOptions(cell, options); got != cell.TableRowText {
|
||||
t.Fatalf("spreadsheet row = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDocumentLineReadsEachTableRowOnce(t *testing.T) {
|
||||
line := atspi.DocumentLine{}
|
||||
for _, name := range []string{"One", "Two"} {
|
||||
line.Contents = append(line.Contents, atspi.DocumentContent{Text: name, Snapshot: atspi.Snapshot{
|
||||
BusName: ":1.42", Path: "/" + name, Role: "table cell", TablePath: "/table", TableRowText: "One, Two",
|
||||
}})
|
||||
}
|
||||
if got := DocumentLineText(line); got != "One, Two" {
|
||||
t.Fatalf("repeated row: %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEachNavigationContextHasItsOwnPreference(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
snapshot atspi.Snapshot
|
||||
kind string
|
||||
disable func(*config.ReadingSettings)
|
||||
}{
|
||||
{atspi.Snapshot{Role: "block quote"}, "blockquote", func(r *config.ReadingSettings) { r.SpeakContextBlockquote = false }},
|
||||
{atspi.Snapshot{Role: "list"}, "list", func(r *config.ReadingSettings) { r.SpeakContextList = false }},
|
||||
{atspi.Snapshot{Role: "table"}, "table", func(r *config.ReadingSettings) { r.SpeakContextTable = false }},
|
||||
{atspi.Snapshot{Role: "panel"}, "panel", func(r *config.ReadingSettings) { r.SpeakContextPanel = false }},
|
||||
{atspi.Snapshot{Role: "section", XMLRoles: "navigation"}, "landmark", func(r *config.ReadingSettings) { r.SpeakContextLandmark = false }},
|
||||
{atspi.Snapshot{Role: "form"}, "form", func(r *config.ReadingSettings) { r.SpeakContextNonLandmarkForm = false }},
|
||||
} {
|
||||
reading := config.DefaultSettings().Reading
|
||||
if ContextType(tc.snapshot) != tc.kind || !ContextEnabled(tc.kind, reading) {
|
||||
t.Fatalf("missing context: %+v", tc)
|
||||
}
|
||||
tc.disable(&reading)
|
||||
if ContextEnabled(tc.kind, reading) {
|
||||
t.Fatalf("disabled context: %s", tc.kind)
|
||||
}
|
||||
}
|
||||
if ContextType(atspi.Snapshot{Role: "table", LayoutTable: true}) != "" {
|
||||
t.Fatal("layout table announced")
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user