135 lines
4.9 KiB
Go
135 lines
4.9 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package app
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.stormux.org/storm/fenrir/internal/command"
|
|
"git.stormux.org/storm/fenrir/internal/config"
|
|
"git.stormux.org/storm/fenrir/internal/interaction"
|
|
"git.stormux.org/storm/fenrir/internal/presentation"
|
|
"git.stormux.org/storm/fenrir/internal/punctuation"
|
|
"git.stormux.org/storm/fenrir/internal/screen"
|
|
)
|
|
|
|
func TestTextProcessingMenuCommitCancelAndFailedSave(t *testing.T) {
|
|
processor, _, err := punctuation.Load([]string{"../../config/punctuation/default.toml"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, action := range []string{"save", "cancel", "failed save"} {
|
|
t.Run(action, func(t *testing.T) {
|
|
path := filepath.Join(t.TempDir(), "settings.toml")
|
|
if err := os.WriteFile(path, []byte("version=3\n[reading]\n"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
settings := config.Defaults()
|
|
text := ":) :) #####"
|
|
source := &fakeSource{snapshot: screen.Snapshot{Terminal: 1, Active: true, Rows: 1, Cols: len(text), Cells: []rune(text)}}
|
|
voice := &fakeVoice{}
|
|
a, err := new_application(context.Background(), source, &fakeKeys{}, voice, RunOptions{Settings: settings, ConfigPath: path, Punctuation: processor})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer a.ui.close()
|
|
if err := a.read_screen(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := strings.Join(strings.Fields(voice.messages[len(voice.messages)-1]), " "); got != "smile smile hash hash hash hash hash" {
|
|
t.Fatal("automatic reading did not use default substitutions", voice.messages)
|
|
}
|
|
if a.voice.last != text {
|
|
t.Fatal("automatic reading changed clipboard echo", a.voice.last)
|
|
}
|
|
a.open_settings()
|
|
receive_ui(t, a.ui)
|
|
focus := func(want string) {
|
|
t.Helper()
|
|
for range 40 {
|
|
a.ui.handle(interaction.Key{Name: "tab"})
|
|
if voice.messages[len(voice.messages)-1] == want {
|
|
return
|
|
}
|
|
}
|
|
t.Fatal("control not found", want, voice.messages)
|
|
}
|
|
focus("Emoticons checked")
|
|
a.ui.handle(interaction.Key{Name: "space"})
|
|
focus("Repeated symbols unchecked")
|
|
a.ui.handle(interaction.Key{Name: "space"})
|
|
focus("Repeated symbols minimum length 4")
|
|
a.ui.handle(interaction.Key{Name: "up"})
|
|
if a.settings.live.Reading != settings.Reading {
|
|
t.Fatal("draft changed runtime processing")
|
|
}
|
|
if action == "cancel" {
|
|
a.ui.handle(interaction.Key{Name: "escape"})
|
|
} else {
|
|
if action == "failed save" {
|
|
if err := os.WriteFile(path, []byte("version=3\n[reading]\nemoticons=false\n"), 0600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
focus("OK button")
|
|
a.ui.handle(interaction.Key{Name: "enter"})
|
|
finish_persistence(t, a, action == "failed save")
|
|
if action == "failed save" {
|
|
if !a.ui.active || !strings.HasPrefix(voice.messages[len(voice.messages)-1], "Could not save settings:") {
|
|
t.Fatal("failed save lost the draft", voice.messages)
|
|
}
|
|
a.ui.handle(interaction.Key{Name: "escape"})
|
|
}
|
|
}
|
|
voice.messages = nil
|
|
a.voice.Say(text)
|
|
if a.voice.last != text {
|
|
t.Fatal("processing changed raw clipboard echo", a.voice.last)
|
|
}
|
|
if action != "save" {
|
|
if a.settings.live.Reading != settings.Reading || strings.Join(strings.Fields(voice.messages[0]), " ") != "smile smile hash hash hash hash hash" {
|
|
t.Fatal("cancel or failed save changed processing", voice.messages)
|
|
}
|
|
return
|
|
}
|
|
if strings.Join(strings.Fields(voice.messages[0]), " ") != ": : 5 number" {
|
|
t.Fatal("saved processing did not apply live", voice.messages)
|
|
}
|
|
saved, _, err := config.Load(path, nil)
|
|
if err != nil || saved.Reading.Emoticons || !saved.Reading.RepeatedSymbols || saved.Reading.RepeatedSymbolsMin != 5 {
|
|
t.Fatal(saved.Reading, err)
|
|
}
|
|
freshVoice := &fakeVoice{}
|
|
fresh, err := new_application(context.Background(), source, &fakeKeys{}, freshVoice, RunOptions{Settings: saved, Punctuation: processor})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer fresh.ui.close()
|
|
if err := fresh.read_screen(); err != nil || strings.Join(strings.Fields(freshVoice.messages[len(freshVoice.messages)-1]), " ") != ": : 5 number" {
|
|
t.Fatal("fresh reader lost saved processing", freshVoice.messages, err)
|
|
}
|
|
voice.messages = nil
|
|
a.review_command(command.CurrentLine)
|
|
if strings.Join(strings.Fields(voice.messages[0]), " ") != ": : 5 number" {
|
|
t.Fatal("review bypassed processing", voice.messages)
|
|
}
|
|
voice.messages = nil
|
|
a.voice.say_spelling(presentation.Spelling{Text: "#####"})
|
|
if !reflect.DeepEqual(voice.messages, []string{"hash", "hash", "hash", "hash", "hash"}) || a.voice.last != "#####" {
|
|
t.Fatal("summary changed spelling or raw copy", voice.messages, a.voice.last)
|
|
}
|
|
voice.messages = nil
|
|
a.voice.say_spelling(presentation.Spelling{Text: ":)", Phonetic: true})
|
|
if !reflect.DeepEqual(voice.messages, []string{"colon", "right paren"}) {
|
|
t.Fatal("emoticon changed phonetic feedback", voice.messages)
|
|
}
|
|
})
|
|
}
|
|
}
|