Explain invocation presentation failures

This commit is contained in:
2026-10-26 14:28:58 +00:00
parent 215fc34d51
commit 13a4d4eacd
7 changed files with 96 additions and 13 deletions

View File

@@ -1,12 +1,67 @@
package commandkit
import (
"bytes"
"errors"
"fmt"
"io"
"strings"
"testing"
)
func TestReporterExplainsItsOwnFailuresWithoutExposingCauses(t *testing.T) {
for _, kind := range []string{"output", "diagnostics"} {
for _, quiet := range []bool{false, true} {
t.Run(fmt.Sprintf("%s/quiet=%t", kind, quiet), func(t *testing.T) {
var diagnostics bytes.Buffer
reporter := newReporter(Streams{Err: &diagnostics})
if quiet {
reporter.setVisibility(modeQuiet, false, false)
}
failure := errors.New("private rendering detail")
render := func(io.Writer) error { return failure }
if kind == "output" {
_ = reporter.RenderOutput(render)
} else {
_ = reporter.Warn("", render)
}
cause := errors.New("private application cause")
got := reporter.finalize(Domain("example", 0).WithCause(cause), nil)
if got.Kind != OutcomeDomain || got.Status != 1 || got.Cause != cause {
t.Fatalf("outcome=%#v", got)
}
if !strings.Contains(got.Explanation.Message, "render") || !strings.Contains(got.Explanation.Message, kind) || !strings.Contains(diagnostics.String(), got.Explanation.Message) {
t.Fatalf("explanation=%#v diagnostics=%q", got.Explanation, diagnostics.String())
}
if strings.Contains(diagnostics.String(), "private") {
t.Fatalf("private error text was exposed: %q", diagnostics.String())
}
})
}
}
}
func TestReporterPreservesExplicitSuccessExplanationOnPresentationFailure(t *testing.T) {
for _, message := range []string{"supplied context", ""} {
t.Run(message, func(t *testing.T) {
var diagnostics bytes.Buffer
reporter := newReporter(Streams{Err: &diagnostics})
_ = reporter.RenderOutput(func(io.Writer) error { return errors.New("render failed") })
calls := 0
got := reporter.finalize(Success().WithExplanation(message, func(io.Writer) error {
calls++
return nil
}), nil)
if got.Status != 1 || got.Explanation.Message != message || calls != 1 {
t.Fatalf("outcome=%#v calls=%d", got, calls)
}
if message == "" && diagnostics.Len() != 0 {
t.Fatalf("explicit zero-byte explanation replaced: %q", diagnostics.String())
}
})
}
}
func TestReporterPreservesJoinedRendererEvidence(t *testing.T) {
for _, kind := range []string{"output", "detail"} {
for _, test := range []struct {