Files
fenrir/internal/app/text_processing_test.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)
}
})
}
}