// 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 . package app import ( "context" "log/slog" "reflect" "testing" "time" "git.stormux.org/storm/cthulhu/internal/sound" ) func TestOutputQueueUsesSpeechFallbackWhenSoundBatchIsRejected(t *testing.T) { speech := &fakeSpeechQueue{spoken: make(chan string, 1), requests: make(chan speechRequest, 1)} queue := outputQueue{speech: speech, sounds: rejectingSound{}} queue.Enqueue(speechRequest{ Text: "Power", Chunks: []string{"Power"}, FallbackText: "Power, toggle button, pressed", FallbackChunks: []string{"Power", "toggle button", "pressed"}, Sound: []sound.Cue{{Name: "button"}, {Name: "togglebutton_checked"}}, }) speaker := &spellingTestSpeaker{} worker := newSpeechWorker(slog.New(slog.DiscardHandler), speaker) if err := worker.deliver(context.Background(), <-speech.requests); err != nil { t.Fatal(err) } if !reflect.DeepEqual(speaker.parts, []string{"Power", "toggle button", "pressed"}) { t.Fatalf("sound fallback lost its pause chunks: %v", speaker.parts) } select { case got := <-speech.spoken: if got != "Power, toggle button, pressed" { t.Fatalf("fallback speech = %q", got) } case <-time.After(time.Second): t.Fatal("missing rejected-sound fallback speech") } }