From c2b5e6f67cafbd048449fbd9aa4a0e8d2f40fc60 Mon Sep 17 00:00:00 2001 From: Hayden Hargreaves Date: Thu, 12 Feb 2026 17:36:07 -0700 Subject: [PATCH] tests: implement tests for insert mode arrows keys --- internal/editor/integration_insert_test.go | 129 +++++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/internal/editor/integration_insert_test.go b/internal/editor/integration_insert_test.go index 9ae65d8..ec4c4ca 100644 --- a/internal/editor/integration_insert_test.go +++ b/internal/editor/integration_insert_test.go @@ -457,6 +457,135 @@ func TestInsertModeDelete(t *testing.T) { } +func TestInsertModeArrowKeys(t *testing.T) { + t.Run("test left arrow moves cursor left", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 3, Line: 0}) + sendKeys(tm, "i", "left", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "heXllo" { + t.Errorf("lines[0] = %q, want 'heXllo'", m.lines[0]) + } + }) + + t.Run("test right arrow moves cursor right", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 1, Line: 0}) + sendKeys(tm, "i", "right", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "heXllo" { + t.Errorf("lines[0] = %q, want 'heXllo'", m.lines[0]) + } + }) + + t.Run("test up arrow moves cursor up", func(t *testing.T) { + lines := []string{"hello", "world"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 2, Line: 1}) + sendKeys(tm, "i", "up", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "heXllo" { + t.Errorf("lines[0] = %q, want 'heXllo'", m.lines[0]) + } + if m.lines[1] != "world" { + t.Errorf("lines[1] = %q, want 'world'", m.lines[1]) + } + }) + + t.Run("test down arrow moves cursor down", func(t *testing.T) { + lines := []string{"hello", "world"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 2, Line: 0}) + sendKeys(tm, "i", "down", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "hello" { + t.Errorf("lines[0] = %q, want 'hello'", m.lines[0]) + } + if m.lines[1] != "woXrld" { + t.Errorf("lines[1] = %q, want 'woXrld'", m.lines[1]) + } + }) + + t.Run("test left arrow at start of line does nothing", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithLines(t, lines) + sendKeys(tm, "i", "left", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "Xhello" { + t.Errorf("lines[0] = %q, want 'Xhello'", m.lines[0]) + } + }) + + t.Run("test right arrow at end of line does nothing", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 4, Line: 0}) + sendKeys(tm, "a", "right", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "helloX" { + t.Errorf("lines[0] = %q, want 'helloX'", m.lines[0]) + } + }) + + t.Run("test up arrow at first line does nothing", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 2, Line: 0}) + sendKeys(tm, "i", "up", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "heXllo" { + t.Errorf("lines[0] = %q, want 'heXllo'", m.lines[0]) + } + }) + + t.Run("test down arrow at last line does nothing", func(t *testing.T) { + lines := []string{"hello"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 2, Line: 0}) + sendKeys(tm, "i", "down", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "heXllo" { + t.Errorf("lines[0] = %q, want 'heXllo'", m.lines[0]) + } + }) + + t.Run("test up arrow clamps cursor to shorter line", func(t *testing.T) { + lines := []string{"hi", "hello"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 4, Line: 1}) + sendKeys(tm, "i", "up", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[0] != "hiX" { + t.Errorf("lines[0] = %q, want 'hiX'", m.lines[0]) + } + }) + + t.Run("test down arrow clamps cursor to shorter line", func(t *testing.T) { + lines := []string{"hello", "hi"} + tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 4, Line: 0}) + sendKeys(tm, "i", "down", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[1] != "hiX" { + t.Errorf("lines[1] = %q, want 'hiX'", m.lines[1]) + } + }) + + t.Run("test multiple arrow keys in sequence", func(t *testing.T) { + lines := []string{"hello", "world"} + tm := newTestModelWithLines(t, lines) + sendKeys(tm, "i", "right", "right", "down", "X", "esc") + + m := getFinalModel(t, tm) + if m.lines[1] != "woXrld" { + t.Errorf("lines[1] = %q, want 'woXrld'", m.lines[1]) + } + }) +} + func TestInsertModeDeletePreviousWord(t *testing.T) { t.Run("test 'ctrl+w' deletes word", func(t *testing.T) { lines := []string{"hello world"}