// Copyright (c) 2026 Storm Dragon // SPDX-License-Identifier: GPL-3.0-or-later package reader import ( "git.stormux.org/storm/fenrir/internal/command" "git.stormux.org/storm/fenrir/internal/screen" "reflect" "strings" "testing" ) func spell_snapshot(text string) screen.Snapshot { return screen.Snapshot{Terminal: 2, Active: true, Rows: 1, Cols: 80, X: len([]rune(text)), Cells: []rune(text + strings.Repeat(" ", 80-len([]rune(text))))} } func TestSpellcheckOnlyUsesConfirmedCompletedWords(t *testing.T) { for _, text := range []string{"helo ", "café!", "don't ", "one,two ", "https://example.com ", "foo.bar ", "./program ", "--option "} { r := New() r.Configure_echo(false, false, false) before := spell_snapshot("$ ") before.X = 2 r.Update(before) for _, char := range text { r.Note_input(true, true, char == ' ') } after := spell_snapshot("$ " + text) after.X = 2 + len([]rune(text)) r.Update(after) want := map[string][]string{"helo ": {"helo"}, "café!": {"café"}, "don't ": {"don't"}, "one,two ": {"one", "two"}}[text] if !reflect.DeepEqual(r.Completed_words(), want) { t.Fatal(text, r.Completed_words(), want) } r.Update(after) if len(r.Completed_words()) != 0 { t.Fatal("repeated unchanged word") } } for _, input := range []bool{false, true} { r := New() before := spell_snapshot("$ ") before.X = 2 r.Update(before) if input { for range 8 { r.Note_input(true, true, true) } } r.Update(before) if len(r.Completed_words()) != 0 { t.Fatal("password input leaked") } r.Note_input(false, false, false) after := fixture("$ typo ") after.X = 7 r.Update(after) if len(r.Completed_words()) != 0 { t.Fatal("passive output checked") } r.Note_input(true, false, false) after.X-- r.Update(after) if len(r.Completed_words()) != 0 { t.Fatal("navigation checked") } } } func TestSpellcheckSourceRespectsReviewWithoutMovingCursors(t *testing.T) { r := New() snapshot := fixture("alpha beta") snapshot.X = 7 r.Update(snapshot) if got := r.Spellcheck_word(); got != "beta" || r.review.Active() { t.Fatal(got, r.review.Active()) } r.Command(command.PreviousWord) if got := r.Spellcheck_word(); got != "alpha" || !r.review.Active() || r.screen.X != 7 { t.Fatal(got, r.screen.X) } }