star/bed/window/window_test.go

1871 lines
53 KiB
Go
Raw Normal View History

2025-04-26 19:33:14 +08:00
package window
import (
"bytes"
"math"
"reflect"
"strings"
"testing"
"b612.me/apps/b612/bed/event"
"b612.me/apps/b612/bed/mode"
)
func TestWindowState(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "test"; s.Name != expected {
t.Errorf("state.Name should be %q but got %q", expected, s.Name)
}
if s.Width != width {
t.Errorf("state.Width should be %d but got %d", width, s.Width)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := 13; s.Size != expected {
t.Errorf("s.Size should be %d but got %d", expected, s.Size)
}
if expected := int64(13); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
if !reflect.DeepEqual(s.EditedIndices, []int64{}) {
t.Errorf("state.EditedIndices should be empty but got %v", s.EditedIndices)
}
expected := []byte("Hello, world!" + strings.Repeat("\x00", height*width-13))
if !reflect.DeepEqual(s.Bytes, expected) {
t.Errorf("s.Bytes should be %q but got %q", expected, s.Bytes)
}
}
func TestWindowEmptyState(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "test"; s.Name != expected {
t.Errorf("state.Name should be %q but got %q", expected, s.Name)
}
if s.Width != width {
t.Errorf("state.Width should be %d but got %d", width, s.Width)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := 0; s.Size != expected {
t.Errorf("s.Size should be %d but got %d", expected, s.Size)
}
if expected := int64(0); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
if !reflect.DeepEqual(s.EditedIndices, []int64{}) {
t.Errorf("state.EditedIndices should be empty but got %v", s.EditedIndices)
}
expected := []byte(strings.Repeat("\x00", height*width))
if !reflect.DeepEqual(s.Bytes, expected) {
t.Errorf("s.Bytes should be %q but got %q", expected, s.Bytes)
}
window.scrollDown(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
}
func TestWindowCursorMotions(t *testing.T) {
r := strings.NewReader(strings.Repeat("Hello, world!", 100))
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorDown(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorDown(1)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width) * 2; s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorUp(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorDown(10)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width) * 11; s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 2; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
if expected := " world!"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.cursorRight(mode.Normal, 3)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width)*11 + 3; s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorRight(mode.Normal, 20)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width)*12 - 1; s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorLeft(3)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width)*12 - 4; s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorLeft(20)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width) * 11; s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorPrev(154)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(22); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if s.Offset != int64(width) {
t.Errorf("s.Offset should be %d but got %d", width, s.Offset)
}
window.cursorNext(mode.Normal, 200)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(222); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 4; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorNext(mode.Normal, 2000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(1299); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 72; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorHead(1)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(1296); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 72; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorEnd(1)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(1299); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 72; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorUp(20)
window.cursorEnd(1)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(991); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 61; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorEnd(11)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(1151); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 62; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorDown(30)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(1299); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 72; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorPrev(2000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorDown(2000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(width) * 81; s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 72; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorRight(mode.Normal, 1000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(1299); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 72; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorUp(2000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(3); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.windowTop(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.windowTop(7)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(96); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.windowTop(20)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(144); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.windowMiddle()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(64); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.windowBottom(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(144); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.windowBottom(7)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(48); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.windowBottom(20)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorGotoPos(event.Absolute{Offset: 0}, "goto")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.Absolute{Offset: 50}, "goto")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(50); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.Absolute{Offset: 100}, "goto")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(100); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.Relative{Offset: -10}, "goto")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(90); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.Absolute{Offset: 30}, "%")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(390); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.Relative{Offset: 30}, "%")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(780); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.End{Offset: -30}, "%")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(909); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.Absolute{Offset: 30}, "go[to]")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(480); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.Relative{Offset: 30}, "go[to]")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(960); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorGotoPos(event.End{Offset: -30}, "go[to]")
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(819); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowScreenMotions(t *testing.T) {
r := strings.NewReader(strings.Repeat("Hello, world!", 100))
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.pageDown()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(128); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(128); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.pageDownHalf()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(208); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(208); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.scrollDown(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(224); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(224); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.scrollUp(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(224); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(208); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.scrollDown(30)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(688); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(688); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.scrollUp(30)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(352); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(208); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.pageUpHalf()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(272); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(128); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.pageUp()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.pageEnd()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(1296); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(width) * 72; s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.pageTop()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorNext(mode.Normal, 5)
window.scrollTop(5)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(85); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(80); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorDown(4)
window.scrollTop(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(149); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(144); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.scrollTopHead(10)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(160); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(160); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorNext(mode.Normal, 5)
window.scrollMiddle(12)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(197); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(112); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.scrollMiddleHead(15)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(240); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(160); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorNext(mode.Normal, 5)
window.scrollBottom(12)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(197); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(48); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.cursorDown(8)
window.scrollBottom(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(325); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(176); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
window.scrollBottomHead(10)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(160); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(16); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
}
func TestWindowDeleteBytes(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 7)
window.deleteBytes(0)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, orld!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(7); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.deleteBytes(3)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, d!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(7); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.deleteBytes(3)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, \x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(6); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.deleteByte()
window.deleteByte()
window.deleteByte()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hell\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(3); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.deleteBytes(0)
window.deleteBytes(0)
window.deleteBytes(0)
window.deleteBytes(0)
window.deleteBytes(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
if expected := int64(0); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
}
func TestWindowDeletePrevBytes(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 5)
window.deletePrevBytes(0)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hell, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(4); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.deletePrevBytes(3)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "H, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(1); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.deletePrevBytes(3)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := ", world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowIncrementDecrement(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.increment(0)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Iello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.increment(1000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "1ello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.increment(math.MaxInt64)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "0ello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.decrement(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "/ello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.decrement(1000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Gello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.decrement(math.MaxInt64)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.cursorNext(mode.Normal, 7)
window.increment(1000)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, _orld!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
}
func TestWindowIncrementDecrementEmpty(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := 0; s.Size != expected {
t.Errorf("s.Size should be %d but got %d", expected, s.Size)
}
if expected := int64(0); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
window.increment(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "\x01\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := 1; s.Size != expected {
t.Errorf("s.Size should be %d but got %d", expected, s.Size)
}
if expected := int64(1); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
window, err = newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.decrement(0)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "\xff\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := 1; s.Size != expected {
t.Errorf("s.Size should be %d but got %d", expected, s.Size)
}
if expected := int64(1); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
}
func TestWindowInsertByte(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 1
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 7)
window.startInsert()
window.insertByte(mode.Insert, 0x04)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := true; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x40'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
window.insertByte(mode.Insert, 0x0a)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, Jworld!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
if expected := int64(14); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
window.exitInsert()
window.startAppendEnd()
window.insertByte(mode.Insert, 0x04)
window.insertByte(mode.Insert, 0x0b)
window.insertByte(mode.Insert, 0x04)
window.insertByte(mode.Insert, 0x0c)
window.insertByte(mode.Insert, 0x04)
window.insertByte(mode.Insert, 0x0d)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "M\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
if expected := int64(18); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(16); s.Offset != expected {
t.Errorf("s.Offset should be %d but got %d", expected, s.Offset)
}
}
func TestWindowInsertEmpty(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.startInsert()
window.insertByte(mode.Insert, 0x04)
window.insertByte(mode.Insert, 0x0a)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "J\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
if expected := int64(2); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "J\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(1); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowInsertHead(t *testing.T) {
r := strings.NewReader(strings.Repeat("Hello, world!", 2))
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.pageEnd()
window.startInsertHead()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(16); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Insert, 0x03)
window.insertByte(mode.Insert, 0x0a)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, world!Hel:lo, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
if expected := int64(27); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(17); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowInsertHeadEmpty(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.startInsertHead()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
if expected := int64(1); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Insert, 0x04)
window.insertByte(mode.Insert, 0x0a)
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "J\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(1); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowAppend(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 7)
window.startAppend()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(8); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Insert, 0x03)
window.insertByte(mode.Insert, 0x0a)
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, w:orld!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(14); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(8); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.cursorNext(mode.Normal, 10)
window.startAppend()
window.insertByte(mode.Insert, 0x03)
window.insertByte(mode.Insert, 0x0A)
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, w:orld!:\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(15); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(14); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowAppendEmpty(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.startAppend()
window.exitInsert()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.startAppend()
window.insertByte(mode.Insert, 0x03)
window.insertByte(mode.Insert, 0x0a)
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := ":\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(1); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.startAppendEnd()
window.insertByte(mode.Insert, 0x03)
window.insertByte(mode.Insert, 0x0b)
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := ":;\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(2); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(1); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowReplaceByte(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 7)
window.startReplaceByte()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(7); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0a)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, :orld!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(13); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(7); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowReplaceByteEmpty(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.startReplaceByte()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0a)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := ":\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(1); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowReplace(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 10)
window.startReplace()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(10); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0a)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, wor:d!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(13); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(11); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0b)
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0c)
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0d)
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0e)
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, wor:;<=>\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(15); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(14); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowReplaceEmpty(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.startReplace()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := int64(0); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0a)
window.insertByte(mode.Replace, 0x03)
window.insertByte(mode.Replace, 0x0b)
window.exitInsert()
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := ":;\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(2); s.Length != expected {
t.Errorf("s.Length should be %d but got %d", expected, s.Length)
}
if expected := int64(1); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
}
func TestWindowInsertByte2(t *testing.T) {
r := strings.NewReader("")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.startInsert()
window.insertByte(mode.Insert, 0x00)
window.insertByte(mode.Insert, 0x01)
window.insertByte(mode.Insert, 0x02)
window.insertByte(mode.Insert, 0x03)
window.insertByte(mode.Insert, 0x04)
window.insertByte(mode.Insert, 0x05)
window.insertByte(mode.Insert, 0x06)
window.insertByte(mode.Insert, 0x07)
window.insertByte(mode.Insert, 0x08)
window.insertByte(mode.Insert, 0x09)
window.insertByte(mode.Insert, 0x0a)
window.insertByte(mode.Insert, 0x0b)
window.insertByte(mode.Insert, 0x0c)
window.insertByte(mode.Insert, 0x0d)
window.insertByte(mode.Insert, 0x0e)
window.insertByte(mode.Insert, 0x0f)
window.exitInsert()
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "\x01\x23\x45\x67\x89\xab\xcd\xef\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
}
func TestWindowBackspace(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 5)
window.startInsert()
window.backspace(mode.Insert)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hell, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
window.backspace(mode.Insert)
window.backspace(mode.Insert)
window.backspace(mode.Insert)
window.backspace(mode.Insert)
window.backspace(mode.Insert)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := ", world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
}
func TestWindowBackspacePending(t *testing.T) {
r := strings.NewReader("Hello, world!")
width, height := 16, 10
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
window.cursorNext(mode.Normal, 5)
window.startInsert()
window.insertByte(mode.Insert, 0x03)
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := true; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x30'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
window.backspace(mode.Insert)
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := false; s.Pending != expected {
t.Errorf("s.Pending should be %v but got %v", expected, s.Pending)
}
if expected := byte('\x00'); s.PendingByte != expected {
t.Errorf("s.PendingByte should be %q but got %q", expected, s.PendingByte)
}
}
func TestWindowEventRune(t *testing.T) {
width, height := 16, 10
redrawCh := make(chan struct{})
window, err := newWindow(strings.NewReader(""), "test", "test", nil, redrawCh)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
str := "48723fffab"
go func() {
defer close(redrawCh)
window.emit(event.Event{Type: event.StartInsert})
for _, r := range str {
window.emit(event.Event{Type: event.Rune, Rune: r, Mode: mode.Insert})
}
}()
<-redrawCh
for range str {
<-redrawCh
}
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "\x48\x72\x3f\xff\xab\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
<-redrawCh
}
func TestWindowEventRuneText(t *testing.T) {
width, height := 16, 10
redrawCh := make(chan struct{})
window, err := newWindow(strings.NewReader(""), "test", "test", nil, redrawCh)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
str := "Hello, World!\nこんにちは、世界\n鰰は魚の一種"
go func() {
defer close(redrawCh)
window.emit(event.Event{Type: event.SwitchFocus})
window.emit(event.Event{Type: event.StartInsert})
for _, r := range str {
window.emit(event.Event{Type: event.Rune, Rune: r, Mode: mode.Insert})
}
}()
<-redrawCh
<-redrawCh
for range str {
<-redrawCh
}
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := str + "\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
<-redrawCh
}
func TestWindowEventUndoRedo(t *testing.T) {
width, height := 16, 10
redrawCh, waitCh := make(chan struct{}), make(chan struct{})
window, err := newWindow(strings.NewReader("Hello, world!"), "test", "test", nil, redrawCh)
if err != nil {
t.Fatal(err)
}
window.setSize(width, height)
go func() {
defer func() {
close(redrawCh)
close(waitCh)
}()
window.emit(event.Event{Type: event.Undo})
window.emit(event.Event{Type: event.SwitchFocus})
window.emit(event.Event{Type: event.StartAppend, Mode: mode.Insert})
<-waitCh
window.emit(event.Event{Type: event.Rune, Rune: 'x', Mode: mode.Insert})
window.emit(event.Event{Type: event.Rune, Rune: 'y', Mode: mode.Insert})
window.emit(event.Event{Type: event.Rune, Rune: 'z', Mode: mode.Insert})
window.emit(event.Event{Type: event.ExitInsert})
<-waitCh
window.emit(event.Event{Type: event.StartInsert, Mode: mode.Insert})
window.emit(event.Event{Type: event.Rune, Rune: 'x', Mode: mode.Insert})
window.emit(event.Event{Type: event.Rune, Rune: 'y', Mode: mode.Insert})
window.emit(event.Event{Type: event.CursorLeft, Mode: mode.Insert})
window.emit(event.Event{Type: event.Rune, Rune: 'z', Mode: mode.Insert})
window.emit(event.Event{Type: event.ExitInsert})
<-waitCh
window.emit(event.Event{Type: event.Undo, Count: 2})
window.emit(event.Event{Type: event.StartInsert, Mode: mode.Insert})
window.emit(event.Event{Type: event.Rune, Rune: 'w', Mode: mode.Insert})
<-waitCh
window.emit(event.Event{Type: event.ExitInsert})
window.emit(event.Event{Type: event.Undo})
<-waitCh
window.emit(event.Event{Type: event.Redo, Count: 2})
}()
for range 3 {
<-redrawCh
}
s, err := window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(1); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
waitCh <- struct{}{}
for range 4 {
<-redrawCh
}
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hxyzello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(3); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
waitCh <- struct{}{}
for range 6 {
<-redrawCh
}
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hxyxzyzello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(5); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
waitCh <- struct{}{}
for range 3 {
<-redrawCh
}
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hxywzello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(4); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
waitCh <- struct{}{}
for range 2 {
<-redrawCh
}
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hxyzello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(3); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
waitCh <- struct{}{}
<-redrawCh
s, err = window.state(width, height)
if err != nil {
t.Fatal(err)
}
if expected := "Hxywzello, world!\x00"; !strings.HasPrefix(string(s.Bytes), expected) {
t.Errorf("s.Bytes should start with %q but got %q", expected, string(s.Bytes))
}
if expected := int64(4); s.Cursor != expected {
t.Errorf("s.Cursor should be %d but got %d", expected, s.Cursor)
}
<-redrawCh
<-waitCh
}
func TestWindowWriteTo(t *testing.T) {
r := strings.NewReader("Hello, world!")
window, err := newWindow(r, "test", "test", nil, nil)
if err != nil {
t.Fatal(err)
}
window.setSize(20, 10)
window.cursorNext(mode.Normal, 3)
window.startVisual()
window.cursorNext(mode.Normal, 7)
for _, testCase := range []struct {
r *event.Range
expected string
}{
{nil, "Hello, world!"},
{&event.Range{From: event.VisualStart{}, To: event.VisualEnd{}}, "lo, worl"},
} {
b := new(bytes.Buffer)
n, err := window.writeTo(testCase.r, b)
if expected := int64(len(testCase.expected)); n != expected {
t.Errorf("writeTo should return %d but got: %d", expected, n)
}
if err != nil {
t.Errorf("err should be nil but got: %v", err)
}
if b.String() != testCase.expected {
t.Errorf("window should write %q with range %+v but got %q", testCase.expected, testCase.r, b.String())
}
}
}