126 lines
4.1 KiB
Go
126 lines
4.1 KiB
Go
// Copyright (c) 2026 Storm Dragon
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
package review
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.stormux.org/storm/fenrir/internal/command"
|
|
"git.stormux.org/storm/fenrir/internal/presentation"
|
|
"git.stormux.org/storm/fenrir/internal/screen"
|
|
)
|
|
|
|
func TestVerticalCharacterRetainsColumnAndDetachedReview(t *testing.T) {
|
|
var r Review
|
|
s := fixture("abcdÉ!", "x", "", "wxyzΩ?")
|
|
s.X = 4
|
|
r.Update(s)
|
|
for _, trial := range []struct {
|
|
action command.ID
|
|
want string
|
|
row int
|
|
cue presentation.Cue
|
|
character rune
|
|
}{
|
|
{command.ReviewUp, "start of screen", 0, presentation.Top, 0},
|
|
{command.ReviewDown, "space", 1, "", ' '},
|
|
{command.ReviewDown, "space", 2, "", ' '},
|
|
{command.ReviewDown, "Ω", 3, "", 'Ω'},
|
|
{command.ReviewDown, "end of screen", 3, presentation.Bottom, 0},
|
|
{command.ReviewUp, "space", 2, "", ' '},
|
|
{command.ReviewUp, "space", 1, "", ' '},
|
|
{command.ReviewUp, "É", 0, "", 'É'},
|
|
} {
|
|
result := r.Execute(trial.action)
|
|
if got := result.Text; got != trial.want || r.x != 4 || r.y != trial.row || result.Cue != trial.cue {
|
|
t.Fatalf("%s: %q at %d,%d cue %q; want %+v", trial.action, got, r.x, r.y, result.Cue, trial)
|
|
}
|
|
char := result.Character
|
|
if (char != nil) != (trial.character != 0) || char != nil && *char != trial.character {
|
|
t.Fatalf("character metadata: %v; want %q", char, trial.character)
|
|
}
|
|
if !r.Active() || r.screen.X != 4 || r.screen.Y != 0 {
|
|
t.Fatal("vertical review changed application ownership or position")
|
|
}
|
|
}
|
|
// Passive application cursor movement must leave detached review intact.
|
|
s.X, s.Y = 0, 3
|
|
r.Update(s)
|
|
if got := r.Execute(command.ReviewDown).Text; got != "space" || r.x != 4 || r.y != 1 {
|
|
t.Fatal("review followed application cursor", got, r.x, r.y)
|
|
}
|
|
r.Execute(command.FollowCursor)
|
|
if got := r.Execute(command.ReviewUp).Text; got != "space" || r.x != 0 || r.y != 2 {
|
|
t.Fatal("follow-cursor did not reset vertical review", got, r.x, r.y)
|
|
}
|
|
}
|
|
|
|
func TestVerticalCharacterScreenEdgesAndSessionReset(t *testing.T) {
|
|
for _, column := range []int{0, 19} {
|
|
var r Review
|
|
s := fixture("", "")
|
|
s.X = column
|
|
r.Update(s)
|
|
if got := r.Execute(command.ReviewDown).Text; got != "space" || r.x != column {
|
|
t.Fatal("empty screen or edge column", got, r.x)
|
|
}
|
|
for _, change := range []string{"generation", "terminal", "resize", "inactive"} {
|
|
next := fixture("new", "last")
|
|
switch change {
|
|
case "generation":
|
|
next.Generation++
|
|
case "terminal":
|
|
next.Terminal++
|
|
case "resize":
|
|
next = fixture("new", "last", "extra")
|
|
case "inactive":
|
|
r.Update(screen.Snapshot{})
|
|
if got := r.Execute(command.ReviewUp).Text; got != "no text console" {
|
|
t.Fatal(got)
|
|
}
|
|
}
|
|
r.Update(next)
|
|
if got := r.Execute(command.ReviewDown).Text; got != "l" || r.x != 0 || r.y != 1 {
|
|
t.Fatal("stale vertical position after", change, got, r.x, r.y)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestVerticalCharacterTableScopeRetainsAbsoluteColumn(t *testing.T) {
|
|
var r Review
|
|
r.Update(fixture("Name|Subject", "é|long word", "wide label|other", "only", "x|", "Name|Subject"))
|
|
r.Set_table_mode(true)
|
|
r.Execute(command.CurrentWord)
|
|
r.Set_mark()
|
|
r.Execute(command.NextWord)
|
|
for _, trial := range []struct {
|
|
action command.ID
|
|
want string
|
|
row int
|
|
}{
|
|
{command.ReviewDown, "g", 1},
|
|
{command.ReviewDown, "no table data", 2}, // column six belongs to the first cell
|
|
{command.ReviewDown, "no table data", 3}, // selected cell missing
|
|
{command.ReviewDown, "blank", 4},
|
|
{command.ReviewDown, "S", 5},
|
|
{command.ReviewUp, "blank", 4},
|
|
{command.ReviewUp, "no table data", 3},
|
|
{command.ReviewUp, "no table data", 2},
|
|
{command.ReviewUp, "g", 1},
|
|
{command.ReviewUp, "S", 0},
|
|
} {
|
|
if got := r.Execute(trial.action).Text; got != trial.want || r.x != 5 || r.y != trial.row || r.tableColumn != 1 {
|
|
t.Fatalf("%s: %q at %d,%d cell %d; want %+v", trial.action, got, r.x, r.y, r.tableColumn, trial)
|
|
}
|
|
}
|
|
if got := r.Execute(command.CurrentWord).Text; got != "Subject Subject" {
|
|
t.Fatal("vertical review lost header or selected cell", got)
|
|
}
|
|
r.Set_table_mode(false)
|
|
if got := r.Execute(command.ReviewDown).Text; got != "g" {
|
|
t.Fatal("ordinary review did not return", got)
|
|
}
|
|
}
|