fix(bonfire): end a live view when its context is cancelled and print later lines plainly (WR-09)

This commit is contained in:
Jakub Zych
2026-10-22 03:56:37 +02:00
parent 1ac75ad59a
commit fce232d7c3
5 changed files with 121 additions and 9 deletions

View File

@@ -655,3 +655,60 @@ func TestNestedProcessBuildsNoProgram(t *testing.T) {
t.Errorf("the item's success line is missing:\n%s", ansi.Strip(out.String()))
}
}
// TestPrintAboveAfterCancel (WR-09): cancelling the context given to
// Process ends its view and unregisters it without waiting for the work
// function; the lines printed afterwards through Println, Info and
// bonfire.PrintAbove (which reports false, so the caller prints the line
// itself, as diary does) are printed plainly once each, none lost.
func TestPrintAboveAfterCancel(t *testing.T) {
out := &lockedBuffer{}
c := newConsole(strings.NewReader(""), out, io.Discard, noEnv, boolPtr(true), boolPtr(true))
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var got []string
err := Process(ctx, c, "Pushing", []string{"first", "second", "third"}, func(_ context.Context, item string) error {
got = append(got, item)
if item != "second" {
return nil
}
cancel()
registered := true
for deadline := time.Now().Add(2 * time.Second); time.Now().Before(deadline); time.Sleep(5 * time.Millisecond) {
liveMu.Lock()
registered = activeView != nil
liveMu.Unlock()
if !registered {
break
}
}
if registered {
t.Errorf("view still registered 2s after the cancellation")
}
c.Println("after-cancel-println")
c.Info("after-cancel-info")
if PrintAbove("after-cancel-printabove") {
t.Errorf("PrintAbove reported true after the cancellation")
} else {
_, _ = io.WriteString(out, "after-cancel-printabove\n")
}
return nil
})
if !errors.Is(err, context.Canceled) {
t.Errorf("Process returned %v, want context.Canceled", err)
}
for _, item := range got {
if item == "third" {
t.Error("fn ran for the item after the cancellation")
}
}
plain := ansi.Strip(out.String())
for _, line := range []string{"after-cancel-println", "after-cancel-info", "after-cancel-printabove"} {
if n := strings.Count(plain, line); n != 1 {
t.Errorf("%q printed %d times, want 1:\n%s", line, n, plain)
}
}
if PrintAbove("after") {
t.Error("a view is still registered after Process returned")
}
}