All checks were successful
Run Test Suite / test (push) Successful in 17s
Began work on replace mode, but not complete.
567 lines
18 KiB
Go
567 lines
18 KiB
Go
package editor
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.gophernest.net/azpect/TextEditor/internal/core"
|
|
)
|
|
|
|
func TestReplaceChar(t *testing.T) {
|
|
t.Run("test 'rx' replaces character under cursor", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xello" {
|
|
t.Errorf("lines[0] = %q, want 'xello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' in middle of line", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 2, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hexlo" {
|
|
t.Errorf("lines[0] = %q, want 'hexlo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' at end of line", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 4, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hellx" {
|
|
t.Errorf("lines[0] = %q, want 'hellx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' cursor position remains at replaced char", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 2, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveWindow().Cursor.Col != 2 {
|
|
t.Errorf("CursorX() = %d, want 2", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' stays in normal mode", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.Mode() != core.NormalMode {
|
|
t.Errorf("Mode() = %v, want NormalMode", m.Mode())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' with space replaces with space", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", " ")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != " ello" {
|
|
t.Errorf("lines[0] = %q, want ' ello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' with digit replaces with digit", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "5")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "5ello" {
|
|
t.Errorf("lines[0] = %q, want '5ello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' with special char replaces correctly", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "@")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "@ello" {
|
|
t.Errorf("lines[0] = %q, want '@ello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test multiple 'r' operations in sequence", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x", "l", "r", "y")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xyllo" {
|
|
t.Errorf("lines[0] = %q, want 'xyllo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceCharWithCount(t *testing.T) {
|
|
t.Run("test '3rx' replaces three characters", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "3", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xxxlo" {
|
|
t.Errorf("lines[0] = %q, want 'xxxlo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '3rx' cursor position after replace", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "3", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// Cursor should be at last replaced character
|
|
if m.ActiveWindow().Cursor.Col != 2 {
|
|
t.Errorf("CursorX() = %d, want 2", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("test '5rx' replaces all five characters", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "5", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xxxxx" {
|
|
t.Errorf("lines[0] = %q, want 'xxxxx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '10rx' with overflow stops at line end", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "1", "0", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// Should only replace 5 chars (all available)
|
|
if m.ActiveBuffer().Lines[0].String() != "xxxxx" {
|
|
t.Errorf("lines[0] = %q, want 'xxxxx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '2rx' from middle", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 1, Line: 0})
|
|
sendKeys(tm, "2", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hxxlo" {
|
|
t.Errorf("lines[0] = %q, want 'hxxlo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '2rx' cursor position from middle", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 1, Line: 0})
|
|
sendKeys(tm, "2", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveWindow().Cursor.Col != 2 {
|
|
t.Errorf("CursorX() = %d, want 2", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("test '4rx' from near end stops at line end", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 3, Line: 0})
|
|
sendKeys(tm, "4", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// Should only replace 2 chars (3 and 4)
|
|
if m.ActiveBuffer().Lines[0].String() != "helxx" {
|
|
t.Errorf("lines[0] = %q, want 'helxx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test large count '100rx' doesn't crash", func(t *testing.T) {
|
|
lines := []string{"short"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "1", "0", "0", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xxxxx" {
|
|
t.Errorf("lines[0] = %q, want 'xxxxx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceCharEdgeCases(t *testing.T) {
|
|
t.Run("test 'r' on empty line does nothing", func(t *testing.T) {
|
|
lines := []string{""}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "" {
|
|
t.Errorf("Line(0) = %q, want ''", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
if m.ActiveWindow().Cursor.Col != 0 {
|
|
t.Errorf("CursorX() = %d, want 0", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' on single character line", func(t *testing.T) {
|
|
lines := []string{"a"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "x" {
|
|
t.Errorf("Line(0) = %q, want 'x'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' at last char replaces it", func(t *testing.T) {
|
|
lines := []string{"ab"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 1, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "ax" {
|
|
t.Errorf("Line(0) = %q, want 'ax'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' with whitespace", func(t *testing.T) {
|
|
lines := []string{"a b c"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 1, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "axb c" {
|
|
t.Errorf("Line(0) = %q, want 'axb c'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' preserves other lines", func(t *testing.T) {
|
|
lines := []string{"hello", "world"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().LineCount() != 2 {
|
|
t.Errorf("LineCount() = %d, want 2", m.ActiveBuffer().LineCount())
|
|
}
|
|
if m.ActiveBuffer().Lines[1].String() != "world" {
|
|
t.Errorf("Line(1) = %q, want 'world'", m.ActiveBuffer().Lines[1].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' on line with tabs", func(t *testing.T) {
|
|
lines := []string{"a\tb"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 1, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "axb" {
|
|
t.Errorf("Line(0) = %q, want 'axb'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '5rx' with only 3 chars available", func(t *testing.T) {
|
|
lines := []string{"abc"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "5", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xxx" {
|
|
t.Errorf("Line(0) = %q, want 'xxx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' in middle preserves surrounding chars", func(t *testing.T) {
|
|
lines := []string{"abcde"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 2, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "abxde" {
|
|
t.Errorf("Line(0) = %q, want 'abxde'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' on whitespace-only line", func(t *testing.T) {
|
|
lines := []string{" "}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 2, Line: 0})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != " x " {
|
|
t.Errorf("Line(0) = %q, want ' x '", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' on different lines independently", func(t *testing.T) {
|
|
lines := []string{"hello", "world"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x", "j", "r", "y")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xello" {
|
|
t.Errorf("Line(0) = %q, want 'xello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
if m.ActiveBuffer().Lines[1].String() != "yorld" {
|
|
t.Errorf("Line(1) = %q, want 'yorld'", m.ActiveBuffer().Lines[1].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' does not affect line count", func(t *testing.T) {
|
|
lines := []string{"line 1", "line 2", "line 3"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().LineCount() != 3 {
|
|
t.Errorf("LineCount() = %d, want 3", m.ActiveBuffer().LineCount())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' with newline character is treated as single char", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
// Note: In vim, 'r' with enter doesn't work the same way
|
|
// This test documents the current behavior
|
|
sendKeys(tm, "r", "\n")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// Replacing with "\n" string (not actual newline)
|
|
if m.ActiveBuffer().Lines[0].String() != "\nello" {
|
|
t.Errorf("Line(0) = %q, want '\\nello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceCharWithMotion(t *testing.T) {
|
|
t.Run("test 'lrx' moves then replaces", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "l", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hxllo" {
|
|
t.Errorf("lines[0] = %q, want 'hxllo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'wrx' moves to next word start then replaces", func(t *testing.T) {
|
|
lines := []string{"hello world"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "w", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hello xorld" {
|
|
t.Errorf("lines[0] = %q, want 'hello xorld'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '$rx' moves to end then replaces", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "$", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hellx" {
|
|
t.Errorf("lines[0] = %q, want 'hellx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '2lrx' moves 2 right then replaces", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "2", "l", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hexlo" {
|
|
t.Errorf("lines[0] = %q, want 'hexlo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceCharUndo(t *testing.T) {
|
|
t.Run("test 'rx' can be undone with 'u'", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x", "u")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hello" {
|
|
t.Errorf("lines[0] = %q, want 'hello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '3rx' can be undone with 'u'", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "3", "r", "x", "u")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hello" {
|
|
t.Errorf("lines[0] = %q, want 'hello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test multiple 'r' operations can be undone separately", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x", "l", "r", "y", "u")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// Only the last 'ry' should be undone
|
|
if m.ActiveBuffer().Lines[0].String() != "xello" {
|
|
t.Errorf("lines[0] = %q, want 'xello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test undo then redo 'rx'", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x", "u", "ctrl+r")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xello" {
|
|
t.Errorf("lines[0] = %q, want 'xello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceCharRepeat(t *testing.T) {
|
|
t.Run("test 'rx' can be repeated with '.'", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "x", "l", ".")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xxllo" {
|
|
t.Errorf("lines[0] = %q, want 'xxllo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '3rx' can be repeated with '.'", func(t *testing.T) {
|
|
lines := []string{"hello world"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "3", "r", "x", "w", ".")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// First 3rx at position 0, second at position 6
|
|
if m.ActiveBuffer().Lines[0].String() != "xxxlo xxxld" {
|
|
t.Errorf("lines[0] = %q, want 'xxxlo xxxld'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '.' repeats last replace char", func(t *testing.T) {
|
|
lines := []string{"hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "r", "a", "l", ".", "l", ".")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "aaalo" {
|
|
t.Errorf("lines[0] = %q, want 'aaalo'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
// NOTE: This is the same as Vim's handling, but that is okay, I like this more, feels more honest
|
|
t.Run("test '.' with count multiplies", func(t *testing.T) {
|
|
lines := []string{"hello world"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "2", "r", "x", "w", "3", ".")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "xxllo xxxxx" {
|
|
t.Errorf("lines[0] = %q, want 'xxllo xxxxx'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceCharMultiLine(t *testing.T) {
|
|
t.Run("test 'r' on second line", func(t *testing.T) {
|
|
lines := []string{"first", "second"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 0, Line: 1})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "first" {
|
|
t.Errorf("Line(0) = %q, want 'first'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
if m.ActiveBuffer().Lines[1].String() != "xecond" {
|
|
t.Errorf("Line(1) = %q, want 'xecond'", m.ActiveBuffer().Lines[1].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' does not cross line boundaries", func(t *testing.T) {
|
|
lines := []string{"ab", "cd"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 1, Line: 0})
|
|
sendKeys(tm, "5", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// Should only replace 'b', not cross to next line
|
|
if m.ActiveBuffer().Lines[0].String() != "ax" {
|
|
t.Errorf("Line(0) = %q, want 'ax'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
if m.ActiveBuffer().Lines[1].String() != "cd" {
|
|
t.Errorf("Line(1) = %q, want 'cd'", m.ActiveBuffer().Lines[1].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test 'r' on last line", func(t *testing.T) {
|
|
lines := []string{"first", "second", "third"}
|
|
tm := newTestModelWithLinesAndCursorPos(t, lines, core.Position{Col: 0, Line: 2})
|
|
sendKeys(tm, "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[2].String() != "xhird" {
|
|
t.Errorf("Line(2) = %q, want 'xhird'", m.ActiveBuffer().Lines[2].String())
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestReplaceCharCombinations(t *testing.T) {
|
|
t.Run("test 'frx' finds then replaces", func(t *testing.T) {
|
|
lines := []string{"hello world"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "f", "w", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != "hello xorld" {
|
|
t.Errorf("lines[0] = %q, want 'hello xorld'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '2frx' finds second occurrence then replaces", func(t *testing.T) {
|
|
lines := []string{"hello hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "2", "f", "l", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
// Find second 'l', which is at position 3
|
|
if m.ActiveBuffer().Lines[0].String() != "helxo hello" {
|
|
t.Errorf("lines[0] = %q, want 'helxo hello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
|
|
t.Run("test '^rx' moves to first non-blank then replaces", func(t *testing.T) {
|
|
lines := []string{" hello"}
|
|
tm := newTestModelWithLines(t, lines)
|
|
sendKeys(tm, "^", "r", "x")
|
|
|
|
m := getFinalModel(t, tm)
|
|
if m.ActiveBuffer().Lines[0].String() != " xello" {
|
|
t.Errorf("lines[0] = %q, want ' xello'", m.ActiveBuffer().Lines[0].String())
|
|
}
|
|
})
|
|
}
|