mirror of
https://github.com/taigrr/bubbletea.git
synced 2026-04-02 11:09:17 -07:00
This fixes Kill resulting in a final nil model being returned. We can also drop the kill channel and rely on our existing context channel.
152 lines
2.4 KiB
Go
152 lines
2.4 KiB
Go
package tea
|
|
|
|
import (
|
|
"bytes"
|
|
"sync/atomic"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type incrementMsg struct{}
|
|
|
|
type testModel struct {
|
|
executed atomic.Value
|
|
counter atomic.Value
|
|
}
|
|
|
|
func (m testModel) Init() Cmd {
|
|
return nil
|
|
}
|
|
|
|
func (m *testModel) Update(msg Msg) (Model, Cmd) {
|
|
switch msg.(type) {
|
|
case incrementMsg:
|
|
i := m.counter.Load()
|
|
if i == nil {
|
|
m.counter.Store(1)
|
|
} else {
|
|
m.counter.Store(i.(int) + 1)
|
|
}
|
|
|
|
case KeyMsg:
|
|
return m, Quit
|
|
}
|
|
|
|
return m, nil
|
|
}
|
|
|
|
func (m *testModel) View() string {
|
|
m.executed.Store(true)
|
|
return "success\n"
|
|
}
|
|
|
|
func TestTeaModel(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
var in bytes.Buffer
|
|
in.Write([]byte("q"))
|
|
|
|
p := NewProgram(&testModel{}, WithInput(&in), WithOutput(&buf))
|
|
if _, err := p.Run(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if buf.Len() == 0 {
|
|
t.Fatal("no output")
|
|
}
|
|
}
|
|
|
|
func TestTeaQuit(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
var in bytes.Buffer
|
|
|
|
m := &testModel{}
|
|
p := NewProgram(m, WithInput(&in), WithOutput(&buf))
|
|
go func() {
|
|
for {
|
|
time.Sleep(time.Millisecond)
|
|
if m.executed.Load() != nil {
|
|
p.Quit()
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
if _, err := p.Run(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestTeaKill(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
var in bytes.Buffer
|
|
|
|
m := &testModel{}
|
|
p := NewProgram(m, WithInput(&in), WithOutput(&buf))
|
|
go func() {
|
|
for {
|
|
time.Sleep(time.Millisecond)
|
|
if m.executed.Load() != nil {
|
|
p.Kill()
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
if _, err := p.Run(); err != ErrProgramKilled {
|
|
t.Fatalf("Expected %v, got %v", ErrProgramKilled, err)
|
|
}
|
|
}
|
|
|
|
func TestTeaBatchMsg(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
var in bytes.Buffer
|
|
|
|
inc := func() Msg {
|
|
return incrementMsg{}
|
|
}
|
|
|
|
m := &testModel{}
|
|
p := NewProgram(m, WithInput(&in), WithOutput(&buf))
|
|
go func() {
|
|
p.Send(batchMsg{inc, inc})
|
|
|
|
for {
|
|
time.Sleep(time.Millisecond)
|
|
i := m.counter.Load()
|
|
if i != nil && i.(int) >= 2 {
|
|
p.Quit()
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
if _, err := p.Run(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if m.counter.Load() != 2 {
|
|
t.Fatalf("counter should be 2, got %d", m.counter.Load())
|
|
}
|
|
}
|
|
|
|
func TestTeaSequenceMsg(t *testing.T) {
|
|
var buf bytes.Buffer
|
|
var in bytes.Buffer
|
|
|
|
inc := func() Msg {
|
|
return incrementMsg{}
|
|
}
|
|
|
|
m := &testModel{}
|
|
p := NewProgram(m, WithInput(&in), WithOutput(&buf))
|
|
go p.Send(sequenceMsg{inc, inc, Quit})
|
|
|
|
if _, err := p.Run(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if m.counter.Load() != 2 {
|
|
t.Fatalf("counter should be 2, got %d", m.counter.Load())
|
|
}
|
|
}
|