180 lines
5.6 KiB
Go
180 lines
5.6 KiB
Go
package editor
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.gophernest.net/azpect/TextEditor/internal/core"
|
|
)
|
|
|
|
func TestJoinLines(t *testing.T) {
|
|
t.Run("J joins current line with next line using a space", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"hello", "world"})
|
|
sendKeys(tm, "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"hello world"})
|
|
if m.ActiveWindow().Cursor.Line != 0 {
|
|
t.Errorf("Cursor.Line = %d, want 0", m.ActiveWindow().Cursor.Line)
|
|
}
|
|
if m.ActiveWindow().Cursor.Col != 0 {
|
|
t.Errorf("Cursor.Col = %d, want 0", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("J joins from the cursor line, not always the first line", func(t *testing.T) {
|
|
tm := newTestModelWithLinesAndCursorPos(t, []string{"one", "two", "three"}, core.Position{Line: 1, Col: 2})
|
|
sendKeys(tm, "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"one", "two three"})
|
|
if m.ActiveWindow().Cursor.Line != 1 {
|
|
t.Errorf("Cursor.Line = %d, want 1", m.ActiveWindow().Cursor.Line)
|
|
}
|
|
if m.ActiveWindow().Cursor.Col != 2 {
|
|
t.Errorf("Cursor.Col = %d, want 2", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("J trims indentation from the joined line", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"foo", " bar"})
|
|
sendKeys(tm, "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"foo bar"})
|
|
})
|
|
}
|
|
|
|
func TestJoinLinesNoSpace(t *testing.T) {
|
|
t.Run("gJ joins without inserting a space", func(t *testing.T) {
|
|
tm := newTestModelWithLinesAndCursorPos(t, []string{"hello", "world"}, core.Position{Line: 0, Col: 3})
|
|
sendKeys(tm, "g", "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"helloworld"})
|
|
if m.ActiveWindow().Cursor.Line != 0 {
|
|
t.Errorf("Cursor.Line = %d, want 0", m.ActiveWindow().Cursor.Line)
|
|
}
|
|
if m.ActiveWindow().Cursor.Col != 3 {
|
|
t.Errorf("Cursor.Col = %d, want 3", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("gJ preserves leading whitespace on the next line", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"foo", " bar"})
|
|
sendKeys(tm, "g", "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"foo bar"})
|
|
})
|
|
}
|
|
|
|
func TestJoinLinesWithCount(t *testing.T) {
|
|
t.Run("3J joins three lines with spaces", func(t *testing.T) {
|
|
tm := newTestModelWithLinesAndCursorPos(t, []string{"a", "b", "c", "d"}, core.Position{Line: 0, Col: 1})
|
|
sendKeys(tm, "3", "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"a b c", "d"})
|
|
if m.ActiveWindow().Cursor.Line != 0 {
|
|
t.Errorf("Cursor.Line = %d, want 0", m.ActiveWindow().Cursor.Line)
|
|
}
|
|
if m.ActiveWindow().Cursor.Col != 1 {
|
|
t.Errorf("Cursor.Col = %d, want 1", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("3gJ joins three lines without spaces", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"a", "b", "c", "d"})
|
|
sendKeys(tm, "3", "g", "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"abc", "d"})
|
|
})
|
|
|
|
t.Run("count larger than remaining lines joins through end of file", func(t *testing.T) {
|
|
tm := newTestModelWithLinesAndCursorPos(t, []string{"a", "b", "c"}, core.Position{Line: 1, Col: 0})
|
|
sendKeys(tm, "9", "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"a", "b c"})
|
|
})
|
|
}
|
|
|
|
func TestJoinLinesEdgeCases(t *testing.T) {
|
|
t.Run("J on last line does nothing", func(t *testing.T) {
|
|
tm := newTestModelWithLinesAndCursorPos(t, []string{"one", "two"}, core.Position{Line: 1, Col: 2})
|
|
sendKeys(tm, "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"one", "two"})
|
|
if m.ActiveWindow().Cursor.Line != 1 {
|
|
t.Errorf("Cursor.Line = %d, want 1", m.ActiveWindow().Cursor.Line)
|
|
}
|
|
if m.ActiveWindow().Cursor.Col != 2 {
|
|
t.Errorf("Cursor.Col = %d, want 2", m.ActiveWindow().Cursor.Col)
|
|
}
|
|
})
|
|
|
|
t.Run("gJ on single-line buffer does nothing", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"solo"})
|
|
sendKeys(tm, "g", "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"solo"})
|
|
})
|
|
|
|
t.Run("J across many empty lines keeps a single separating space", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"foo", "", "", "", "bar"})
|
|
sendKeys(tm, "5", "J")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"foo bar"})
|
|
})
|
|
}
|
|
|
|
func TestJoinLinesRepeatAndUndo(t *testing.T) {
|
|
t.Run("dot repeats J join", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"a", "b", "c", "d"})
|
|
sendKeys(tm, "J", "j", ".")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"a b", "c d"})
|
|
})
|
|
|
|
t.Run("dot repeats gJ join", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"a", "b", "c", "d"})
|
|
sendKeys(tm, "g", "J", "j", ".")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"ab", "cd"})
|
|
})
|
|
|
|
t.Run("undo restores lines after J", func(t *testing.T) {
|
|
tm := newTestModelWithLines(t, []string{"left", "right"})
|
|
sendKeys(tm, "J", "u")
|
|
|
|
m := getFinalModel(t, tm)
|
|
assertBufferLines(t, m.ActiveBuffer(), []string{"left", "right"})
|
|
})
|
|
}
|
|
|
|
func assertBufferLines(t *testing.T, buf *core.Buffer, want []string) {
|
|
t.Helper()
|
|
got := make([]string, buf.LineCount())
|
|
for i := 0; i < buf.LineCount(); i++ {
|
|
got[i] = buf.Line(i)
|
|
}
|
|
|
|
if len(got) != len(want) {
|
|
t.Errorf("lines = %q (len=%d), want %q (len=%d)", got, len(got), want, len(want))
|
|
return
|
|
}
|
|
|
|
for i := range got {
|
|
if got[i] != want[i] {
|
|
t.Errorf("lines = %q (len=%d), want %q (len=%d)", got, len(got), want, len(want))
|
|
return
|
|
}
|
|
}
|
|
}
|