From 25022e9789dd7038bb87cb2c37c2d758c7cbbe05 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Fri, 5 May 2023 16:14:26 -0300 Subject: [PATCH] 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 * feat: teatest Signed-off-by: Carlos A Becker * fix: improve api Signed-off-by: Carlos A Becker * fix: improve api Signed-off-by: Carlos A Becker * feat: goldenfiles Signed-off-by: Carlos A Becker * chore: minor improvements Signed-off-by: Carlos A Becker * feat: type text, diff Signed-off-by: Carlos A Becker * fix: release terminal Signed-off-by: Carlos A Becker * fix: lint Signed-off-by: Carlos A Becker * fix: update cancelreader Signed-off-by: Carlos A Becker * fix: make it safe Signed-off-by: Carlos A Becker * feat: functional options Signed-off-by: Carlos A Becker * feat: IsQuit and IsQuitMsg * fix: save file Signed-off-by: Carlos A Becker * fix: do not use deprecate func Signed-off-by: Carlos A Becker * fix: make diff not complain about trailing whitespaces Signed-off-by: Carlos A Becker * feat: with term size Signed-off-by: Carlos A Becker * feat: RequireRegexOutput Signed-off-by: Carlos A Becker * fix: update Signed-off-by: Carlos A Becker * chore: rename Signed-off-by: Carlos A Becker * fix: improve reliability * fix: use returned model * fix: making it more predictable, avoid sleeps * fix: remove WithRequiredRegexpOutput Signed-off-by: Carlos A Becker * fix: allow to assert within interactions * feat: added wait for Signed-off-by: Carlos A Becker * fix: optional * feat: improve usage Signed-off-by: Carlos A Becker * fix: use udiff Signed-off-by: Carlos A Becker * feat: tea.Wait wait for the underlying context to finish. extract from #352 * fix: merge Signed-off-by: Carlos A Becker * fix: wait til the end of shutdown Signed-off-by: Carlos Alexandro Becker * fix: final output * feat: use x/exp/teatest Signed-off-by: Carlos Alexandro Becker * chore: go mod tidy Signed-off-by: Carlos Alexandro Becker --------- Signed-off-by: Carlos A Becker Signed-off-by: Carlos Alexandro Becker --- examples/go.mod | 6 +- examples/go.sum | 6 ++ examples/simple/main_test.go | 86 +++++++++++++++++++++++++ examples/simple/testdata/TestApp.golden | 3 + 4 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 examples/simple/main_test.go create mode 100644 examples/simple/testdata/TestApp.golden diff --git a/examples/go.mod b/examples/go.mod index 1183e5e..4d12f76 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -4,11 +4,11 @@ go 1.17 require ( 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/harmonica v0.2.0 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/lucasb-eyer/go-colorful v1.2.0 github.com/mattn/go-isatty v0.0.18 @@ -20,9 +20,11 @@ require ( github.com/alecthomas/chroma v0.10.0 // indirect github.com/atotto/clipboard v0.1.4 // 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/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // 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/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect diff --git a/examples/go.sum b/examples/go.sum index cce9745..bc3e500 100644 --- a/examples/go.sum +++ b/examples/go.sum @@ -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/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= 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/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= 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.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= 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/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= diff --git a/examples/simple/main_test.go b/examples/simple/main_test.go new file mode 100644 index 0000000..f736de7 --- /dev/null +++ b/examples/simple/main_test.go @@ -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 +} diff --git a/examples/simple/testdata/TestApp.golden b/examples/simple/testdata/TestApp.golden new file mode 100644 index 0000000..0a973b2 --- /dev/null +++ b/examples/simple/testdata/TestApp.golden @@ -0,0 +1,3 @@ +[?25lHi. This program will exit in 10 seconds. To quit sooner press any key +Hi. This program will exit in 9 seconds. To quit sooner press any key. +[?25h[?1002l[?1003l \ No newline at end of file