Files
fenrir/internal/reader/application_feedback_test.go

109 lines
3.3 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
package reader
import (
"reflect"
"testing"
"time"
"git.stormux.org/storm/fenrir/internal/applicationoverrides"
"git.stormux.org/storm/fenrir/internal/command"
"git.stormux.org/storm/fenrir/internal/presentation"
"git.stormux.org/storm/fenrir/internal/screen"
)
func TestApplicationComposerCursorFeedback(t *testing.T) {
for _, mode := range []string{"left", "right", "status redraw", "leave review", "passive", "cursor off", "automatic off", "outside input", "edited input", "other adapter"} {
t.Run(mode, func(t *testing.T) {
r := New()
r.Configure_review(true, true, true, true)
before := fixture("Working", "› hello")
before.X, before.Y = 7, 1
frame := applicationoverrides.Frame{Recognized: true, OwnsPresentation: true, InputCursor: true, Input: &screen.Region{Left: 2, Top: 1, Right: 19, Bottom: 1}}
r.Update_application(before, frame)
next := fixture("Working", "› hello")
next.X, next.Y = 6, 1
want := []presentation.Message{presentation.Character_message('o')}
if mode == "right" {
before.X = 5
r.Update_application(before, frame)
}
if mode == "status redraw" {
copy(next.Line(0), []rune("Reading file"))
}
if mode == "leave review" {
r.Command(command.CurrentLine)
}
if mode != "passive" {
r.Note_input(true, false, false)
}
switch mode {
case "passive":
want = nil
case "cursor off":
r.Configure(true, false)
want = nil
case "automatic off":
r.Configure(false, true)
want = nil
case "outside input":
next.Y = 0
want = nil
case "edited input":
next.Line(1)[2] = 'X'
want = nil
case "other adapter":
frame.InputCursor = false
want = nil
}
if got := r.Update_application(next, frame); !reflect.DeepEqual(got, want) {
t.Fatal(mode, got, want)
}
if mode == "leave review" && r.review.Active() {
t.Fatal("direct navigation remained in detached review")
}
})
}
}
func TestApplicationActivityUsesSoundTimerWithoutScreenRedraws(t *testing.T) {
r := New()
r.Configure_progress(true)
r.Configure(false, false) // Working cues are independent of speech/automatic reading.
s := fixture("Working", "› ")
frame := applicationoverrides.Frame{Recognized: true, OwnsPresentation: true, Activity: true}
r.Update_application(s, frame)
now := time.Now()
for _, elapsed := range []time.Duration{0, 4 * time.Second, 8 * time.Second} {
if value, ok := r.Next_progress(now.Add(elapsed)); !ok || value != 50 {
t.Fatal(elapsed, value, ok)
}
if _, ok := r.Next_progress(now.Add(elapsed + 3999*time.Millisecond)); ok {
t.Fatal("activity flooded")
}
}
frame.Activity = false
r.Update_application(s, frame)
if r.Progress_active() {
t.Fatal("idle retained activity")
}
if _, ok := r.Next_progress(now.Add(12 * time.Second)); ok {
t.Fatal("idle beeped")
}
frame.Activity = true
r.Configure_progress(false)
r.Update_application(s, frame)
if _, ok := r.Next_progress(now.Add(16 * time.Second)); ok {
t.Fatal("progress toggle ignored")
}
r.Configure_progress(true)
r.Update_application(s, frame)
s.Active = false
r.Update_application(s, frame)
if _, ok := r.Next_progress(now.Add(20 * time.Second)); ok {
t.Fatal("inactive terminal beeped")
}
}