Files

120 lines
3.8 KiB
Go

// Fenrir console screen reader.
// Copyright (c) 2026 Storm Dragon
// SPDX-License-Identifier: GPL-3.0-or-later
//
// 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 reader
import (
"reflect"
"testing"
"time"
"git.stormux.org/storm/fenrir/internal/presentation"
)
func TestProgressIndependentOfAutomaticReadingAndTypingEcho(t *testing.T) {
r := New()
r.Configure_progress(true)
r.Configure(false, false)
before, after := fixture("Download 20%", ""), fixture("Download 30%", "")
r.Update(before)
if _, ok := r.Next_progress(time.Now()); ok {
t.Fatal("initial screen")
}
if output := r.Update(after); len(output) != 0 {
t.Fatal("enabled autoread")
}
if value, ok := r.Next_progress(time.Now()); !ok || value != 30 {
t.Fatal(value, ok)
}
r.Configure_progress(false)
r.Update(fixture("Download 40%", ""))
if _, ok := r.Next_progress(time.Now().Add(time.Second)); ok {
t.Fatal("disabled progress")
}
r.Configure_progress(true)
// Typing a percentage must stay silent even when key echo is disabled.
r.Configure_echo(false, false, false)
before, after = fixture("50", ""), fixture("50%", "")
before.X, after.X = 2, 3
r.Update(before)
r.Note_input(true, true, false)
r.Update(after)
if _, ok := r.Next_progress(time.Now().Add(2 * time.Second)); ok || r.Progress_active() {
t.Fatal("typing recognized as progress")
}
}
func TestProgressIgnoresDeletionButKeepsOtherRows(t *testing.T) {
for _, mode := range []string{"backspace", "delete", "word deletion", "background together", "background before edit", "passive change", "expired"} {
t.Run(mode, func(t *testing.T) {
r := New()
r.Configure_progress(true)
r.Configure_echo(false, false, false)
before, after := fixture("type 2% abc", "Download 20%"), fixture("type 2% ab", "Download 20%")
before.X, after.X = 11, 10
if mode == "delete" {
before.X, after.X = 10, 10
}
if mode == "word deletion" {
after = fixture("type 2% ", "Download 20%")
after.X = 8
}
if mode == "background together" {
after = fixture("type 2% ab", "Download 30%")
after.X = 10
}
r.Update(before)
if mode != "passive change" {
r.Note_input(true, false, false)
r.Note_deletion()
if mode == "expired" {
r.progressDeletionAt = time.Now().Add(-time.Second)
}
}
if mode == "background before edit" {
update := fixture("type 2% abc", "Download 30%")
update.X = 11
r.Update(update)
if value, ok := r.Next_progress(time.Now()); !ok || value != 30 {
t.Fatal("lost background output", value, ok)
}
after = fixture("type 2% ab", "Download 30%")
after.X = 10
}
output := r.Update(after)
value, ok := r.Next_progress(time.Now().Add(time.Second))
switch mode {
case "background together":
if !ok || value != 30 {
t.Fatal("concurrent progress lost", value, ok)
}
case "passive change", "expired":
if !ok || value != 2 {
t.Fatal("passive output suppressed", value, ok)
}
default:
if ok {
t.Fatal("deletion produced progress", value)
}
}
if mode == "backspace" && !reflect.DeepEqual(output, []presentation.Message{presentation.Character_message('c')}) {
t.Fatal("lost deletion speech", output)
}
})
}
}