Files
fenrir/internal/reader/indentation_test.go

133 lines
3.7 KiB
Go

// 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/presentation"
"testing"
)
func TestIndentationNavigationModesBlankRowsAndRepeatedLevels(t *testing.T) {
for _, mode := range []string{"none", "speech", "beeps", "both"} {
t.Run(mode, func(t *testing.T) {
r := New()
r.Configure_indentation(mode)
s := fixture("root", " first", " second", "", " third", "root again")
r.Update(s)
for _, row := range []int{1, 2, 3, 4, 5} {
r.Note_input(true, false, false)
s.Y = row
output := r.Update(s)
wantIndent := mode != "none" && (row == 1 || row == 5)
if (len(output) == 2) != wantIndent {
t.Fatalf("row %d: %+v", row, output)
}
if wantIndent {
level := 4
if row == 5 {
level = 0
}
if output[0].Text != presentation.Indentation_message(level, mode).Text ||
(output[0].Indentation != nil) != (mode == "beeps" || mode == "both") {
t.Fatal(output[0])
}
if output[0].Indentation != nil && output[0].Indentation.Speech != (mode == "both") {
t.Fatal(output[0])
}
}
if got := r.Update(s); len(got) != 0 {
t.Fatal("stationary update repeated feedback", got)
}
}
})
}
}
func TestIndentationEditsIncludeDedentToZeroWithoutOrdinaryTypingChatter(t *testing.T) {
r := New()
r.Configure_indentation("speech")
s := fixture("value")
r.Update(s)
for _, trial := range []struct {
text string
level int
}{{" value", 4}, {" value", 2}, {"value", 0}} {
s = fixture(trial.text)
s.X = trial.level
r.Note_input(true, false, false)
output := r.Update(s)
if len(output) == 0 || output[0].Text != presentation.Indentation_message(trial.level, "speech").Text {
t.Fatal(output)
}
}
r.Note_input(true, true, false)
s = fixture("Zvalue")
s.X = 1
for _, message := range r.Update(s) {
if message.Text == "indented 0 " {
t.Fatal("typing repeated indentation", message)
}
}
}
func TestIndentationDoesNotFollowPassiveOutputDisabledReadingOrOtherTracking(t *testing.T) {
for _, trial := range []string{"passive", "automatic off", "cursor off", "table", "highlight", "session", "output", "detached"} {
t.Run(trial, func(t *testing.T) {
r := New()
r.Configure_indentation("both")
s := fixture("root", " child")
r.Update(s)
r.Note_input(true, false, false)
s.Y = 1
switch trial {
case "passive":
r.Note_input(false, false, false)
case "automatic off":
r.Configure(false, true)
case "cursor off":
r.Configure(true, false)
case "table", "highlight":
r.Configure_tracking(trial)
case "session":
s.Generation++
case "output":
s = fixture("root", " new output")
s.Y = 1
case "detached":
r.Command(command.CurrentLine)
r.Note_input(false, false, false)
}
for _, message := range r.Update(s) {
if message.Indentation != nil {
t.Fatal(message)
}
}
})
}
}
func TestReviewIndentationWithAutomaticReadingOffAndApplicationCursorElsewhere(t *testing.T) {
r := New()
r.Configure_indentation("speech")
r.Configure(false, false)
s := fixture("root", " child", "", " peer", "root again")
r.Update(s)
for index, want := range []string{"indented 4 ", "", "", "indented 0 "} {
result := r.Command(command.NextLine)
got := ""
if message := result.Indentation; message != nil {
got = message.Text
}
if got != want {
t.Fatal(index, got, want)
}
r.Update(s) // Passive application state must not reset review's baseline.
}
result := r.Command(command.CurrentLine)
if result.Indentation != nil {
t.Fatal("same-line review repeated indentation")
}
}