Improve textarea tests (#490)

This commit is contained in:
Michael Lorant
2024-03-08 19:23:05 -05:00
committed by GitHub
parent e3823b2f22
commit b9e62cbfe1
+268 -187
View File
@@ -10,101 +10,6 @@ import (
tea "github.com/charmbracelet/bubbletea"
)
func TestNew(t *testing.T) {
textarea := newTextArea()
view := textarea.View()
if !strings.Contains(view, ">") {
t.Log(view)
t.Error("Text area did not render the prompt")
}
if !strings.Contains(view, "World!") {
t.Log(view)
t.Error("Text area did not render the placeholder")
}
}
func TestInput(t *testing.T) {
textarea := newTextArea()
input := "foo"
for _, k := range []rune(input) {
textarea, _ = textarea.Update(keyPress(k))
}
view := textarea.View()
if !strings.Contains(view, input) {
t.Log(view)
t.Error("Text area did not render the input")
}
if textarea.col != len(input) {
t.Log(view)
t.Error("Text area did not move the cursor to the correct position")
}
}
func TestSoftWrap(t *testing.T) {
textarea := newTextArea()
textarea.Prompt = ""
textarea.ShowLineNumbers = false
textarea.SetWidth(5)
textarea.SetHeight(5)
textarea.CharLimit = 60
textarea, _ = textarea.Update(nil)
input := "foo bar baz"
for _, k := range []rune(input) {
textarea, _ = textarea.Update(keyPress(k))
}
view := textarea.View()
for _, word := range strings.Split(input, " ") {
if !strings.Contains(view, word) {
t.Log(view)
t.Error("Text area did not render the input")
}
}
// Due to the word wrapping, each word will be on a new line and the
// text area will look like this:
//
// > foo
// > bar
// > baz█
//
// However, due to soft-wrapping the column will still be at the end of the line.
if textarea.row != 0 || textarea.col != len(input) {
t.Log(view)
t.Error("Text area did not move the cursor to the correct position")
}
}
func TestCharLimit(t *testing.T) {
textarea := newTextArea()
// First input (foo bar) should be accepted as it will fall within the
// CharLimit. Second input (baz) should not appear in the input.
input := []string{"foo bar", "baz"}
textarea.CharLimit = len(input[0])
for _, k := range []rune(strings.Join(input, " ")) {
textarea, _ = textarea.Update(keyPress(k))
}
view := textarea.View()
if strings.Contains(view, input[1]) {
t.Log(view)
t.Error("Text area should not include input past the character limit")
}
}
func TestVerticalScrolling(t *testing.T) {
textarea := newTextArea()
textarea.Prompt = ""
@@ -420,21 +325,29 @@ func TestVerticalNavigationShouldRememberPositionWhileTraversing(t *testing.T) {
}
func TestView(t *testing.T) {
type want struct {
view string
cursorRow int
cursorCol int
}
tests := []struct {
name string
modelFunc func(Model) Model
expected string
want want
}{
{
name: "placeholder",
expected: heredoc.Doc(`
> 1 Hello, World!
> ~
> ~
> ~
> ~
> ~
`),
want: want{
view: heredoc.Doc(`
> 1 Hello, World!
> ~
> ~
> ~
> ~
> ~
`),
},
},
{
name: "single line",
@@ -443,14 +356,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> 1 the first line
> ~
> ~
> ~
> ~
> ~
`),
want: want{
view: heredoc.Doc(`
> 1 the first line
> ~
> ~
> ~
> ~
> ~
`),
cursorRow: 0,
cursorCol: 14,
},
},
{
name: "multiple lines",
@@ -459,14 +376,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> 1 the first line
> 2 the second line
> 3 the third line
> ~
> ~
> ~
`),
want: want{
view: heredoc.Doc(`
> 1 the first line
> 2 the second line
> 3 the third line
> ~
> ~
> ~
`),
cursorRow: 2,
cursorCol: 14,
},
},
{
name: "single line without line numbers",
@@ -476,14 +397,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> the first line
> ~
> ~
> ~
> ~
> ~
`),
want: want{
view: heredoc.Doc(`
> the first line
> ~
> ~
> ~
> ~
> ~
`),
cursorRow: 0,
cursorCol: 14,
},
},
{
name: "multipline lines without line numbers",
@@ -493,14 +418,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> the first line
> the second line
> the third line
> ~
> ~
> ~
`),
want: want{
view: heredoc.Doc(`
> the first line
> the second line
> the third line
> ~
> ~
> ~
`),
cursorRow: 2,
cursorCol: 14,
},
},
{
name: "single line and custom end of buffer character",
@@ -510,14 +439,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> 1 the first line
> *
> *
> *
> *
> *
`),
want: want{
view: heredoc.Doc(`
> 1 the first line
> *
> *
> *
> *
> *
`),
cursorRow: 0,
cursorCol: 14,
},
},
{
name: "multiple lines and custom end of buffer character",
@@ -527,14 +460,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> 1 the first line
> 2 the second line
> 3 the third line
> *
> *
> *
`),
want: want{
view: heredoc.Doc(`
> 1 the first line
> 2 the second line
> 3 the third line
> *
> *
> *
`),
cursorRow: 2,
cursorCol: 14,
},
},
{
name: "single line without line numbers and custom end of buffer character",
@@ -545,14 +482,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> the first line
> *
> *
> *
> *
> *
`),
want: want{
view: heredoc.Doc(`
> the first line
> *
> *
> *
> *
> *
`),
cursorRow: 0,
cursorCol: 14,
},
},
{
name: "multiple lines without line numbers and custom end of buffer character",
@@ -563,14 +504,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
> the first line
> the second line
> the third line
> *
> *
> *
`),
want: want{
view: heredoc.Doc(`
> the first line
> the second line
> the third line
> *
> *
> *
`),
cursorRow: 2,
cursorCol: 14,
},
},
{
name: "single line and custom prompt",
@@ -580,14 +525,18 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
* 1 the first line
* ~
* ~
* ~
* ~
* ~
`),
want: want{
view: heredoc.Doc(`
* 1 the first line
* ~
* ~
* ~
* ~
* ~
`),
cursorRow: 0,
cursorCol: 14,
},
},
{
name: "multiple lines and custom prompt",
@@ -597,14 +546,131 @@ func TestView(t *testing.T) {
return m
},
expected: heredoc.Doc(`
* 1 the first line
* 2 the second line
* 3 the third line
* ~
* ~
* ~
`),
want: want{
view: heredoc.Doc(`
* 1 the first line
* 2 the second line
* 3 the third line
* ~
* ~
* ~
`),
cursorRow: 2,
cursorCol: 14,
},
},
{
name: "type single line",
modelFunc: func(m Model) Model {
input := "foo"
m = sendString(m, input)
return m
},
want: want{
view: heredoc.Doc(`
> 1 foo
> ~
> ~
> ~
> ~
> ~
`),
cursorRow: 0,
cursorCol: 3,
},
},
{
name: "type multiple lines",
modelFunc: func(m Model) Model {
input := "foo\nbar\nbaz"
m = sendString(m, input)
return m
},
want: want{
view: heredoc.Doc(`
> 1 foo
> 2 bar
> 3 baz
> ~
> ~
> ~
`),
cursorRow: 2,
cursorCol: 3,
},
},
{
name: "softwrap",
modelFunc: func(m Model) Model {
m.ShowLineNumbers = false
m.Prompt = ""
m.SetWidth(5)
input := "foo bar baz"
m = sendString(m, input)
return m
},
want: want{
view: heredoc.Doc(`
foo
bar
baz
~
~
~
`),
cursorRow: 2,
cursorCol: 3,
},
},
{
name: "single line character limit",
modelFunc: func(m Model) Model {
m.CharLimit = 7
input := "foo bar baz"
m = sendString(m, input)
return m
},
want: want{
view: heredoc.Doc(`
> 1 foo bar
> ~
> ~
> ~
> ~
> ~
`),
cursorRow: 0,
cursorCol: 7,
},
},
{
name: "multiple lines character limit",
modelFunc: func(m Model) Model {
m.CharLimit = 19
input := "foo bar baz\nfoo bar baz"
m = sendString(m, input)
return m
},
want: want{
view: heredoc.Doc(`
> 1 foo bar baz
> 2 foo bar
> ~
> ~
> ~
> ~
`),
cursorRow: 1,
cursorCol: 7,
},
},
}
@@ -617,10 +683,17 @@ func TestView(t *testing.T) {
}
view := stripString(textarea.View())
expected := stripString(tt.expected)
wantView := stripString(tt.want.view)
if view != expected {
t.Fatalf("Expected:\n%v\nGot:\n%v\n", expected, view)
if view != wantView {
t.Fatalf("Want:\n%v\nGot:\n%v\n", wantView, view)
}
cursorRow := textarea.cursorLineNumber()
cursorCol := textarea.LineInfo().ColumnOffset
if tt.want.cursorRow != cursorRow || tt.want.cursorCol != cursorCol {
format := "Want cursor at row: %v, col: %v Got: row: %v col: %v\n"
t.Fatalf(format, tt.want.cursorRow, tt.want.cursorCol, cursorRow, cursorCol)
}
})
}
@@ -643,6 +716,14 @@ func keyPress(key rune) tea.Msg {
return tea.KeyMsg{Type: tea.KeyRunes, Runes: []rune{key}, Alt: false}
}
func sendString(m Model, str string) Model {
for _, k := range []rune(str) {
m, _ = m.Update(keyPress(k))
}
return m
}
func stripString(str string) string {
s := stripansi.Strip(str)
ss := strings.Split(s, "\n")