Some echo tests added.
This commit is contained in:
1 parent
8a32895457
commit
eb5b2038d6
38 files changed
+1739
-31
No files matched your search
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) 2026 Storm Dragon
|
||||
// Authors: Storm Dragon, Angus Kola
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
package app
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"git.stormux.org/storm/cthulhu/internal/atspi"
|
||||
"git.stormux.org/storm/cthulhu/internal/config"
|
||||
)
|
||||
|
||||
func TestNativeTypingEchoLineSplit(t *testing.T) {
|
||||
if os.Getenv("CTHULHU_NATIVE_TYPING_ECHO") != "1" {
|
||||
t.Skip("requires native_test_session.py private GTK session")
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(t.Context(), 20*time.Second)
|
||||
defer cancel()
|
||||
adapter := atspi.New()
|
||||
if err := adapter.Start(ctx); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer adapter.Stop(context.Background())
|
||||
previousBus := ""
|
||||
for _, mode := range []string{"word", "sentence"} {
|
||||
for _, offset := range []string{"5", "0"} {
|
||||
t.Run(mode+"/offset="+offset, func(t *testing.T) {
|
||||
fixture := exec.CommandContext(ctx, "/usr/bin/python3", filepath.Join("..", "..", "tests", "gtk_typing_echo.py"), offset)
|
||||
output, err := fixture.StdoutPipe()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fixture.Stderr = os.Stderr
|
||||
if err := fixture.Start(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { fixture.Process.Kill(); fixture.Wait() }()
|
||||
if line, err := bufio.NewReader(output).ReadString('\n'); err != nil || line != "READY\n" {
|
||||
t.Fatalf("GTK fixture readiness: %q %v", line, err)
|
||||
}
|
||||
keys := func(args ...string) {
|
||||
t.Helper()
|
||||
if out, err := exec.CommandContext(ctx, "xdotool", args...).CombinedOutput(); err != nil {
|
||||
t.Fatalf("xdotool: %v: %s", err, out)
|
||||
}
|
||||
}
|
||||
keys("search", "--sync", "--onlyvisible", "--pid", strconv.Itoa(fixture.Process.Pid), "--name", "^Typing echo probe$", "windowfocus", "--sync")
|
||||
var focus atspi.Event
|
||||
for focus.Source.Name != "Echo editor" || focus.Source.BusName == previousBus || !isFocusGainEvent(focus) {
|
||||
select {
|
||||
case focus = <-adapter.Events():
|
||||
case <-ctx.Done():
|
||||
t.Fatal(ctx.Err())
|
||||
}
|
||||
}
|
||||
previousBus = focus.Source.BusName
|
||||
want := "Hello"
|
||||
if offset == "0" {
|
||||
want = ""
|
||||
}
|
||||
if !focus.Source.TextCaretKnown || focus.Source.TextBeforeCaret != want {
|
||||
t.Fatalf("initial native caret context: %+v", focus.Source)
|
||||
}
|
||||
settings := config.DefaultSettings()
|
||||
settings.EnableEchoByWord = mode == "word"
|
||||
settings.EnableEchoBySentence = mode == "sentence"
|
||||
live := &liveSettings{}
|
||||
live.Store(settings)
|
||||
queue := &remoteSpeechQueue{}
|
||||
presenter := eventPresenter{state: &eventLoopState{}, live: live, speech: queue, logger: slog.New(slog.DiscardHandler)}
|
||||
presenter.speak(focus)
|
||||
queue.requests = nil
|
||||
keys("key", "--clearmodifiers", "Return")
|
||||
for {
|
||||
select {
|
||||
case event := <-adapter.Events():
|
||||
if event.Source.ID() != focus.Source.ID() || event.Type != atspi.TextInsertedEvent || event.Payload != "\n" {
|
||||
continue
|
||||
}
|
||||
presenter.speak(event)
|
||||
if want == "" {
|
||||
if len(queue.requests) != 0 {
|
||||
t.Fatalf("start of line echoed following text: %+v", queue.requests)
|
||||
}
|
||||
} else if len(queue.requests) != 1 || queue.requests[0].Text != want {
|
||||
t.Fatalf("line split echo=%+v, want %q; native line=%q before=%q", queue.requests, want, event.Source.Text, event.Source.TextBeforeCaret)
|
||||
}
|
||||
return
|
||||
case <-ctx.Done():
|
||||
t.Fatal(ctx.Err())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user