test: generated loads of tests for the delete operator.
This commit is contained in:
parent
b3276efe94
commit
175ff1daa7
@ -6,6 +6,8 @@ import (
|
|||||||
"git.gophernest.net/azpect/TextEditor/internal/action"
|
"git.gophernest.net/azpect/TextEditor/internal/action"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// NOTE: AI Generated tests
|
||||||
|
|
||||||
func TestDeleteLine(t *testing.T) {
|
func TestDeleteLine(t *testing.T) {
|
||||||
t.Run("test 'dd' deletes first line", func(t *testing.T) {
|
t.Run("test 'dd' deletes first line", func(t *testing.T) {
|
||||||
lines := []string{"hello", "world"}
|
lines := []string{"hello", "world"}
|
||||||
@ -531,6 +533,366 @@ func TestDeleteOperatorWithVerticalMotion(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDeleteOperatorWithWordMotion(t *testing.T) {
|
||||||
|
// --- dw tests (delete to start of next word) ---
|
||||||
|
t.Run("test 'dw' deletes word from start of word", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "w")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.CursorX() != 0 {
|
||||||
|
t.Errorf("CursorX() = %d, want 0", m.CursorX())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'dw' deletes from middle of word to start of next word", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 2, Line: 0})
|
||||||
|
sendKeys(tm, "d", "w")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "heworld" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"heworld\"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.CursorX() != 2 {
|
||||||
|
t.Errorf("CursorX() = %d, want 2", m.CursorX())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'dw' at last word deletes to end of line", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 6, Line: 0})
|
||||||
|
sendKeys(tm, "d", "w")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "hello " {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello \"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test '2dw' deletes two words", func(t *testing.T) {
|
||||||
|
lines := []string{"one two three four"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "2", "d", "w")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "three four" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"three four\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd2w' deletes two words", func(t *testing.T) {
|
||||||
|
lines := []string{"one two three four"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "2", "w")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "three four" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"three four\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'dw' with punctuation", func(t *testing.T) {
|
||||||
|
lines := []string{"hello, world"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "w")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// 'w' motion stops at punctuation, so it should delete "hello"
|
||||||
|
if m.Line(0) != ", world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \", world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- de tests (delete to end of word, inclusive) ---
|
||||||
|
t.Run("test 'de' deletes to end of word from start (inclusive)", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "e")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// 'e' is inclusive - deletes "hello" (cols 0-4 inclusive)
|
||||||
|
if m.Line(0) != "o world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"o world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.CursorX() != 0 {
|
||||||
|
t.Errorf("CursorX() = %d, want 0", m.CursorX())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'de' deletes to end of word from middle (inclusive)", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 2, Line: 0})
|
||||||
|
sendKeys(tm, "d", "e")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// From 'l' (col 2) to 'o' (col 4) inclusive → deletes "llo"
|
||||||
|
if m.Line(0) != "heo world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"heo world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'de' at end of word jumps to next word end", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 4, Line: 0})
|
||||||
|
sendKeys(tm, "d", "e")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// From 'o' of "hello" (col 4) to 'd' of "world" (col 10) inclusive
|
||||||
|
if m.Line(0) != "helld" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"helld\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test '2de' deletes to end of second word (inclusive)", func(t *testing.T) {
|
||||||
|
lines := []string{"one two three four"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "2", "d", "e")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// Deletes "one" and "two" (to end of second word inclusive)
|
||||||
|
if m.Line(0) != "o three four" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"o three four\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- db tests (delete backward word) ---
|
||||||
|
t.Run("test 'db' does nothing at start of line", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "b")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "hello world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'db' deletes back to start of current word", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 8, Line: 0})
|
||||||
|
sendKeys(tm, "d", "b")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// cursor at 'r' of "world", db should delete back to start of "world"
|
||||||
|
if m.Line(0) != "hello rld" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello rld\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'db' at start of word deletes previous word", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 6, Line: 0})
|
||||||
|
sendKeys(tm, "d", "b")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// cursor at 'w', db should delete "hello " back
|
||||||
|
if m.Line(0) != "world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test '2db' deletes two words backward", func(t *testing.T) {
|
||||||
|
lines := []string{"one two three four"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 14, Line: 0})
|
||||||
|
sendKeys(tm, "2", "d", "b")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// cursor at 'f' of "four", 2db should delete "two three "
|
||||||
|
if m.Line(0) != "one four" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"one four\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'db' at end of line", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 10, Line: 0})
|
||||||
|
sendKeys(tm, "d", "b")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// cursor at 'd' (last char), db should delete back to start of "world"
|
||||||
|
if m.Line(0) != "hello d" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello d\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteOperatorWithLinePositionMotion(t *testing.T) {
|
||||||
|
// --- d0 tests (delete to line start) ---
|
||||||
|
t.Run("test 'd0' does nothing at start of line", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "0")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "hello world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd0' deletes from cursor to start of line", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 6, Line: 0})
|
||||||
|
sendKeys(tm, "d", "0")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.CursorX() != 0 {
|
||||||
|
t.Errorf("CursorX() = %d, want 0", m.CursorX())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd0' from end of line", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 10, Line: 0})
|
||||||
|
sendKeys(tm, "d", "0")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "d" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"d\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd0' from middle of line", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 3, Line: 0})
|
||||||
|
sendKeys(tm, "d", "0")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "lo world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"lo world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- d$ tests (delete to line end) ---
|
||||||
|
t.Run("test 'd$' deletes to end of line from start", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "$")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd$' deletes to end of line from middle", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 6, Line: 0})
|
||||||
|
sendKeys(tm, "d", "$")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "hello " {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello \"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd$' at end of line deletes last char", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 10, Line: 0})
|
||||||
|
sendKeys(tm, "d", "$")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "hello worl" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello worl\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd$' does not affect other lines", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world", "second line"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 6, Line: 0})
|
||||||
|
sendKeys(tm, "d", "$")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "hello " {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello \"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.Line(1) != "second line" {
|
||||||
|
t.Errorf("Line(1) = %q, want \"second line\"", m.Line(1))
|
||||||
|
}
|
||||||
|
if m.LineCount() != 2 {
|
||||||
|
t.Errorf("LineCount() = %d, want 2", m.LineCount())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd$' on empty line does nothing", func(t *testing.T) {
|
||||||
|
lines := []string{"", "second line"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "$")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
if m.Line(0) != "" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"\"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.LineCount() != 2 {
|
||||||
|
t.Errorf("LineCount() = %d, want 2", m.LineCount())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// --- d_ tests (delete to first non-whitespace) ---
|
||||||
|
t.Run("test 'd_' from start deletes leading whitespace", func(t *testing.T) {
|
||||||
|
lines := []string{" hello world"}
|
||||||
|
tm := newTestModelWithLines(t, lines)
|
||||||
|
sendKeys(tm, "d", "_")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// From col 0 to first non-whitespace (col 3, 'h') - deletes leading spaces
|
||||||
|
if m.Line(0) != "hello world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \"hello world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.CursorX() != 0 {
|
||||||
|
t.Errorf("CursorX() = %d, want 0", m.CursorX())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd_' from middle whitespace deletes to first non-blank", func(t *testing.T) {
|
||||||
|
lines := []string{" hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 1, Line: 0})
|
||||||
|
sendKeys(tm, "d", "_")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// From col 1 to first non-whitespace (col 3, 'h') - deletes cols 1-2
|
||||||
|
if m.Line(0) != " hello world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \" hello world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
if m.CursorX() != 1 {
|
||||||
|
t.Errorf("CursorX() = %d, want 1", m.CursorX())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd_' from after first char deletes back to first non-whitespace", func(t *testing.T) {
|
||||||
|
lines := []string{" hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 6, Line: 0})
|
||||||
|
sendKeys(tm, "d", "_")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// From col 6 ('l') back to col 3 ('h')
|
||||||
|
// Should delete "hel" leaving " lo world"
|
||||||
|
if m.Line(0) != " lo world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \" lo world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("test 'd_' on line with no leading whitespace", func(t *testing.T) {
|
||||||
|
lines := []string{"hello world"}
|
||||||
|
tm := newTestModelWithLinesAndCursorPos(t, lines, action.Position{Col: 5, Line: 0})
|
||||||
|
sendKeys(tm, "d", "_")
|
||||||
|
|
||||||
|
m := getFinalModel(t, tm)
|
||||||
|
// From col 5 (' ') back to col 0 ('h')
|
||||||
|
// Should delete "hello" leaving " world"
|
||||||
|
if m.Line(0) != " world" {
|
||||||
|
t.Errorf("Line(0) = %q, want \" world\"", m.Line(0))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func TestDeleteOperatorWithJumpMotion(t *testing.T) {
|
func TestDeleteOperatorWithJumpMotion(t *testing.T) {
|
||||||
t.Run("test 'dG' deletes from cursor to end of file", func(t *testing.T) {
|
t.Run("test 'dG' deletes from cursor to end of file", func(t *testing.T) {
|
||||||
lines := []string{"line 1", "line 2", "line 3", "line 4", "line 5"}
|
lines := []string{"line 1", "line 2", "line 3", "line 4", "line 5"}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user