141 lines
4.4 KiB
Go
141 lines
4.4 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 app
|
|
|
|
import "testing"
|
|
|
|
type remoteSpeechQueue struct {
|
|
requests []speechRequest
|
|
interrupts int
|
|
}
|
|
|
|
type remoteBrailleQueue struct {
|
|
running bool
|
|
text []string
|
|
}
|
|
|
|
func (queue *remoteBrailleQueue) EnqueueMessage(text string) bool {
|
|
if !queue.running {
|
|
return false
|
|
}
|
|
queue.text = append(queue.text, text)
|
|
return true
|
|
}
|
|
|
|
func TestRemoteBrailleMessage(t *testing.T) {
|
|
queue := &remoteBrailleQueue{}
|
|
presenter := remoteSpeech{braille: queue}
|
|
if presenter.BrailleMessage("Unavailable") || len(queue.text) != 0 {
|
|
t.Fatal("message accepted while braille is stopped")
|
|
}
|
|
queue.running = true
|
|
if !presenter.BrailleMessage("Braille") || len(queue.text) != 1 || queue.text[0] != "Braille" {
|
|
t.Fatalf("braille message was not queued: %v", queue.text)
|
|
}
|
|
if presenter.BrailleMessage("") {
|
|
t.Fatal("empty message accepted")
|
|
}
|
|
}
|
|
|
|
func TestRemotePresentMessageUsesSpeechAndBraille(t *testing.T) {
|
|
speech := &remoteSpeechQueue{}
|
|
braille := &remoteBrailleQueue{running: true}
|
|
presenter := remoteSpeech{speech: speech, braille: braille}
|
|
if !presenter.PresentMessage("Status") || len(speech.requests) != 1 ||
|
|
len(braille.text) != 1 || braille.text[0] != "Status" {
|
|
t.Fatalf("present message: speech=%v braille=%v", speech.requests, braille.text)
|
|
}
|
|
if !(remoteSpeech{braille: braille}).PresentMessage("Braille only") {
|
|
t.Fatal("braille-only presentation rejected")
|
|
}
|
|
}
|
|
|
|
func TestWineMessageKeepsSourcePrivateInSpeechRequest(t *testing.T) {
|
|
speech := &remoteSpeechQueue{}
|
|
presenter := remoteSpeech{speech: speech}
|
|
if !presenter.presentMessage("Game control", "wine-accessible-event") {
|
|
t.Fatal("Wine presentation rejected")
|
|
}
|
|
if len(speech.requests) != 1 || speech.requests[0].Cause != "wine-accessible-event" {
|
|
t.Fatalf("speech requests = %+v", speech.requests)
|
|
}
|
|
}
|
|
|
|
func (queue *remoteSpeechQueue) Enqueue(request speechRequest) {
|
|
queue.requests = append(queue.requests, request)
|
|
}
|
|
|
|
func (queue *remoteSpeechQueue) Interrupt() {
|
|
queue.interrupts++
|
|
}
|
|
|
|
func TestRemoteSpeechQueuesWithoutInterruptingByDefault(t *testing.T) {
|
|
queue := &remoteSpeechQueue{}
|
|
presenter := remoteSpeech{speech: queue}
|
|
if !presenter.PresentMessage("Status") {
|
|
t.Fatal("PresentMessage rejected available speech")
|
|
}
|
|
if !presenter.SpeakText("Queued", false) {
|
|
t.Fatal("SpeakText rejected available speech")
|
|
}
|
|
if queue.interrupts != 0 {
|
|
t.Fatalf("interrupts = %d, want 0", queue.interrupts)
|
|
}
|
|
if len(queue.requests) != 2 {
|
|
t.Fatalf("requests = %d, want 2", len(queue.requests))
|
|
}
|
|
for index, request := range queue.requests {
|
|
if !request.Append {
|
|
t.Fatalf("request %d was not queued as append speech", index)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestRemoteSpeechInterruptsBeforeRequestedSpeech(t *testing.T) {
|
|
queue := &remoteSpeechQueue{}
|
|
presenter := remoteSpeech{speech: queue}
|
|
if !presenter.SpeakText("Now", true) {
|
|
t.Fatal("SpeakText rejected available speech")
|
|
}
|
|
if queue.interrupts != 1 {
|
|
t.Fatalf("interrupts = %d, want 1", queue.interrupts)
|
|
}
|
|
if len(queue.requests) != 1 || queue.requests[0].Text != "Now" || !queue.requests[0].Append {
|
|
t.Fatalf("request = %+v, want queued Now speech", queue.requests)
|
|
}
|
|
}
|
|
|
|
func TestRemoteSpeechCancellationAndUnavailableBraille(t *testing.T) {
|
|
queue := &remoteSpeechQueue{}
|
|
presenter := remoteSpeech{speech: queue}
|
|
if !presenter.CancelSpeech() {
|
|
t.Fatal("CancelSpeech rejected available speech")
|
|
}
|
|
if queue.interrupts != 1 {
|
|
t.Fatalf("interrupts = %d, want 1", queue.interrupts)
|
|
}
|
|
if presenter.BrailleMessage("Braille") {
|
|
t.Fatal("BrailleMessage succeeded without a braille backend")
|
|
}
|
|
|
|
unavailable := remoteSpeech{}
|
|
if unavailable.PresentMessage("Status") || unavailable.SpeakText("Text", false) || unavailable.CancelSpeech() {
|
|
t.Fatal("remote speech succeeded without a speech worker")
|
|
}
|
|
}
|