package editor import ( "testing" "git.gophernest.net/azpect/TextEditor/internal/action" ) // --- G and gg Tests --- func TestMoveToBottom(t *testing.T) { t.Run("test 'G' from top", func(t *testing.T) { tm := newTestModel(t) sendKeys(tm, "G") m := getFinalModel(t, tm) if m.cursor.y != 5 { t.Errorf("cursor.y = %d, want 5", m.cursor.y) } }) t.Run("test 'G' from middle", func(t *testing.T) { tm := newTestModelWithCursorPos(t, action.Position{Col: 0, Line: 2}) sendKeys(tm, "G") m := getFinalModel(t, tm) if m.cursor.y != 5 { t.Errorf("cursor.y = %d, want 5", m.cursor.y) } }) t.Run("test 'G' already at bottom", func(t *testing.T) { tm := newTestModelWithCursorPos(t, action.Position{Col: 0, Line: 5}) sendKeys(tm, "G") m := getFinalModel(t, tm) if m.cursor.y != 5 { t.Errorf("cursor.y = %d, want 5", m.cursor.y) } }) t.Run("test 'G' clamps cursor.x", func(t *testing.T) { lines := []string{"long line here", "short"} tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 10, Line: 0}) sendKeys(tm, "G") m := getFinalModel(t, tm) if m.cursor.y != 1 { t.Errorf("cursor.y = %d, want 1", m.cursor.y) } want := len(lines[1]) if m.cursor.x != want { t.Errorf("cursor.x = %d, want %d", m.cursor.x, want) } }) t.Run("test 'G' on single line file", func(t *testing.T) { lines := []string{"only line"} tm := newTestModelWithLines(t, lines) sendKeys(tm, "G") m := getFinalModel(t, tm) if m.cursor.y != 0 { t.Errorf("cursor.y = %d, want 0", m.cursor.y) } }) } func TestMoveToTop(t *testing.T) { t.Run("test 'gg' from bottom", func(t *testing.T) { tm := newTestModelWithCursorPos(t, action.Position{Col: 0, Line: 5}) sendKeys(tm, "g", "g") m := getFinalModel(t, tm) if m.cursor.y != 0 { t.Errorf("cursor.y = %d, want 0", m.cursor.y) } }) t.Run("test 'gg' from middle", func(t *testing.T) { tm := newTestModelWithCursorPos(t, action.Position{Col: 0, Line: 3}) sendKeys(tm, "g", "g") m := getFinalModel(t, tm) if m.cursor.y != 0 { t.Errorf("cursor.y = %d, want 0", m.cursor.y) } }) t.Run("test 'gg' already at top", func(t *testing.T) { tm := newTestModel(t) sendKeys(tm, "g", "g") m := getFinalModel(t, tm) if m.cursor.y != 0 { t.Errorf("cursor.y = %d, want 0", m.cursor.y) } }) t.Run("test 'gg' clamps cursor.x", func(t *testing.T) { lines := []string{"short", "long line here"} tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 10, Line: 1}) sendKeys(tm, "g", "g") m := getFinalModel(t, tm) if m.cursor.y != 0 { t.Errorf("cursor.y = %d, want 0", m.cursor.y) } want := len(lines[0]) if m.cursor.x != want { t.Errorf("cursor.x = %d, want %d", m.cursor.x, want) } }) } // --- 0 and $ Tests --- func TestMoveToLineStart(t *testing.T) { t.Run("test '0' from middle of line", func(t *testing.T) { tm := newTestModelWithCursorPos(t, action.Position{Col: 3, Line: 0}) sendKeys(tm, "0") m := getFinalModel(t, tm) if m.cursor.x != 0 { t.Errorf("cursor.x = %d, want 0", m.cursor.x) } }) t.Run("test '0' from end of line", func(t *testing.T) { lines := []string{"hello world"} tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: len(lines[0]), Line: 0}) sendKeys(tm, "0") m := getFinalModel(t, tm) if m.cursor.x != 0 { t.Errorf("cursor.x = %d, want 0", m.cursor.x) } }) t.Run("test '0' already at start", func(t *testing.T) { tm := newTestModel(t) sendKeys(tm, "0") m := getFinalModel(t, tm) if m.cursor.x != 0 { t.Errorf("cursor.x = %d, want 0", m.cursor.x) } }) t.Run("test '0' on empty line", func(t *testing.T) { lines := []string{""} tm := newTestModelWithLines(t, lines) sendKeys(tm, "0") m := getFinalModel(t, tm) if m.cursor.x != 0 { t.Errorf("cursor.x = %d, want 0", m.cursor.x) } }) t.Run("test '0' preserves line", func(t *testing.T) { tm := newTestModelWithCursorPos(t, action.Position{Col: 3, Line: 2}) sendKeys(tm, "0") m := getFinalModel(t, tm) if m.cursor.y != 2 { t.Errorf("cursor.y = %d, want 2", m.cursor.y) } }) } func TestMoveToLineEnd(t *testing.T) { t.Run("test '$' from start of line", func(t *testing.T) { lines := []string{"hello"} tm := newTestModelWithLines(t, lines) sendKeys(tm, "$") m := getFinalModel(t, tm) want := len(lines[0]) if m.cursor.x != want { t.Errorf("cursor.x = %d, want %d", m.cursor.x, want) } }) t.Run("test '$' from middle of line", func(t *testing.T) { lines := []string{"hello world"} tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 3, Line: 0}) sendKeys(tm, "$") m := getFinalModel(t, tm) want := len(lines[0]) if m.cursor.x != want { t.Errorf("cursor.x = %d, want %d", m.cursor.x, want) } }) t.Run("test '$' already at end", func(t *testing.T) { lines := []string{"hello"} tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: len(lines[0]), Line: 0}) sendKeys(tm, "$") m := getFinalModel(t, tm) want := len(lines[0]) if m.cursor.x != want { t.Errorf("cursor.x = %d, want %d", m.cursor.x, want) } }) t.Run("test '$' on empty line", func(t *testing.T) { lines := []string{""} tm := newTestModelWithLines(t, lines) sendKeys(tm, "$") m := getFinalModel(t, tm) if m.cursor.x != 0 { t.Errorf("cursor.x = %d, want 0", m.cursor.x) } }) t.Run("test '$' preserves line", func(t *testing.T) { tm := newTestModelWithCursorPos(t, action.Position{Col: 0, Line: 2}) sendKeys(tm, "$") m := getFinalModel(t, tm) if m.cursor.y != 2 { t.Errorf("cursor.y = %d, want 2", m.cursor.y) } }) }