A panic in Update returned a nil model, so Bubble Tea panicked drawing it and printed its own stack over 012's crash lines. The e2e check compares the crash lines without the whitespace a wrap drops.
- commit
- 0f539e254fd5a385804c43de764f4232f6e3c3cc
- parent
- 2d1e1fb2d8d09e471cb37b9426192006a66cc925
- author
- Dami <dami.etoile@gmail.com>
- kind
- fix risk score 1.3 of 3, Jev's estimate
| M | e2e/ | 7 | +++++-- |
| M | internal/ | 8 | ++++---- |
| M | internal/ | 7 | ++++++- |
@@ -33,7 +33,10 @@ func TestPanicKeepsWork(t *testing.T) {
3333 if !visible {3434 t.Error("the cursor is hidden after the crash")3535 }36- text := strings.ReplaceAll(s.screen(), "\n", "")36+ // The lines wrap at the terminal's width, dropping the space a37+ // line ends on, so compare without whitespace.38+ flat := func(s string) string { return strings.Join(strings.Fields(s), "") }39+ text := flat(s.screen())3740 recovery, _ := filepath.Glob(filepath.Join(dir, ".config", "012", "recovery", "*budget-*.012"))3841 reports, _ := filepath.Glob(filepath.Join(dir, ".config", "012", "crashes", "crash-*.txt"))3942 if len(recovery) != 1 || len(reports) != 1 {@@ -41,7 +44,7 @@ func TestPanicKeepsWork(t *testing.T) {
4144 }4245 for _, want := range []string{"012: stopped on an internal error (a panic in " + strings.Replace(where, "command", "a command", 1), "unsaved changes kept in " + recovery[0] + "; open budget.012 again to restore them",4346 "a report is in " + reports[0]} {44- if !strings.Contains(text, want) {47+ if !strings.Contains(text, flat(want)) {4548 t.Errorf("the screen lacks %q:\n%s", want, s.screen())4649 }4750 }@@ -68,7 +68,7 @@ func (g *Guarded) Init() (cmd tea.Cmd) {
6868 }6969 7070 // Update implements tea.Model.71-func (g *Guarded) Update(msg tea.Msg) (_ tea.Model, cmd tea.Cmd) {71+func (g *Guarded) Update(msg tea.Msg) (next tea.Model, cmd tea.Cmd) {7272 if c, ok := msg.(crashMsg); ok {7373 if g.crash == nil {7474 g.crash = c.crash@@ -81,7 +81,7 @@ func (g *Guarded) Update(msg tea.Msg) (_ tea.Model, cmd tea.Cmd) {
8181 defer func() {8282 if r := recover(); r != nil {8383 g.crash = caught("update", r)84- cmd = tea.Quit84+ next, cmd = g, tea.Quit // never nil: Bubble Tea draws what Update returns8585 }8686 }()8787 if crashTest != nil {@@ -89,8 +89,8 @@ func (g *Guarded) Update(msg tea.Msg) (_ tea.Model, cmd tea.Cmd) {
8989 return g, c9090 }9191 }92- next, cmd := g.m.Update(msg)93- if m, ok := next.(*Model); ok {92+ inner, cmd := g.m.Update(msg)93+ if m, ok := inner.(*Model); ok {9494 g.m = m9595 }9696 return g, g.guard(cmd)@@ -48,9 +48,14 @@ func TestGuardUpdatePanicKeepsWork(t *testing.T) {
4848 m.filename = "book.012"4949 press(t, m, "mine", "<enter>")5050 g := Guard(m)51- if _, cmd := g.Update(f12); !isQuit(cmd) {51+ next, cmd := g.Update(f12)52+ if !isQuit(cmd) {5253 t.Fatal("a panic in Update didn't quit")5354 }55+ if next != g {56+ t.Fatalf("Update returned %v after a panic; Bubble Tea draws what it returns", next)57+ }58+ next.View()5459 if _, cmd := g.Update(tea.KeyPressMsg{Code: 'x', Text: "x"}); cmd != nil {5560 t.Error("a crashed model took more input")5661 }