forked from Mirrors/bubbletea
example: using the x/exp/teatest package (#352)
teatest was originally designed in this PR, and was later moved into `github.com/charmbracelet/x`. * docs: example test Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: teatest Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: improve api Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: improve api Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: goldenfiles Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * chore: minor improvements Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: type text, diff Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: release terminal Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: lint Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: update cancelreader Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: make it safe Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: functional options Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: IsQuit and IsQuitMsg * fix: save file Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: do not use deprecate func Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: make diff not complain about trailing whitespaces Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: with term size Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: RequireRegexOutput Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: update Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * chore: rename Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: improve reliability * fix: use returned model * fix: making it more predictable, avoid sleeps * fix: remove WithRequiredRegexpOutput Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: allow to assert within interactions * feat: added wait for Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: optional * feat: improve usage Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: use udiff Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * feat: tea.Wait wait for the underlying context to finish. extract from #352 * fix: merge Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix: wait til the end of shutdown Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * fix: final output * feat: use x/exp/teatest Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> * chore: go mod tidy Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com> --------- Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> Signed-off-by: Carlos Alexandro Becker <caarlos0@users.noreply.github.com>
This commit is contained in:
parent
5326d76c40
commit
25022e9789
|
@ -4,11 +4,11 @@ go 1.17
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/charmbracelet/bubbles v0.15.1-0.20230306155959-3372cf1aea2b
|
github.com/charmbracelet/bubbles v0.15.1-0.20230306155959-3372cf1aea2b
|
||||||
github.com/charmbracelet/bubbletea v0.23.2
|
github.com/charmbracelet/bubbletea v0.23.3-0.20230504193325-5326d76c402a
|
||||||
github.com/charmbracelet/glamour v0.6.0
|
github.com/charmbracelet/glamour v0.6.0
|
||||||
github.com/charmbracelet/harmonica v0.2.0
|
github.com/charmbracelet/harmonica v0.2.0
|
||||||
github.com/charmbracelet/lipgloss v0.7.1
|
github.com/charmbracelet/lipgloss v0.7.1
|
||||||
github.com/dustin/go-humanize v1.0.1
|
github.com/charmbracelet/x/exp/teatest v0.0.0-20230505175841-25a09ea9b713
|
||||||
github.com/fogleman/ease v0.0.0-20170301025033-8da417bf1776
|
github.com/fogleman/ease v0.0.0-20170301025033-8da417bf1776
|
||||||
github.com/lucasb-eyer/go-colorful v1.2.0
|
github.com/lucasb-eyer/go-colorful v1.2.0
|
||||||
github.com/mattn/go-isatty v0.0.18
|
github.com/mattn/go-isatty v0.0.18
|
||||||
|
@ -20,9 +20,11 @@ require (
|
||||||
github.com/alecthomas/chroma v0.10.0 // indirect
|
github.com/alecthomas/chroma v0.10.0 // indirect
|
||||||
github.com/atotto/clipboard v0.1.4 // indirect
|
github.com/atotto/clipboard v0.1.4 // indirect
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||||
|
github.com/aymanbagabas/go-udiff v0.1.0 // indirect
|
||||||
github.com/aymerick/douceur v0.2.0 // indirect
|
github.com/aymerick/douceur v0.2.0 // indirect
|
||||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect
|
||||||
github.com/dlclark/regexp2 v1.4.0 // indirect
|
github.com/dlclark/regexp2 v1.4.0 // indirect
|
||||||
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||||
github.com/gorilla/css v1.0.0 // indirect
|
github.com/gorilla/css v1.0.0 // indirect
|
||||||
github.com/mattn/go-localereader v0.0.1 // indirect
|
github.com/mattn/go-localereader v0.0.1 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.14 // indirect
|
github.com/mattn/go-runewidth v0.0.14 // indirect
|
||||||
|
|
|
@ -7,6 +7,8 @@ github.com/aymanbagabas/go-osc52 v1.2.1 h1:q2sWUyDcozPLcLabEMd+a+7Ea2DitxZVN9hTx
|
||||||
github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
|
github.com/aymanbagabas/go-osc52 v1.2.1/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||||
|
github.com/aymanbagabas/go-udiff v0.1.0 h1:9Dpklm2oBBhMxIFbMffmPvDaF7vOYfv9B5HXVr42KMU=
|
||||||
|
github.com/aymanbagabas/go-udiff v0.1.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
|
||||||
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk=
|
||||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||||
github.com/charmbracelet/bubbles v0.15.1-0.20230306155959-3372cf1aea2b h1:K9dWJ2spDhDhIrqnchjG867djPxWWe3mwdk6RdLMfhg=
|
github.com/charmbracelet/bubbles v0.15.1-0.20230306155959-3372cf1aea2b h1:K9dWJ2spDhDhIrqnchjG867djPxWWe3mwdk6RdLMfhg=
|
||||||
|
@ -18,6 +20,10 @@ github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJ
|
||||||
github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk=
|
github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk=
|
||||||
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
|
github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
|
||||||
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
|
github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
|
||||||
|
github.com/charmbracelet/x/exp/teatest v0.0.0-20230504195420-fee909365d1c h1:3Dha70yq12co31grOoSMOaBIo8POU4ARhvp9W8RsOsw=
|
||||||
|
github.com/charmbracelet/x/exp/teatest v0.0.0-20230504195420-fee909365d1c/go.mod h1:dpMo6PfGlhavn+ofggWhfFQmK9sZB2Ewljiz9bZtKVI=
|
||||||
|
github.com/charmbracelet/x/exp/teatest v0.0.0-20230505175841-25a09ea9b713 h1:aRUlesfHrzj9NECuQ1O2h1yBK5M4LFKwLYTQVoEkaQ8=
|
||||||
|
github.com/charmbracelet/x/exp/teatest v0.0.0-20230505175841-25a09ea9b713/go.mod h1:dpMo6PfGlhavn+ofggWhfFQmK9sZB2Ewljiz9bZtKVI=
|
||||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
|
||||||
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|
|
@ -0,0 +1,86 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"io"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
tea "github.com/charmbracelet/bubbletea"
|
||||||
|
"github.com/charmbracelet/x/exp/teatest"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestApp(t *testing.T) {
|
||||||
|
m := model(10)
|
||||||
|
tm := teatest.NewTestModel(
|
||||||
|
t, m,
|
||||||
|
teatest.WithInitialTermSize(70, 30),
|
||||||
|
)
|
||||||
|
t.Cleanup(func() {
|
||||||
|
if err := tm.Quit(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
time.Sleep(time.Second + time.Millisecond*200)
|
||||||
|
tm.Type("I'm typing things, but it'll be ignored by my program")
|
||||||
|
tm.Send("ignored msg")
|
||||||
|
tm.Send(tea.KeyMsg{
|
||||||
|
Type: tea.KeyEnter,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := tm.Quit(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
out := readBts(t, tm.FinalOutput())
|
||||||
|
if !regexp.MustCompile(`This program will exit in \d+ seconds`).Match(out) {
|
||||||
|
t.Fatalf("output does not match the given regular expression: %s", string(out))
|
||||||
|
}
|
||||||
|
teatest.RequireEqualOutput(t, out)
|
||||||
|
|
||||||
|
if tm.FinalModel().(model) != 9 {
|
||||||
|
t.Errorf("expected model to be 10, was %d", m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppInteractive(t *testing.T) {
|
||||||
|
m := model(10)
|
||||||
|
tm := teatest.NewTestModel(
|
||||||
|
t, m,
|
||||||
|
teatest.WithInitialTermSize(70, 30),
|
||||||
|
)
|
||||||
|
|
||||||
|
time.Sleep(time.Second + time.Millisecond*200)
|
||||||
|
tm.Send("ignored msg")
|
||||||
|
|
||||||
|
if bts := readBts(t, tm.Output()); !bytes.Contains(bts, []byte("This program will exit in 9 seconds")) {
|
||||||
|
t.Fatalf("output does not match: expected %q", string(bts))
|
||||||
|
}
|
||||||
|
|
||||||
|
teatest.WaitFor(t, tm.Output(), func(out []byte) bool {
|
||||||
|
return bytes.Contains(out, []byte("This program will exit in 7 seconds"))
|
||||||
|
}, teatest.WithDuration(5*time.Second))
|
||||||
|
|
||||||
|
tm.Send(tea.KeyMsg{
|
||||||
|
Type: tea.KeyEnter,
|
||||||
|
})
|
||||||
|
|
||||||
|
if err := tm.Quit(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if tm.FinalModel().(model) != 7 {
|
||||||
|
t.Errorf("expected model to be 7, was %d", m)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func readBts(tb testing.TB, r io.Reader) []byte {
|
||||||
|
tb.Helper()
|
||||||
|
bts, err := io.ReadAll(r)
|
||||||
|
if err != nil {
|
||||||
|
tb.Fatal(err)
|
||||||
|
}
|
||||||
|
return bts
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
[?25lHi. This program will exit in 10 seconds. To quit sooner press any key
|
||||||
|
[70D[1A[70D[2KHi. This program will exit in 9 seconds. To quit sooner press any key.
|
||||||
|
[70D[2K[?25h[?1002l[?1003l
|
Loading…
Reference in New Issue