100 lines
3.7 KiB
Go
100 lines
3.7 KiB
Go
package app
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"log/slog"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.stormux.org/storm/cthulhu/internal/clipboard"
|
|
"git.stormux.org/storm/cthulhu/internal/config"
|
|
"git.stormux.org/storm/cthulhu/internal/input"
|
|
)
|
|
|
|
func TestAutomaticClipboardQueuesTextAndNormalInputCancels(t *testing.T) {
|
|
live := &liveSettings{}
|
|
settings := config.DefaultSettings()
|
|
if settings.Reading.AutomaticallyReadClipboardChanges {
|
|
t.Fatal("clipboard reading defaults on")
|
|
}
|
|
settings.Reading.AutomaticallyReadClipboardChanges = true
|
|
live.Store(settings)
|
|
worker := newSpeechWorker(slog.New(slog.DiscardHandler), nil)
|
|
worker.running = true // Inspect the real FIFO without a delivery goroutine.
|
|
changes := make(chan clipboard.TextChange, 6)
|
|
changes <- clipboard.TextChange{Text: "First", Epoch: 1, Timestamp: 10}
|
|
changes <- clipboard.TextChange{Text: "Second", Epoch: 1, Timestamp: 20}
|
|
changes <- clipboard.TextChange{Text: "", Epoch: 1, Timestamp: 30}
|
|
changes <- clipboard.TextChange{Text: "Third", Epoch: 1, Timestamp: 40}
|
|
close(changes)
|
|
var output bytes.Buffer
|
|
serve_clipboard_changes(context.Background(), live, nil, worker, json.NewEncoder(&output), changes, nil)
|
|
if len(worker.pending) != 3 {
|
|
t.Fatalf("clipboard queue = %+v", worker.pending)
|
|
}
|
|
for i, want := range []string{"First", "Second", "Third"} {
|
|
if worker.pending[i].Text != want || !worker.pending[i].Append {
|
|
t.Fatalf("clipboard request %d = %+v", i, worker.pending[i])
|
|
}
|
|
}
|
|
if !worker.InterruptForInput(input.Event{Pressed: true, Name: "Control_L", Timestamp: 50}) || len(worker.pending) != 0 {
|
|
t.Fatal("normal input did not clear clipboard queue")
|
|
}
|
|
worker.Enqueue(speechRequest{Text: "Late old clipboard", Cause: "clipboard", Append: true, ClipboardTimestamp: 40})
|
|
if len(worker.pending) != 0 {
|
|
t.Fatal("old asynchronous clipboard reply replayed after interruption")
|
|
}
|
|
worker.Enqueue(speechRequest{Text: "New clipboard", Cause: "clipboard", Append: true, ClipboardTimestamp: 60})
|
|
if len(worker.pending) != 1 {
|
|
t.Fatal("new clipboard change suppressed after interruption")
|
|
}
|
|
worker.Enqueue(speechRequest{Text: "Same millisecond copy", Cause: "clipboard", Append: true, ClipboardTimestamp: 50})
|
|
if len(worker.pending) != 2 {
|
|
t.Fatal("copy result in same server millisecond as input was suppressed")
|
|
}
|
|
}
|
|
|
|
func TestAutomaticClipboardRejectsDisabledAndStaleApplications(t *testing.T) {
|
|
for _, tc := range []struct {
|
|
name string
|
|
enabled, pending bool
|
|
}{
|
|
{"disabled", false, false}, {"switching", true, true}, {"stale epoch", true, false},
|
|
} {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
live := &liveSettings{}
|
|
settings := config.DefaultSettings()
|
|
settings.Reading.AutomaticallyReadClipboardChanges = tc.enabled
|
|
live.Store(settings)
|
|
if tc.pending {
|
|
name := "Other Application"
|
|
live.requestedApplication.Store(&name)
|
|
}
|
|
changes := make(chan clipboard.TextChange, 1)
|
|
changes <- clipboard.TextChange{Text: "Do not speak", Epoch: 0}
|
|
close(changes)
|
|
speech := &fakeSpeechQueue{spoken: make(chan string, 1), interrupt: make(chan struct{}, 1)}
|
|
var output bytes.Buffer
|
|
serve_clipboard_changes(context.Background(), live, nil, speech, json.NewEncoder(&output), changes, nil)
|
|
if len(speech.spoken) != 0 || len(speech.interrupt) != 0 {
|
|
t.Fatal("disabled/stale clipboard was spoken")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAutomaticClipboardDisabledStartsNoHelperAndStops(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
live := &liveSettings{clipboardChanges: make(chan struct{}, 1)}
|
|
live.Store(config.DefaultSettings())
|
|
done := run_automatic_clipboard(ctx, slog.New(slog.DiscardHandler), live, nil, discardSpeech{})
|
|
cancel()
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Fatal("disabled clipboard worker did not stop")
|
|
}
|
|
}
|