Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions internal/editor/buffer.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ type Buffer struct {

func NewBuffer(content string) *Buffer {
lines := strings.Split(content, "\n")
if len(lines) == 0 {
lines = []string{""}
}
return &Buffer{lines: lines}
}

Expand Down
115 changes: 115 additions & 0 deletions internal/editor/buffer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,118 @@ func TestBuffer_Modified(t *testing.T) {
t.Fatal("buffer should be modified after insert")
}
}

func TestBuffer_GetLine_OutOfBounds(t *testing.T) {
b := NewBuffer("hello")
if got := b.GetLine(-1); got != "" {
t.Fatalf("expected empty string for negative row, got %q", got)
}
if got := b.GetLine(5); got != "" {
t.Fatalf("expected empty string for row beyond end, got %q", got)
}
}

func TestBuffer_LineLen_OutOfBounds(t *testing.T) {
b := NewBuffer("hello")
if got := b.LineLen(-1); got != 0 {
t.Fatalf("expected 0 for negative row, got %d", got)
}
if got := b.LineLen(5); got != 0 {
t.Fatalf("expected 0 for row beyond end, got %d", got)
}
}

func TestBuffer_InsertChar_OutOfBounds(t *testing.T) {
b := NewBuffer("hello")
// Invalid row — should be no-op
b.InsertChar(-1, 0, 'x')
b.InsertChar(5, 0, 'x')
if got := b.GetLine(0); got != "hello" {
t.Fatalf("expected unchanged line, got %q", got)
}
// Col beyond line length — should clamp
b.InsertChar(0, 100, '!')
if got := b.GetLine(0); got != "hello!" {
t.Fatalf("expected 'hello!' with clamped col, got %q", got)
}
}

func TestBuffer_DeleteChar_OutOfBounds(t *testing.T) {
b := NewBuffer("hello")
// Invalid row
b.DeleteChar(-1, 0)
b.DeleteChar(5, 0)
// Invalid col
b.DeleteChar(0, -1)
b.DeleteChar(0, 10)
if got := b.GetLine(0); got != "hello" {
t.Fatalf("expected unchanged line, got %q", got)
}
}

func TestBuffer_Backspace_AtStart(t *testing.T) {
b := NewBuffer("hello")
b.Backspace(0, 0) // at start of line — should be no-op
if got := b.GetLine(0); got != "hello" {
t.Fatalf("expected unchanged line, got %q", got)
}
}

func TestBuffer_InsertNewline_OutOfBounds(t *testing.T) {
b := NewBuffer("hello")
b.InsertNewline(-1, 0)
b.InsertNewline(5, 0)
if b.LineCount() != 1 {
t.Fatalf("expected 1 line after out-of-bounds newline inserts, got %d", b.LineCount())
}
}

func TestBuffer_InsertNewline_ColClamp(t *testing.T) {
b := NewBuffer("hello")
b.InsertNewline(0, 100) // col beyond length, should clamp
if b.LineCount() != 2 {
t.Fatalf("expected 2 lines, got %d", b.LineCount())
}
if got := b.GetLine(0); got != "hello" {
t.Fatalf("expected 'hello', got %q", got)
}
if got := b.GetLine(1); got != "" {
t.Fatalf("expected empty second line, got %q", got)
}
}

func TestBuffer_JoinLines_OutOfBounds(t *testing.T) {
b := NewBuffer("hello\nworld")
// row 0 — can't join with row above
col := b.JoinLines(0)
if col != 0 {
t.Fatalf("expected 0 for out-of-bounds join, got %d", col)
}
// row beyond end
col = b.JoinLines(5)
if col != 0 {
t.Fatalf("expected 0 for out-of-bounds join, got %d", col)
}
if b.LineCount() != 2 {
t.Fatalf("expected unchanged line count 2, got %d", b.LineCount())
}
}

func TestBuffer_LineLen_Unicode(t *testing.T) {
b := NewBuffer("héllo 世界")
if got := b.LineLen(0); got != 8 {
t.Fatalf("expected 8 runes, got %d", got)
}
}

func TestBuffer_ResetModified(t *testing.T) {
b := NewBuffer("hello")
b.InsertChar(0, 0, 'x')
if !b.Modified() {
t.Fatal("expected modified after insert")
}
b.ResetModified()
if b.Modified() {
t.Fatal("expected not modified after reset")
}
}
2 changes: 2 additions & 0 deletions internal/editor/editor.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} else if m.cursorRow > 0 {
m.cursorRow--
m.cursorCol = m.buffer.LineLen(m.cursorRow)
m.scrollToCursor()
}
return m, nil

Expand All @@ -135,6 +136,7 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
} else if m.cursorRow < m.buffer.LineCount()-1 {
m.cursorRow++
m.cursorCol = 0
m.scrollToCursor()
}
return m, nil

Expand Down
Loading
Loading