From b1afac56bbdb6b89352d54abae2653029d033f95 Mon Sep 17 00:00:00 2001 From: Virgil Date: Thu, 2 Apr 2026 13:24:23 +0000 Subject: [PATCH] fix(cli): add explicit output setters Co-Authored-By: Virgil --- pkg/cli/frame.go | 9 +++++++++ pkg/cli/frame_test.go | 10 ++++++++++ pkg/cli/tracker.go | 9 +++++++++ pkg/cli/tracker_test.go | 14 ++++++++++++-- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/pkg/cli/frame.go b/pkg/cli/frame.go index ff9be95..7219a78 100644 --- a/pkg/cli/frame.go +++ b/pkg/cli/frame.go @@ -70,6 +70,15 @@ func NewFrame(variant string) *Frame { } } +// WithOutput sets the destination writer for rendered output. +// Pass nil to keep the current writer unchanged. +func (f *Frame) WithOutput(out io.Writer) *Frame { + if out != nil { + f.out = out + } + return f +} + // Header sets the Header region model. func (f *Frame) Header(m Model) *Frame { f.setModel(RegionHeader, m); return f } diff --git a/pkg/cli/frame_test.go b/pkg/cli/frame_test.go index 5efbb97..aafcbc6 100644 --- a/pkg/cli/frame_test.go +++ b/pkg/cli/frame_test.go @@ -142,6 +142,16 @@ func TestFrame_Good(t *testing.T) { f := NewFrame("C") assert.Same(t, os.Stderr, f.out) }) + + t.Run("WithOutput sets output writer", func(t *testing.T) { + var buf bytes.Buffer + f := NewFrame("C").WithOutput(&buf) + f.Content(StaticModel("timed")) + + f.Run() + + assert.Contains(t, buf.String(), "timed") + }) } func TestFrame_Bad(t *testing.T) { diff --git a/pkg/cli/tracker.go b/pkg/cli/tracker.go index 681a3f1..d92ee31 100644 --- a/pkg/cli/tracker.go +++ b/pkg/cli/tracker.go @@ -123,6 +123,15 @@ func NewTaskTracker() *TaskTracker { return &TaskTracker{out: os.Stderr} } +// WithOutput sets the destination writer for tracker output. +// Pass nil to keep the current writer unchanged. +func (tr *TaskTracker) WithOutput(out io.Writer) *TaskTracker { + if out != nil { + tr.out = out + } + return tr +} + // Add registers a task and returns it for goroutine use. func (tr *TaskTracker) Add(name string) *TrackedTask { t := &TrackedTask{ diff --git a/pkg/cli/tracker_test.go b/pkg/cli/tracker_test.go index 98122e9..f8d37f3 100644 --- a/pkg/cli/tracker_test.go +++ b/pkg/cli/tracker_test.go @@ -121,8 +121,7 @@ func TestTaskTracker_Good(t *testing.T) { t.Run("wait completes for non-TTY", func(t *testing.T) { var buf bytes.Buffer - tr := NewTaskTracker() - tr.out = &buf + tr := NewTaskTracker().WithOutput(&buf) task := tr.Add("quick") go func() { @@ -135,6 +134,17 @@ func TestTaskTracker_Good(t *testing.T) { assert.Contains(t, buf.String(), "done") }) + t.Run("WithOutput sets output writer", func(t *testing.T) { + var buf bytes.Buffer + tr := NewTaskTracker().WithOutput(&buf) + + tr.Add("quick").Done("done") + tr.Wait() + + assert.Contains(t, buf.String(), "quick") + assert.Contains(t, buf.String(), "done") + }) + t.Run("name width alignment", func(t *testing.T) { tr := NewTaskTracker() tr.out = &bytes.Buffer{}