Files
wen/internal/editor/buffer/buffer_test.go
T
2026-10-26 02:32:03 +00:00

185 lines
3.6 KiB
Go

package buffer
import (
"io"
"log/slog"
"reflect"
"testing"
"code.chimeric.al/dwrz/wen/internal/editor/buffer/line"
)
func newTestBuffer(lines ...string) *Buffer {
var b = &Buffer{
cursor: &Cursor{},
lines: make([]*line.Line, 0, len(lines)),
log: slog.New(slog.NewTextHandler(io.Discard, nil)),
offset: &offset{},
}
for _, s := range lines {
b.lines = append(b.lines, line.New(s))
}
if len(b.lines) == 0 {
b.lines = append(b.lines, &line.Line{})
}
return b
}
func bufferLines(b *Buffer) []string {
var out = make([]string, len(b.lines))
for i, l := range b.lines {
out[i] = l.String()
}
return out
}
type CursorMoveTest struct {
lines []string
action func(b *Buffer)
want Cursor
}
func TestCursorMovement(t *testing.T) {
var tests = []CursorMoveTest{
{
lines: []string{"ab", "cd"},
action: func(b *Buffer) { b.CursorRight() },
want: Cursor{line: 0, index: 1, glyph: 1},
},
{
lines: []string{"a", "b"},
action: func(b *Buffer) {
b.CursorRight()
b.CursorRight()
},
want: Cursor{line: 1, index: 0, glyph: 0},
},
{
lines: []string{"ab", "cd"},
action: func(b *Buffer) {
b.CursorDown()
b.CursorLeft()
},
want: Cursor{line: 0, index: 2, glyph: 2},
},
{
lines: []string{"hello", "hi"},
action: func(b *Buffer) {
b.CursorEnd()
b.CursorDown()
},
want: Cursor{line: 1, index: 2, glyph: 2},
},
{
lines: []string{"abc", "世界"},
action: func(b *Buffer) {
b.CursorRight()
b.CursorDown()
},
want: Cursor{line: 1, index: 0, glyph: 0},
},
{
lines: []string{"abc", "世界"},
action: func(b *Buffer) {
b.CursorEnd()
b.CursorDown()
},
want: Cursor{line: 1, index: 3, glyph: 2},
},
}
for n, test := range tests {
b := newTestBuffer(test.lines...)
test.action(b)
if got := b.Cursor(); got != test.want {
t.Errorf(
"#%d: expected cursor %+v, but got %+v",
n, test.want, got,
)
}
}
}
type EditTest struct {
lines []string
action func(b *Buffer)
wantLines []string
wantCursor Cursor
}
func TestEdit(t *testing.T) {
var tests = []EditTest{
{
lines: []string{""},
action: func(b *Buffer) {
b.Insert('a')
b.Insert('世')
},
wantLines: []string{"a世"},
wantCursor: Cursor{line: 0, index: 4, glyph: 3},
},
{
lines: []string{"hello"},
action: func(b *Buffer) { b.Newline() },
wantLines: []string{"", "hello"},
wantCursor: Cursor{line: 1, index: 0, glyph: 0},
},
{
lines: []string{"abcd"},
action: func(b *Buffer) {
b.CursorRight()
b.CursorRight()
b.Newline()
},
wantLines: []string{"ab", "cd"},
wantCursor: Cursor{line: 1, index: 0, glyph: 0},
},
{
lines: []string{"abcd"},
action: func(b *Buffer) {
b.CursorEnd()
b.Newline()
},
wantLines: []string{"abcd", ""},
wantCursor: Cursor{line: 1, index: 0, glyph: 0},
},
{
lines: []string{"ab", ""},
action: func(b *Buffer) {
b.CursorDown()
b.Backspace()
},
wantLines: []string{"ab"},
wantCursor: Cursor{line: 0, index: 2, glyph: 2},
},
{
lines: []string{"ab", "cd"},
action: func(b *Buffer) {
b.CursorDown()
b.Backspace()
},
wantLines: []string{"abcd"},
wantCursor: Cursor{line: 0, index: 2, glyph: 2},
},
}
for n, test := range tests {
b := newTestBuffer(test.lines...)
test.action(b)
if got := bufferLines(b); !reflect.DeepEqual(got, test.wantLines) {
t.Errorf(
"#%d: expected lines %q, but got %q",
n, test.wantLines, got,
)
}
if got := b.Cursor(); got != test.wantCursor {
t.Errorf(
"#%d: expected cursor %+v, but got %+v",
n, test.wantCursor, got,
)
}
}
}